diff --git a/EvtGen/EvtGen.hh b/EvtGen/EvtGen.hh index ec154e2..673bdd1 100644 --- a/EvtGen/EvtGen.hh +++ b/EvtGen/EvtGen.hh @@ -1,72 +1,73 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #ifndef EVTGEN_HH #define EVTGEN_HH #include "EvtGenBase/EvtPDL.hh" #include #include class EvtParticle; class EvtRandomEngine; class EvtVector4R; class EvtStdHep; class EvtSpinDensity; class EvtAbsRadCorr; class EvtDecayBase; class EvtHepMCEvent; class EvtGen { public: EvtGen( const std::string& decayName, const std::string& pdtTableName, - EvtRandomEngine* randomEngine = 0, EvtAbsRadCorr* isrEngine = 0, - const std::list* extraModels = 0, int mixingType = 1, - bool useXml = false ); + EvtRandomEngine* randomEngine = nullptr, + EvtAbsRadCorr* isrEngine = nullptr, + const std::list* extraModels = nullptr, + int mixingType = 1, bool useXml = false ); EvtGen( const std::string& decayName, std::istream& pdtTableData, - EvtRandomEngine* randomEngine = 0, EvtAbsRadCorr* isrEngine = 0, - const std::list* extraModels = 0, int mixingType = 1, - bool useXml = false ); + EvtRandomEngine* randomEngine = nullptr, + EvtAbsRadCorr* isrEngine = nullptr, + const std::list* extraModels = nullptr, + int mixingType = 1, bool useXml = false ); ~EvtGen(); void readUDecay( const std::string& udecay_name, bool useXml = false ); EvtHepMCEvent* generateDecay( int PDGid, EvtVector4R refFrameP4, EvtVector4R translation, - EvtSpinDensity* spinDensity = 0 ); + EvtSpinDensity* spinDensity = nullptr ); void generateDecay( EvtParticle* p ); private: - void initialize( const std::string& decayName, std::istream& pdtTable, - EvtRandomEngine* randomEngine = 0, - EvtAbsRadCorr* isrEngine = 0, - const std::list* extraModels = 0, + EvtRandomEngine* randomEngine = nullptr, + EvtAbsRadCorr* isrEngine = nullptr, + const std::list* extraModels = nullptr, int mixingType = 1, bool useXml = false ); EvtPDL _pdl; int _mixingType; }; #endif diff --git a/EvtGenBase/EvtModel.hh b/EvtGenBase/EvtModel.hh index 4551562..36d79fa 100644 --- a/EvtGenBase/EvtModel.hh +++ b/EvtGenBase/EvtModel.hh @@ -1,63 +1,63 @@ /*********************************************************************** * 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 EVTMODEL_HH #define EVTMODEL_HH #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtStringHash.hh" #include //#include //Class to read in and handle the decays available //to EvtGen for each particle, and the model to be //used for each one. class EvtModel { public: static EvtModel& instance(); void registerModel( EvtDecayBase* prototype ); int isModel( std::string name ); EvtDecayBase* getFcn( std::string model_name ); int isCommand( std::string cmd ); void storeCommand( std::string cmd, std::string cnfgstr ); private: EvtModel(); static EvtModel* _instance; std::map _modelNameHash; std::map _commandNameHash; }; inline EvtModel& EvtModel::instance() { - if ( _instance == 0 ) + if ( _instance == nullptr ) _instance = new EvtModel; return *_instance; } #endif diff --git a/EvtGenBase/EvtParticle.hh b/EvtGenBase/EvtParticle.hh index 084cb9f..42b28bf 100644 --- a/EvtGenBase/EvtParticle.hh +++ b/EvtGenBase/EvtParticle.hh @@ -1,503 +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 . * ***********************************************************************/ #ifndef EVTPARTICLE_HH #define EVTPARTICLE_HH #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( const int i ) { return _daug[i]; } /** * Get const pointer the the i:th daugther. */ const EvtParticle* getDaug( const int i ) const { return _daug[i]; } /** * Iterates over the particles in a decay chain. */ - EvtParticle* nextIter( EvtParticle* rootOfTree = 0 ); + EvtParticle* nextIter( EvtParticle* rootOfTree = nullptr ); /** * 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() const; /** * 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 // FIXME - this should probably be changed to std::optional const double* decayProb() const { return _decayProb; } void setDecayProb( double p ); // Return the name of the particle (from the EvtId number) std::string getName() const; // 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/EvtGenBase/EvtParticleDecay.hh b/EvtGenBase/EvtParticleDecay.hh index e2030d8..4a3393e 100644 --- a/EvtGenBase/EvtParticleDecay.hh +++ b/EvtGenBase/EvtParticleDecay.hh @@ -1,59 +1,59 @@ /*********************************************************************** * 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 EVTPARTICLEDECAY_HH #define EVTPARTICLEDECAY_HH #include "EvtGenBase/EvtDecayBase.hh" class EvtParticleDecay { public: EvtParticleDecay() { - _decay = 0; + _decay = nullptr; _brfrsum = 0.0; _massmin = 0.0; } ~EvtParticleDecay() { - if ( _decay != 0 ) + if ( _decay != nullptr ) delete _decay; } void chargeConj( EvtParticleDecay* decay ); void setDecayModel( EvtDecayBase* decay ) { _decay = decay; } EvtDecayBase* getDecayModel() { return _decay; } double getBrfrSum() { return _brfrsum; } void setBrfrSum( double brfrsum ) { _brfrsum = brfrsum; } double getMassMin() { return _massmin; } void setMassMin( double massmin ) { _massmin = massmin; } void printSummary(); private: EvtDecayBase* _decay; double _brfrsum; double _massmin; }; #endif diff --git a/EvtGenBase/EvtParticleDecayList.hh b/EvtGenBase/EvtParticleDecayList.hh index 029d6ab..796959d 100644 --- a/EvtGenBase/EvtParticleDecayList.hh +++ b/EvtGenBase/EvtParticleDecayList.hh @@ -1,80 +1,80 @@ /*********************************************************************** * 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 EVTPARTICLEDECAYLIST_HH #define EVTPARTICLEDECAYLIST_HH #include "EvtGenBase/EvtParticleDecay.hh" typedef EvtParticleDecay* EvtParticleDecayPtr; class EvtParticleDecayList { public: EvtParticleDecayList() { - _decaylist = 0; + _decaylist = nullptr; _nmode = 0; _rawbrfrsum = 0; } EvtParticleDecayList( const EvtParticleDecayList& o ); ~EvtParticleDecayList(); EvtParticleDecayList& operator=( const EvtParticleDecayList& o ); int getNMode() const { return _nmode; } void setNMode( int nmode ); EvtDecayBase* getDecayModel( EvtParticle* p ); EvtDecayBase* getDecayModel( int imode ); EvtParticleDecay& getDecay( int nchannel ) const; double getRawBrfrSum() { return _rawbrfrsum; } void setRawBrfrSum( double rawbrfrsum ) { _rawbrfrsum = rawbrfrsum; } void makeChargeConj( EvtParticleDecayList* conjDecayList ); void removeDecay(); void alocateDecay( int nmode ) { _decaylist = new EvtParticleDecayPtr[nmode]; } void removeMode( EvtDecayBase* decay ); void addMode( EvtDecayBase* decay, double brfr, double massmin ); void finalize(); void printSummary(); bool isJetSet() const; private: EvtParticleDecayPtr* _decaylist; double _rawbrfrsum; int _nmode; }; #endif diff --git a/EvtGenBase/EvtPdf.hh b/EvtGenBase/EvtPdf.hh index 25f3bf9..28894e9 100644 --- a/EvtGenBase/EvtPdf.hh +++ b/EvtGenBase/EvtPdf.hh @@ -1,340 +1,340 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #ifndef EVT_PDF_HH #define EVT_PDF_HH #include "EvtGenBase/EvtMacros.hh" #include "EvtGenBase/EvtPdfMax.hh" #include "EvtGenBase/EvtPredGen.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtStreamInputIterator.hh" #include "EvtGenBase/EvtValError.hh" #include #include /* * All classes are templated on the point type T * * EvtPdf: * * Probability density function defined on an interval of phase-space. * Integral over the interval can be calculated by Monte Carlo integration. * Some (but not all) PDFs are analytic in the sense that they can be integrated * by numeric quadrature and distributions can be generated according to them. * * EvtPdfGen: * * Generator adaptor. Can be used to generate random points * distributed according to the PDF for analytic PDFs. * * EvtPdfPred: * * Predicate adaptor for PDFs. Can be used for generating random points distributed * according to the PDF for any PDF using rejection method. (See "Numerical Recipes"). * * EvtPdfUnary: * * Adapter for generic algorithms. Evaluates the PDF and returns the value * * EvtPdfDiv: * * PDF obtained by division of one PDF by another. Because the two PDFs are * arbitrary this PDF is not analytic. When importance sampling is used the * original PDF is divided by the analytic comparison function. EvtPdfDiv is * used to represent the modified PDF. */ template class EvtPdfPred; template class EvtPdfGen; template class EvtPdf { public: EvtPdf() {} EvtPdf( const EvtPdf& other ) : _itg( other._itg ) {} virtual ~EvtPdf() {} virtual EvtPdf* clone() const = 0; double evaluate( const T& p ) const { if ( p.isValid() ) return pdf( p ); else return 0.; } // Find PDF maximum. Points are sampled according to pc EvtPdfMax findMax( const EvtPdf& pc, int N ); // Find generation efficiency. EvtValError findGenEff( const EvtPdf& pc, int N, int nFindMax ); // Analytic integration. Calls cascade down until an overridden // method is called. void setItg( EvtValError itg ) { _itg = itg; } EvtValError getItg() const { if ( !_itg.valueKnown() ) _itg = compute_integral(); return _itg; } EvtValError getItg( int N ) const { if ( !_itg.valueKnown() ) _itg = compute_integral( N ); return _itg; } virtual EvtValError compute_integral() const { printf( "Analytic integration of PDF is not defined\n" ); assert( 0 ); return EvtValError{}; } virtual EvtValError compute_integral( int ) const { return compute_integral(); } // Monte Carlo integration. EvtValError compute_mc_integral( const EvtPdf& pc, int N ); // Generation. Create predicate accept-reject generators. // nMax iterations will be used to find the maximum of the accept-reject predicate EvtPredGen, EvtPdfPred> accRejGen( const EvtPdf& pc, int nMax, double factor = 1. ); virtual T randomPoint(); protected: virtual double pdf( const T& ) const = 0; mutable EvtValError _itg; }; template class EvtPdfGen { public: typedef T result_type; EvtPdfGen() : _pdf( 0 ) {} EvtPdfGen( const EvtPdfGen& other ) : - _pdf( other._pdf ? other._pdf->clone() : 0 ) + _pdf( other._pdf ? other._pdf->clone() : nullptr ) { } EvtPdfGen( const EvtPdf& pdf ) : _pdf( pdf.clone() ) {} ~EvtPdfGen() { delete _pdf; } result_type operator()() { return _pdf->randomPoint(); } private: EvtPdf* _pdf; }; template class EvtPdfPred { public: typedef T argument_type; typedef bool result_type; EvtPdfPred() {} EvtPdfPred( const EvtPdf& thePdf ) : itsPdf( thePdf.clone() ) {} EvtPdfPred( const EvtPdfPred& other ) : COPY_PTR( itsPdf ), COPY_MEM( itsPdfMax ) { } ~EvtPdfPred() { delete itsPdf; } result_type operator()( argument_type p ) { assert( itsPdf ); assert( itsPdfMax.valueKnown() ); double random = EvtRandom::Flat( 0., itsPdfMax.value() ); return ( random <= itsPdf->evaluate( p ) ); } EvtPdfMax getMax() const { return itsPdfMax; } void setMax( const EvtPdfMax& max ) { itsPdfMax = max; } template void compute_max( InputIterator it, InputIterator end, double factor = 1. ) { T p = *it++; itsPdfMax = EvtPdfMax( p, itsPdf->evaluate( p ) * factor ); while ( !( it == end ) ) { T p = *it++; double val = itsPdf->evaluate( p ) * factor; if ( val > itsPdfMax.value() ) itsPdfMax = EvtPdfMax( p, val ); } } private: EvtPdf* itsPdf; EvtPdfMax itsPdfMax; }; template class EvtPdfUnary { public: typedef double result_type; typedef T argument_type; EvtPdfUnary() {} EvtPdfUnary( const EvtPdf& thePdf ) : itsPdf( thePdf.clone() ) {} EvtPdfUnary( const EvtPdfUnary& other ) : COPY_PTR( itsPdf ) {} ~EvtPdfUnary() { delete itsPdf; } result_type operator()( argument_type p ) { assert( itsPdf ); double ret = itsPdf->evaluate( p ); return ret; } private: EvtPdf* itsPdf; }; template class EvtPdfDiv : public EvtPdf { public: EvtPdfDiv() : itsNum( 0 ), itsDen( 0 ) {} EvtPdfDiv( const EvtPdf& theNum, const EvtPdf& theDen ) : EvtPdf(), itsNum( theNum.clone() ), itsDen( theDen.clone() ) { } EvtPdfDiv( const EvtPdfDiv& other ) : EvtPdf( other ), COPY_PTR( itsNum ), COPY_PTR( itsDen ) { } virtual ~EvtPdfDiv() { delete itsNum; delete itsDen; } EvtPdf* clone() const override { return new EvtPdfDiv( *this ); } double pdf( const T& p ) const override { double num = itsNum->evaluate( p ); double den = itsDen->evaluate( p ); assert( den != 0 ); return num / den; } private: EvtPdf* itsNum; // numerator EvtPdf* itsDen; // denominator }; template EvtPdfMax EvtPdf::findMax( const EvtPdf& pc, int N ) { EvtPdfPred pred( *this ); EvtPdfGen gen( pc ); pred.compute_max( iter( gen, N ), iter( gen ) ); EvtPdfMax p = pred.getMax(); return p; } template EvtValError EvtPdf::findGenEff( const EvtPdf& pc, int N, int nFindMax ) { assert( N > 0 || nFindMax > 0 ); EvtPredGen, EvtPdfPred> gen = accRejGen( pc, nFindMax ); int i; for ( i = 0; i < N; i++ ) gen(); double eff = double( gen.getPassed() ) / double( gen.getTried() ); double err = sqrt( double( gen.getPassed() ) ) / double( gen.getTried() ); return EvtValError( eff, err ); } template EvtValError EvtPdf::compute_mc_integral( const EvtPdf& pc, int N ) { assert( N > 0 ); EvtPdfDiv pdfdiv( *this, pc ); EvtPdfUnary unary( pdfdiv ); EvtPdfGen gen( pc ); EvtStreamInputIterator begin = iter( gen, N ); EvtStreamInputIterator end; double sum = 0.; double sum2 = 0.; while ( !( begin == end ) ) { double value = pdfdiv.evaluate( *begin++ ); sum += value; sum2 += value * value; } EvtValError x; if ( N > 0 ) { double av = sum / ( (double)N ); if ( N > 1 ) { double dev2 = ( sum2 - av * av * N ) / ( (double)( N - 1 ) ); // Due to numerical precision dev2 may sometimes be negative if ( dev2 < 0. ) dev2 = 0.; double error = sqrt( dev2 / ( (double)N ) ); x = EvtValError( av, error ); } else x = EvtValError( av ); } _itg = x * pc.getItg(); return _itg; } template T EvtPdf::randomPoint() { printf( "Function defined for analytic PDFs only\n" ); assert( 0 ); T temp; return temp; } template EvtPredGen, EvtPdfPred> EvtPdf::accRejGen( const EvtPdf& pc, int nMax, double factor ) { EvtPdfGen gen( pc ); EvtPdfDiv pdfdiv( *this, pc ); EvtPdfPred pred( pdfdiv ); pred.compute_max( iter( gen, nMax ), iter( gen ), factor ); return EvtPredGen, EvtPdfPred>( gen, pred ); } #endif diff --git a/EvtGenBase/EvtReport.hh b/EvtGenBase/EvtReport.hh index 27d9b21..b7efe03 100644 --- a/EvtGenBase/EvtReport.hh +++ b/EvtGenBase/EvtReport.hh @@ -1,61 +1,62 @@ /*********************************************************************** * 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 . * ***********************************************************************/ #if !defined( TOOLBOX_FUNCTIONS_HH ) #define TOOLBOX_FUNCTIONS_HH #if !defined( FILENAME_ONLY ) /* relative path includes */ // system include files #include // user include files #else /* filename-only includes */ #include #include #endif /* filename-only includes */ // system include files // user include files // forward declarations // // constants, enums and typedefs // enum EvtGenSeverity { EVTGEN_EMERGENCY, // fatal EVTGEN_ALERT, // requires immediate action EVTGEN_CRITICAL, // serious EVTGEN_ERROR, EVTGEN_WARNING, EVTGEN_NOTICE, // "normal but significant" EVTGEN_INFO, // informational EVTGEN_DEBUG // debug }; // function declaration -std::ostream& EvtGenReport( EvtGenSeverity severity, const char* facility = 0 ); +std::ostream& EvtGenReport( EvtGenSeverity severity, + const char* facility = nullptr ); // inline function definitions #endif /* TOOLBOX_FUNCTIONS_HH */ diff --git a/EvtGenBase/EvtStreamInputIterator.hh b/EvtGenBase/EvtStreamInputIterator.hh index df9a38d..2c02260 100644 --- a/EvtGenBase/EvtStreamInputIterator.hh +++ b/EvtGenBase/EvtStreamInputIterator.hh @@ -1,117 +1,117 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #ifndef EVT_STREAM_INPUT_ITERATOR_HH #define EVT_STREAM_INPUT_ITERATOR_HH #include "EvtGenBase/EvtStreamAdapter.hh" #include #include using std::input_iterator_tag; // Adapters are used to convert various types of input streams // into an iteratable interface. template class EvtStreamInputIterator { public: typedef input_iterator_tag iterator_category; typedef Point value_type; typedef ptrdiff_t difference_type; typedef const Point* pointer; typedef const Point& reference; EvtStreamInputIterator() : _counter( 0 ) {} EvtStreamInputIterator( const EvtStreamInputIterator& other ) : - _counter( other._counter ? other._counter->clone() : 0 ), + _counter( other._counter ? other._counter->clone() : nullptr ), _currentValue( other._currentValue ) { } EvtStreamInputIterator( EvtStreamAdapter& counter ) : _counter( counter.clone() ) { _currentValue = _counter->currentValue(); } ~EvtStreamInputIterator() { if ( _counter ) delete _counter; } reference operator*() const { return _currentValue; } EvtStreamInputIterator& operator++() { _read(); return *this; } EvtStreamInputIterator operator++( int ) { EvtStreamInputIterator tmp = *this; _read(); return tmp; } bool operator==( const EvtStreamInputIterator& other ) const { // Equality is only defined for two past the end iterators return ( pastEnd() && other.pastEnd() ); } protected: EvtStreamAdapter* _counter; value_type _currentValue; bool pastEnd() const { bool ret = true; if ( _counter ) ret = _counter->pastEnd(); return ret; } // Advances the iterator void _read() { _counter->advance(); _currentValue = _counter->currentValue(); } }; // For adaptable generators these shorthand functions can be used // to construct iterators. template EvtStreamInputIterator iter( Generator gen, int N = 0 ) { typedef typename Generator::result_type Point; EvtGenStreamAdapter counter( gen, N ); return EvtStreamInputIterator( counter ); } #endif diff --git a/EvtGenModels/EvtIntervalDecayAmp.hh b/EvtGenModels/EvtIntervalDecayAmp.hh index 291cbaf..b5c820d 100644 --- a/EvtGenModels/EvtIntervalDecayAmp.hh +++ b/EvtGenModels/EvtIntervalDecayAmp.hh @@ -1,201 +1,201 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #ifndef EVT_INTERVAL_DECAY_AMP #define EVT_INTERVAL_DECAY_AMP #define VERBOSE true #include "EvtGenBase/EvtAmpFactory.hh" #include "EvtGenBase/EvtAmpPdf.hh" #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtCyclic3.hh" #include "EvtGenBase/EvtDecayAmp.hh" #include "EvtGenBase/EvtMacros.hh" #include "EvtGenBase/EvtMultiChannelParser.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPdf.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include // Decay model that uses the "amplitude on an interval" // templatization template class EvtIntervalDecayAmp : public EvtDecayAmp { public: - EvtIntervalDecayAmp() : _probMax( 0. ), _nScan( 0 ), _fact( 0 ) {} + EvtIntervalDecayAmp() : _probMax( 0. ), _nScan( 0 ), _fact( nullptr ) {} EvtIntervalDecayAmp( const EvtIntervalDecayAmp& other ) : _probMax( other._probMax ), _nScan( other._nScan ), COPY_PTR( _fact ) { } virtual ~EvtIntervalDecayAmp() { delete _fact; } // Initialize model void init() override { // Collect model parameters and parse them vector args; int i; for ( i = 0; i < getNArg(); i++ ) args.push_back( getArgStr( i ) ); EvtMultiChannelParser parser; parser.parse( args ); // Create factory and interval if ( VERBOSE ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Create factory and interval" << std::endl; _fact = createFactory( parser ); // Maximum PDF value over the Dalitz plot can be specified, or a scan // can be performed. _probMax = parser.pdfMax(); _nScan = parser.nScan(); if ( VERBOSE ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Pdf maximum " << _probMax << std::endl; if ( VERBOSE ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Scan number " << _nScan << std::endl; } void initProbMax() override { if ( 0 == _nScan ) { if ( _probMax > 0 ) setProbMax( _probMax ); else assert( 0 ); } else { double factor = 1.2; // increase maximum probability by 20% EvtAmpPdf pdf( *_fact->getAmp() ); EvtPdfSum* pc = _fact->getPC(); EvtPdfDiv pdfdiv( pdf, *pc ); printf( "Sampling %d points to find maximum\n", _nScan ); EvtPdfMax x = pdfdiv.findMax( *pc, _nScan ); _probMax = factor * x.value(); printf( "Found maximum %f\n", x.value() ); printf( "Increase to %f\n", _probMax ); setProbMax( _probMax ); } } void decay( EvtParticle* p ) override { // Set things up in most general way static EvtId B0 = EvtPDL::getId( "B0" ); static EvtId B0B = EvtPDL::getId( "anti-B0" ); double t; EvtId other_b; EvtComplex ampl( 0., 0. ); // Sample using pole-compensator pdf EvtPdfSum* pc = getPC(); _x = pc->randomPoint(); if ( _fact->isCPModel() ) { // Time-dependent Dalitz plot changes // Dec 2005 (ddujmic@slac.stanford.edu) EvtComplex A = _fact->getAmp()->evaluate( _x ); EvtComplex Abar = _fact->getAmpConj()->evaluate( _x ); EvtCPUtil::getInstance()->OtherB( p, t, other_b ); double dm = _fact->dm(); double mixAmpli = _fact->mixAmpli(); double mixPhase = _fact->mixPhase(); EvtComplex qoverp( cos( mixPhase ) * mixAmpli, sin( mixPhase ) * mixAmpli ); EvtComplex poverq( cos( mixPhase ) / mixAmpli, -sin( mixPhase ) / mixAmpli ); if ( other_b == B0B ) ampl = A * cos( dm * t / ( 2 * EvtConst::c ) ) + EvtComplex( 0., 1. ) * Abar * sin( dm * t / ( 2 * EvtConst::c ) ) * qoverp; if ( other_b == B0 ) ampl = Abar * cos( dm * t / ( 2 * EvtConst::c ) ) + EvtComplex( 0., 1. ) * A * sin( dm * t / ( 2 * EvtConst::c ) ) * poverq; } else { ampl = amplNonCP( _x ); } // Pole-compensate double comp = sqrt( pc->evaluate( _x ) ); assert( comp > 0 ); vertex( ampl / comp ); // Now generate random angles, rotate and setup // the daughters std::vector v = initDaughters( _x ); size_t N = p->getNDaug(); if ( v.size() != N ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Number of daughters " << N << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Momentum vector size " << v.size() << std::endl; assert( 0 ); } for ( size_t i = 0; i < N; i++ ) { p->getDaug( i )->init( getDaugs()[i], v[i] ); } } virtual EvtAmpFactory* createFactory( const EvtMultiChannelParser& parser ) = 0; virtual std::vector initDaughters( const T& p ) const = 0; // provide access to the decay point and to the amplitude of any decay point. // this is used by EvtBtoKD3P: const T& x() const { return _x; } EvtComplex amplNonCP( const T& x ) { return _fact->getAmp()->evaluate( x ); } EvtPdfSum* getPC() { return _fact->getPC(); } protected: double _probMax; // Maximum probability int _nScan; // Number of points for max prob DP scan T _x; // Decay point EvtAmpFactory* _fact; // factory }; #endif diff --git a/EvtGenModels/EvtModelReg.hh b/EvtGenModels/EvtModelReg.hh index f656871..a8c1239 100644 --- a/EvtGenModels/EvtModelReg.hh +++ b/EvtGenModels/EvtModelReg.hh @@ -1,35 +1,35 @@ /*********************************************************************** * 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 EVTMODELREG_HH #define EVTMODELREG_HH #include class EvtDecayBase; class EvtModelReg { public: - EvtModelReg( const std::list* extraModels = 0 ); + EvtModelReg( const std::list* extraModels = nullptr ); private: }; #endif diff --git a/EvtGenModels/EvtMultibody.hh b/EvtGenModels/EvtMultibody.hh index 91063c6..05295f9 100644 --- a/EvtGenModels/EvtMultibody.hh +++ b/EvtGenModels/EvtMultibody.hh @@ -1,50 +1,50 @@ /*********************************************************************** * 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 EVTMULTIBODY_HH #define EVTMULTIBODY_HH #include "EvtGenBase/EvtDecayAmp.hh" #include "EvtGenBase/EvtMTree.hh" #include "EvtGenBase/EvtSpinAmp.hh" class EvtMultibody : public EvtDecayAmp { public: EvtMultibody() { - _decayTree = NULL; - _ilist = NULL; + _decayTree = nullptr; + _ilist = nullptr; } ~EvtMultibody(); std::string getName() override; EvtDecayBase* clone() override; void init() override; void initProbMax() override; void decay( EvtParticle* p ) override; private: EvtMTree* _decayTree; int* _ilist; }; #endif diff --git a/src/EvtGen.cpp b/src/EvtGen.cpp index 2f871e2..6e9498e 100644 --- a/src/EvtGen.cpp +++ b/src/EvtGen.cpp @@ -1,214 +1,214 @@ /*********************************************************************** * 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 "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRadCorr.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtRandomEngine.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtStatus.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtModelReg.hh" #include "EvtGenModels/EvtNoRadCorr.hh" #include #include #include using std::endl; using std::fstream; using std::ifstream; EvtGen::~EvtGen() { //This is a bit ugly, should not do anything //in a destructor. This will fail if EvtGen is made a static //because then this destructor might be called _after_ //the destruction of objects that it depends on, e.g., EvtPDL. if ( getenv( "EVTINFO" ) ) { EvtDecayTable::getInstance()->printSummary(); } } EvtGen::EvtGen( const std::string& decayName, const std::string& pdtTableName, EvtRandomEngine* randomEngine, EvtAbsRadCorr* isrEngine, const std::list* extraModels, int mixingType, bool useXml ) { std::ifstream pdtIn( pdtTableName ); if ( !pdtIn ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Could not open:" << pdtTableName << "EvtPDL" << endl; return; } initialize( decayName, pdtIn, randomEngine, isrEngine, extraModels, mixingType, useXml ); pdtIn.close(); } EvtGen::EvtGen( const std::string& decayName, std::istream& pdtTableData, EvtRandomEngine* randomEngine, EvtAbsRadCorr* isrEngine, const std::list* extraModels, int mixingType, bool useXml ) { initialize( decayName, pdtTableData, randomEngine, isrEngine, extraModels, mixingType, useXml ); } void EvtGen::initialize( const std::string& decayName, std::istream& pdtTable, EvtRandomEngine* randomEngine, EvtAbsRadCorr* isrEngine, const std::list* extraModels, int mixingType, bool useXml ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Initializing EvtGen" << endl; - if ( randomEngine == 0 ) { + if ( randomEngine == nullptr ) { static EvtSimpleRandomEngine defaultRandomEngine; EvtRandom::setRandomEngine( &defaultRandomEngine ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "No random engine given in " << "EvtGen::EvtGen constructor, " << "will use default EvtSimpleRandomEngine." << endl; } else { EvtRandom::setRandomEngine( randomEngine ); } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Storing known decay models" << endl; EvtModelReg dummy( extraModels ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Main decay file name :" << decayName << endl; _pdl.readPDT( pdtTable ); if ( useXml ) { EvtDecayTable::getInstance()->readXMLDecayFile( decayName, false ); } else { EvtDecayTable::getInstance()->readDecayFile( decayName, false ); } _mixingType = mixingType; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Mixing type integer set to " << _mixingType << endl; EvtCPUtil::getInstance()->setMixingType( _mixingType ); // Set the radiative correction engine - if ( isrEngine != 0 ) { + if ( isrEngine != nullptr ) { EvtRadCorr::setRadCorrEngine( isrEngine ); } else { // Owing to the pure abstract interface, we still need to define a concrete // implementation of a radiative correction engine. Use one which does nothing. EvtAbsRadCorr* noRadCorr = new EvtNoRadCorr(); EvtRadCorr::setRadCorrEngine( noRadCorr ); } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Done initializing EvtGen" << endl; } void EvtGen::readUDecay( const std::string& uDecayName, bool useXml ) { ifstream indec; if ( uDecayName.size() == 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Is not reading a user decay file!" << endl; } else { indec.open( uDecayName ); if ( indec ) { if ( useXml ) { EvtDecayTable::getInstance()->readXMLDecayFile( uDecayName, true ); } else { EvtDecayTable::getInstance()->readDecayFile( uDecayName, true ); } } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Can not find UDECAY file '" << uDecayName << "'. Stopping" << endl; ::abort(); } } } EvtHepMCEvent* EvtGen::generateDecay( int PDGId, EvtVector4R refFrameP4, EvtVector4R translation, EvtSpinDensity* spinDensity ) { - EvtParticle* theParticle( 0 ); + EvtParticle* theParticle( nullptr ); - if ( spinDensity == 0 ) { + if ( spinDensity == nullptr ) { theParticle = EvtParticleFactory::particleFactory( EvtPDL::evtIdFromStdHep( PDGId ), refFrameP4 ); } else { theParticle = EvtParticleFactory::particleFactory( EvtPDL::evtIdFromStdHep( PDGId ), refFrameP4, *spinDensity ); } generateDecay( theParticle ); EvtHepMCEvent* hepMCEvent = new EvtHepMCEvent(); hepMCEvent->constructEvent( theParticle, translation ); theParticle->deleteTree(); return hepMCEvent; } void EvtGen::generateDecay( EvtParticle* p ) { int times = 0; do { times += 1; EvtStatus::initRejectFlag(); p->decay(); //ok then finish. if ( EvtStatus::getRejectFlag() == 0 ) { times = 0; } else { for ( size_t ii = 0; ii < p->getNDaug(); ii++ ) { EvtParticle* temp = p->getDaug( ii ); temp->deleteTree(); } p->resetFirstOrNot(); p->resetNDaug(); } if ( times == 10000 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Your event has been rejected 10000 times!" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will now abort." << endl; ::abort(); times = 0; } } while ( times ); } diff --git a/src/EvtGenBase/EvtCPUtil.cpp b/src/EvtGenBase/EvtCPUtil.cpp index b246eda..7069bd6 100644 --- a/src/EvtGenBase/EvtCPUtil.cpp +++ b/src/EvtGenBase/EvtCPUtil.cpp @@ -1,574 +1,577 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtSymTable.hh" #include #include #include using std::endl; EvtCPUtil::EvtCPUtil( int mixingType ) { _enableFlip = false; _mixingType = mixingType; } EvtCPUtil* EvtCPUtil::getInstance() { - static EvtCPUtil* theCPUtil = 0; + static EvtCPUtil* theCPUtil = nullptr; - if ( theCPUtil == 0 ) { + if ( theCPUtil == nullptr ) { theCPUtil = new EvtCPUtil( 1 ); } return theCPUtil; } //added two functions for finding the fraction of B0 tags for decays into //both CP eigenstates and non-CP eigenstates -- NK, Jan. 27th, 1998 void EvtCPUtil::fractB0CP( EvtComplex Af, EvtComplex Abarf, double /*deltam*/, double beta, double& fract ) { //This function returns the number of B0 tags for decays into CP-eigenstates //(the "probB0" in the new EvtOtherB) //double gamma_B = EvtPDL::getWidth(B0); //double xd = deltam/gamma_B; //double xd = 0.65; double ratio = 1 / ( 1 + 0.65 * 0.65 ); EvtComplex rf, rbarf; rf = EvtComplex( cos( 2.0 * beta ), sin( 2.0 * beta ) ) * Abarf / Af; rbarf = EvtComplex( 1.0 ) / rf; double A2 = real( Af ) * real( Af ) + imag( Af ) * imag( Af ); double Abar2 = real( Abarf ) * real( Abarf ) + imag( Abarf ) * imag( Abarf ); double rf2 = real( rf ) * real( rf ) + imag( rf ) * imag( rf ); double rbarf2 = real( rbarf ) * real( rbarf ) + imag( rbarf ) * imag( rbarf ); fract = ( Abar2 * ( 1 + rbarf2 + ( 1 - rbarf2 ) * ratio ) ) / ( Abar2 * ( 1 + rbarf2 + ( 1 - rbarf2 ) * ratio ) + A2 * ( 1 + rf2 + ( 1 - rf2 ) * ratio ) ); return; } void EvtCPUtil::fractB0nonCP( EvtComplex Af, EvtComplex Abarf, EvtComplex Afbar, EvtComplex Abarfbar, double deltam, double beta, int flip, double& fract ) { //this function returns the number of B0 tags for decays into non-CP eigenstates //(the "probB0" in the new EvtOtherB) //this needs more thought... //double gamma_B = EvtPDL::getWidth(B0); //EvtGenReport(EVTGEN_INFO,"EvtGen") << "gamma " << gamma_B<< endl; //double xd = deltam/gamma_B; //why is the width of B0 0 in PDL?? double xd = 0.65; double gamma_B = deltam / xd; double IAf, IAfbar, IAbarf, IAbarfbar; EvtComplex rf, rfbar, rbarf, rbarfbar; double rf2, rfbar2, rbarf2, rbarfbar2; double Af2, Afbar2, Abarf2, Abarfbar2; rf = EvtComplex( cos( 2.0 * beta ), sin( 2.0 * beta ) ) * Abarf / Af; rfbar = EvtComplex( cos( 2.0 * beta ), sin( 2.0 * beta ) ) * Abarfbar / Afbar; rbarf = EvtComplex( cos( -2.0 * beta ), sin( -2.0 * beta ) ) * Af / Abarf; rbarfbar = EvtComplex( cos( -2.0 * beta ), sin( -2.0 * beta ) ) * Afbar / Abarfbar; rf2 = real( rf ) * real( rf ) + imag( rf ) * imag( rf ); rfbar2 = real( rfbar ) * real( rfbar ) + imag( rfbar ) * imag( rfbar ); rbarf2 = real( rbarf ) * real( rbarf ) + imag( rbarf ) * imag( rbarf ); rbarfbar2 = real( rbarfbar ) * real( rbarfbar ) + imag( rbarfbar ) * imag( rbarfbar ); Af2 = real( Af ) * real( Af ) + imag( Af ) * imag( Af ); Afbar2 = real( Afbar ) * real( Afbar ) + imag( Afbar ) * imag( Afbar ); Abarf2 = real( Abarf ) * real( Abarf ) + imag( Abarf ) * imag( Abarf ); Abarfbar2 = real( Abarfbar ) * real( Abarfbar ) + imag( Abarfbar ) * imag( Abarfbar ); // //IAf = integral(gamma(B0->f)), etc. // IAf = ( Af2 / ( 2 * gamma_B ) ) * ( 1 + rf2 + ( 1 - rf2 ) / ( 1 + xd * xd ) ); IAfbar = ( Afbar2 / ( 2 * gamma_B ) ) * ( 1 + rfbar2 + ( 1 - rfbar2 ) / ( 1 + xd * xd ) ); IAbarf = ( Abarf2 / ( 2 * gamma_B ) ) * ( 1 + rbarf2 + ( 1 - rbarf2 ) / ( 1 + xd * xd ) ); IAbarfbar = ( Abarfbar2 / ( 2 * gamma_B ) ) * ( 1 + rbarfbar2 + ( 1 - rbarfbar2 ) / ( 1 + xd * xd ) ); //flip specifies the relative fraction of fbar events fract = IAbarf / ( IAbarf + IAf ) + flip * IAbarfbar / ( IAfbar + IAbarfbar ); return; } void EvtCPUtil::OtherB( EvtParticle* p, double& t, EvtId& otherb, double probB0 ) { if ( _mixingType == EvtCPUtil::Coherent ) { OtherCoherentB( p, t, otherb, probB0 ); } else if ( _mixingType == EvtCPUtil::Incoherent ) { OtherIncoherentB( p, t, otherb, probB0 ); } } void EvtCPUtil::OtherCoherentB( EvtParticle* p, double& t, EvtId& otherb, double probB0 ) { //Can not call this recursively!!! static int entryCount = 0; entryCount++; //added by Lange Jan4,2000 static EvtId B0B = EvtPDL::getId( "anti-B0" ); static EvtId B0 = EvtPDL::getId( "B0" ); static EvtId BSB = EvtPDL::getId( "anti-B_s0" ); static EvtId BS = EvtPDL::getId( "B_s0" ); static EvtId UPS4S = EvtPDL::getId( "Upsilon(4S)" ); int isB0 = EvtRandom::Flat( 0.0, 1.0 ) < probB0; int idaug; p->setLifetime(); // now get the time between the decay of this B and the other B! EvtParticle* parent = p->getParent(); EvtParticle* other; bool incoherentmix = false; - if ( ( parent != 0 ) && ( parent->getId() == B0 || parent->getId() == B0B || - parent->getId() == BS || parent->getId() == BSB ) ) { + if ( ( parent != nullptr ) && + ( parent->getId() == B0 || parent->getId() == B0B || + parent->getId() == BS || parent->getId() == BSB ) ) { incoherentmix = true; } if ( incoherentmix ) parent = parent->getParent(); - if ( parent == 0 || parent->getId() != UPS4S ) { + if ( parent == nullptr || parent->getId() != UPS4S ) { //Need to make this more general, but for now //assume no parent. If we have parent of B we //need to charge conj. full decay tree. - if ( parent != 0 ) { + if ( parent != nullptr ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "p=" << EvtPDL::name( p->getId() ) << " parent=" << EvtPDL::name( parent->getId() ) << endl; } assert( parent == 0 ); p->setLifetime(); t = p->getLifetime(); bool needToChargeConj = false; if ( p->getId() == B0B && isB0 ) needToChargeConj = true; if ( p->getId() == B0 && !isB0 ) needToChargeConj = true; if ( p->getId() == BSB && isB0 ) needToChargeConj = true; if ( p->getId() == BS && !isB0 ) needToChargeConj = true; if ( needToChargeConj ) { p->setId( EvtPDL::chargeConj( p->getId() ) ); if ( incoherentmix ) { p->getDaug( 0 )->setId( EvtPDL::chargeConj( p->getDaug( 0 )->getId() ) ); } } otherb = EvtPDL::chargeConj( p->getId() ); entryCount--; return; } else { if ( parent->getDaug( 0 ) != p ) { other = parent->getDaug( 0 ); idaug = 0; } else { other = parent->getDaug( 1 ); idaug = 1; } } - if ( parent != 0 ) { + if ( parent != nullptr ) { //if (entryCount>1){ // EvtGenReport(EVTGEN_INFO,"EvtGen") << "Double CP decay:"<getId().isAlias() ) { OtherB( p, t, otherb ); entryCount--; return; } if ( entryCount == 1 ) { EvtVector4R p_init = other->getP4(); //int decayed=other->getNDaug()>0; bool decayed = other->isDecayed(); other->deleteTree(); EvtScalarParticle* scalar_part; scalar_part = new EvtScalarParticle; if ( isB0 ) { scalar_part->init( B0, p_init ); } else { scalar_part->init( B0B, p_init ); } other = (EvtParticle*)scalar_part; // other->set_type(EvtSpinType::SCALAR); other->setDiagonalSpinDensity(); parent->insertDaugPtr( idaug, other ); if ( decayed ) { //EvtGenReport(EVTGEN_INFO,"EvtGen") << "In CP Util calling decay \n"; other->decay(); } } otherb = other->getId(); other->setLifetime(); t = p->getLifetime() - other->getLifetime(); otherb = other->getId(); } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "We have an error here!!!!" << endl; otherb = EvtId( -1, -1 ); } entryCount--; return; } // ======================================================================== bool EvtCPUtil::isBsMixed( EvtParticle* p ) { if ( !( p->getParent() ) ) return false; static EvtId BS0 = EvtPDL::getId( "B_s0" ); static EvtId BSB = EvtPDL::getId( "anti-B_s0" ); if ( ( p->getId() != BS0 ) && ( p->getId() != BSB ) ) return false; if ( ( p->getParent()->getId() == BS0 ) || ( p->getParent()->getId() == BSB ) ) return true; return false; } // ======================================================================== bool EvtCPUtil::isB0Mixed( EvtParticle* p ) { if ( !( p->getParent() ) ) return false; static EvtId B0 = EvtPDL::getId( "B0" ); static EvtId B0B = EvtPDL::getId( "anti-B0" ); if ( ( p->getId() != B0 ) && ( p->getId() != B0B ) ) return false; if ( ( p->getParent()->getId() == B0 ) || ( p->getParent()->getId() == B0B ) ) return true; return false; } //============================================================================ // Return the tag of the event (ie the anti-flavour of the produced // B meson). Flip the flavour of the event with probB probability //============================================================================ void EvtCPUtil::OtherIncoherentB( EvtParticle* p, double& t, EvtId& otherb, double probB ) { //std::cout<<"New routine running"<getId() == B0 || p->getId() == B0B) //added by liming Zhang enableFlip(); if ( ( isB0Mixed( p ) ) || ( isBsMixed( p ) ) ) { p->getParent()->setLifetime(); t = p->getParent()->getLifetime(); } else { p->setLifetime(); t = p->getLifetime(); } if ( flipIsEnabled() ) { //std::cout << " liming << flipIsEnabled " << std::endl; // Flip the flavour of the particle with probability probB bool isFlipped = ( EvtRandom::Flat( 0., 1. ) < probB ); if ( isFlipped ) { if ( ( isB0Mixed( p ) ) || ( isBsMixed( p ) ) ) { p->getParent()->setId( EvtPDL::chargeConj( p->getParent()->getId() ) ); p->setId( EvtPDL::chargeConj( p->getId() ) ); } else { p->setId( EvtPDL::chargeConj( p->getId() ) ); } } } if ( ( isB0Mixed( p ) ) || ( isBsMixed( p ) ) ) { // if B has mixed, tag flavour is charge conjugate of parent of B-meson otherb = EvtPDL::chargeConj( p->getParent()->getId() ); } else { // else it is opposite flavour than this B hadron otherb = EvtPDL::chargeConj( p->getId() ); } return; } //============================================================================ void EvtCPUtil::OtherB( EvtParticle* p, double& t, EvtId& otherb ) { static EvtId BSB = EvtPDL::getId( "anti-B_s0" ); static EvtId BS0 = EvtPDL::getId( "B_s0" ); static EvtId B0B = EvtPDL::getId( "anti-B0" ); static EvtId B0 = EvtPDL::getId( "B0" ); static EvtId D0B = EvtPDL::getId( "anti-D0" ); static EvtId D0 = EvtPDL::getId( "D0" ); static EvtId UPS4 = EvtPDL::getId( "Upsilon(4S)" ); if ( p->getId() == BS0 || p->getId() == BSB ) { static double ctauL = EvtPDL::getctau( EvtPDL::getId( "B_s0L" ) ); static double ctauH = EvtPDL::getctau( EvtPDL::getId( "B_s0H" ) ); static double ctau = ctauL < ctauH ? ctauH : ctauL; t = -log( EvtRandom::Flat() ) * ctau; EvtParticle* parent = p->getParent(); - if ( parent != 0 && ( parent->getId() == BS0 || parent->getId() == BSB ) ) { + if ( parent != nullptr && + ( parent->getId() == BS0 || parent->getId() == BSB ) ) { if ( parent->getId() == BS0 ) otherb = BSB; if ( parent->getId() == BSB ) otherb = BS0; parent->setLifetime( t ); return; } if ( p->getId() == BS0 ) otherb = BSB; if ( p->getId() == BSB ) otherb = BS0; p->setLifetime( t ); return; } if ( p->getId() == D0 || p->getId() == D0B ) { static double ctauL = EvtPDL::getctau( EvtPDL::getId( "D0L" ) ); static double ctauH = EvtPDL::getctau( EvtPDL::getId( "D0H" ) ); static double ctau = ctauL < ctauH ? ctauH : ctauL; t = -log( EvtRandom::Flat() ) * ctau; EvtParticle* parent = p->getParent(); - if ( parent != 0 && ( parent->getId() == D0 || parent->getId() == D0B ) ) { + if ( parent != nullptr && + ( parent->getId() == D0 || parent->getId() == D0B ) ) { if ( parent->getId() == D0 ) otherb = D0B; if ( parent->getId() == D0B ) otherb = D0; parent->setLifetime( t ); return; } if ( p->getId() == D0 ) otherb = D0B; if ( p->getId() == D0B ) otherb = D0; p->setLifetime( t ); return; } p->setLifetime(); // now get the time between the decay of this B and the other B! EvtParticle* parent = p->getParent(); - if ( parent == 0 || parent->getId() != UPS4 ) { + if ( parent == nullptr || parent->getId() != UPS4 ) { //EvtGenReport(EVTGEN_ERROR,"EvtGen") << // "Warning CP violation with B having no parent!"<getLifetime(); if ( p->getId() == B0 ) otherb = B0B; if ( p->getId() == B0B ) otherb = B0; if ( p->getId() == BS0 ) otherb = BSB; if ( p->getId() == BSB ) otherb = BS0; return; } else { if ( parent->getDaug( 0 ) != p ) { otherb = parent->getDaug( 0 )->getId(); parent->getDaug( 0 )->setLifetime(); t = p->getLifetime() - parent->getDaug( 0 )->getLifetime(); } else { otherb = parent->getDaug( 1 )->getId(); parent->getDaug( 1 )->setLifetime(); t = p->getLifetime() - parent->getDaug( 1 )->getLifetime(); } } return; } // No CP violation is assumed void EvtCPUtil::incoherentMix( const EvtId id, double& t, int& mix ) { int stdHepNum = EvtPDL::getStdHep( id ); stdHepNum = abs( stdHepNum ); EvtId partId = EvtPDL::evtIdFromStdHep( stdHepNum ); std::string partName = EvtPDL::name( partId ); std::string hname = partName + std::string( "H" ); std::string lname = partName + std::string( "L" ); EvtId lId = EvtPDL::getId( lname ); EvtId hId = EvtPDL::getId( hname ); double ctauL = EvtPDL::getctau( lId ); double ctauH = EvtPDL::getctau( hId ); // Bug Fixed: Corrected the average as gamma is the relevent parameter double ctau = 2.0 * ( ctauL * ctauH ) / ( ctauL + ctauH ); //double ctau=0.5*(ctauL+ctauH); // Bug Fixed: ctau definition changed above //double y=(ctauH-ctauL)/(2*ctau); double y = ( ctauH - ctauL ) / ( ctauH + ctauL ); //deltam and qoverp defined in DECAY.DEC std::string qoverpParmName = std::string( "qoverp_incohMix_" ) + partName; std::string mdParmName = std::string( "dm_incohMix_" ) + partName; int ierr; double qoverp = atof( EvtSymTable::get( qoverpParmName, ierr ).c_str() ); double x = atof( EvtSymTable::get( mdParmName, ierr ).c_str() ) * ctau / EvtConst::c; double fac; if ( id == partId ) { fac = 1.0 / ( qoverp * qoverp ); } else { fac = qoverp * qoverp; } double mixprob = ( x * x + y * y ) / ( x * x + y * y + fac * ( 2.0 + x * x - y * y ) ); int mixsign; mixsign = ( mixprob > EvtRandom::Flat( 0.0, 1.0 ) ) ? -1 : 1; double prob; // Find the longest of the two lifetimes double ctaulong = ctauL <= ctauH ? ctauH : ctauL; // Bug fixed: Ensure cosine argument is dimensionless so /ctau do { t = -log( EvtRandom::Flat() ) * ctaulong; prob = 1.0 + exp( -2.0 * fabs( y ) * t / ctau ) + mixsign * 2.0 * exp( -fabs( y ) * t / ctau ) * cos( x * t / ctau ); } while ( prob < 4.0 * EvtRandom::Flat() ); mix = 0; if ( mixsign == -1 ) mix = 1; return; } double EvtCPUtil::getDeltaGamma( const EvtId id ) { int stdHepNum = EvtPDL::getStdHep( id ); stdHepNum = abs( stdHepNum ); EvtId partId = EvtPDL::evtIdFromStdHep( stdHepNum ); std::string partName = EvtPDL::name( partId ); std::string hname = partName + std::string( "H" ); std::string lname = partName + std::string( "L" ); EvtId lId = EvtPDL::getId( lname ); EvtId hId = EvtPDL::getId( hname ); double ctauL = EvtPDL::getctau( lId ); double ctauH = EvtPDL::getctau( hId ); double dGamma = ( 1 / ctauL - 1 / ctauH ) * EvtConst::c; return dGamma; } double EvtCPUtil::getDeltaM( const EvtId id ) { int stdHepNum = EvtPDL::getStdHep( id ); stdHepNum = abs( stdHepNum ); EvtId partId = EvtPDL::evtIdFromStdHep( stdHepNum ); std::string partName = EvtPDL::name( partId ); std::string parmName = std::string( "dm_incohMix_" ) + partName; int ierr; double dM = atof( EvtSymTable::get( parmName, ierr ).c_str() ); return dM; } bool EvtCPUtil::flipIsEnabled() { return _enableFlip; } void EvtCPUtil::enableFlip() { _enableFlip = true; } void EvtCPUtil::disableFlip() { _enableFlip = false; } diff --git a/src/EvtGenBase/EvtCyclic3.cpp b/src/EvtGenBase/EvtCyclic3.cpp index e2ff613..89bd414 100644 --- a/src/EvtGenBase/EvtCyclic3.cpp +++ b/src/EvtGenBase/EvtCyclic3.cpp @@ -1,427 +1,427 @@ /*********************************************************************** * 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/EvtCyclic3.hh" #include "EvtGenBase/EvtPatches.hh" #include #include #include using std::ostream; using namespace EvtCyclic3; Index EvtCyclic3::permute( Index i, Perm p ) { if ( p == ABC ) return i; else if ( p == BCA ) { if ( i == A ) return C; else if ( i == B ) return A; else if ( i == C ) return B; } else if ( p == BCA ) { if ( i == A ) return C; else if ( i == B ) return A; else if ( i == C ) return B; } else if ( p == CAB ) { if ( i == A ) return B; else if ( i == B ) return C; else if ( i == C ) return A; } else if ( p == CBA ) { if ( i == A ) return C; else if ( i == B ) return B; else if ( i == C ) return A; } else if ( p == BAC ) { if ( i == A ) return B; else if ( i == B ) return A; else if ( i == C ) return C; } else if ( p == ACB ) { if ( i == A ) return A; else if ( i == B ) return C; else if ( i == C ) return B; } assert( 0 ); return A; } Perm EvtCyclic3::permutation( Index i1, Index i2, Index i3 ) { assert( i1 != i2 && i2 != i3 && i3 != i1 ); _unused( i3 ); if ( i1 == A ) return ( i2 == B ) ? ABC : ACB; if ( i1 == B ) return ( i2 == C ) ? BCA : BAC; if ( i1 == C ) return ( i2 == A ) ? CAB : CBA; assert( 0 ); return ABC; } Perm EvtCyclic3::permute( Perm i, Perm p ) { Index i1 = permute( permute( A, i ), p ); Index i2 = permute( permute( B, i ), p ); Index i3 = permute( permute( C, i ), p ); return permutation( i1, i2, i3 ); } Pair EvtCyclic3::permute( Pair i, Perm p ) { Index i1 = permute( first( i ), p ); Index i2 = permute( second( i ), p ); return combine( i1, i2 ); } Pair EvtCyclic3::i2pair( int i ) { assert( 0 <= i && i <= 2 ); switch ( i ) { case 0: return BC; case 1: return CA; case 2: return AB; } assert( 0 ); return AB; // should never get here } Index EvtCyclic3::prev( Index i ) { switch ( i ) { case A: return C; case B: return A; case C: return B; } assert( 0 ); return A; // should never get here } Index EvtCyclic3::next( Index i ) { switch ( i ) { case A: return B; case B: return C; case C: return A; } assert( 0 ); return A; // should never get here } Index EvtCyclic3::other( Index i, Index j ) { assert( i != j ); switch ( i ) { case A: switch ( j ) { case B: return C; case C: return B; default: assert( 0 ); } case B: switch ( j ) { case C: return A; case A: return C; default: assert( 0 ); } case C: switch ( j ) { case A: return B; case B: return A; default: assert( 0 ); } } assert( 0 ); return A; // should never get here } // Index-to-pair conversions Pair EvtCyclic3::other( Index i ) { switch ( i ) { case A: return BC; case B: return CA; case C: return AB; } assert( 0 ); return AB; // should never get here } Pair EvtCyclic3::combine( Index i, Index j ) { return other( other( i, j ) ); } // Pair-to-pair conversions Pair EvtCyclic3::prev( Pair i ) { switch ( i ) { case BC: return AB; case CA: return BC; case AB: return CA; } assert( 0 ); return AB; // should never get here } Pair EvtCyclic3::next( Pair i ) { switch ( i ) { case BC: return CA; case CA: return AB; case AB: return BC; } assert( 0 ); return AB; // should never get here } Pair EvtCyclic3::other( Pair i, Pair j ) { return combine( other( i ), other( j ) ); } // Pair-to-index conversions Index EvtCyclic3::first( Pair i ) { switch ( i ) { case BC: return B; case CA: return C; case AB: return A; } assert( 0 ); return A; // should never get here } Index EvtCyclic3::second( Pair i ) { switch ( i ) { case BC: return C; case CA: return A; case AB: return B; } assert( 0 ); return A; // should never get here } Index EvtCyclic3::other( Pair i ) { switch ( i ) { case BC: return A; case CA: return B; case AB: return C; } assert( 0 ); return A; // should never get here } Index EvtCyclic3::common( Pair i, Pair j ) { return other( other( i, j ) ); } Index EvtCyclic3::strToIndex( const char* str ) { if ( strcmp( str, "A" ) ) return A; else if ( strcmp( str, "B" ) ) return B; else if ( strcmp( str, "C" ) ) return C; else assert( 0 ); return A; } Pair EvtCyclic3::strToPair( const char* str ) { if ( !strcmp( str, "AB" ) || !strcmp( str, "BA" ) ) return AB; else if ( !strcmp( str, "BC" ) || !strcmp( str, "CB" ) ) return BC; else if ( !strcmp( str, "CA" ) || !strcmp( str, "AC" ) ) return CA; else assert( 0 ); return AB; } const char* EvtCyclic3::c_str( Index i ) { switch ( i ) { case A: return "A"; case B: return "B"; case C: return "C"; } assert( 0 ); - return 0; // sngh + return nullptr; // sngh } const char* EvtCyclic3::c_str( Pair i ) { switch ( i ) { case BC: return "BC"; case CA: return "CA"; case AB: return "AB"; } assert( 0 ); - return 0; // sngh + return nullptr; // sngh } const char* EvtCyclic3::c_str( Perm p ) { if ( p == ABC ) return "ABC"; if ( p == BCA ) return "BCA"; if ( p == CAB ) return "CAB"; if ( p == CBA ) return "CBA"; if ( p == BAC ) return "BAC"; if ( p == ACB ) return "ACB"; assert( 0 ); return "ABC"; } char* EvtCyclic3::append( const char* str, EvtCyclic3::Index i ) { // str + null + 1 character char* s = new char[strlen( str ) + 2]; strcpy( s, str ); strcat( s, c_str( i ) ); return s; } char* EvtCyclic3::append( const char* str, EvtCyclic3::Pair i ) { // str + null + 2 characters char* s = new char[strlen( str ) + 3]; strcpy( s, str ); strcat( s, c_str( i ) ); return s; } ostream& operator<<( ostream& os, EvtCyclic3::Index i ) { switch ( i ) { case A: { os << "A"; return os; } case B: { os << "B"; return os; } case C: { os << "C"; return os; } } assert( 0 ); return os; // should never get here } ostream& operator<<( ostream& os, EvtCyclic3::Pair i ) { switch ( i ) { case BC: { os << "BC"; return os; } case CA: { os << "CA"; return os; } case AB: { os << "AB"; return os; } } assert( 0 ); return os; // should never get here } diff --git a/src/EvtGenBase/EvtDecayAmp.cpp b/src/EvtGenBase/EvtDecayAmp.cpp index 71ade0c..de4af16 100644 --- a/src/EvtGenBase/EvtDecayAmp.cpp +++ b/src/EvtGenBase/EvtDecayAmp.cpp @@ -1,259 +1,259 @@ /*********************************************************************** * 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/EvtDecayAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRadCorr.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" using std::endl; void EvtDecayAmp::makeDecay( EvtParticle* p, bool recursive ) { //original default value int ntimes = 10000; int more; EvtSpinDensity rho; double prob, prob_max; _amp2.init( p->getId(), getNDaug(), getDaugs() ); do { _daugsDecayedByParentModel = false; _weight = 1.0; decay( p ); rho = _amp2.getSpinDensity(); prob = p->getSpinDensityForward().normalizedProb( rho ); if ( prob < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Negative prob:" << p->getId().getId() << " " << p->getChannel() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "rho_forward:" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << p->getSpinDensityForward(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "rho decay:" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << rho << endl; } if ( prob != prob ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Forward density matrix:" << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << p->getSpinDensityForward(); EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Decay density matrix:" << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << rho; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "prob:" << prob << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Particle:" << EvtPDL::name( p->getId() ).c_str() << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "channel :" << p->getChannel() << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Momentum:" << p->getP4() << " " << p->mass() << endl; - if ( p->getParent() != 0 ) { + if ( p->getParent() != nullptr ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "parent:" << EvtPDL::name( p->getParent()->getId() ).c_str() << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "parent channel :" << p->getParent()->getChannel() << endl; size_t i; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "parent daughters :"; for ( i = 0; i < p->getParent()->getNDaug(); i++ ) { EvtGenReport( EVTGEN_DEBUG, "" ) << EvtPDL::name( p->getParent()->getDaug( i )->getId() ) .c_str() << " "; } EvtGenReport( EVTGEN_DEBUG, "" ) << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "daughters :"; for ( size_t i = 0; i < p->getNDaug(); i++ ) { EvtGenReport( EVTGEN_DEBUG, "" ) << EvtPDL::name( p->getDaug( i )->getId() ).c_str() << " "; } EvtGenReport( EVTGEN_DEBUG, "" ) << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "daughter momenta :" << endl; ; for ( size_t i = 0; i < p->getNDaug(); i++ ) { EvtGenReport( EVTGEN_DEBUG, "" ) << p->getDaug( i )->getP4() << " " << p->getDaug( i )->mass(); EvtGenReport( EVTGEN_DEBUG, "" ) << endl; } } } prob /= _weight; prob_max = getProbMax( prob ); p->setDecayProb( prob / prob_max ); more = prob < EvtRandom::Flat( prob_max ); ntimes--; } while ( ntimes && more ); if ( ntimes == 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Tried accept/reject: 10000" << " times, and rejected all the times!" << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << p->getSpinDensityForward() << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Is therefore accepting the last event!" << endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Decay of particle:" << EvtPDL::name( p->getId() ).c_str() << "(channel:" << p->getChannel() << ") with mass " << p->mass() << endl; for ( size_t ii = 0; ii < p->getNDaug(); ii++ ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Daughter " << ii << ":" << EvtPDL::name( p->getDaug( ii )->getId() ).c_str() << " with mass " << p->getDaug( ii )->mass() << endl; } } EvtSpinDensity rho_list[10]; rho_list[0] = p->getSpinDensityForward(); EvtAmp ampcont; if ( _amp2._pstates != 1 ) { ampcont = _amp2.contract( 0, p->getSpinDensityForward() ); } else { ampcont = _amp2; } // it may be that the parent decay model has already // done the decay - this should be rare and the // model better know what it is doing.. if ( !daugsDecayedByParentModel() ) { if ( recursive ) { for ( size_t i = 0; i < p->getNDaug(); i++ ) { rho.setDim( _amp2.dstates[i] ); if ( _amp2.dstates[i] == 1 ) { rho.set( 0, 0, EvtComplex( 1.0, 0.0 ) ); } else { rho = ampcont.contract( _amp2._dnontrivial[i], _amp2 ); } if ( !rho.check() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "-------start error-------" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "forward rho failed Check:" << EvtPDL::name( p->getId() ).c_str() << " " << p->getChannel() << " " << i << endl; p->printTree(); for ( size_t idaug = 0; idaug < p->getNDaug(); idaug++ ) { EvtParticle* daughter = p->getDaug( idaug ); - if ( daughter != 0 ) { + if ( daughter != nullptr ) { daughter->printTree(); } } EvtParticle* pParent = p->getParent(); - if ( pParent != 0 ) { + if ( pParent != nullptr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parent:" << EvtPDL::name( pParent->getId() ).c_str() << endl; EvtParticle* grandParent = pParent->getParent(); - if ( grandParent != 0 ) { + if ( grandParent != nullptr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "GrandParent:" << EvtPDL::name( grandParent->getId() ).c_str() << endl; } } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtSpinDensity rho: " << rho; _amp2.dump(); for ( size_t ii = 0; ii < i + 1; ii++ ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "rho_list[" << ii << "] = " << rho_list[ii]; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "-------Done with error-------" << endl; } p->getDaug( i )->setSpinDensityForward( rho ); p->getDaug( i )->decay(); rho_list[i + 1] = p->getDaug( i )->getSpinDensityBackward(); if ( _amp2.dstates[i] != 1 ) { ampcont = ampcont.contract( _amp2._dnontrivial[i], rho_list[i + 1] ); } } p->setSpinDensityBackward( _amp2.getBackwardSpinDensity( rho_list ) ); if ( !p->getSpinDensityBackward().check() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "rho_backward failed Check" << p->getId().getId() << " " << p->getChannel() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << p->getSpinDensityBackward(); } } } if ( getPHOTOS() || EvtRadCorr::alwaysRadCorr() ) { int n_daug_orig = p->getNDaug(); EvtRadCorr::doRadCorr( p ); int n_daug_new = p->getNDaug(); for ( int i = n_daug_orig; i < n_daug_new; i++ ) { p->getDaug( i )->decay(); } } } diff --git a/src/EvtGenBase/EvtDecayBase.cpp b/src/EvtGenBase/EvtDecayBase.cpp index 2fb770c..e09dd81 100644 --- a/src/EvtGenBase/EvtDecayBase.cpp +++ b/src/EvtGenBase/EvtDecayBase.cpp @@ -1,665 +1,665 @@ /*********************************************************************** * 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/EvtDecayBase.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtStatus.hh" #include #include #include #include #include using std::endl; using std::fstream; void EvtDecayBase::checkQ() { int i; int q = 0; int qpar; //If there are no daughters (jetset etc) then we do not //want to do this test. Why? Because sometimes the parent //will have a nonzero charge. if ( _ndaug != 0 ) { for ( i = 0; i < _ndaug; i++ ) { q += EvtPDL::chg3( _daug[i] ); } qpar = EvtPDL::chg3( _parent ); if ( q != qpar ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << _modelname.c_str() << " generator expected " << " charge to be conserved, found:" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parent charge of " << ( qpar / 3 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Sum of daughter charge of " << ( q / 3 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "The parent is " << EvtPDL::name( _parent ).c_str() << endl; for ( i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Daughter " << EvtPDL::name( _daug[i] ).c_str() << endl; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } } double EvtDecayBase::getProbMax( double prob ) { int i; //diagnostics sum_prob += prob; if ( prob > max_prob ) max_prob = prob; if ( defaultprobmax && ntimes_prob <= 500 ) { //We are building up probmax with this iteration ntimes_prob += 1; if ( prob > probmax ) { probmax = prob; } if ( ntimes_prob == 500 ) { probmax *= 1.2; } return 1000000.0 * prob; } if ( prob > probmax * 1.0001 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "prob > probmax:(" << prob << ">" << probmax << ")"; EvtGenReport( EVTGEN_INFO, "" ) << "(" << _modelname.c_str() << ") "; EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> "; for ( i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _daug[i] ).c_str() << " "; } EvtGenReport( EVTGEN_INFO, "" ) << endl; if ( defaultprobmax ) probmax = prob; } ntimes_prob += 1; return probmax; } //getProbMax double EvtDecayBase::resetProbMax( double prob ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Reseting prob max\n"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "prob > probmax:(" << prob << ">" << probmax << ")"; EvtGenReport( EVTGEN_INFO, "" ) << "(" << _modelname.c_str() << ")"; EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::getStdHep( _parent ) << "->"; for ( int i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::getStdHep( _daug[i] ) << " "; } EvtGenReport( EVTGEN_INFO, "" ) << endl; probmax = 0.0; defaultprobmax = 0; ntimes_prob = 0; return prob; } std::string EvtDecayBase::commandName() { return std::string( "" ); } void EvtDecayBase::command( std::string ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Should never call EvtDecayBase::command" << endl; ::abort(); } std::string EvtDecayBase::getParamName( int i ) { switch ( i ) { case 0: return "param00"; case 1: return "param01"; case 2: return "param02"; case 3: return "param03"; case 4: return "param04"; case 5: return "param05"; case 6: return "param06"; case 7: return "param07"; case 8: return "param08"; case 9: return "param09"; default: return ""; } } std::string EvtDecayBase::getParamDefault( int /*i*/ ) { return ""; } void EvtDecayBase::init() { //This default version of init does nothing; //A specialized version of this function can be //supplied for each decay model to do initialization. return; } void EvtDecayBase::initProbMax() { //This function is called if the decay does not have a //specialized initialization. //The default is to set the maximum //probability to 0 and the number of times called to 0 //and defaultprobmax to 1 such that the decay will be //generated many many times //in order to generate a reasonable maximum probability //for the decay. defaultprobmax = 1; ntimes_prob = 0; probmax = 0.0; } //initProbMax void EvtDecayBase::saveDecayInfo( EvtId ipar, int ndaug, EvtId* daug, int narg, std::vector& args, std::string name, double brfr ) { int i; _brfr = brfr; _ndaug = ndaug; _narg = narg; _parent = ipar; _dsum = 0; if ( _ndaug > 0 ) { _daug.resize( _ndaug ); for ( i = 0; i < _ndaug; i++ ) { _daug[i] = daug[i]; _dsum += daug[i].getAlias(); } } else { _daug.clear(); } if ( _narg > 0 ) { _args.resize( _narg + 1 ); for ( i = 0; i < _narg; i++ ) { _args[i] = args[i]; } } else { _args.clear(); } _modelname = name; this->init(); this->initProbMax(); if ( _chkCharge ) { this->checkQ(); } if ( defaultprobmax ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "No default probmax for "; EvtGenReport( EVTGEN_INFO, "" ) << "(" << _modelname.c_str() << ") "; EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> "; for ( i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _daug[i] ).c_str() << " "; } EvtGenReport( EVTGEN_INFO, "" ) << endl; EvtGenReport( EVTGEN_INFO, "" ) << "This is fine for development, but must be provided for production." << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Never fear though - the decay will use the \n"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "500 iterations to build up a good probmax \n"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "before accepting a decay. " << endl; } } EvtDecayBase::EvtDecayBase() { //the default is that the user module does _not_ set // any probmax. defaultprobmax = 1; ntimes_prob = 0; probmax = 0.0; _photos = 0; _verbose = 0; _summary = 0; _parent = EvtId( -1, -1 ); _ndaug = 0; _narg = 0; _modelname = "**********"; //Default is to check that charge is conserved _chkCharge = 1; //statistics collection! max_prob = 0.0; sum_prob = 0.0; } void EvtDecayBase::printSummary() const { if ( ntimes_prob > 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Calls = " << ntimes_prob << " eff: " << sum_prob / ( probmax * ntimes_prob ) << " frac. max:" << max_prob / probmax; EvtGenReport( EVTGEN_INFO, "" ) << " probmax:" << probmax << " max:" << max_prob << " : "; } printInfo(); } void EvtDecayBase::printInfo() const { EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> "; for ( int i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _daug[i] ).c_str() << " "; } EvtGenReport( EVTGEN_INFO, "" ) << " (" << _modelname.c_str() << ")" << endl; } void EvtDecayBase::setProbMax( double prbmx ) { defaultprobmax = 0; probmax = prbmx; } void EvtDecayBase::noProbMax() { defaultprobmax = 0; } double EvtDecayBase::findMaxMass( EvtParticle* p ) { double maxOkMass = EvtPDL::getMaxMass( p->getId() ); //protect against vphotons if ( maxOkMass < 0.0000000001 ) return 10000000.; //and against already determined masses if ( p->hasValidP4() ) maxOkMass = p->mass(); EvtParticle* par = p->getParent(); if ( par ) { double maxParMass = findMaxMass( par ); size_t i; double minDaugMass = 0.; for ( i = 0; i < par->getNDaug(); i++ ) { EvtParticle* dau = par->getDaug( i ); if ( dau != p ) { // it might already have a mass if ( dau->isInitialized() || dau->hasValidP4() ) minDaugMass += dau->mass(); else //give it a bit of phase space minDaugMass += 1.000001 * EvtPDL::getMinMass( dau->getId() ); } } if ( maxOkMass > ( maxParMass - minDaugMass ) ) maxOkMass = maxParMass - minDaugMass; } return maxOkMass; } // given list of daughters ( by number ) returns a // list of viable masses. void EvtDecayBase::findMass( EvtParticle* p ) { //Need to also check that this mass does not screw //up the parent //This code assumes that for the ith daughter, 0..i-1 //already have a mass double maxOkMass = findMaxMass( p ); int count = 0; double mass; bool massOk = false; size_t i; while ( !massOk ) { count++; if ( count > 10000 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Can not find a valid mass for: " << EvtPDL::name( p->getId() ).c_str() << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Now printing parent and/or grandparent tree\n"; if ( p->getParent() ) { if ( p->getParent()->getParent() ) { p->getParent()->getParent()->printTree(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << p->getParent()->getParent()->mass() << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << p->getParent()->mass() << endl; } else { p->getParent()->printTree(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << p->getParent()->mass() << endl; } } else p->printTree(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "maxokmass=" << maxOkMass << " " << EvtPDL::getMinMass( p->getId() ) << " " << EvtPDL::getMaxMass( p->getId() ) << endl; if ( p->getNDaug() ) { for ( i = 0; i < p->getNDaug(); i++ ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << p->getDaug( i )->mass() << " "; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << endl; } if ( maxOkMass >= EvtPDL::getMinMass( p->getId() ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "taking a default value\n"; p->setMass( maxOkMass ); return; } assert( 0 ); } mass = EvtPDL::getMass( p->getId() ); //Just need to check that this mass is > than //the mass of all daughters double massSum = 0.; if ( p->getNDaug() ) { for ( i = 0; i < p->getNDaug(); i++ ) { massSum += p->getDaug( i )->mass(); } } //some special cases are handled with 0 (stable) or 1 (k0->ks/kl) daughters if ( p->getNDaug() < 2 ) massOk = true; if ( p->getParent() ) { if ( p->getParent()->getNDaug() == 1 ) massOk = true; } if ( !massOk ) { if ( massSum < mass ) massOk = true; if ( mass > maxOkMass ) massOk = false; } } p->setMass( mass ); } void EvtDecayBase::findMasses( EvtParticle* p, int ndaugs, EvtId daugs[10], double masses[10] ) { int i; double mass_sum; int count = 0; if ( !( p->firstornot() ) ) { for ( i = 0; i < ndaugs; i++ ) { masses[i] = p->getDaug( i )->mass(); } //for } //if else { p->setFirstOrNot(); // if only one daughter do it if ( ndaugs == 1 ) { masses[0] = p->mass(); return; } //until we get a combo whose masses are less than _parent mass. do { mass_sum = 0.0; for ( i = 0; i < ndaugs; i++ ) { masses[i] = EvtPDL::getMass( daugs[i] ); mass_sum = mass_sum + masses[i]; } count++; if ( count == 10000 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Decaying particle:" << EvtPDL::name( p->getId() ).c_str() << " (m=" << p->mass() << ")" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "To the following daugthers" << endl; for ( i = 0; i < ndaugs; i++ ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << EvtPDL::name( daugs[i] ).c_str() << endl; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Has been rejected " << count << " times, will now take minimal masses " << " of daugthers" << endl; mass_sum = 0.; for ( i = 0; i < ndaugs; i++ ) { masses[i] = EvtPDL::getMinMass( daugs[i] ); mass_sum = mass_sum + masses[i]; } if ( mass_sum > p->mass() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parent mass=" << p->mass() << "to light for daugthers." << endl << "Will throw the event away." << endl; //dont terminate - start over on the event. EvtStatus::setRejectFlag(); mass_sum = 0.; // ::abort(); } } } while ( mass_sum > p->mass() ); } //else return; } void EvtDecayBase::checkNArg( int a1, int a2, int a3, int a4 ) { if ( _narg != a1 && _narg != a2 && _narg != a3 && _narg != a4 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << _modelname.c_str() << " generator expected " << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << a1 << endl; ; if ( a2 > -1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << a2 << endl; } if ( a3 > -1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << a3 << endl; } if ( a4 > -1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << a4 << endl; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " arguments but found:" << _narg << endl; printSummary(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } void EvtDecayBase::checkNDaug( int d1, int d2 ) { if ( _ndaug != d1 && _ndaug != d2 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << _modelname.c_str() << " generator expected "; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << d1; if ( d2 > -1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << d2; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " daughters but found:" << _ndaug << endl; printSummary(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } void EvtDecayBase::checkSpinParent( EvtSpinType::spintype sp ) { EvtSpinType::spintype parenttype = EvtPDL::getSpinType( getParentId() ); if ( parenttype != sp ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << _modelname.c_str() << " did not get the correct parent spin\n"; printSummary(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } void EvtDecayBase::checkSpinDaughter( int d1, EvtSpinType::spintype sp ) { EvtSpinType::spintype parenttype = EvtPDL::getSpinType( getDaug( d1 ) ); if ( parenttype != sp ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << _modelname.c_str() << " did not get the correct daughter spin d=" << d1 << endl; printSummary(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } double* EvtDecayBase::getArgs() { if ( !_argsD.empty() ) return _argsD.data(); //The user has asked for a list of doubles - the arguments //better all be doubles... if ( _narg == 0 ) return _argsD.data(); _argsD.resize( _narg ); for ( int i = 0; i < _narg; i++ ) { char* tc; _argsD[i] = strtod( _args[i].c_str(), &tc ); } return _argsD.data(); } double EvtDecayBase::getArg( unsigned int j ) { // Verify string if ( getParentId().getId() == 25 ) { int i = 0; ++i; } const char* str = _args[j].c_str(); int i = 0; while ( str[i] != 0 ) { if ( isalpha( str[i] ) && str[i] != 'e' ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "String " << str << " is not a number" << endl; assert( 0 ); } i++; } - char** tc = 0; + char** tc = nullptr; double result = strtod( _args[j].c_str(), tc ); if ( _storedArgs.size() < j + 1 ) { // then store the argument's value _storedArgs.push_back( result ); } return result; } bool EvtDecayBase::matchingDecay( const EvtDecayBase& other ) const { if ( _ndaug != other._ndaug ) return false; if ( _parent != other._parent ) return false; std::vector useDs; for ( int i = 0; i < _ndaug; i++ ) useDs.push_back( 0 ); for ( int i = 0; i < _ndaug; i++ ) { bool foundIt = false; for ( int j = 0; j < _ndaug; j++ ) { if ( useDs[j] == 1 ) continue; if ( _daug[i] == other._daug[j] && _daug[i].getAlias() == other._daug[j].getAlias() ) { foundIt = true; useDs[j] = 1; break; } } if ( foundIt == false ) return false; } for ( int i = 0; i < _ndaug; i++ ) if ( useDs[i] == 0 ) return false; return true; } diff --git a/src/EvtGenBase/EvtDecayParm.cpp b/src/EvtGenBase/EvtDecayParm.cpp index a441f3b..0a8e69e 100644 --- a/src/EvtGenBase/EvtDecayParm.cpp +++ b/src/EvtGenBase/EvtDecayParm.cpp @@ -1,72 +1,72 @@ /*********************************************************************** * 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/EvtDecayParm.hh" #include "EvtGenBase/EvtPatches.hh" #include #include #include #include #include using std::fstream; void EvtDecayParm::init( fcnPtr pfcn, int ndaug, int* daugs, int narg, double* args, std::string name ) { int i; itsfcn = pfcn; itsndaug = ndaug; itsnarg = narg; itsdaugs = new int[itsndaug]; for ( i = 0; i < itsndaug; i++ ) { itsdaugs[i] = daugs[i]; } itsargs = new double[itsnarg]; for ( i = 0; i < itsnarg; i++ ) { itsargs[i] = args[i]; } modelname = name; } EvtDecayParm::EvtDecayParm() { - itsfcn = 0; + itsfcn = nullptr; itsndaug = 0; itsnarg = 0; - itsdaugs = 0; - itsargs = 0; + itsdaugs = nullptr; + itsargs = nullptr; modelname = "**********"; } EvtDecayParm::~EvtDecayParm() { - if ( itsdaugs != 0 ) { + if ( itsdaugs != nullptr ) { delete[] itsdaugs; } - if ( itsargs != 0 ) { + if ( itsargs != nullptr ) { delete[] itsargs; } } diff --git a/src/EvtGenBase/EvtDecayTable.cpp b/src/EvtGenBase/EvtDecayTable.cpp index af0bfe2..69d5d9d 100644 --- a/src/EvtGenBase/EvtDecayTable.cpp +++ b/src/EvtGenBase/EvtDecayTable.cpp @@ -1,1634 +1,1634 @@ /*********************************************************************** * 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/EvtDecayTable.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtExtGeneratorCommandsTable.hh" #include "EvtGenBase/EvtModel.hh" #include "EvtGenBase/EvtModelAlias.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParser.hh" #include "EvtGenBase/EvtParserXml.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRadCorr.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSymTable.hh" #include #include #include #include #include #include #include using std::endl; using std::fstream; using std::ifstream; EvtDecayTable::EvtDecayTable() { _decaytable.clear(); } EvtDecayTable::~EvtDecayTable() { _decaytable.clear(); } EvtDecayTable* EvtDecayTable::getInstance() { - static EvtDecayTable* theDecayTable = 0; + static EvtDecayTable* theDecayTable = nullptr; - if ( theDecayTable == 0 ) { + if ( theDecayTable == nullptr ) { theDecayTable = new EvtDecayTable(); } return theDecayTable; } int EvtDecayTable::getNMode( int ipar ) { return _decaytable[ipar].getNMode(); } EvtDecayBase* EvtDecayTable::getDecay( int ipar, int imode ) { return _decaytable[ipar].getDecayModel( imode ); } void EvtDecayTable::printSummary() { for ( size_t i = 0; i < EvtPDL::entries(); i++ ) { _decaytable[i].printSummary(); } } EvtDecayBase* EvtDecayTable::getDecayFunc( EvtParticle* p ) { int partnum; partnum = p->getId().getAlias(); if ( _decaytable[partnum].getNMode() == 0 ) - return 0; + return nullptr; return _decaytable[partnum].getDecayModel( p ); } void EvtDecayTable::readDecayFile( const std::string dec_name, bool verbose ) { if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize( EvtPDL::entries() ); EvtModel& modelist = EvtModel::instance(); EvtExtGeneratorCommandsTable* extGenCommands = EvtExtGeneratorCommandsTable::getInstance(); std::string colon( ":" ), equals( "=" ); int i; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "In readDecayFile, reading:" << dec_name.c_str() << endl; ifstream fin; fin.open( dec_name.c_str() ); if ( !fin ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Could not open " << dec_name.c_str() << endl; } fin.close(); EvtParser parser; parser.read( dec_name ); int itok; int hasend = 0; std::string token; for ( itok = 0; itok < parser.getNToken(); itok++ ) { token = parser.getToken( itok ); if ( token == "End" ) hasend = 1; } if ( !hasend ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Could not find an 'End' in " << dec_name.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution." << endl; ::abort(); } std::string model, parent, sdaug; EvtId ipar; int n_daugh; EvtId daught[MAX_DAUG]; double brfr; int itoken = 0; std::vector modelAliasList; do { token = parser.getToken( itoken++ ); //Easy way to turn off photos... Lange September 5, 2000 if ( token == "noPhotos" ) { EvtRadCorr::setNeverRadCorr(); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "As requested, PHOTOS will be turned off." << endl; } else if ( token == "yesPhotos" ) { EvtRadCorr::setAlwaysRadCorr(); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "As requested, PHOTOS will be turned on for all decays." << endl; } else if ( token == "normalPhotos" ) { EvtRadCorr::setNormalRadCorr(); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "As requested, PHOTOS will be turned on only when requested." << endl; } else if ( token == "Alias" ) { std::string newname; std::string oldname; newname = parser.getToken( itoken++ ); oldname = parser.getToken( itoken++ ); EvtId id = EvtPDL::getId( oldname ); if ( id == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << oldname.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } EvtPDL::alias( id, newname ); if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize( EvtPDL::entries() ); } else if ( token == "ModelAlias" ) { std::vector modelArgList; std::string aliasName = parser.getToken( itoken++ ); std::string modelName = parser.getToken( itoken++ ); std::string nameTemp; do { nameTemp = parser.getToken( itoken++ ); if ( nameTemp != ";" ) { modelArgList.push_back( nameTemp ); } } while ( nameTemp != ";" ); EvtModelAlias newAlias( aliasName, modelName, modelArgList ); modelAliasList.push_back( newAlias ); } else if ( token == "ChargeConj" ) { std::string aname; std::string abarname; aname = parser.getToken( itoken++ ); abarname = parser.getToken( itoken++ ); EvtId a = EvtPDL::getId( aname ); EvtId abar = EvtPDL::getId( abarname ); if ( a == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << aname.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( abar == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << abarname.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } EvtPDL::aliasChgConj( a, abar ); } else if ( token == "JetSetPar" ) { // Check if any old Pythia 6 commands are present std::string pythiaCommand = parser.getToken( itoken++ ); Command command; // The old command format is NAME(INT)=VALUE int i1 = pythiaCommand.find_first_of( "(" ); int i2 = pythiaCommand.find_first_of( ")" ); int i3 = pythiaCommand.find_first_of( "=" ); std::string pythiaModule = pythiaCommand.substr( 0, i1 ); std::string pythiaParam = pythiaCommand.substr( i1 + 1, i2 - i1 - 1 ); std::string pythiaValue = pythiaCommand.substr( i3 + 1 ); command["MODULE"] = pythiaModule; command["PARAM"] = pythiaParam; command["VALUE"] = pythiaValue; command["GENERATOR"] = "Both"; command["VERSION"] = "PYTHIA6"; extGenCommands->addCommand( "PYTHIA", command ); } else if ( modelist.isCommand( token ) ) { std::string cnfgstr; cnfgstr = parser.getToken( itoken++ ); modelist.storeCommand( token, cnfgstr ); } else if ( token == "PythiaGenericParam" || token == "PythiaAliasParam" || token == "PythiaBothParam" ) { // Read in any Pythia 8 commands, which will be of the form // pythiaParam module:param=value, with no spaces in the parameter // string! Here, specifies whether the command is for generic // decays, alias decays, or both. // Pythia 6 commands will be defined by the old JetSetPar command // name, which is handled by the modelist.isCommand() statement above. std::string pythiaCommand = parser.getToken( itoken++ ); std::string pythiaModule( "" ), pythiaParam( "" ), pythiaValue( "" ); // Separate out the string into the 3 sections using the delimiters // ":" and "=". std::vector pComVect1 = this->splitString( pythiaCommand, colon ); if ( pComVect1.size() == 2 ) { pythiaModule = pComVect1[0]; std::string pCom2 = pComVect1[1]; std::vector pComVect2 = this->splitString( pCom2, equals ); if ( pComVect2.size() == 2 ) { pythiaParam = pComVect2[0]; pythiaValue = pComVect2[1]; } } // Define the Pythia 8 command and pass it to the external generator // command list. Command command; if ( token == "PythiaGenericParam" ) { command["GENERATOR"] = "Generic"; } else if ( token == "PythiaAliasParam" ) { command["GENERATOR"] = "Alias"; } else { command["GENERATOR"] = "Both"; } command["MODULE"] = pythiaModule; command["PARAM"] = pythiaParam; command["VALUE"] = pythiaValue; command["VERSION"] = "PYTHIA8"; extGenCommands->addCommand( "PYTHIA", command ); } else if ( token == "CDecay" ) { std::string name; name = parser.getToken( itoken++ ); ipar = EvtPDL::getId( name ); if ( ipar == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << name.c_str() << " on line " << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } EvtId cipar = EvtPDL::chargeConj( ipar ); if ( _decaytable[ipar.getAlias()].getNMode() != 0 ) { if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined decay of " << name.c_str() << " in CDecay" << endl; _decaytable[ipar.getAlias()].removeDecay(); } //take contents of cipar and conjugate and store in ipar _decaytable[ipar.getAlias()].makeChargeConj( &_decaytable[cipar.getAlias()] ); } else if ( token == "Define" ) { std::string name; name = parser.getToken( itoken++ ); // value=atof(parser.getToken(itoken++).c_str()); EvtSymTable::define( name, parser.getToken( itoken++ ) ); //New code Lange April 10, 2001 - allow the user //to change particle definitions of EXISTING //particles on the fly } else if ( token == "Particle" ) { std::string pname; pname = parser.getToken( itoken++ ); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << pname.c_str() << endl; //There should be at least the mass double newMass = atof( parser.getToken( itoken++ ).c_str() ); EvtId thisPart = EvtPDL::getId( pname ); double newWidth = EvtPDL::getMeanMass( thisPart ); if ( parser.getNToken() > 3 ) newWidth = atof( parser.getToken( itoken++ ).c_str() ); //Now make the change! EvtPDL::reSetMass( thisPart, newMass ); EvtPDL::reSetWidth( thisPart, newWidth ); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Changing particle properties of " << pname.c_str() << " Mass=" << newMass << " Width=" << newWidth << endl; } else if ( token == "ChangeMassMin" ) { std::string pname; pname = parser.getToken( itoken++ ); double tmass = atof( parser.getToken( itoken++ ).c_str() ); EvtId thisPart = EvtPDL::getId( pname ); EvtPDL::reSetMassMin( thisPart, tmass ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Refined minimum mass for " << EvtPDL::name( thisPart ).c_str() << " to be " << tmass << endl; } else if ( token == "ChangeMassMax" ) { std::string pname; pname = parser.getToken( itoken++ ); double tmass = atof( parser.getToken( itoken++ ).c_str() ); EvtId thisPart = EvtPDL::getId( pname ); EvtPDL::reSetMassMax( thisPart, tmass ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Refined maximum mass for " << EvtPDL::name( thisPart ).c_str() << " to be " << tmass << endl; } else if ( token == "IncludeBirthFactor" ) { std::string pname; pname = parser.getToken( itoken++ ); bool yesno = false; if ( parser.getToken( itoken++ ) == "yes" ) yesno = true; EvtId thisPart = EvtPDL::getId( pname ); EvtPDL::includeBirthFactor( thisPart, yesno ); if ( verbose ) { if ( yesno ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Include birth factor for " << EvtPDL::name( thisPart ).c_str() << endl; if ( !yesno ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "No longer include birth factor for " << EvtPDL::name( thisPart ).c_str() << endl; } } else if ( token == "IncludeDecayFactor" ) { std::string pname; pname = parser.getToken( itoken++ ); bool yesno = false; if ( parser.getToken( itoken++ ) == "yes" ) yesno = true; EvtId thisPart = EvtPDL::getId( pname ); EvtPDL::includeDecayFactor( thisPart, yesno ); if ( verbose ) { if ( yesno ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Include decay factor for " << EvtPDL::name( thisPart ).c_str() << endl; if ( !yesno ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "No longer include decay factor for " << EvtPDL::name( thisPart ).c_str() << endl; } } else if ( token == "LSNONRELBW" ) { std::string pname; pname = parser.getToken( itoken++ ); EvtId thisPart = EvtPDL::getId( pname ); std::string tstr = "NONRELBW"; EvtPDL::changeLS( thisPart, tstr ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Change lineshape to non-rel BW for " << EvtPDL::name( thisPart ).c_str() << endl; } else if ( token == "LSFLAT" ) { std::string pname; pname = parser.getToken( itoken++ ); EvtId thisPart = EvtPDL::getId( pname ); std::string tstr = "FLAT"; EvtPDL::changeLS( thisPart, tstr ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Change lineshape to flat for " << EvtPDL::name( thisPart ).c_str() << endl; } else if ( token == "LSMANYDELTAFUNC" ) { std::string pname; pname = parser.getToken( itoken++ ); EvtId thisPart = EvtPDL::getId( pname ); std::string tstr = "MANYDELTAFUNC"; EvtPDL::changeLS( thisPart, tstr ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Change lineshape to spikes for " << EvtPDL::name( thisPart ).c_str() << endl; } else if ( token == "BlattWeisskopf" ) { std::string pname; pname = parser.getToken( itoken++ ); double tnum = atof( parser.getToken( itoken++ ).c_str() ); EvtId thisPart = EvtPDL::getId( pname ); EvtPDL::reSetBlatt( thisPart, tnum ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined Blatt-Weisskopf factor " << EvtPDL::name( thisPart ).c_str() << " to be " << tnum << endl; } else if ( token == "BlattWeisskopfBirth" ) { std::string pname; pname = parser.getToken( itoken++ ); double tnum = atof( parser.getToken( itoken++ ).c_str() ); EvtId thisPart = EvtPDL::getId( pname ); EvtPDL::reSetBlattBirth( thisPart, tnum ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined Blatt-Weisskopf birth factor " << EvtPDL::name( thisPart ).c_str() << " to be " << tnum << endl; } else if ( token == "SetLineshapePW" ) { std::string pname; pname = parser.getToken( itoken++ ); EvtId thisPart = EvtPDL::getId( pname ); std::string pnameD1 = parser.getToken( itoken++ ); EvtId thisD1 = EvtPDL::getId( pnameD1 ); std::string pnameD2 = parser.getToken( itoken++ ); EvtId thisD2 = EvtPDL::getId( pnameD2 ); int pw = atoi( parser.getToken( itoken++ ).c_str() ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined Partial wave for " << pname.c_str() << " to " << pnameD1.c_str() << " " << pnameD2.c_str() << " (" << pw << ")" << endl; EvtPDL::setPWForDecay( thisPart, pw, thisD1, thisD2 ); EvtPDL::setPWForBirthL( thisD1, pw, thisPart, thisD2 ); EvtPDL::setPWForBirthL( thisD2, pw, thisPart, thisD1 ); } else if ( token == "Decay" ) { std::string temp_fcn_new_model; EvtDecayBase* temp_fcn_new; double brfrsum = 0.0; parent = parser.getToken( itoken++ ); ipar = EvtPDL::getId( parent ); if ( ipar == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << parent.c_str() << " on line " << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _decaytable[ipar.getAlias()].getNMode() != 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined decay of " << parent.c_str() << endl; _decaytable[ipar.getAlias()].removeDecay(); } do { token = parser.getToken( itoken++ ); if ( token != "Enddecay" ) { i = 0; while ( token.c_str()[i++] != 0 ) { if ( isalpha( token.c_str()[i] ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected to find a branching fraction or Enddecay " << "but found:" << token.c_str() << " on line " << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Possibly to few arguments to model " << "on previous line!" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } brfr = atof( token.c_str() ); int isname = EvtPDL::getId( parser.getToken( itoken ) ).getId() >= 0; int ismodel = modelist.isModel( parser.getToken( itoken ) ); if ( !( isname || ismodel ) ) { //see if this is an aliased model for ( size_t iAlias = 0; iAlias < modelAliasList.size(); iAlias++ ) { if ( modelAliasList[iAlias].matchAlias( parser.getToken( itoken ) ) ) { ismodel = 2; break; } } } if ( !( isname || ismodel ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << parser.getToken( itoken ).c_str() << " is neither a particle name nor " << "the name of a model. " << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "It was encountered on line " << parser.getLineofToken( itoken ) << " of the decay file." << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Please fix it. Thank you." << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Be sure to check that the " << "correct case has been used. \n"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Terminating execution. \n"; ::abort(); itoken++; } n_daugh = 0; while ( EvtPDL::getId( parser.getToken( itoken ) ).getId() >= 0 ) { sdaug = parser.getToken( itoken++ ); daught[n_daugh++] = EvtPDL::getId( sdaug ); if ( daught[n_daugh - 1] == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << sdaug.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } model = parser.getToken( itoken++ ); int photos = 0; int verbose = 0; int summary = 0; do { if ( model == "PHOTOS" ) { photos = 1; model = parser.getToken( itoken++ ); } if ( model == "VERBOSE" ) { verbose = 1; model = parser.getToken( itoken++ ); } if ( model == "SUMMARY" ) { summary = 1; model = parser.getToken( itoken++ ); } } while ( model == "PHOTOS" || model == "VERBOSE" || model == "SUMMARY" ); //see if this is an aliased model int foundAnAlias = -1; for ( size_t iAlias = 0; iAlias < modelAliasList.size(); iAlias++ ) { if ( modelAliasList[iAlias].matchAlias( model ) ) { foundAnAlias = iAlias; break; } } if ( foundAnAlias == -1 ) { if ( !modelist.isModel( model ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected to find a model name," << "found:" << model.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } else { model = modelAliasList[foundAnAlias].getName(); } temp_fcn_new_model = model; temp_fcn_new = modelist.getFcn( model ); if ( photos ) { temp_fcn_new->setPHOTOS(); } if ( verbose ) { temp_fcn_new->setVerbose(); } if ( summary ) { temp_fcn_new->setSummary(); } std::vector temp_fcn_new_args; std::string name; int ierr; if ( foundAnAlias == -1 ) { do { name = parser.getToken( itoken++ ); if ( name != ";" ) { temp_fcn_new_args.push_back( EvtSymTable::get( name, ierr ) ); if ( ierr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Reading arguments and found:" << name.c_str() << " on line:" << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } //int isname=EvtPDL::getId(name).getId()>=0; int ismodel = modelist.isModel( name ); if ( ismodel ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected ';' but found:" << name.c_str() << " on line:" << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Most probable error is omitted ';'." << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } while ( name != ";" ); } else { std::vector copyMe = modelAliasList[foundAnAlias].getArgList(); temp_fcn_new_args = copyMe; itoken++; } //Found one decay. brfrsum += brfr; temp_fcn_new->saveDecayInfo( ipar, n_daugh, daught, temp_fcn_new_args.size(), temp_fcn_new_args, temp_fcn_new_model, brfr ); double massmin = 0.0; // for (i=0;inRealDaughters(); i++ ) { if ( EvtPDL::getMinMass( daught[i] ) > 0.0001 ) { massmin += EvtPDL::getMinMass( daught[i] ); } else { massmin += EvtPDL::getMeanMass( daught[i] ); } } _decaytable[ipar.getAlias()].addMode( temp_fcn_new, brfrsum, massmin ); } } while ( token != "Enddecay" ); _decaytable[ipar.getAlias()].finalize(); } // Allow copying of decays from one particle to another; useful // in combination with RemoveDecay else if ( token == "CopyDecay" ) { std::string newname; std::string oldname; newname = parser.getToken( itoken++ ); oldname = parser.getToken( itoken++ ); EvtId newipar = EvtPDL::getId( newname ); EvtId oldipar = EvtPDL::getId( oldname ); if ( oldipar == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << oldname.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( newipar == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << newname.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _decaytable[newipar.getAlias()].getNMode() != 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefining decay of " << newname << endl; _decaytable[newipar.getAlias()].removeDecay(); } _decaytable[newipar.getAlias()] = _decaytable[oldipar.getAlias()]; } // Enable decay deletion; intended primarily for aliases // Peter Onyisi, March 2008 else if ( token == "RemoveDecay" ) { parent = parser.getToken( itoken++ ); ipar = EvtPDL::getId( parent ); if ( ipar == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << parent.c_str() << " on line " << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _decaytable[ipar.getAlias()].getNMode() == 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "No decays to delete for " << parent.c_str() << endl; } else { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Deleting selected decays of " << parent.c_str() << endl; } do { token = parser.getToken( itoken ); if ( token != "Enddecay" ) { n_daugh = 0; while ( EvtPDL::getId( parser.getToken( itoken ) ).getId() >= 0 ) { sdaug = parser.getToken( itoken++ ); daught[n_daugh++] = EvtPDL::getId( sdaug ); if ( daught[n_daugh - 1] == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << sdaug.c_str() << " on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } token = parser.getToken( itoken ); if ( token != ";" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected ';' but found:" << token << " on line:" << parser.getLineofToken( itoken - 1 ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Most probable error is omitted ';'." << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } token = parser.getToken( itoken++ ); EvtDecayBase* temp_fcn_new = modelist.getFcn( "PHSP" ); std::vector temp_fcn_new_args; std::string temp_fcn_new_model( "PHSP" ); temp_fcn_new->saveDecayInfo( ipar, n_daugh, daught, 0, temp_fcn_new_args, temp_fcn_new_model, 0. ); _decaytable[ipar.getAlias()].removeMode( temp_fcn_new ); } } while ( token != "Enddecay" ); itoken++; } else if ( token != "End" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Found unknown command:'" << token.c_str() << "' on line " << parser.getLineofToken( itoken ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } while ( ( token != "End" ) && itoken != parser.getNToken() ); //Now we may need to reset the minimum mass for some particles???? for ( size_t ii = 0; ii < EvtPDL::entries(); ii++ ) { EvtId temp( ii, ii ); int nModTot = getNMode( ii ); //no decay modes if ( nModTot == 0 ) continue; //0 width? if ( EvtPDL::getWidth( temp ) < 0.0000001 ) continue; int jj; double minMass = EvtPDL::getMaxMass( temp ); for ( jj = 0; jj < nModTot; jj++ ) { double tmass = _decaytable[ii].getDecay( jj ).getMassMin(); if ( tmass < minMass ) minMass = tmass; } if ( minMass > EvtPDL::getMinMass( temp ) ) { if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Given allowed decays, resetting minMass " << EvtPDL::name( temp ).c_str() << " " << EvtPDL::getMinMass( temp ) << " to " << minMass << endl; EvtPDL::reSetMassMin( temp, minMass ); } } } void EvtDecayTable::readXMLDecayFile( const std::string dec_name, bool verbose ) { if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize( EvtPDL::entries() ); EvtModel& modelist = EvtModel::instance(); EvtExtGeneratorCommandsTable* extGenCommands = EvtExtGeneratorCommandsTable::getInstance(); EvtParserXml parser; parser.open( dec_name ); EvtId ipar; std::string decayParent = ""; double brfrSum = 0.; std::vector modelAliasList; bool endReached = false; while ( parser.readNextTag() ) { //TAGS FOUND UNDER DATA if ( parser.getParentTagTitle() == "data" ) { if ( parser.getTagTitle() == "photos" ) { std::string usage = parser.readAttribute( "usage" ); if ( usage == "always" ) { EvtRadCorr::setAlwaysRadCorr(); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "As requested, PHOTOS will be turned on for all decays." << endl; } else if ( usage == "never" ) { EvtRadCorr::setNeverRadCorr(); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "As requested, PHOTOS will be turned off." << endl; } else { EvtRadCorr::setNormalRadCorr(); if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "As requested, PHOTOS will be turned on only when requested." << endl; } } else if ( parser.getTagTitle() == "alias" ) { std::string alias = parser.readAttribute( "name" ); std::string particle = parser.readAttribute( "particle" ); checkParticle( particle ); EvtId id = EvtPDL::getId( particle ); EvtPDL::alias( id, alias ); if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize( EvtPDL::entries() ); } else if ( parser.getTagTitle() == "modelAlias" ) { std::vector modelArgList; std::string alias = parser.readAttribute( "name" ); std::string model = parser.readAttribute( "model" ); std::string paramStr = parser.readAttribute( "params" ); std::istringstream paramStream( paramStr ); std::string param; if ( paramStr == "" ) { EvtDecayBase* fcn = modelist.getFcn( model ); int i( 0 ); std::string paramName = fcn->getParamName( 0 ); while ( paramName != "" ) { param = parser.readAttribute( paramName, fcn->getParamDefault( i ) ); if ( param == "" ) break; modelArgList.push_back( param ); ++i; paramName = fcn->getParamName( i ); } } else { while ( std::getline( paramStream, param, ' ' ) ) { modelArgList.push_back( param ); } } EvtModelAlias newAlias( alias, model, modelArgList ); modelAliasList.push_back( newAlias ); } else if ( parser.getTagTitle() == "chargeConj" ) { std::string particle = parser.readAttribute( "particle" ); std::string conjugate = parser.readAttribute( "conjugate" ); EvtId a = EvtPDL::getId( particle ); EvtId abar = EvtPDL::getId( conjugate ); checkParticle( particle ); checkParticle( conjugate ); EvtPDL::aliasChgConj( a, abar ); } else if ( parser.getTagTitle() == "conjDecay" ) { std::string particle = parser.readAttribute( "particle" ); EvtId a = EvtPDL::getId( particle ); EvtId abar = EvtPDL::chargeConj( a ); checkParticle( particle ); checkParticle( abar.getName() ); if ( _decaytable[a.getAlias()].getNMode() != 0 ) { if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined decay of " << particle.c_str() << " in ConjDecay" << endl; _decaytable[a.getAlias()].removeDecay(); } //take contents of abar and conjugate and store in a _decaytable[a.getAlias()].makeChargeConj( &_decaytable[abar.getAlias()] ); } else if ( parser.getTagTitle() == "define" ) { std::string name = parser.readAttribute( "name" ); std::string value = parser.readAttribute( "value" ); EvtSymTable::define( name, value ); } else if ( parser.getTagTitle() == "particle" ) { std::string name = parser.readAttribute( "name" ); double mass = parser.readAttributeDouble( "mass" ); double width = parser.readAttributeDouble( "width" ); double minMass = parser.readAttributeDouble( "massMin" ); double maxMass = parser.readAttributeDouble( "massMax" ); std::string birthFactor = parser.readAttribute( "includeBirthFactor" ); std::string decayFactor = parser.readAttribute( "includeDecayFactor" ); std::string lineShape = parser.readAttribute( "lineShape" ); double blattWeisskopfD = parser.readAttributeDouble( "blattWeisskopfFactor" ); double blattWeisskopfB = parser.readAttributeDouble( "blattWeisskopfBirth" ); EvtId thisPart = EvtPDL::getId( name ); checkParticle( name ); if ( mass != -1 ) { EvtPDL::reSetMass( thisPart, mass ); EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Refined mass for " << EvtPDL::name( thisPart ).c_str() << " to be " << mass << endl; } if ( width != -1 ) { EvtPDL::reSetWidth( thisPart, width ); EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Refined width for " << EvtPDL::name( thisPart ).c_str() << " to be " << width << endl; } if ( minMass != -1 ) { EvtPDL::reSetMassMin( thisPart, minMass ); EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Refined minimum mass for " << EvtPDL::name( thisPart ).c_str() << " to be " << minMass << endl; } if ( maxMass != -1 ) { EvtPDL::reSetMassMax( thisPart, maxMass ); EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Refined maximum mass for " << EvtPDL::name( thisPart ).c_str() << " to be " << maxMass << endl; } if ( !birthFactor.empty() ) { EvtPDL::includeBirthFactor( thisPart, stringToBoolean( birthFactor ) ); if ( verbose ) { if ( stringToBoolean( birthFactor ) ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Include birth factor for " << EvtPDL::name( thisPart ).c_str() << endl; } else { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "No longer include birth factor for " << EvtPDL::name( thisPart ).c_str() << endl; } } } if ( !decayFactor.empty() ) { EvtPDL::includeDecayFactor( thisPart, stringToBoolean( decayFactor ) ); if ( verbose ) { if ( stringToBoolean( decayFactor ) ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Include decay factor for " << EvtPDL::name( thisPart ).c_str() << endl; } else { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "No longer include decay factor for " << EvtPDL::name( thisPart ).c_str() << endl; } } } if ( !lineShape.empty() ) { EvtPDL::changeLS( thisPart, lineShape ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Change lineshape to " << lineShape << " for " << EvtPDL::name( thisPart ).c_str() << endl; } if ( blattWeisskopfD != -1 ) { EvtPDL::reSetBlatt( thisPart, blattWeisskopfD ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined Blatt-Weisskopf factor " << EvtPDL::name( thisPart ).c_str() << " to be " << blattWeisskopfD << endl; } if ( blattWeisskopfB != -1 ) { EvtPDL::reSetBlattBirth( thisPart, blattWeisskopfB ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined Blatt-Weisskopf birth factor " << EvtPDL::name( thisPart ).c_str() << " to be " << blattWeisskopfB << endl; } } else if ( parser.getTagTitle() == "lineShapePW" ) { std::string parent = parser.readAttribute( "parent" ); std::string daug1 = parser.readAttribute( "daug1" ); std::string daug2 = parser.readAttribute( "daug2" ); int pw = parser.readAttributeInt( "pw" ); checkParticle( parent ); checkParticle( daug1 ); checkParticle( daug2 ); EvtId thisPart = EvtPDL::getId( parent ); EvtId thisD1 = EvtPDL::getId( daug1 ); EvtId thisD2 = EvtPDL::getId( daug2 ); EvtPDL::setPWForDecay( thisPart, pw, thisD1, thisD2 ); EvtPDL::setPWForBirthL( thisD1, pw, thisPart, thisD2 ); EvtPDL::setPWForBirthL( thisD2, pw, thisPart, thisD1 ); if ( verbose ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined Partial wave for " << parent.c_str() << " to " << daug1.c_str() << " " << daug2.c_str() << " (" << pw << ")" << endl; } else if ( parser.getTagTitle() == "decay" ) { //start of a particle brfrSum = 0.; decayParent = parser.readAttribute( "name" ); checkParticle( decayParent ); ipar = EvtPDL::getId( decayParent ); if ( _decaytable[ipar.getAlias()].getNMode() != 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefined decay of " << decayParent.c_str() << endl; _decaytable[ipar.getAlias()].removeDecay(); } } else if ( parser.getTagTitle() == "copyDecay" ) { std::string particle = parser.readAttribute( "particle" ); std::string copy = parser.readAttribute( "copy" ); EvtId newipar = EvtPDL::getId( particle ); EvtId oldipar = EvtPDL::getId( copy ); checkParticle( particle ); checkParticle( copy ); if ( _decaytable[newipar.getAlias()].getNMode() != 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Redefining decay of " << particle << endl; _decaytable[newipar.getAlias()].removeDecay(); } _decaytable[newipar.getAlias()] = _decaytable[oldipar.getAlias()]; } else if ( parser.getTagTitle() == "removeDecay" ) { decayParent = parser.readAttribute( "particle" ); checkParticle( decayParent ); ipar = EvtPDL::getId( decayParent ); if ( _decaytable[ipar.getAlias()].getNMode() == 0 ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "No decays to delete for " << decayParent.c_str() << endl; } else { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "Deleting selected decays of " << decayParent.c_str() << endl; } } else if ( parser.getTagTitle() == "pythiaParam" ) { Command command; command["GENERATOR"] = parser.readAttribute( "generator" ); command["MODULE"] = parser.readAttribute( "module" ); command["PARAM"] = parser.readAttribute( "param" ); command["VALUE"] = parser.readAttribute( "value" ); command["VERSION"] = "PYTHIA8"; extGenCommands->addCommand( "PYTHIA", command ); } else if ( parser.getTagTitle() == "pythia6Param" ) { Command command; command["GENERATOR"] = parser.readAttribute( "generator" ); command["MODULE"] = parser.readAttribute( "module" ); command["PARAM"] = parser.readAttribute( "param" ); command["VALUE"] = parser.readAttribute( "value" ); command["VERSION"] = "PYTHIA6"; extGenCommands->addCommand( "PYTHIA", command ); } else if ( parser.getTagTitle() == "/data" ) { //end of data endReached = true; parser.close(); break; } else if ( parser.getTagTitle() == "Title" || parser.getTagTitle() == "Details" || parser.getTagTitle() == "Author" || parser.getTagTitle() == "Version" //the above tags are expected to be in the XML decay file but are not used by EvtGen || parser.getTagTitle() == "dalitzDecay" || parser.getTagTitle() == "copyDalitz" ) { //the above tags are only used by EvtGenModels/EvtDalitzTable } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Unknown tag " << parser.getTagTitle() << " found in XML decay file near line " << parser.getLineNumber() << ". Tag will be ignored." << endl; } //TAGS FOUND UNDER DECAY } else if ( parser.getParentTagTitle() == "decay" ) { if ( parser.getTagTitle() == "channel" ) { //start of a channel int nDaughters = 0; EvtId daughter[MAX_DAUG]; EvtDecayBase* temp_fcn_new; std::string temp_fcn_new_model; std::vector temp_fcn_new_args; double brfr = parser.readAttributeDouble( "br" ); std::string daugStr = parser.readAttribute( "daughters" ); std::istringstream daugStream( daugStr ); std::string model = parser.readAttribute( "model" ); std::string paramStr = parser.readAttribute( "params" ); std::istringstream paramStream( paramStr ); bool decVerbose = parser.readAttributeBool( "verbose" ); bool decPhotos = parser.readAttributeBool( "photos" ); bool decSummary = parser.readAttributeBool( "summary" ); std::string daugh; while ( std::getline( daugStream, daugh, ' ' ) ) { checkParticle( daugh ); daughter[nDaughters++] = EvtPDL::getId( daugh ); } int modelAlias = -1; for ( size_t iAlias = 0; iAlias < modelAliasList.size(); iAlias++ ) { if ( modelAliasList[iAlias].matchAlias( model ) ) { modelAlias = iAlias; break; } } if ( modelAlias == -1 ) { if ( !modelist.isModel( model ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected to find a model name near line " << parser.getLineNumber() << "," << "found:" << model.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } else { model = modelAliasList[modelAlias].getName(); } temp_fcn_new_model = model; temp_fcn_new = modelist.getFcn( model ); if ( decPhotos ) temp_fcn_new->setPHOTOS(); if ( decVerbose ) temp_fcn_new->setVerbose(); if ( decSummary ) temp_fcn_new->setSummary(); int ierr; if ( modelAlias == -1 ) { std::string param; if ( paramStr == "" ) { int i( 0 ); std::string paramName = temp_fcn_new->getParamName( 0 ); while ( paramName != "" ) { param = parser.readAttribute( paramName, temp_fcn_new->getParamDefault( i ) ); if ( param == "" ) break; //params must be added in order so we can't just skip the missing ones temp_fcn_new_args.push_back( EvtSymTable::get( param, ierr ) ); if ( ierr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Reading arguments near line " << parser.getLineNumber() << " and found:" << param.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } ++i; paramName = temp_fcn_new->getParamName( i ); } } else { //if the params are not set seperately while ( std::getline( paramStream, param, ' ' ) ) { temp_fcn_new_args.push_back( EvtSymTable::get( param, ierr ) ); if ( ierr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Reading arguments near line " << parser.getLineNumber() << " and found:" << param.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } } } else { std::vector copyMe = modelAliasList[modelAlias].getArgList(); temp_fcn_new_args = copyMe; } brfrSum += brfr; temp_fcn_new->saveDecayInfo( ipar, nDaughters, daughter, temp_fcn_new_args.size(), temp_fcn_new_args, temp_fcn_new_model, brfr ); double massMin = 0.0; for ( int i = 0; i < temp_fcn_new->nRealDaughters(); i++ ) { if ( EvtPDL::getMinMass( daughter[i] ) > 0.0001 ) { massMin += EvtPDL::getMinMass( daughter[i] ); } else { massMin += EvtPDL::getMeanMass( daughter[i] ); } } _decaytable[ipar.getAlias()].addMode( temp_fcn_new, brfrSum, massMin ); } else if ( parser.getTagTitle() == "/decay" ) { //end of a particle _decaytable[ipar.getAlias()].finalize(); } else EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Unexpected tag " << parser.getTagTitle() << " found in XML decay file near line " << parser.getLineNumber() << ". Tag will be ignored." << endl; //TAGS FOUND UNDER REMOVEDECAY } else if ( parser.getParentTagTitle() == "removeDecay" ) { if ( parser.getTagTitle() == "channel" ) { //start of a channel int nDaughters = 0; EvtId daughter[MAX_DAUG]; std::string daugStr = parser.readAttribute( "daughters" ); std::istringstream daugStream( daugStr ); std::string daugh; while ( std::getline( daugStream, daugh, ' ' ) ) { checkParticle( daugh ); daughter[nDaughters++] = EvtPDL::getId( daugh ); } EvtDecayBase* temp_fcn_new = modelist.getFcn( "PHSP" ); std::vector temp_fcn_new_args; std::string temp_fcn_new_model( "PHSP" ); temp_fcn_new->saveDecayInfo( ipar, nDaughters, daughter, 0, temp_fcn_new_args, temp_fcn_new_model, 0. ); _decaytable[ipar.getAlias()].removeMode( temp_fcn_new ); } else if ( parser.getTagTitle() != "/removeDecay" ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Unexpected tag " << parser.getTagTitle() << " found in XML decay file near line " << parser.getLineNumber() << ". Tag will be ignored." << endl; } } } //while lines in file if ( !endReached ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Either the decay file ended prematurely or the file is badly formed.\n" << "Error occured near line" << parser.getLineNumber() << endl; ::abort(); } //Now we may need to reset the minimum mass for some particles???? for ( size_t ii = 0; ii < EvtPDL::entries(); ii++ ) { EvtId temp( ii, ii ); int nModTot = getNMode( ii ); //no decay modes if ( nModTot == 0 ) continue; //0 width? if ( EvtPDL::getWidth( temp ) < 0.0000001 ) continue; int jj; double minMass = EvtPDL::getMaxMass( temp ); for ( jj = 0; jj < nModTot; jj++ ) { double tmass = _decaytable[ii].getDecay( jj ).getMassMin(); if ( tmass < minMass ) minMass = tmass; } if ( minMass > EvtPDL::getMinMass( temp ) ) { if ( verbose ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Given allowed decays, resetting minMass " << EvtPDL::name( temp ).c_str() << " " << EvtPDL::getMinMass( temp ) << " to " << minMass << endl; EvtPDL::reSetMassMin( temp, minMass ); } } } bool EvtDecayTable::stringToBoolean( std::string valStr ) { return ( valStr == "true" || valStr == "1" || valStr == "on" || valStr == "yes" ); } void EvtDecayTable::checkParticle( std::string particle ) { if ( EvtPDL::getId( particle ) == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << particle.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } EvtDecayBase* EvtDecayTable::findDecayModel( EvtId id, int modeInt ) { int aliasInt = id.getAlias(); EvtDecayBase* theModel = this->findDecayModel( aliasInt, modeInt ); return theModel; } EvtDecayBase* EvtDecayTable::findDecayModel( int aliasInt, int modeInt ) { - EvtDecayBase* theModel( 0 ); + EvtDecayBase* theModel( nullptr ); if ( aliasInt >= 0 && aliasInt < (int)EvtPDL::entries() ) { theModel = _decaytable[aliasInt].getDecayModel( modeInt ); } return theModel; } bool EvtDecayTable::hasPythia( EvtId id ) { bool hasPythia = this->hasPythia( id.getAlias() ); return hasPythia; } bool EvtDecayTable::hasPythia( int aliasInt ) { bool hasPythia( false ); if ( aliasInt >= 0 && aliasInt < (int)EvtPDL::entries() ) { hasPythia = _decaytable[aliasInt].isJetSet(); } return hasPythia; } int EvtDecayTable::getNModes( EvtId id ) { int nModes = this->getNModes( id.getAlias() ); return nModes; } int EvtDecayTable::getNModes( int aliasInt ) { int nModes( 0 ); if ( aliasInt >= 0 && aliasInt < (int)EvtPDL::entries() ) { nModes = _decaytable[aliasInt].getNMode(); } return nModes; } int EvtDecayTable::findChannel( EvtId parent, std::string model, int ndaug, EvtId* daugs, int narg, std::string* args ) { int i, j, right; EvtId daugs_scratch[50]; int nmatch, k; for ( i = 0; i < _decaytable[parent.getAlias()].getNMode(); i++ ) { right = 1; right = right && model == _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getModelName(); right = right && ( ndaug == _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getNDaug() ); right = right && ( narg == _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getNArg() ); if ( right ) { for ( j = 0; j < ndaug; j++ ) { daugs_scratch[j] = daugs[j]; } nmatch = 0; for ( j = 0; j < _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getNDaug(); j++ ) { for ( k = 0; k < ndaug; k++ ) { if ( daugs_scratch[k] == _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getDaug( j ) ) { daugs_scratch[k] = EvtId( -1, -1 ); nmatch++; break; } } } right = right && ( nmatch == ndaug ); for ( j = 0; j < _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getNArg(); j++ ) { right = right && ( args[j] == _decaytable[parent.getAlias()] .getDecay( i ) .getDecayModel() ->getArgStr( j ) ); } } if ( right ) return i; } return -1; } int EvtDecayTable::inChannelList( EvtId parent, int ndaug, EvtId* daugs ) { int i, j, k; EvtId daugs_scratch[MAX_DAUG]; int dsum = 0; for ( i = 0; i < ndaug; i++ ) { dsum += daugs[i].getAlias(); } int nmatch; int ipar = parent.getAlias(); int nmode = _decaytable[ipar].getNMode(); for ( i = 0; i < nmode; i++ ) { EvtDecayBase* thedecaymodel = _decaytable[ipar].getDecay( i ).getDecayModel(); if ( thedecaymodel->getDSum() == dsum ) { int nd = thedecaymodel->getNDaug(); if ( ndaug == nd ) { for ( j = 0; j < ndaug; j++ ) { daugs_scratch[j] = daugs[j]; } nmatch = 0; for ( j = 0; j < nd; j++ ) { for ( k = 0; k < ndaug; k++ ) { if ( EvtId( daugs_scratch[k] ) == thedecaymodel->getDaug( j ) ) { daugs_scratch[k] = EvtId( -1, -1 ); nmatch++; break; } } } if ( ( nmatch == ndaug ) && ( !( ( thedecaymodel->getModelName() == "JETSET" ) || ( thedecaymodel->getModelName() == "PYTHIA" ) ) ) ) { return i; } } } } return -1; } std::vector EvtDecayTable::splitString( std::string& theString, std::string& splitter ) { // Code from STLplus std::vector result; if ( !theString.empty() && !splitter.empty() ) { for ( std::string::size_type offset = 0;; ) { std::string::size_type found = theString.find( splitter, offset ); if ( found != std::string::npos ) { std::string tmpString = theString.substr( offset, found - offset ); if ( tmpString.size() > 0 ) { result.push_back( tmpString ); } offset = found + splitter.size(); } else { std::string tmpString = theString.substr( offset, theString.size() - offset ); if ( tmpString.size() > 0 ) { result.push_back( tmpString ); } break; } } } return result; } diff --git a/src/EvtGenBase/EvtExtGeneratorCommandsTable.cpp b/src/EvtGenBase/EvtExtGeneratorCommandsTable.cpp index 03c023c..ebdb620 100644 --- a/src/EvtGenBase/EvtExtGeneratorCommandsTable.cpp +++ b/src/EvtGenBase/EvtExtGeneratorCommandsTable.cpp @@ -1,42 +1,42 @@ /*********************************************************************** * 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/EvtExtGeneratorCommandsTable.hh" EvtExtGeneratorCommandsTable::EvtExtGeneratorCommandsTable() { _commandMap.clear(); } EvtExtGeneratorCommandsTable::~EvtExtGeneratorCommandsTable() { _commandMap.clear(); } EvtExtGeneratorCommandsTable* EvtExtGeneratorCommandsTable::getInstance() { - static EvtExtGeneratorCommandsTable* theCommandMap = 0; + static EvtExtGeneratorCommandsTable* theCommandMap = nullptr; - if ( theCommandMap == 0 ) { + if ( theCommandMap == nullptr ) { theCommandMap = new EvtExtGeneratorCommandsTable(); } return theCommandMap; } diff --git a/src/EvtGenBase/EvtHepMCEvent.cpp b/src/EvtGenBase/EvtHepMCEvent.cpp index 68547e1..045d0f4 100644 --- a/src/EvtGenBase/EvtHepMCEvent.cpp +++ b/src/EvtGenBase/EvtHepMCEvent.cpp @@ -1,194 +1,195 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" EvtHepMCEvent::EvtHepMCEvent() : - _theEvent( 0 ), _translation( 0.0, 0.0, 0.0, 0.0 ) + _theEvent( nullptr ), _translation( 0.0, 0.0, 0.0, 0.0 ) { } EvtHepMCEvent::~EvtHepMCEvent() { this->deleteEvent(); } void EvtHepMCEvent::deleteEvent() { - if ( _theEvent != 0 ) { + if ( _theEvent != nullptr ) { _theEvent->clear(); delete _theEvent; - _theEvent = 0; + _theEvent = nullptr; } } void EvtHepMCEvent::constructEvent( EvtParticle* baseParticle ) { EvtVector4R origin( 0.0, 0.0, 0.0, 0.0 ); this->constructEvent( baseParticle, origin ); } void EvtHepMCEvent::constructEvent( EvtParticle* baseParticle, EvtVector4R& translation ) { // This class does not take ownership of the base particle pointer. // Rather, it uses the base particle to construct the event. this->deleteEvent(); - if ( baseParticle == 0 ) { + if ( baseParticle == nullptr ) { return; } _theEvent = new GenEvent( Units::GEV, Units::MM ); _translation = translation; // Use the recursive function addVertex to add a vertex with incoming/outgoing // particles. Adds a new vertex for any EvtParticles with decay daughters. // All particles are in the rest frame of the base particle ("lab frame"). GenParticlePtr hepMCGenParticle = this->createGenParticle( baseParticle, EvtHepMCEvent::LAB ); this->addVertex( baseParticle, hepMCGenParticle ); } GenParticlePtr EvtHepMCEvent::createGenParticle( EvtParticle* theParticle, int frameType ) { // Create an HepMC GenParticle, with the 4-momenta in the frame given by the frameType integer GenParticlePtr genParticle{nullptr}; - if ( theParticle != 0 ) { + if ( theParticle != nullptr ) { // Set the particle status integer to either stable or decayed int status( EvtHepMCEvent::STABLE ); int nDaug = theParticle->getNDaug(); if ( nDaug > 0 ) { status = EvtHepMCEvent::DECAYED; } // Get the 4-momentum (E, px, py, pz) for the EvtParticle. EvtVector4R p4( 0.0, 0.0, 0.0, 0.0 ); if ( frameType == EvtHepMCEvent::RESTFRAME ) { p4 = theParticle->getP4Restframe(); } else if ( frameType == EvtHepMCEvent::LAB ) { p4 = theParticle->getP4Lab(); } else { p4 = theParticle->getP4(); } // Convert this to the HepMC 4-momentum double E = p4.get( 0 ); double px = p4.get( 1 ); double py = p4.get( 2 ); double pz = p4.get( 3 ); FourVector hepMC_p4( px, py, pz, E ); // Get the particle PDG integer id int PDGInt = EvtPDL::getStdHep( theParticle->getId() ); genParticle = newGenParticlePtr( hepMC_p4, PDGInt, status ); } return genParticle; } void EvtHepMCEvent::addVertex( EvtParticle* inEvtParticle, GenParticlePtr inGenParticle ) { // This is a recursive function that adds GenVertices to the GenEvent for // the incoming EvtParticle and its daughters. We use two separate // pointers for the EvtParticle and GenParticle information: the former // to obtain the PDGId, 4-momenta, daughter and vertex positions, the latter to // set the incoming particle to the vertex. Note that the outgoing particle for // one vertex might be the incoming particle for another vertex - this needs to // be the same GenParticle pointer, hence the reason for using it as a 2nd argument // in this function. - if ( _theEvent == 0 || inEvtParticle == 0 || inGenParticle == 0 ) { + if ( _theEvent == nullptr || inEvtParticle == nullptr || + inGenParticle == nullptr ) { return; } // Create the decay vertex FourVector vtxCoord = this->getVertexCoord( inEvtParticle ); GenVertexPtr theVertex = newGenVertexPtr( vtxCoord ); // Add the vertex to the event _theEvent->add_vertex( theVertex ); // Set the incoming particle theVertex->add_particle_in( inGenParticle ); // Set the outgoing particles (decay products) int nDaug = inEvtParticle->getNDaug(); int iDaug( 0 ); // Loop over the daughters for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* evtDaughter = inEvtParticle->getDaug( iDaug ); GenParticlePtr genDaughter = this->createGenParticle( evtDaughter, EvtHepMCEvent::LAB ); - if ( genDaughter != 0 ) { + if ( genDaughter != nullptr ) { // Add a new GenParticle (outgoing) particle daughter to the vertex theVertex->add_particle_out( genDaughter ); // Find out if the daughter also has decay products. // If so, recursively run this function again. int nDaugProducts = evtDaughter->getNDaug(); if ( nDaugProducts > 0 ) { // Recursively process daughter particles and add their vertices to the event this->addVertex( evtDaughter, genDaughter ); } // Have daughter products } // hepMCDaughter != 0 } // Loop over daughters } FourVector EvtHepMCEvent::getVertexCoord( EvtParticle* theParticle ) { FourVector vertexCoord( 0.0, 0.0, 0.0, 0.0 ); - if ( theParticle != 0 && theParticle->getNDaug() != 0 ) { + if ( theParticle != nullptr && theParticle->getNDaug() != 0 ) { // Get the position (t,x,y,z) of the EvtParticle, offset by the translation vector. // This position will be the point where the particle decays. So we ask // the position of the (1st) daughter particle. EvtParticle* daugParticle = theParticle->getDaug( 0 ); - if ( daugParticle != 0 ) { + if ( daugParticle != nullptr ) { EvtVector4R vtxPosition = daugParticle->get4Pos() + _translation; // Create the HepMC 4 vector of the position (x,y,z,t) vertexCoord.setX( vtxPosition.get( 1 ) ); vertexCoord.setY( vtxPosition.get( 2 ) ); vertexCoord.setZ( vtxPosition.get( 3 ) ); vertexCoord.setT( vtxPosition.get( 0 ) ); } } return vertexCoord; } diff --git a/src/EvtGenBase/EvtMHelAmp.cpp b/src/EvtGenBase/EvtMHelAmp.cpp index f1d8dfe..f13d6cc 100644 --- a/src/EvtGenBase/EvtMHelAmp.cpp +++ b/src/EvtGenBase/EvtMHelAmp.cpp @@ -1,148 +1,148 @@ /*********************************************************************** * 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/EvtMHelAmp.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include using std::endl; EvtMHelAmp::EvtMHelAmp( const EvtId& id, EvtMLineShape* lineshape, const vector& children, const vector& elem ) { _id = id; _twospin = EvtSpinType::getSpin2( EvtPDL::getSpinType( id ) ); - _parent = NULL; + _parent = nullptr; _lineshape = lineshape; _elem = elem; vector type; for ( size_t i = 0; i < children.size(); ++i ) { _children.push_back( children[i] ); type.push_back( children[i]->getspintype() ); const vector& res = children[i]->getresonance(); for ( size_t j = 0; j < res.size(); ++j ) _resonance.push_back( res[j] ); children[i]->setparent( this ); } // XXX New code - bugs could appear here XXX _amp = EvtSpinAmp( type ); vector index = _amp.iterinit(); size_t i = 0; do { if ( !_amp.allowed( index ) ) _amp( index ) = 0.0; else if ( abs( index[0] - index[1] ) > _twospin ) _amp( index ) = 0.0; else { _amp( index ) = elem[i]; ++i; } } while ( _amp.iterate( index ) ); if ( elem.size() != i ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong number of elements input in helicity amplitude." << endl; ::abort(); } if ( children.size() > 2 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Helicity amplitude formalism can only handle two body resonances" << endl; ::abort(); } } EvtSpinAmp EvtMHelAmp::amplitude( const vector& product ) const { EvtVector4R d = _children[0]->get4vector( product ); double phi, theta; - if ( _parent == NULL ) { + if ( _parent == nullptr ) { // This means that we're calculating the first level and we need to just // calculate the polar and azymuthal angles daughters in rest frame of // this (root) particle (this is automatic). phi = atan2( d.get( 1 ), d.get( 2 ) ); theta = acos( d.get( 3 ) / d.d3mag() ); } else { // We have parents therefore calculate things in correct coordinate // system EvtVector4R p = _parent->get4vector( product ); EvtVector4R q = get4vector( product ); // See if we have a grandparent - if no then the z-axis is defined by // the z-axis of the root particle - EvtVector4R g = _parent->getparent() == NULL + EvtVector4R g = _parent->getparent() == nullptr ? EvtVector4R( 0.0, 0.0, 0.0, 1.0 ) : _parent->getparent()->get4vector( product ); theta = acos( EvtDecayAngle( p, q, d ) ); phi = EvtDecayAnglePhi( g, p, q, d ); } vector types( 3 ); types[0] = getspintype(); types[1] = _children[0]->getspintype(); types[2] = _children[1]->getspintype(); EvtSpinAmp amp( types, EvtComplex( 0.0, 0.0 ) ); vector index = amp.iterallowedinit(); do { if ( abs( index[1] - index[2] ) > _twospin ) continue; amp( index ) += conj( wignerD( _twospin, index[0], index[1] - index[2], phi, theta, 0.0 ) ) * _amp( index[1], index[2] ); } while ( amp.iterateallowed( index ) ); EvtSpinAmp amp0 = _children[0]->amplitude( product ); EvtSpinAmp amp1 = _children[1]->amplitude( product ); amp.extcont( amp0, 1, 0 ); amp.extcont( amp1, 1, 0 ); amp *= sqrt( ( _twospin + 1 ) / ( 2 * EvtConst::twoPi ) ) * _children[0]->line( product ) * _children[1]->line( product ); return amp; } EvtMNode* EvtMHelAmp::duplicate() const { vector children; for ( size_t i = 0; i < _children.size(); ++i ) { children.push_back( _children[i]->duplicate() ); } EvtMLineShape* lineshape = _lineshape->duplicate(); EvtMHelAmp* ret = new EvtMHelAmp( _id, lineshape, children, _elem ); lineshape->setres( ret ); return ret; } diff --git a/src/EvtGenBase/EvtMTree.cpp b/src/EvtGenBase/EvtMTree.cpp index 9ddc973..c3f8642 100644 --- a/src/EvtGenBase/EvtMTree.cpp +++ b/src/EvtGenBase/EvtMTree.cpp @@ -1,471 +1,471 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenBase/EvtMTree.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtMBreitWigner.hh" #include "EvtGenBase/EvtMHelAmp.hh" #include "EvtGenBase/EvtMTrivialLS.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include using std::endl; EvtMTree::EvtMTree( const EvtId* idtbl, unsigned int ndaug ) { for ( size_t i = 0; i < ndaug; ++i ) { _lbltbl.push_back( EvtPDL::name( idtbl[i] ) ); } } EvtMTree::~EvtMTree() { for ( size_t i = 0; i < _root.size(); ++i ) delete _root[i]; } bool EvtMTree::parsecheck( char arg, const string& chars ) { bool ret = false; for ( size_t i = 0; i < chars.size(); ++i ) { ret = ret || ( chars[i] == arg ); } return ret; } vector EvtMTree::makeparticles( const string& strid ) { vector particles; vector labels; for ( size_t i = 0; i < _lbltbl.size(); ++i ) { if ( _lbltbl[i] == strid ) labels.push_back( i ); } if ( labels.size() == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error unknown particle label " << strid << endl; ::abort(); } for ( size_t i = 0; i < labels.size(); ++i ) particles.push_back( new EvtMParticle( labels[i], EvtPDL::getId( strid ) ) ); return particles; } EvtMRes* EvtMTree::makeresonance( const EvtId& id, const string& ls, const vector& lsarg, const string& type, const vector& amps, const vector& children ) { - EvtMRes* resonance = NULL; - EvtMLineShape* lineshape = NULL; + EvtMRes* resonance = nullptr; + EvtMLineShape* lineshape = nullptr; if ( ls == "BREITWIGNER" ) { lineshape = new EvtMBreitWigner( id, lsarg ); } else if ( ls == "TRIVIAL" ) { lineshape = new EvtMTrivialLS( id, lsarg ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Lineshape " << lineshape << " not recognized." << endl; ::abort(); } if ( type == "HELAMP" ) { resonance = new EvtMHelAmp( id, lineshape, children, amps ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Model " << type << " not recognized." << endl; ::abort(); } lineshape->setres( resonance ); return resonance; } void EvtMTree::parseerror( bool flag, ptype& c_iter, ptype& c_begin, ptype& c_end ) { if ( !flag ) return; string error; while ( c_begin != c_end ) { if ( c_begin == c_iter ) { error += '_'; error += *c_begin; error += '_'; } else error += *c_begin; ++c_begin; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parse error at: " << error << endl; ::abort(); } string EvtMTree::parseId( ptype& c_iter, ptype& c_begin, ptype& c_end ) { string strid; while ( c_iter != c_end ) { parseerror( parsecheck( *c_iter, ")[]," ), c_iter, c_begin, c_end ); if ( *c_iter == '(' ) { ++c_iter; return strid; } strid += *c_iter; ++c_iter; } return strid; } string EvtMTree::parseKey( ptype& c_iter, ptype& c_begin, ptype& c_end ) { string key; while ( *c_iter != ',' ) { parseerror( c_iter == c_end || parsecheck( *c_iter, "()[]" ), c_iter, c_begin, c_end ); key += *c_iter; ++c_iter; } ++c_iter; parseerror( c_iter == c_end, c_iter, c_begin, c_end ); return key; } vector EvtMTree::parseArg( ptype& c_iter, ptype& c_begin, ptype& c_end ) { vector arg; if ( *c_iter != '[' ) return arg; ++c_iter; string temp; while ( true ) { parseerror( c_iter == c_end || parsecheck( *c_iter, "[()" ), c_iter, c_begin, c_end ); if ( *c_iter == ']' ) { ++c_iter; if ( temp.size() > 0 ) arg.push_back( temp ); break; } if ( *c_iter == ',' ) { arg.push_back( temp ); temp.clear(); ++c_iter; continue; } temp += *c_iter; ++c_iter; } parseerror( c_iter == c_end || *c_iter != ',', c_iter, c_begin, c_end ); ++c_iter; return arg; } vector EvtMTree::parseAmps( ptype& c_iter, ptype& c_begin, ptype& c_end ) { vector parg = parseArg( c_iter, c_begin, c_end ); parseerror( parg.size() == 0, c_iter, c_begin, c_end ); // Get parametrization amplitudes vector::iterator amp_iter = parg.begin(); vector::iterator amp_end = parg.end(); vector amps; while ( amp_iter != amp_end ) { const char* nptr; - char* endptr = NULL; + char* endptr = nullptr; double amp = 0.0, phase = 0.0; nptr = ( *amp_iter ).c_str(); amp = strtod( nptr, &endptr ); parseerror( nptr == endptr, c_iter, c_begin, c_end ); ++amp_iter; parseerror( amp_iter == amp_end, c_iter, c_begin, c_end ); nptr = ( *amp_iter ).c_str(); phase = strtod( nptr, &endptr ); parseerror( nptr == endptr, c_iter, c_begin, c_end ); amps.push_back( amp * exp( EvtComplex( 0.0, phase ) ) ); ++amp_iter; } return amps; } vector EvtMTree::duplicate( const vector& list ) const { vector newlist; for ( size_t i = 0; i < list.size(); ++i ) newlist.push_back( list[i]->duplicate() ); return newlist; } // XXX Warning it is unsafe to use cl1 after a call to this function XXX vector> EvtMTree::unionChildren( const string& nodestr, vector>& cl1 ) { vector cl2 = parsenode( nodestr, false ); vector> cl; if ( cl1.size() == 0 ) { for ( size_t i = 0; i < cl2.size(); ++i ) { vector temp( 1, cl2[i] ); cl.push_back( temp ); } return cl; } for ( size_t i = 0; i < cl1.size(); ++i ) { for ( size_t j = 0; j < cl2.size(); ++j ) { vector temp; temp = duplicate( cl1[i] ); temp.push_back( cl2[j]->duplicate() ); cl.push_back( temp ); } } for ( size_t i = 0; i < cl1.size(); ++i ) for ( size_t j = 0; j < cl1[i].size(); ++j ) delete cl1[i][j]; for ( size_t i = 0; i < cl2.size(); ++i ) delete ( cl2[i] ); return cl; } vector> EvtMTree::parseChildren( ptype& c_iter, ptype& c_begin, ptype& c_end ) { bool test = true; int pcount = 0; string nodestr; vector> children; parseerror( c_iter == c_end || *c_iter != '[', c_iter, c_begin, c_end ); ++c_iter; while ( test ) { parseerror( c_iter == c_end || pcount < 0, c_iter, c_begin, c_end ); switch ( *c_iter ) { case ')': --pcount; nodestr += *c_iter; break; case '(': ++pcount; nodestr += *c_iter; break; case ']': if ( pcount == 0 ) { children = unionChildren( nodestr, children ); test = false; } else { nodestr += *c_iter; } break; case ',': if ( pcount == 0 ) { children = unionChildren( nodestr, children ); nodestr.clear(); } else { nodestr += *c_iter; } break; default: nodestr += *c_iter; break; } ++c_iter; } return children; } vector EvtMTree::parsenode( const string& args, bool rootnode ) { ptype c_iter, c_begin, c_end; c_iter = c_begin = args.begin(); c_end = args.end(); string strid = parseId( c_iter, c_begin, c_end ); // Case 1: Particle if ( c_iter == c_end ) return makeparticles( strid ); // Case 2: Resonance - parse further EvtId id = EvtPDL::getId( strid ); parseerror( EvtId( -1, -1 ) == id, c_iter, c_begin, c_end ); string ls; vector lsarg; if ( rootnode ) { ls = "TRIVIAL"; } else { // Get lineshape (e.g. BREITWIGNER) ls = parseKey( c_iter, c_begin, c_end ); lsarg = parseArg( c_iter, c_begin, c_end ); } // Get resonance parametrization type (e.g. HELAMP) string type = parseKey( c_iter, c_begin, c_end ); vector amps = parseAmps( c_iter, c_begin, c_end ); // Children vector> children = parseChildren( c_iter, c_begin, c_end ); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << children.size() << endl; vector resonances; for ( size_t i = 0; i < children.size(); ++i ) { resonances.push_back( makeresonance( id, ls, lsarg, type, amps, children[i] ) ); } parseerror( c_iter == c_end || *c_iter != ')', c_iter, c_begin, c_end ); return resonances; } bool EvtMTree::validTree( const EvtMNode* root ) const { vector res = root->getresonance(); vector check( res.size(), false ); for ( size_t i = 0; i < res.size(); ++i ) { check[res[i]] = true; } bool ret = true; for ( size_t i = 0; i < check.size(); ++i ) { ret = ret && check[i]; } // Function appears to check child integer indices, but this fails if they are // not always the first and second ones, so just return true for all cases ret = true; return ret; } void EvtMTree::addtree( const string& str ) { // vector roots = parsenode( str, true ); // Edit previous line to allow the creation of node resonances: vector roots = parsenode( str, false ); _norm = 0; for ( size_t i = 0; i < roots.size(); ++i ) { if ( validTree( roots[i] ) ) { _root.push_back( roots[i] ); _norm = _norm + 1; } else delete roots[i]; } _norm = 1.0 / sqrt( _norm ); } EvtSpinAmp EvtMTree::getrotation( EvtParticle* p ) const { // Set up the rotation matrix for the root particle (for now) EvtSpinDensity sd = p->rotateToHelicityBasis(); EvtSpinType::spintype type = EvtPDL::getSpinType( _root[0]->getid() ); int twospin = EvtSpinType::getSpin2( type ); vector types( 2, type ); EvtSpinAmp rot( types, EvtComplex( 0.0, 0.0 ) ); vector index = rot.iterallowedinit(); do { rot( index ) = sd.get( ( index[0] + twospin ) / 2, ( index[1] + twospin ) / 2 ); } while ( rot.iterateallowed( index ) ); return rot; } EvtSpinAmp EvtMTree::amplitude( EvtParticle* p ) const { vector product; for ( size_t i = 0; i < p->getNDaug(); ++i ) product.push_back( p->getDaug( i )->getP4Lab() ); if ( _root.size() == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "No decay tree present." << endl; ::abort(); } EvtSpinAmp amp = _root[0]->amplitude( product ); for ( size_t i = 1; i < _root.size(); ++i ) { // Assume that helicity amplitude is returned amp += _root[i]->amplitude( product ); } amp = _norm * amp; //ryd return amp; // Do Rotation to Proper Frame EvtSpinAmp newamp = getrotation( p ); newamp.extcont( amp, 1, 0 ); return newamp; } diff --git a/src/EvtGenBase/EvtModel.cpp b/src/EvtGenBase/EvtModel.cpp index a185f93..5f11a5b 100644 --- a/src/EvtGenBase/EvtModel.cpp +++ b/src/EvtGenBase/EvtModel.cpp @@ -1,102 +1,102 @@ /*********************************************************************** * 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/EvtModel.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParser.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleDecayList.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include #include #include #include #include using std::fstream; -EvtModel* EvtModel::_instance = 0; +EvtModel* EvtModel::_instance = nullptr; EvtModel::EvtModel() { } EvtDecayBase* EvtModel::getFcn( std::string model_name ) { - EvtDecayBase* model = 0; + EvtDecayBase* model = nullptr; if ( _modelNameHash.find( model_name ) != _modelNameHash.end() ) { model = _modelNameHash[model_name]; } - if ( model == 0 ) { + if ( model == nullptr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Did not find the right model:" << model_name.c_str() << "\n"; - return 0; + return nullptr; } return model->clone(); } void EvtModel::registerModel( EvtDecayBase* prototype ) { std::string modelName = prototype->getName(); _modelNameHash[modelName] = prototype; std::string commandName = prototype->commandName(); if ( commandName != "" ) { _commandNameHash[commandName] = prototype; } } int EvtModel::isModel( std::string model_name ) { if ( _modelNameHash.find( model_name ) != _modelNameHash.end() ) { return 1; } return 0; } int EvtModel::isCommand( std::string cmd ) { if ( _commandNameHash.find( cmd ) != _commandNameHash.end() ) { return 1; } return 0; } void EvtModel::storeCommand( std::string cmd, std::string cnfgstr ) { - EvtDecayBase* model = 0; + EvtDecayBase* model = nullptr; if ( _commandNameHash.find( cmd ) != _commandNameHash.end() ) { model = _commandNameHash[cmd]; } assert( model != 0 ); model->command( cnfgstr ); } diff --git a/src/EvtGenBase/EvtMultiChannelParser.cpp b/src/EvtGenBase/EvtMultiChannelParser.cpp index a163d96..5624951 100644 --- a/src/EvtGenBase/EvtMultiChannelParser.cpp +++ b/src/EvtGenBase/EvtMultiChannelParser.cpp @@ -1,259 +1,259 @@ /*********************************************************************** * 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/EvtMultiChannelParser.hh" #include "EvtGenBase/EvtDecayMode.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParser.hh" #include "EvtGenBase/EvtPatches.hh" #include #include #include #include #include #include using std::string; using std::vector; EvtDecayMode EvtMultiChannelParser::getDecayMode( const char* file ) { // Open file, read tokens EvtParser parser; parser.read( file ); // Seek Decay int i = 0; int N = parser.getNToken(); while ( i < N ) { std::string tok = parser.getToken( i++ ); if ( tok == std::string( "Decay" ) ) break; } // Get mother string mother = string( parser.getToken( i++ ).c_str() ); std::string bf = parser.getToken( i++ ); vector dauV; // Get daughters while ( 1 ) { std::string d = parser.getToken( i++ ); if ( EvtPDL::getStdHep( EvtPDL::getId( d.c_str() ) ) == 0 ) break; dauV.push_back( string( d.c_str() ) ); } EvtDecayMode mode( mother, dauV ); printf( "Decay File defines mode %s\n", mode.mode().c_str() ); return mode; } void EvtMultiChannelParser::parse( const char* file, const char* model ) { // Open file, read tokens EvtParser parser; parser.read( file ); // Get parameters (tokens between the model name and ;) int i = 0; int N = parser.getNToken(); // Seek the model name while ( i < N ) { std::string tok = parser.getToken( i++ ); if ( tok == std::string( model ) ) break; } if ( i == N ) { printf( "No model %s found in decay file %s", model, file ); exit( 0 ); } // Add all tokens up to a semicolon to vector std::vector v; while ( i < N ) { std::string tok = parser.getToken( i++ ); if ( tok == std::string( ";" ) ) break; else v.push_back( tok ); } if ( i == N ) { printf( "No terminating ; found in decay file %s", file ); assert( 0 ); } parse( v ); } void EvtMultiChannelParser::parse( const std::vector& v ) { // place holder for strtod - char** tc = 0; + char** tc = nullptr; // Get PDF maximum or number of points to // use in the scan. if ( v[0] == std::string( "MAXPDF" ) ) { _pdfMax = strtod( v[1].c_str(), tc ); if ( _pdfMax <= 0 ) { printf( "Bad pdfMax=%f\n", _pdfMax ); assert( 0 ); } } else if ( v[0] == std::string( "SCANPDF" ) ) { _nScan = atoi( v[1].c_str() ); } else { printf( "Error parsing decay file\n" ); assert( 0 ); } // Now parse the rest of file for amplitude specifications. bool conjugate = false; size_t i = 2; assert( isKeyword( v[2] ) ); while ( i < v.size() ) { size_t i0 = i; // Switch to conjugate amplitudes after keyword if ( v[i] == std::string( "CONJUGATE" ) ) { assert( conjugate == false ); conjugate = true; i++; _dm = strtod( v[i++].c_str(), tc ); _mixAmpli = strtod( v[i++].c_str(), tc ); _mixPhase = strtod( v[i++].c_str(), tc ); } if ( i >= v.size() ) break; std::vector params; EvtComplex c; int format; if ( !conjugate && v[i] == std::string( "AMPLITUDE" ) ) { while ( !isKeyword( v[++i] ) ) params.push_back( v[i] ); _amp.push_back( params ); parseComplexCoef( i, v, c, format ); _ampCoef.push_back( c ); _coefFormat.push_back( format ); continue; } else if ( conjugate && v[i] == std::string( "AMPLITUDE" ) ) { while ( !isKeyword( v[++i] ) ) params.push_back( v[i] ); _ampConj.push_back( params ); parseComplexCoef( i, v, c, format ); _ampConjCoef.push_back( c ); _coefConjFormat.push_back( format ); continue; } else { printf( "Expect keyword, found parameter %s\n", v[i].c_str() ); assert( 0 ); } assert( i > i0 ); _unused( i0 ); } printf( "PARSING SUCCESSFUL\n" ); printf( "%d amplitude terms\n", (int)_amp.size() ); printf( "%d conj amplitude terms\n", (int)_ampConj.size() ); } void EvtMultiChannelParser::parseComplexCoef( size_t& i, const std::vector& v, EvtComplex& c, int& format ) { // place holder for strtod - char** tc = 0; + char** tc = nullptr; std::string coefString = v[i++]; assert( coefString == std::string( "COEFFICIENT" ) ); if ( v[i] == std::string( "POLAR_DEG" ) ) { double mag = strtod( v[i + 1].c_str(), tc ); double phaseRad = strtod( v[i + 2].c_str(), tc ) * EvtConst::pi / 180.0; i += 3; c = EvtComplex( mag * cos( phaseRad ), mag * sin( phaseRad ) ); format = POLAR_DEG; } else if ( v[i] == std::string( "POLAR_RAD" ) ) { double mag = strtod( v[i + 1].c_str(), tc ); double phaseRad = strtod( v[i + 2].c_str(), tc ); i += 3; c = EvtComplex( mag * cos( phaseRad ), mag * sin( phaseRad ) ); format = POLAR_RAD; } else if ( v[i] == std::string( "CARTESIAN" ) ) { double re = strtod( v[i + 1].c_str(), tc ); double im = strtod( v[i + 2].c_str(), tc ); i += 3; c = EvtComplex( re, im ); format = CARTESIAN; } else { printf( "Invalid format %s for complex coefficient\n", v[i].c_str() ); exit( 0 ); } } double EvtMultiChannelParser::parseRealCoef( int& i, const std::vector& v ) { // place holder for strtod - char** tc = 0; + char** tc = nullptr; double value = 0; if ( v[i] == std::string( "COEFFICIENT" ) ) { value = strtod( v[i + 1].c_str(), tc ); } else assert( 0 ); i += 2; assert( value > 0. ); return value; } bool EvtMultiChannelParser::isKeyword( const std::string& s ) { if ( s == std::string( "AMPLITUDE" ) ) return true; if ( s == std::string( "CONJUGATE" ) ) return true; if ( s == std::string( "COEFFICIENT" ) ) return true; return false; } diff --git a/src/EvtGenBase/EvtParser.cpp b/src/EvtGenBase/EvtParser.cpp index 8b77f51..394a578 100644 --- a/src/EvtGenBase/EvtParser.cpp +++ b/src/EvtGenBase/EvtParser.cpp @@ -1,162 +1,162 @@ /*********************************************************************** * 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/EvtParser.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include using namespace std; #define MAXBUF 1024 EvtParser::EvtParser() { _ntoken = 0; _lengthoftokenlist = 0; - _tokenlist = 0; - _linelist = 0; + _tokenlist = nullptr; + _linelist = nullptr; } EvtParser::~EvtParser() { delete[] _tokenlist; delete[] _linelist; } int EvtParser::getNToken() { return _ntoken; } const std::string& EvtParser::getToken( int i ) { return _tokenlist[i]; } int EvtParser::getLineofToken( int i ) { return _linelist[i]; } int EvtParser::read( const std::string filename ) { ifstream fin; fin.open( filename.c_str() ); if ( !fin ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Could not open file '" << filename.c_str() << "'" << endl; return -1; } char buf[MAXBUF]; char buf2[MAXBUF]; char c; int line = 0; int i; while ( fin.peek() != EOF ) { line++; i = 0; while ( ( c = fin.get() ) != '\n' && c != EOF && i < MAXBUF ) { buf[i] = c; i++; } if ( i == MAXBUF ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error in EvtParser: line:" << line << " to long" << endl; } else { buf[i] = '\0'; } //search for '#' which indicates comment for rest of line! i = 0; do { if ( buf[i] == '#' ) buf[i] = 0; i++; } while ( buf[i - 1] != 0 ); string tmp( buf, strlen( buf ) ); //read each token istringstream ist( tmp ); while ( ist >> buf2 ) { i = 0; int semicolon = 0; do { if ( buf2[i] == ';' ) { buf2[i] = 0; semicolon = 1; } } while ( buf2[i++] != 0 ); if ( buf2[0] != 0 ) { addToken( line, buf2 ); } if ( semicolon ) addToken( line, ";" ); } } fin.close(); return 0; } void EvtParser::addToken( int line, const std::string& string ) { //EvtGenReport(EVTGEN_INFO,"EvtGen") <<_ntoken<<" "<. * ***********************************************************************/ #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; + _parent = nullptr; _channel = -10; _t = 0.0; _genlifetime = 1; _first = 1; _isInit = false; _validP4 = false; _isDecayed = false; - _decayProb = 0; + _decayProb = nullptr; _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::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() const { 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 != nullptr ) { 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; + EvtId* dauId = nullptr; + double* dauMasses = nullptr; 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; + EvtId* parId = nullptr; + EvtId* othDauId = nullptr; 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; + EvtId* dauId = nullptr; + double* dauMasses = nullptr; 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; + EvtId* parId = nullptr; + EvtId* othDauId = nullptr; 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 ) { + if ( decayer != nullptr ) { 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; + double* dMasses = nullptr; 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 ) { + while ( ptemp->getParent() != nullptr ) { 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 ) { + while ( ptemp->getParent() != nullptr ) { 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 ) + if ( ptemp == nullptr ) return temp; temp = ( ptemp->_t / ptemp->mass() ) * ( ptemp->getP4() ); - while ( ptemp->getParent() != 0 ) { + while ( ptemp->getParent() != nullptr ) { 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; + if ( bpart == nullptr ) + return nullptr; i = 0; while ( bpart->_daug[i] != current ) { i++; } if ( bpart == rootOfTree ) { if ( i + 1 == bpart->_ndaug ) - return 0; + return nullptr; } 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 ) + if ( _decayProb == nullptr ) _decayProb = new double; *_decayProb = prob; } std::string EvtParticle::getName() const { 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/EvtGenBase/EvtParticleDecay.cpp b/src/EvtGenBase/EvtParticleDecay.cpp index cb0c747..8ce5080 100644 --- a/src/EvtGenBase/EvtParticleDecay.cpp +++ b/src/EvtGenBase/EvtParticleDecay.cpp @@ -1,72 +1,72 @@ /*********************************************************************** * 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/EvtParticleDecay.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include #include #include #include using std::fstream; void EvtParticleDecay::printSummary() { - if ( _decay != 0 ) + if ( _decay != nullptr ) _decay->printSummary(); } void EvtParticleDecay::chargeConj( EvtParticleDecay* decay ) { _brfrsum = decay->_brfrsum; _massmin = decay->_massmin; _decay = decay->_decay->clone(); int ndaug = decay->_decay->getNDaug(); int narg = decay->_decay->getNArg(); double brfr = decay->_decay->getBranchingFraction(); std::string name = decay->_decay->getName(); EvtId ipar = EvtPDL::chargeConj( decay->_decay->getParentId() ); int i; EvtId* daug = new EvtId[ndaug]; for ( i = 0; i < ndaug; i++ ) { daug[i] = EvtPDL::chargeConj( decay->_decay->getDaug( i ) ); } //Had to add 1 to make sure the vector is not empty! std::vector args; for ( i = 0; i < narg; i++ ) { args.push_back( decay->_decay->getArgStr( i ) ); } _decay->saveDecayInfo( ipar, ndaug, daug, narg, args, name, brfr ); if ( decay->_decay->getPHOTOS() ) _decay->setPHOTOS(); delete[] daug; } diff --git a/src/EvtGenBase/EvtParticleDecayList.cpp b/src/EvtGenBase/EvtParticleDecayList.cpp index 2a563fe..ea8b3a3 100644 --- a/src/EvtGenBase/EvtParticleDecayList.cpp +++ b/src/EvtGenBase/EvtParticleDecayList.cpp @@ -1,463 +1,463 @@ /*********************************************************************** * 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/EvtParticleDecayList.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtStatus.hh" #include #include #include #include using std::endl; using std::fstream; EvtParticleDecayList::EvtParticleDecayList( const EvtParticleDecayList& o ) { _nmode = o._nmode; _rawbrfrsum = o._rawbrfrsum; _decaylist = new EvtParticleDecayPtr[_nmode]; int i; for ( i = 0; i < _nmode; i++ ) { _decaylist[i] = new EvtParticleDecay; EvtDecayBase* tModel = o._decaylist[i]->getDecayModel(); EvtDecayBase* tModelNew = tModel->clone(); if ( tModel->getPHOTOS() ) { tModelNew->setPHOTOS(); } if ( tModel->verbose() ) { tModelNew->setVerbose(); } if ( tModel->summary() ) { tModelNew->setSummary(); } std::vector args; int j; for ( j = 0; j < tModel->getNArg(); j++ ) { args.push_back( tModel->getArgStr( j ) ); } tModelNew->saveDecayInfo( tModel->getParentId(), tModel->getNDaug(), tModel->getDaugs(), tModel->getNArg(), args, tModel->getModelName(), tModel->getBranchingFraction() ); _decaylist[i]->setDecayModel( tModelNew ); _decaylist[i]->setBrfrSum( o._decaylist[i]->getBrfrSum() ); _decaylist[i]->setMassMin( o._decaylist[i]->getMassMin() ); } } EvtParticleDecayList::~EvtParticleDecayList() { int i; for ( i = 0; i < _nmode; i++ ) { delete _decaylist[i]; } - if ( _decaylist != 0 ) + if ( _decaylist != nullptr ) delete[] _decaylist; } void EvtParticleDecayList::printSummary() { int i; for ( i = 0; i < _nmode; i++ ) { _decaylist[i]->printSummary(); } } void EvtParticleDecayList::removeDecay() { int i; for ( i = 0; i < _nmode; i++ ) { delete _decaylist[i]; } delete[] _decaylist; - _decaylist = 0; + _decaylist = nullptr; _nmode = 0; _rawbrfrsum = 0.0; } EvtDecayBase* EvtParticleDecayList::getDecayModel( int imode ) { - EvtDecayBase* theModel( 0 ); + EvtDecayBase* theModel( nullptr ); if ( imode >= 0 && imode < _nmode ) { EvtParticleDecay* theDecay = _decaylist[imode]; - if ( theDecay != 0 ) { + if ( theDecay != nullptr ) { theModel = theDecay->getDecayModel(); } } return theModel; } EvtDecayBase* EvtParticleDecayList::getDecayModel( EvtParticle* p ) { if ( p->getNDaug() != 0 ) { assert( p->getChannel() >= 0 ); return getDecay( p->getChannel() ).getDecayModel(); } if ( p->getChannel() > ( -1 ) ) { return getDecay( p->getChannel() ).getDecayModel(); } if ( getNMode() == 0 ) { - return 0; + return nullptr; } if ( getRawBrfrSum() < 0.00000001 ) { - return 0; + return nullptr; } if ( getNMode() == 1 ) { p->setChannel( 0 ); return getDecay( 0 ).getDecayModel(); } if ( p->getChannel() > ( -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Internal error!!!" << endl; ::abort(); } int j; for ( j = 0; j < 10000000; j++ ) { double u = EvtRandom::Flat(); int i; bool breakL = false; for ( i = 0; i < getNMode(); i++ ) { if ( breakL ) continue; if ( u < getDecay( i ).getBrfrSum() ) { breakL = true; //special case for decay of on particel to another // e.g. K0->K0S if ( getDecay( i ).getDecayModel()->getNDaug() == 1 ) { p->setChannel( i ); return getDecay( i ).getDecayModel(); } if ( p->hasValidP4() ) { if ( getDecay( i ).getMassMin() < p->mass() ) { p->setChannel( i ); return getDecay( i ).getDecayModel(); } } else { //Lange apr29-2002 - dont know the mass yet p->setChannel( i ); return getDecay( i ).getDecayModel(); } } } } //Ok, we tried 10000000 times above to pick a decay channel that is //kinematically allowed! Now we give up and search all channels! //if that fails, the particle will not be decayed! EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Tried 10000000 times to generate decay of " << EvtPDL::name( p->getId() ) << " with mass=" << p->mass() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will take first kinematically allowed decay in the decay table" << endl; int i; //Need to check that we don't use modes with 0 branching fractions. double previousBrSum = 0.0; for ( i = 0; i < getNMode(); i++ ) { if ( getDecay( i ).getBrfrSum() != previousBrSum ) { if ( getDecay( i ).getMassMin() < p->mass() ) { p->setChannel( i ); return getDecay( i ).getDecayModel(); } } previousBrSum = getDecay( i ).getBrfrSum(); } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Could not decay:" << EvtPDL::name( p->getId() ).c_str() << " with mass:" << p->mass() << " will throw event away! " << endl; EvtStatus::setRejectFlag(); - return 0; + return nullptr; } void EvtParticleDecayList::setNMode( int nmode ) { EvtParticleDecayPtr* _decaylist_new = new EvtParticleDecayPtr[nmode]; if ( _nmode != 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error _nmode not equal to zero!!!" << endl; ::abort(); } - if ( _decaylist != 0 ) { + if ( _decaylist != nullptr ) { delete[] _decaylist; } _decaylist = _decaylist_new; _nmode = nmode; } EvtParticleDecay& EvtParticleDecayList::getDecay( int nchannel ) const { if ( nchannel >= _nmode ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error getting channel:" << nchannel << " with only " << _nmode << " stored!" << endl; ::abort(); } return *( _decaylist[nchannel] ); } void EvtParticleDecayList::makeChargeConj( EvtParticleDecayList* conjDecayList ) { _rawbrfrsum = conjDecayList->_rawbrfrsum; setNMode( conjDecayList->_nmode ); int i; for ( i = 0; i < _nmode; i++ ) { _decaylist[i] = new EvtParticleDecay; _decaylist[i]->chargeConj( conjDecayList->_decaylist[i] ); } } void EvtParticleDecayList::addMode( EvtDecayBase* decay, double brfrsum, double massmin ) { EvtParticleDecayPtr* newlist = new EvtParticleDecayPtr[_nmode + 1]; int i; for ( i = 0; i < _nmode; i++ ) { newlist[i] = _decaylist[i]; } _rawbrfrsum = brfrsum; newlist[_nmode] = new EvtParticleDecay; newlist[_nmode]->setDecayModel( decay ); newlist[_nmode]->setBrfrSum( brfrsum ); newlist[_nmode]->setMassMin( massmin ); EvtDecayBase* newDec = newlist[_nmode]->getDecayModel(); for ( i = 0; i < _nmode; i++ ) { if ( newDec->matchingDecay( *( newlist[i]->getDecayModel() ) ) ) { //sometimes its ok.. if ( newDec->getModelName() == "JETSET" || newDec->getModelName() == "PYTHIA" ) continue; if ( newDec->getModelName() == "JSCONT" || newDec->getModelName() == "PYCONT" ) continue; if ( newDec->getModelName() == "PYGAGA" ) continue; if ( newDec->getModelName() == "LUNDAREALAW" ) continue; if ( newDec->getModelName() == "TAUOLA" ) continue; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Two matching decays with same parent in decay table\n"; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Please fix that\n"; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parent " << EvtPDL::name( newDec->getParentId() ).c_str() << endl; for ( int j = 0; j < newDec->getNDaug(); j++ ) EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Daughter " << EvtPDL::name( newDec->getDaug( j ) ).c_str() << endl; assert( 0 ); } } if ( _nmode != 0 ) { delete[] _decaylist; } - if ( ( _nmode == 0 ) && ( _decaylist != 0 ) ) + if ( ( _nmode == 0 ) && ( _decaylist != nullptr ) ) delete[] _decaylist; _nmode++; _decaylist = newlist; } void EvtParticleDecayList::finalize() { if ( _nmode > 0 ) { if ( _rawbrfrsum < 0.000001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Please give me a " << "branching fraction sum greater than 0\n"; assert( 0 ); } if ( fabs( _rawbrfrsum - 1.0 ) > 0.0001 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Warning, sum of branching fractions for " << EvtPDL::name( _decaylist[0]->getDecayModel()->getParentId() ) .c_str() << " is " << _rawbrfrsum << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "rescaled to one! " << endl; } int i; for ( i = 0; i < _nmode; i++ ) { double brfrsum = _decaylist[i]->getBrfrSum() / _rawbrfrsum; _decaylist[i]->setBrfrSum( brfrsum ); } } } EvtParticleDecayList& EvtParticleDecayList::operator=( const EvtParticleDecayList& o ) { if ( this != &o ) { removeDecay(); _nmode = o._nmode; _rawbrfrsum = o._rawbrfrsum; _decaylist = new EvtParticleDecayPtr[_nmode]; int i; for ( i = 0; i < _nmode; i++ ) { _decaylist[i] = new EvtParticleDecay; EvtDecayBase* tModel = o._decaylist[i]->getDecayModel(); EvtDecayBase* tModelNew = tModel->clone(); if ( tModel->getPHOTOS() ) { tModelNew->setPHOTOS(); } if ( tModel->verbose() ) { tModelNew->setVerbose(); } if ( tModel->summary() ) { tModelNew->setSummary(); } std::vector args; int j; for ( j = 0; j < tModel->getNArg(); j++ ) { args.push_back( tModel->getArgStr( j ) ); } tModelNew->saveDecayInfo( tModel->getParentId(), tModel->getNDaug(), tModel->getDaugs(), tModel->getNArg(), args, tModel->getModelName(), tModel->getBranchingFraction() ); _decaylist[i]->setDecayModel( tModelNew ); //_decaylist[i]->setDecayModel(tModel); _decaylist[i]->setBrfrSum( o._decaylist[i]->getBrfrSum() ); _decaylist[i]->setMassMin( o._decaylist[i]->getMassMin() ); } } return *this; } void EvtParticleDecayList::removeMode( EvtDecayBase* decay ) { // here we will delete a decay with the same final state particles // and recalculate the branching fractions for the remaining modes int match = -1; int i; double match_bf; for ( i = 0; i < _nmode; i++ ) { if ( decay->matchingDecay( *( _decaylist[i]->getDecayModel() ) ) ) { match = i; } } if ( match < 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " Attempt to remove undefined mode for" << endl << "Parent " << EvtPDL::name( decay->getParentId() ).c_str() << endl << "Daughters: "; for ( int j = 0; j < decay->getNDaug(); j++ ) EvtGenReport( EVTGEN_ERROR, "" ) << EvtPDL::name( decay->getDaug( j ) ).c_str() << " "; EvtGenReport( EVTGEN_ERROR, "" ) << endl; ::abort(); } if ( match == 0 ) { match_bf = _decaylist[match]->getBrfrSum(); } else { match_bf = ( _decaylist[match]->getBrfrSum() - _decaylist[match - 1]->getBrfrSum() ); } double divisor = 1 - match_bf; if ( divisor < 0.000001 && _nmode > 1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Removing requested mode leaves " << EvtPDL::name( decay->getParentId() ).c_str() << " with zero sum branching fraction," << endl << "but more than one decay mode remains. Aborting." << endl; ::abort(); } EvtParticleDecayPtr* newlist = new EvtParticleDecayPtr[_nmode - 1]; for ( i = 0; i < match; i++ ) { newlist[i] = _decaylist[i]; newlist[i]->setBrfrSum( newlist[i]->getBrfrSum() / divisor ); } for ( i = match + 1; i < _nmode; i++ ) { newlist[i - 1] = _decaylist[i]; newlist[i - 1]->setBrfrSum( ( newlist[i - 1]->getBrfrSum() - match_bf ) / divisor ); } delete[] _decaylist; _nmode--; _decaylist = newlist; if ( _nmode == 0 ) { delete[] _decaylist; } } bool EvtParticleDecayList::isJetSet() const { int i; EvtDecayBase* decayer; for ( i = 0; i < getNMode(); i++ ) { decayer = getDecay( i ).getDecayModel(); if ( decayer->getModelName() == "PYTHIA" ) return true; } return false; } diff --git a/src/EvtGenBase/EvtParticleFactory.cpp b/src/EvtGenBase/EvtParticleFactory.cpp index a8c22ae..7db0339 100644 --- a/src/EvtGenBase/EvtParticleFactory.cpp +++ b/src/EvtGenBase/EvtParticleFactory.cpp @@ -1,207 +1,207 @@ /*********************************************************************** * 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/EvtParticleFactory.hh" #include "EvtGenBase/EvtDiracParticle.hh" #include "EvtGenBase/EvtHighSpinParticle.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtNeutrinoParticle.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPhotonParticle.hh" #include "EvtGenBase/EvtRaritaSchwingerParticle.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtStringParticle.hh" #include "EvtGenBase/EvtTensorParticle.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include #include #include #include using std::endl; EvtParticle* EvtParticleFactory::particleFactory( EvtSpinType::spintype spinType ) { if ( spinType == EvtSpinType::SCALAR ) { return new EvtScalarParticle; } if ( spinType == EvtSpinType::VECTOR ) { return new EvtVectorParticle; } if ( spinType == EvtSpinType::DIRAC ) { return new EvtDiracParticle; } if ( spinType == EvtSpinType::NEUTRINO ) { return new EvtNeutrinoParticle; } if ( spinType == EvtSpinType::PHOTON ) { return new EvtPhotonParticle; } if ( spinType == EvtSpinType::TENSOR ) { return new EvtTensorParticle; } if ( spinType == EvtSpinType::STRING ) { return new EvtStringParticle; } if ( spinType == EvtSpinType::RARITASCHWINGER ) { return new EvtRaritaSchwingerParticle; } if ( spinType == EvtSpinType::SPIN5HALF ) { return new EvtHighSpinParticle; } if ( spinType == EvtSpinType::SPIN3 ) { return new EvtHighSpinParticle; } if ( spinType == EvtSpinType::SPIN7HALF ) { return new EvtHighSpinParticle; } if ( spinType == EvtSpinType::SPIN4 ) { return new EvtHighSpinParticle; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error in EvtParticleFactory::particleFactory" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Tried to create non-existing particle" << " with spin type:" << spinType << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution" << endl; ::abort(); - return 0; + return nullptr; } EvtParticle* EvtParticleFactory::particleFactory( EvtId id, EvtVector4R p4, EvtSpinDensity rho ) { EvtSpinType::spintype thisSpin = EvtPDL::getSpinType( id ); if ( thisSpin == EvtSpinType::SCALAR ) { EvtScalarParticle* myPart; myPart = new EvtScalarParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::VECTOR ) { EvtVectorParticle* myPart; myPart = new EvtVectorParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::DIRAC ) { EvtDiracParticle* myPart; myPart = new EvtDiracParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::NEUTRINO ) { EvtNeutrinoParticle* myPart; myPart = new EvtNeutrinoParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::PHOTON ) { EvtPhotonParticle* myPart; myPart = new EvtPhotonParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::TENSOR ) { EvtTensorParticle* myPart; myPart = new EvtTensorParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::STRING ) { EvtStringParticle* myPart; myPart = new EvtStringParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::SPIN3 ) { EvtHighSpinParticle* myPart; myPart = new EvtHighSpinParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::SPIN5HALF ) { EvtHighSpinParticle* myPart; myPart = new EvtHighSpinParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::SPIN7HALF ) { EvtHighSpinParticle* myPart; myPart = new EvtHighSpinParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::RARITASCHWINGER ) { EvtRaritaSchwingerParticle* myPart; myPart = new EvtRaritaSchwingerParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } if ( thisSpin == EvtSpinType::SPIN4 ) { EvtHighSpinParticle* myPart; myPart = new EvtHighSpinParticle; myPart->init( id, p4 ); myPart->setSpinDensityForward( rho ); return myPart; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error in EvtParticleFactory::particleFactory" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Tried to create non-existing particle" << " with spin type:" << thisSpin << " and name:" << EvtPDL::name( id ).c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution" << endl; ::abort(); - return 0; + return nullptr; } EvtParticle* EvtParticleFactory::particleFactory( EvtId id, EvtVector4R p4 ) { EvtSpinDensity rho; rho.setDiag( EvtSpinType::getSpinStates( EvtPDL::getSpinType( id ) ) ); return particleFactory( id, p4, rho ); } diff --git a/src/EvtGenBase/EvtPto3PAmp.cpp b/src/EvtGenBase/EvtPto3PAmp.cpp index 1ee4410..f21b559 100644 --- a/src/EvtGenBase/EvtPto3PAmp.cpp +++ b/src/EvtGenBase/EvtPto3PAmp.cpp @@ -1,218 +1,218 @@ /*********************************************************************** * 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/EvtPto3PAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtCyclic3.hh" #include "EvtGenBase/EvtDalitzCoord.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtdFunction.hh" #include #include #include using EvtCyclic3::Index; using EvtCyclic3::Pair; using std::endl; EvtPto3PAmp::EvtPto3PAmp( EvtDalitzPlot dp, Pair pairAng, Pair pairRes, EvtSpinType::spintype spin, const EvtPropagator& prop, NumType typeN ) : EvtAmplitude(), _pairAng( pairAng ), _pairRes( pairRes ), _spin( spin ), _typeN( typeN ), _prop( (EvtPropagator*)prop.clone() ), _g0( prop.g0() ), _min( 0 ), _max( 0 ), _vb( prop.m0(), dp.m( EvtCyclic3::other( pairRes ) ), dp.bigM(), spin ), _vd( dp.m( EvtCyclic3::first( pairRes ) ), dp.m( EvtCyclic3::second( pairRes ) ), prop.m0(), spin ) { } EvtPto3PAmp::EvtPto3PAmp( const EvtPto3PAmp& other ) : EvtAmplitude( other ), _pairAng( other._pairAng ), _pairRes( other._pairRes ), _spin( other._spin ), _typeN( other._typeN ), - _prop( ( other._prop ) ? (EvtPropagator*)other._prop->clone() : 0 ), + _prop( ( other._prop ) ? (EvtPropagator*)other._prop->clone() : nullptr ), _g0( other._g0 ), _min( other._min ), _max( other._max ), _vb( other._vb ), _vd( other._vd ) { } EvtPto3PAmp::~EvtPto3PAmp() { if ( _prop ) delete _prop; } void EvtPto3PAmp::set_fd( double R ) { _vd.set_f( R ); } void EvtPto3PAmp::set_fb( double R ) { _vb.set_f( R ); } EvtComplex EvtPto3PAmp::amplitude( const EvtDalitzPoint& x ) const { EvtComplex amp( 1.0, 0.0 ); double m = sqrt( x.q( _pairRes ) ); if ( ( _max > 0 && m > _max ) || ( _min > 0 && m < _min ) ) return EvtComplex( 0.0, 0.0 ); EvtTwoBodyKine vd( x.m( EvtCyclic3::first( _pairRes ) ), x.m( EvtCyclic3::second( _pairRes ) ), m ); EvtTwoBodyKine vb( m, x.m( EvtCyclic3::other( _pairRes ) ), x.bigM() ); // Compute mass-dependent width for relativistic propagators if ( _typeN != NBW && _typeN != FLATTE ) { _prop->set_g0( _g0 * _vd.widthFactor( vd ) ); } // Compute propagator amp *= evalPropagator( m ); // Compute form-factors amp *= _vd.formFactor( vd ); amp *= _vb.formFactor( vb ); amp *= numerator( x ); return amp; } EvtComplex EvtPto3PAmp::numerator( const EvtDalitzPoint& x ) const { EvtComplex ret( 0., 0. ); double m = sqrt( x.q( _pairRes ) ); EvtTwoBodyKine vd( x.m( EvtCyclic3::first( _pairRes ) ), x.m( EvtCyclic3::second( _pairRes ) ), m ); EvtTwoBodyKine vb( m, x.m( EvtCyclic3::other( _pairRes ) ), x.bigM() ); // Non-relativistic Breit-Wigner if ( NBW == _typeN ) { ret = angDep( x ); } // Standard relativistic Zemach propagator else if ( RBW_ZEMACH == _typeN ) { ret = _vd.phaseSpaceFactor( vd, EvtTwoBodyKine::AB ) * angDep( x ); } // Kuehn-Santamaria normalization: else if ( RBW_KUEHN == _typeN ) { ret = _prop->m0() * _prop->m0() * angDep( x ); } // CLEO amplitude is not factorizable // // The CLEO amplitude numerator is proportional to: // // m2_AC - m2_BC + (m2_D - m2_C)(m2_B - m2_A)/m2_0 // // m2_AC = (eA + eC)^2 + (P - P_C cosTh(BC))^2 // m2_BC = (eB + eC)^2 + (P + P_C cosTh(BC))^2 // // The first term m2_AB-m2_BC is therefore a p-wave term // - 4PP_C cosTh(BC) // The second term is an s-wave, the amplitude // does not factorize! // // The first term is just Zemach. However, the sign is flipped! // Let's consistently use the convention in which the amplitude // is proportional to +cosTh(BC). In the CLEO expressions, I will // therefore exchange AB to get rid of the sign flip. if ( RBW_CLEO == _typeN || FLATTE == _typeN || GS == _typeN ) { Index iA = EvtCyclic3::other( _pairAng ); // A = other(BC) Index iB = EvtCyclic3::common( _pairRes, _pairAng ); // B = common(AB,BC) Index iC = EvtCyclic3::other( _pairRes ); // C = other(AB) double M = x.bigM(); double mA = x.m( iA ); double mB = x.m( iB ); double mC = x.m( iC ); double qAB = x.q( EvtCyclic3::combine( iA, iB ) ); double qBC = x.q( EvtCyclic3::combine( iB, iC ) ); double qCA = x.q( EvtCyclic3::combine( iC, iA ) ); //double m0 = _prop->m0(); if ( _spin == EvtSpinType::SCALAR ) ret = EvtComplex( 1., 0. ); else if ( _spin == EvtSpinType::VECTOR ) { //ret = qCA - qBC - (M*M - mC*mC)*(mA*mA - mB*mB)/m0/m0; ret = qCA - qBC - ( M * M - mC * mC ) * ( mA * mA - mB * mB ) / qAB; } else if ( _spin == EvtSpinType::TENSOR ) { //double x1 = qBC - qCA + (M*M - mC*mC)*(mA*mA - mB*mB)/m0/m0; double x1 = qBC - qCA + ( M * M - mC * mC ) * ( mA * mA - mB * mB ) / qAB; double x2 = M * M - mC * mC; //double x3 = qAB - 2*M*M - 2*mC*mC + x2*x2/m0/m0; double x3 = qAB - 2 * M * M - 2 * mC * mC + x2 * x2 / qAB; double x4 = mB * mB - mA * mA; //double x5 = qAB - 2*mB*mB - 2*mA*mA + x4*x4/m0/m0; double x5 = qAB - 2 * mB * mB - 2 * mA * mA + x4 * x4 / qAB; ret = ( x1 * x1 - 1. / 3. * x3 * x5 ); } else assert( 0 ); } return ret; } double EvtPto3PAmp::angDep( const EvtDalitzPoint& x ) const { // Angular dependece for factorizable amplitudes // unphysical cosines indicate we are in big trouble double cosTh = x.cosTh( _pairAng, _pairRes ); if ( fabs( cosTh ) > 1. ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "cosTh " << cosTh << endl; assert( 0 ); } // in units of half-spin return EvtdFunction::d( EvtSpinType::getSpin2( _spin ), 2 * 0, 2 * 0, acos( cosTh ) ); } diff --git a/src/EvtGenBase/EvtPto3PAmpFactory.cpp b/src/EvtGenBase/EvtPto3PAmpFactory.cpp index 94f4e9b..e2ec6a3 100644 --- a/src/EvtGenBase/EvtPto3PAmpFactory.cpp +++ b/src/EvtGenBase/EvtPto3PAmpFactory.cpp @@ -1,371 +1,371 @@ /*********************************************************************** * 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/EvtPto3PAmpFactory.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtCyclic3.hh" #include "EvtGenBase/EvtDalitzFlatPdf.hh" #include "EvtGenBase/EvtDalitzResPdf.hh" #include "EvtGenBase/EvtFlatAmp.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtLASSAmp.hh" #include "EvtGenBase/EvtNonresonantAmp.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPropBreitWigner.hh" #include "EvtGenBase/EvtPropBreitWignerRel.hh" #include "EvtGenBase/EvtPropFlatte.hh" #include "EvtGenBase/EvtPto3PAmp.hh" #include "EvtGenBase/EvtSpinType.hh" #include #include #include #include #include using namespace EvtCyclic3; #include void EvtPto3PAmpFactory::processAmp( EvtComplex c, std::vector vv, bool conj ) { if ( _verbose ) { printf( "Make %samplitude\n", conj ? "CP conjugate" : "" ); unsigned i; for ( i = 0; i < vv.size(); i++ ) printf( "%s\n", vv[i].c_str() ); printf( "\n" ); } std::unique_ptr> amp; std::unique_ptr> pdf; std::string name; Pair pairRes = AB; size_t i; /* Experimental amplitudes */ if ( vv[0] == "PHASESPACE" ) { pdf = std::make_unique( _dp ); amp = std::make_unique>(); name = "NR"; } else if ( !vv[0].find( "NONRES" ) ) { double alpha = 0; EvtPto3PAmp::NumType typeNRes = EvtPto3PAmp::NONRES; if ( vv[0] == "NONRES_LIN" ) { typeNRes = EvtPto3PAmp::NONRES_LIN; pairRes = strToPair( vv[1].c_str() ); } else if ( vv[0] == "NONRES_EXP" ) { typeNRes = EvtPto3PAmp::NONRES_EXP; pairRes = strToPair( vv[1].c_str() ); - alpha = strtod( vv[2].c_str(), 0 ); + alpha = strtod( vv[2].c_str(), nullptr ); } else assert( 0 ); pdf = std::make_unique( _dp ); amp = std::make_unique( &_dp, typeNRes, pairRes, alpha ); } else if ( vv[0] == "LASS" || vv[0] == "LASS_ELASTIC" || vv[0] == "LASS_RESONANT" ) { pairRes = strToPair( vv[1].c_str() ); - double m0 = strtod( vv[2].c_str(), 0 ); - double g0 = strtod( vv[3].c_str(), 0 ); - double a = strtod( vv[4].c_str(), 0 ); - double r = strtod( vv[5].c_str(), 0 ); - double cutoff = strtod( vv[6].c_str(), 0 ); + double m0 = strtod( vv[2].c_str(), nullptr ); + double g0 = strtod( vv[3].c_str(), nullptr ); + double a = strtod( vv[4].c_str(), nullptr ); + double r = strtod( vv[5].c_str(), nullptr ); + double cutoff = strtod( vv[6].c_str(), nullptr ); pdf = std::make_unique( _dp, m0, g0, pairRes ); amp = std::make_unique( &_dp, pairRes, m0, g0, a, r, cutoff, vv[0] ); } /* Resonant amplitudes */ else if ( vv[0] == "RESONANCE" ) { std::unique_ptr partAmp; // RESONANCE stanza pairRes = strToPair( vv[1].c_str() ); EvtSpinType::spintype spinR = EvtSpinType::SCALAR; double mR, gR; name = vv[2]; EvtId resId = EvtPDL::getId( vv[2] ); if ( _verbose ) printf( "Particles %s form %sresonance %s\n", vv[1].c_str(), vv[2].c_str(), conj ? "(conj) " : "" ); // If no valid particle name is given, assume that // it is the spin, the mass and the width of the particle. if ( resId.getId() == -1 ) { switch ( atoi( vv[2].c_str() ) ) { case 0: { spinR = EvtSpinType::SCALAR; break; } case 1: { spinR = EvtSpinType::VECTOR; break; } case 2: { spinR = EvtSpinType::TENSOR; break; } case 3: { spinR = EvtSpinType::SPIN3; break; } case 4: { spinR = EvtSpinType::SPIN4; break; } default: { assert( 0 ); break; } } - mR = strtod( vv[3].c_str(), 0 ); - gR = strtod( vv[4].c_str(), 0 ); + mR = strtod( vv[3].c_str(), nullptr ); + gR = strtod( vv[4].c_str(), nullptr ); i = 4; } else { // For a valid particle get spin, mass and width spinR = EvtPDL::getSpinType( resId ); mR = EvtPDL::getMeanMass( resId ); gR = EvtPDL::getWidth( resId ); i = 2; // It's possible to specify mass and width of a particle // explicitly if ( vv[3] != "ANGULAR" ) { if ( _verbose ) printf( "Setting m(%s)=%s g(%s)=%s\n", vv[2].c_str(), vv[3].c_str(), vv[2].c_str(), vv[4].c_str() ); - mR = strtod( vv[3].c_str(), 0 ); - gR = strtod( vv[4].c_str(), 0 ); + mR = strtod( vv[3].c_str(), nullptr ); + gR = strtod( vv[4].c_str(), nullptr ); i = 4; } } // ANGULAR stanza if ( vv[++i] != "ANGULAR" ) { printf( "%s instead of ANGULAR\n", vv[i].c_str() ); exit( 0 ); } Pair pairAng = strToPair( vv[++i].c_str() ); if ( _verbose ) printf( "Angle is measured between particles %s\n", vv[i].c_str() ); // TYPE stanza std::string typeName = vv[++i]; assert( typeName == "TYPE" ); std::string type = vv[++i]; if ( _verbose ) printf( "Propagator type %s\n", vv[i].c_str() ); if ( type == "NBW" ) { EvtPropBreitWigner prop( mR, gR ); partAmp = std::make_unique( _dp, pairAng, pairRes, spinR, prop, EvtPto3PAmp::NBW ); } else if ( type == "RBW_ZEMACH" ) { EvtPropBreitWignerRel prop( mR, gR ); partAmp = std::make_unique( _dp, pairAng, pairRes, spinR, prop, EvtPto3PAmp::RBW_ZEMACH ); } else if ( type == "RBW_KUEHN" ) { EvtPropBreitWignerRel prop( mR, gR ); partAmp = std::make_unique( _dp, pairAng, pairRes, spinR, prop, EvtPto3PAmp::RBW_KUEHN ); } else if ( type == "RBW_CLEO" ) { EvtPropBreitWignerRel prop( mR, gR ); partAmp = std::make_unique( _dp, pairAng, pairRes, spinR, prop, EvtPto3PAmp::RBW_CLEO ); } else if ( type == "FLATTE" ) { double m1a = _dp.m( first( pairRes ) ); double m1b = _dp.m( second( pairRes ) ); // 2nd channel - double g2 = strtod( vv[++i].c_str(), 0 ); - double m2a = strtod( vv[++i].c_str(), 0 ); - double m2b = strtod( vv[++i].c_str(), 0 ); + double g2 = strtod( vv[++i].c_str(), nullptr ); + double m2a = strtod( vv[++i].c_str(), nullptr ); + double m2b = strtod( vv[++i].c_str(), nullptr ); EvtPropFlatte prop( mR, gR, m1a, m1b, g2, m2a, m2b ); partAmp = std::make_unique( _dp, pairAng, pairRes, spinR, prop, EvtPto3PAmp::FLATTE ); } else assert( 0 ); // Optional DVFF, BVFF stanzas if ( i < vv.size() - 1 ) { if ( vv[i + 1] == "DVFF" ) { i++; if ( vv[++i] == "BLATTWEISSKOPF" ) { - double R = strtod( vv[++i].c_str(), 0 ); + double R = strtod( vv[++i].c_str(), nullptr ); partAmp->set_fd( R ); } else assert( 0 ); } } if ( i < vv.size() - 1 ) { if ( vv[i + 1] == "BVFF" ) { i++; if ( vv[++i] == "BLATTWEISSKOPF" ) { if ( _verbose ) printf( "BVFF=%s\n", vv[i].c_str() ); - double R = strtod( vv[++i].c_str(), 0 ); + double R = strtod( vv[++i].c_str(), nullptr ); partAmp->set_fb( R ); } else assert( 0 ); } } const int minwidths = 5; //Optional resonance minimum and maximum if ( i < vv.size() - 1 ) { if ( vv[i + 1] == "CUTOFF" ) { i++; if ( vv[i + 1] == "MIN" ) { i++; - double min = strtod( vv[++i].c_str(), 0 ); + double min = strtod( vv[++i].c_str(), nullptr ); if ( _verbose ) std::cout << "CUTOFF MIN = " << min << " " << minwidths << std::endl; //ensure against cutting off too close to the resonance assert( min < ( mR - minwidths * gR ) ); partAmp->setmin( min ); } else if ( vv[i + 1] == "MAX" ) { i++; - double max = strtod( vv[++i].c_str(), 0 ); + double max = strtod( vv[++i].c_str(), nullptr ); if ( _verbose ) std::cout << "CUTOFF MAX = " << max << " " << minwidths << std::endl; //ensure against cutting off too close to the resonance assert( max > ( mR + minwidths * gR ) ); partAmp->setmax( max ); } else assert( 0 ); } } //2nd iteration in case min and max are both specified if ( i < vv.size() - 1 ) { if ( vv[i + 1] == "CUTOFF" ) { i++; if ( vv[i + 1] == "MIN" ) { i++; - double min = strtod( vv[++i].c_str(), 0 ); + double min = strtod( vv[++i].c_str(), nullptr ); if ( _verbose ) std::cout << "CUTOFF MIN = " << min << std::endl; //ensure against cutting off too close to the resonance assert( min < ( mR - minwidths * gR ) ); partAmp->setmin( min ); } else if ( vv[i + 1] == "MAX" ) { i++; - double max = strtod( vv[++i].c_str(), 0 ); + double max = strtod( vv[++i].c_str(), nullptr ); if ( _verbose ) std::cout << "CUTOFF MAX = " << max << std::endl; //ensure against cutting off too close to the resonance assert( max > ( mR + minwidths * gR ) ); partAmp->setmax( max ); } else assert( 0 ); } } i++; pdf = std::make_unique( _dp, mR, gR, pairRes ); amp = std::move( partAmp ); } assert( amp ); assert( pdf ); double scale = matchIsobarCoef( *amp, *pdf, pairRes ); if ( !conj ) { _amp->addOwnedTerm( c, std::move( amp ) ); } else { _ampConj->addOwnedTerm( c, std::move( amp ) ); } _pc->addOwnedTerm( abs2( c ) * scale, std::move( pdf ) ); _names.push_back( name ); } double EvtPto3PAmpFactory::matchIsobarCoef( EvtAmplitude& amp, EvtPdf& pdf, EvtCyclic3::Pair ipair ) { // account for differences in the definition of amplitudes by matching // Integral( c'*pdf ) = Integral( c*|A|^2 ) // to improve generation efficiency ... double Ipdf = pdf.compute_integral( 10000 ).value(); double Iamp2 = 0; EvtCyclic3::Pair jpair = EvtCyclic3::next( ipair ); EvtCyclic3::Pair kpair = EvtCyclic3::next( jpair ); // Trapezoidal integral int N = 10000; double di = ( _dp.qAbsMax( ipair ) - _dp.qAbsMin( ipair ) ) / ( (double)N ); double siMin = _dp.qAbsMin( ipair ); double s[3]; // playing with fire for ( int i = 1; i < N; i++ ) { s[ipair] = siMin + di * i; s[jpair] = _dp.q( jpair, 0.9999, ipair, s[ipair] ); s[kpair] = _dp.bigM() * _dp.bigM() - s[ipair] - s[jpair] + _dp.mA() * _dp.mA() + _dp.mB() * _dp.mB() + _dp.mC() * _dp.mC(); EvtDalitzPoint point( _dp.mA(), _dp.mB(), _dp.mC(), s[EvtCyclic3::AB], s[EvtCyclic3::BC], s[EvtCyclic3::CA] ); if ( !point.isValid() ) continue; double p = point.p( other( ipair ), ipair ); double q = point.p( first( ipair ), ipair ); double itg = abs2( amp.evaluate( point ) ) * di * 4 * q * p; Iamp2 += itg; } if ( _verbose ) std::cout << "integral = " << Iamp2 << " pdf=" << Ipdf << std::endl; assert( Ipdf > 0 && Iamp2 > 0 ); return Iamp2 / Ipdf; } diff --git a/src/EvtGenBase/EvtRadCorr.cpp b/src/EvtGenBase/EvtRadCorr.cpp index 73554f0..322494e 100644 --- a/src/EvtGenBase/EvtRadCorr.cpp +++ b/src/EvtGenBase/EvtRadCorr.cpp @@ -1,91 +1,91 @@ /*********************************************************************** * 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/EvtRadCorr.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include #include using std::endl; -EvtAbsRadCorr* EvtRadCorr::_fsrEngine = 0; +EvtAbsRadCorr* EvtRadCorr::_fsrEngine = nullptr; bool EvtRadCorr::_alwaysRadCorr = false; bool EvtRadCorr::_neverRadCorr = false; EvtRadCorr::EvtRadCorr() { - _fsrEngine = 0; + _fsrEngine = nullptr; _alwaysRadCorr = false; _neverRadCorr = false; } EvtRadCorr::~EvtRadCorr() { if ( _fsrEngine ) delete _fsrEngine; - _fsrEngine = 0; + _fsrEngine = nullptr; } void EvtRadCorr::setRadCorrEngine( EvtAbsRadCorr* fsrEngine ) { _fsrEngine = fsrEngine; } void EvtRadCorr::doRadCorr( EvtParticle* p ) { - if ( _fsrEngine == 0 ) { + if ( _fsrEngine == nullptr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "No RadCorr model available in " << "EvtRadCorr::doRadCorr()." << endl; ::abort(); } if ( !_neverRadCorr ) _fsrEngine->doRadCorr( p ); return; } bool EvtRadCorr::alwaysRadCorr() { return _alwaysRadCorr; } bool EvtRadCorr::neverRadCorr() { return _neverRadCorr; } void EvtRadCorr::setAlwaysRadCorr() { _alwaysRadCorr = true; _neverRadCorr = false; } void EvtRadCorr::setNeverRadCorr() { _alwaysRadCorr = false; _neverRadCorr = true; } void EvtRadCorr::setNormalRadCorr() { _alwaysRadCorr = false; _neverRadCorr = false; } diff --git a/src/EvtGenBase/EvtRandom.cpp b/src/EvtGenBase/EvtRandom.cpp index 9fc4ee2..60cef07 100644 --- a/src/EvtGenBase/EvtRandom.cpp +++ b/src/EvtGenBase/EvtRandom.cpp @@ -1,83 +1,83 @@ /*********************************************************************** * 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/EvtRandom.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandomEngine.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include #include using std::endl; -EvtRandomEngine* EvtRandom::_randomEngine = 0; +EvtRandomEngine* EvtRandom::_randomEngine = nullptr; void EvtRandom::setRandomEngine( EvtRandomEngine* randomEngine ) { _randomEngine = randomEngine; } double EvtRandom::random() { - if ( _randomEngine == 0 ) { + if ( _randomEngine == nullptr ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "No random engine available in " << "EvtRandom::random()." << endl; ::abort(); } return _randomEngine->random(); } // Random number routine to generate numbers between // min and max. By djl on July 27, 1995. double EvtRandom::Flat( double min, double max ) { if ( min > max ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "min>max in EvtRandom::Flat(" << min << "," << max << ")" << endl; ::abort(); } return EvtRandom::random() * ( max - min ) + min; } double EvtRandom::Flat( double max ) { return max * EvtRandom::random(); } double EvtRandom::Flat() { return EvtRandom::random(); } double EvtRandom::Gaussian() { double x = EvtRandom::random(); double y = EvtRandom::random(); return cos( x * EvtConst::twoPi ) * sqrt( -2.0 * log( 1 - y ) ); } diff --git a/src/EvtGenBase/EvtReport.cpp b/src/EvtGenBase/EvtReport.cpp index 3ba688d..9670f2f 100644 --- a/src/EvtGenBase/EvtReport.cpp +++ b/src/EvtGenBase/EvtReport.cpp @@ -1,51 +1,51 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtPatches.hh" using std::cerr; using std::cout; using std::endl; using std::ostream; // // constants, enums and typedefs // ostream& EvtGenReport( EvtGenSeverity severity, const char* facility ) { int printNoFacility = 1; - if ( ( facility == 0 ) && ( printNoFacility == 1 ) ) { + if ( ( facility == nullptr ) && ( printNoFacility == 1 ) ) { cout << "There is no `facility' implemented in `report'" << endl; printNoFacility = 0; } if ( severity < EVTGEN_WARNING ) { if ( facility[0] != 0 ) { cerr << facility << ":"; } return ( cerr ); } if ( facility[0] != 0 ) { cout << facility << ":"; } return cout; } diff --git a/src/EvtGenBase/EvtSpinDensity.cpp b/src/EvtGenBase/EvtSpinDensity.cpp index b75629e..5457379 100644 --- a/src/EvtGenBase/EvtSpinDensity.cpp +++ b/src/EvtGenBase/EvtSpinDensity.cpp @@ -1,222 +1,222 @@ /*********************************************************************** * 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/EvtSpinDensity.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include #include using std::endl; using std::ostream; EvtSpinDensity::EvtSpinDensity( const EvtSpinDensity& density ) { dim = 0; - rho = 0; + rho = nullptr; int i, j; setDim( density.dim ); for ( i = 0; i < dim; i++ ) { for ( j = 0; j < dim; j++ ) { rho[i][j] = density.rho[i][j]; } } } EvtSpinDensity& EvtSpinDensity::operator=( const EvtSpinDensity& density ) { int i, j; setDim( density.dim ); for ( i = 0; i < dim; i++ ) { for ( j = 0; j < dim; j++ ) { rho[i][j] = density.rho[i][j]; } } return *this; } EvtSpinDensity::~EvtSpinDensity() { if ( dim != 0 ) { int i; for ( i = 0; i < dim; i++ ) delete[] rho[i]; } delete[] rho; } EvtSpinDensity::EvtSpinDensity() { dim = 0; - rho = 0; + rho = nullptr; } void EvtSpinDensity::setDim( int n ) { if ( dim == n ) return; if ( dim != 0 ) { int i; for ( i = 0; i < dim; i++ ) delete[] rho[i]; delete[] rho; - rho = 0; + rho = nullptr; dim = 0; } if ( n == 0 ) return; dim = n; rho = new EvtComplexPtr[n]; int i; for ( i = 0; i < n; i++ ) { rho[i] = new EvtComplex[n]; } } int EvtSpinDensity::getDim() const { return dim; } void EvtSpinDensity::set( int i, int j, const EvtComplex& rhoij ) { assert( i < dim && j < dim ); rho[i][j] = rhoij; } const EvtComplex& EvtSpinDensity::get( int i, int j ) const { assert( i < dim && j < dim ); return rho[i][j]; } void EvtSpinDensity::setDiag( int n ) { setDim( n ); int i, j; for ( i = 0; i < n; i++ ) { for ( j = 0; j < n; j++ ) { rho[i][j] = EvtComplex( 0.0 ); } rho[i][i] = EvtComplex( 1.0 ); } } double EvtSpinDensity::normalizedProb( const EvtSpinDensity& d ) { int i, j; EvtComplex prob( 0.0, 0.0 ); double norm = 0.0; if ( dim != d.dim ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Not matching dimensions in NormalizedProb" << endl; ::abort(); } for ( i = 0; i < dim; i++ ) { norm += real( rho[i][i] ); for ( j = 0; j < dim; j++ ) { prob += rho[i][j] * d.rho[i][j]; } } if ( imag( prob ) > 0.00000001 * real( prob ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Imaginary probability:" << prob << " " << norm << endl; } if ( real( prob ) < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Negative probability:" << prob << " " << norm << endl; } return real( prob ) / norm; } int EvtSpinDensity::check() { if ( dim < 1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "dim=" << dim << "in SpinDensity::Check" << endl; } int i, j; double trace( 0.0 ); for ( i = 0; i < dim; i++ ) { trace += abs( rho[i][i] ); } for ( i = 0; i < dim; i++ ) { if ( real( rho[i][i] ) < 0.0 ) return 0; if ( imag( rho[i][i] ) * 1000000.0 > trace ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << *this << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << trace << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Failing 1" << endl; return 0; } } for ( i = 0; i < dim; i++ ) { for ( j = i + 1; j < dim; j++ ) { if ( fabs( real( rho[i][j] - rho[j][i] ) ) > 0.00000001 * ( abs( rho[i][i] ) + abs( rho[j][j] ) ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Failing 2" << endl; return 0; } if ( fabs( imag( rho[i][j] + rho[j][i] ) ) > 0.00000001 * ( abs( rho[i][i] ) + abs( rho[j][j] ) ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Failing 3" << endl; return 0; } } } return 1; } ostream& operator<<( ostream& s, const EvtSpinDensity& d ) { int i, j; s << endl; s << "Dimension:" << d.dim << endl; for ( i = 0; i < d.dim; i++ ) { for ( j = 0; j < d.dim; j++ ) { s << d.rho[i][j] << " "; } s << endl; } return s; } diff --git a/src/EvtGenBase/EvtdFunctionSingle.cpp b/src/EvtGenBase/EvtdFunctionSingle.cpp index d8942c7..086cd69 100644 --- a/src/EvtGenBase/EvtdFunctionSingle.cpp +++ b/src/EvtGenBase/EvtdFunctionSingle.cpp @@ -1,110 +1,110 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenBase/EvtdFunctionSingle.hh" #include "EvtGenBase/EvtPatches.hh" #include #include #include #include EvtdFunctionSingle::EvtdFunctionSingle() { _j = 0; _m1 = 0; _m2 = 0; - _coef = 0; + _coef = nullptr; _kmin = 0; _kmax = 0; } EvtdFunctionSingle::~EvtdFunctionSingle() { - if ( _coef != 0 ) + if ( _coef != nullptr ) delete[] _coef; } void EvtdFunctionSingle::init( int j, int m1, int m2 ) { assert( abs( m2 ) >= abs( m1 ) ); assert( m2 >= 0 ); _j = j; _m1 = m1; _m2 = m2; _kmin = _m2 - _m1; _kmax = _j - _m1; assert( _kmin <= _kmax ); _coef = new double[( _kmax - _kmin ) / 2 + 1]; int k; for ( k = _kmin; k <= _kmax; k += 2 ) { int sign = 1; if ( ( k - _m2 + _m1 ) % 4 != 0 ) sign = -sign; double tmp = fact( ( _j + _m2 ) / 2 ) * fact( ( _j - _m2 ) / 2 ) * fact( ( _j + _m1 ) / 2 ) * fact( ( _j - _m1 ) / 2 ); _coef[( k - _kmin ) / 2] = sign * sqrt( tmp ) / ( fact( ( _j + _m2 - k ) / 2 ) * fact( k / 2 ) * fact( ( _j - _m1 - k ) / 2 ) * fact( ( k - _m2 + _m1 ) / 2 ) ); } } double EvtdFunctionSingle::d( int j, int m1, int m2, double theta ) { assert( j == _j ); _unused( j ); assert( m1 == _m1 ); assert( m2 == _m2 ); double c2 = cos( 0.5 * theta ); double s2 = sin( 0.5 * theta ); double d = 0.0; int k; for ( k = _kmin; k <= _kmax; k += 2 ) { d += _coef[( k - _kmin ) / 2] * pow( c2, ( 2 * _j - 2 * k + m2 - m1 ) / 2 ) * pow( s2, ( 2 * k - m2 + m1 ) / 2 ); } return d; } int EvtdFunctionSingle::fact( int n ) { assert( n >= 0 ); int f = 1; int k; for ( k = 2; k <= n; k++ ) f *= k; return f; } diff --git a/src/EvtGenExternal/EvtExternalGenFactory.cpp b/src/EvtGenExternal/EvtExternalGenFactory.cpp index b96fdae..1453917 100644 --- a/src/EvtGenExternal/EvtExternalGenFactory.cpp +++ b/src/EvtGenExternal/EvtExternalGenFactory.cpp @@ -1,165 +1,165 @@ /*********************************************************************** * 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 "EvtGenExternal/EvtExternalGenFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #ifdef EVTGEN_PYTHIA #include "EvtGenExternal/EvtPythiaEngine.hh" #endif #ifdef EVTGEN_PHOTOS #include "EvtGenExternal/EvtPhotosEngine.hh" #endif #ifdef EVTGEN_TAUOLA #include "EvtGenExternal/EvtTauolaEngine.hh" #endif #include using std::endl; EvtExternalGenFactory::EvtExternalGenFactory() { _extGenMap.clear(); } EvtExternalGenFactory::~EvtExternalGenFactory() { ExtGenMap::iterator iter; for ( iter = _extGenMap.begin(); iter != _extGenMap.end(); ++iter ) { EvtAbsExternalGen* theGenerator = iter->second; delete theGenerator; } _extGenMap.clear(); } EvtExternalGenFactory* EvtExternalGenFactory::getInstance() { - static EvtExternalGenFactory* theFactory = 0; + static EvtExternalGenFactory* theFactory = nullptr; - if ( theFactory == 0 ) { + if ( theFactory == nullptr ) { theFactory = new EvtExternalGenFactory(); } return theFactory; } // Only define the generator if we have the external ifdef variable set #ifdef EVTGEN_PYTHIA void EvtExternalGenFactory::definePythiaGenerator( std::string xmlDir, bool convertPhysCodes, bool useEvtGenRandom ) { int genId = EvtExternalGenFactory::PythiaGenId; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Defining EvtPythiaEngine: data tables defined in " << xmlDir << endl; if ( convertPhysCodes == true ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Pythia 6 codes in decay files will be converted to Pythia 8 codes" << endl; } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Pythia 8 codes need to be used in decay files" << endl; } if ( useEvtGenRandom == true ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Using EvtGen random engine for Pythia 8 as well" << endl; } EvtAbsExternalGen* pythiaGenerator = new EvtPythiaEngine( xmlDir, convertPhysCodes, useEvtGenRandom ); _extGenMap[genId] = pythiaGenerator; } #else void EvtExternalGenFactory::definePythiaGenerator( std::string, bool, bool ) { } #endif #ifdef EVTGEN_PHOTOS void EvtExternalGenFactory::definePhotosGenerator( std::string photonType, bool useEvtGenRandom ) { int genId = EvtExternalGenFactory::PhotosGenId; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Defining EvtPhotosEngine using photonType = " << photonType << endl; EvtAbsExternalGen* photosGenerator = new EvtPhotosEngine( photonType, useEvtGenRandom ); _extGenMap[genId] = photosGenerator; } #else void EvtExternalGenFactory::definePhotosGenerator( std::string, bool ) { } #endif #ifdef EVTGEN_TAUOLA void EvtExternalGenFactory::defineTauolaGenerator( bool useEvtGenRandom ) { int genId = EvtExternalGenFactory::TauolaGenId; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Defining EvtTauolaEngine." << endl; EvtAbsExternalGen* tauolaGenerator = new EvtTauolaEngine( useEvtGenRandom ); _extGenMap[genId] = tauolaGenerator; } #else void EvtExternalGenFactory::defineTauolaGenerator( bool ) { } #endif EvtAbsExternalGen* EvtExternalGenFactory::getGenerator( int genId ) { - EvtAbsExternalGen* theGenerator( 0 ); + EvtAbsExternalGen* theGenerator( nullptr ); ExtGenMap::iterator iter; if ( ( iter = _extGenMap.find( genId ) ) != _extGenMap.end() ) { // Retrieve the external generator engine theGenerator = iter->second; } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "EvtAbsExternalGen::getGenerator: could not find generator for genId = " << genId << endl; } return theGenerator; } void EvtExternalGenFactory::initialiseAllGenerators() { ExtGenMap::iterator iter; for ( iter = _extGenMap.begin(); iter != _extGenMap.end(); ++iter ) { EvtAbsExternalGen* theGenerator = iter->second; - if ( theGenerator != 0 ) { + if ( theGenerator != nullptr ) { theGenerator->initialise(); } } } diff --git a/src/EvtGenExternal/EvtExternalGenList.cpp b/src/EvtGenExternal/EvtExternalGenList.cpp index 003706d..ba5af95 100644 --- a/src/EvtGenExternal/EvtExternalGenList.cpp +++ b/src/EvtGenExternal/EvtExternalGenList.cpp @@ -1,78 +1,78 @@ /*********************************************************************** * 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 "EvtGenExternal/EvtExternalGenList.hh" #include "EvtGenExternal/EvtExternalGenFactory.hh" #include "EvtGenExternal/EvtPHOTOS.hh" #include "EvtGenExternal/EvtPythia.hh" #include "EvtGenExternal/EvtTauola.hh" EvtExternalGenList::EvtExternalGenList( bool convertPythiaCodes, std::string pythiaXmlDir, std::string photonType, bool useEvtGenRandom ) { // Instantiate the external generator factory EvtExternalGenFactory* extFactory = EvtExternalGenFactory::getInstance(); // Define the external generator "engines" here extFactory->definePhotosGenerator( photonType, useEvtGenRandom ); if ( pythiaXmlDir.size() < 1 ) { // If we have no string defined, check the value of the // PYTHIA8DATA environment variable which should be set to the // xmldoc Pythia directory char* pythiaDataDir = getenv( "PYTHIA8DATA" ); - if ( pythiaDataDir != 0 ) { + if ( pythiaDataDir != nullptr ) { pythiaXmlDir = pythiaDataDir; } } extFactory->definePythiaGenerator( pythiaXmlDir, convertPythiaCodes, useEvtGenRandom ); extFactory->defineTauolaGenerator( useEvtGenRandom ); } EvtExternalGenList::~EvtExternalGenList() { } EvtAbsRadCorr* EvtExternalGenList::getPhotosModel() { // Define the Photos model, which uses the EvtPhotosEngine class. EvtPHOTOS* photosModel = new EvtPHOTOS(); return photosModel; } std::list EvtExternalGenList::getListOfModels() { // Create the Pythia and Tauola models, which use their own engine classes. EvtPythia* pythiaModel = new EvtPythia(); EvtTauola* tauolaModel = new EvtTauola(); std::list extraModels; extraModels.push_back( pythiaModel ); extraModels.push_back( tauolaModel ); // Return the list of models return extraModels; } diff --git a/src/EvtGenExternal/EvtPhotosEngine.cpp b/src/EvtGenExternal/EvtPhotosEngine.cpp index 74febff..1c367ac 100644 --- a/src/EvtGenExternal/EvtPhotosEngine.cpp +++ b/src/EvtGenExternal/EvtPhotosEngine.cpp @@ -1,307 +1,307 @@ /*********************************************************************** * 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 . * ***********************************************************************/ #ifdef EVTGEN_PHOTOS #include "EvtGenExternal/EvtPhotosEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtPhotonParticle.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include #include #include using std::endl; EvtPhotosEngine::EvtPhotosEngine( std::string photonType, bool useEvtGenRandom ) { _photonType = photonType; _gammaId = EvtId( -1, -1 ); _gammaPDG = 22; // default photon pdg integer _mPhoton = 0.0; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Setting up PHOTOS." << endl; if ( useEvtGenRandom == true ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Using EvtGen random number engine also for Photos++" << endl; Photospp::Photos::setRandomGenerator( EvtRandom::Flat ); } Photospp::Photos::initialize(); // Increase the maximum possible value of the interference weight Photospp::Photos::maxWtInterference( 64.0 ); // 2^n, where n = number of charges (+,-) Photospp::Photos::setInterference( true ); Photospp::Photos::setExponentiation( true ); // Sets the infrared cutoff at 1e-7 // Reset the minimum photon energy, if required, in units of half of the decaying particle mass. // This must be done after exponentiation! Keep the cut at 1e-7, i.e. 0.1 keV at the 1 GeV scale, // which is appropriate for B decays Photospp::Photos::setInfraredCutOff( 1.0e-7 ); _initialised = false; } void EvtPhotosEngine::initialise() { if ( _initialised == false ) { _gammaId = EvtPDL::getId( _photonType ); if ( _gammaId == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Error in EvtPhotosEngine. Do not recognise the photon type " << _photonType << ". Setting this to \"gamma\". " << endl; _gammaId = EvtPDL::getId( "gamma" ); } _gammaPDG = EvtPDL::getStdHep( _gammaId ); _mPhoton = EvtPDL::getMeanMass( _gammaId ); _initialised = true; } } bool EvtPhotosEngine::doDecay( EvtParticle* theMother ) { if ( _initialised == false ) { this->initialise(); } - if ( theMother == 0 ) { + if ( theMother == nullptr ) { return false; } // Create a dummy HepMC GenEvent containing a single vertex, with the mother // assigned as the incoming particle and its daughters as outgoing particles. // We then pass this event to Photos for processing. // It will return a modified version of the event, updating the momentum of // the original particles and will contain any new photon particles. // We add these extra photons to the mother particle daughter list. // Skip running Photos if the particle has no daughters, since we can't add FSR. // Also skip Photos if the particle has too many daughters (>= 10) to avoid a problem // with a hard coded upper limit in the PHOENE subroutine. int nDaug( theMother->getNDaug() ); if ( nDaug == 0 || nDaug >= 10 ) { return false; } // Create the dummy event. auto theEvent = std::make_unique( Units::GEV, Units::MM ); // Create the decay "vertex". GenVertexPtr theVertex = newGenVertexPtr(); theEvent->add_vertex( theVertex ); // Add the mother particle as the incoming particle to the vertex. GenParticlePtr hepMCMother = this->createGenParticle( theMother, true ); theVertex->add_particle_in( hepMCMother ); // Find all daughter particles and assign them as outgoing particles to the vertex. // Keep track of the number of photons already in the decay (e.g. we may have B -> K* gamma) int iDaug( 0 ), nGamma( 0 ); for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* theDaughter = theMother->getDaug( iDaug ); GenParticlePtr hepMCDaughter = this->createGenParticle( theDaughter, false ); theVertex->add_particle_out( hepMCDaughter ); if ( theDaughter ) { int daugId = theDaughter->getPDGId(); if ( daugId == _gammaPDG ) { nGamma++; } } } // Now pass the event to Photos for processing // Create a Photos event object #ifdef EVTGEN_HEPMC3 Photospp::PhotosHepMC3Event photosEvent( theEvent.get() ); #else Photospp::PhotosHepMCEvent photosEvent( theEvent.get() ); #endif // Run the Photos algorithm photosEvent.process(); // Find the number of (outgoing) photons in the event int nPhotons = this->getNumberOfPhotons( theVertex ); // See if Photos has created additional photons. If not, do nothing extra int nDiffPhotons = nPhotons - nGamma; int iLoop( 0 ); if ( nDiffPhotons > 0 ) { // We have extra particles from Photos; these would have been appended // to the outgoing particle list // Get the iterator of outgoing particles for this vertex #ifdef EVTGEN_HEPMC3 for ( auto outParticle : theVertex->particles_out() ) { #else HepMC::GenVertex::particles_out_const_iterator outIter; for ( outIter = theVertex->particles_out_const_begin(); outIter != theVertex->particles_out_const_end(); ++outIter ) { // Get the next HepMC GenParticle HepMC::GenParticle* outParticle = *outIter; #endif // Get the three-momentum Photos result for this particle, and the PDG id double px( 0.0 ), py( 0.0 ), pz( 0.0 ); int pdgId( 0 ); - if ( outParticle != 0 ) { + if ( outParticle != nullptr ) { FourVector HepMCP4 = outParticle->momentum(); px = HepMCP4.px(); py = HepMCP4.py(); pz = HepMCP4.pz(); pdgId = outParticle->pdg_id(); } // Create an empty 4-momentum vector for the new/modified daughters EvtVector4R newP4; if ( iLoop < nDaug ) { // Original daughters EvtParticle* daugParticle = theMother->getDaug( iLoop ); - if ( daugParticle != 0 ) { + if ( daugParticle != nullptr ) { // Keep the original particle mass, but set the three-momentum // according to what Photos has modified. However, this will // violate energy conservation (from what Photos has provided). double mass = daugParticle->mass(); double energy = sqrt( mass * mass + px * px + py * py + pz * pz ); newP4.set( energy, px, py, pz ); // Set the new four-momentum (FSR applied) daugParticle->setP4WithFSR( newP4 ); } } else if ( pdgId == _gammaPDG ) { // Extra photon particle. Setup the four-momentum object double energy = sqrt( _mPhoton * _mPhoton + px * px + py * py + pz * pz ); newP4.set( energy, px, py, pz ); // Create a new photon particle and add it to the list of daughters EvtPhotonParticle* gamma = new EvtPhotonParticle(); gamma->init( _gammaId, newP4 ); // Set the pre-FSR photon momentum to zero gamma->setFSRP4toZero(); // Let the mother know about this new photon gamma->addDaug( theMother ); // Set its particle attribute to specify it is a FSR photon gamma->setAttribute( "FSR", 1 ); // it is a FSR photon gamma->setAttribute( "ISR", 0 ); // it is not an ISR photon } // Increment the loop counter for detecting additional photon particles iLoop++; } } // Cleanup theEvent->clear(); return true; } GenParticlePtr EvtPhotosEngine::createGenParticle( EvtParticle* theParticle, bool incoming ) { // Method to create an HepMC::GenParticle version of the given EvtParticle. - if ( theParticle == 0 ) { - return 0; + if ( theParticle == nullptr ) { + return nullptr; } // Get the 4-momentum (E, px, py, pz) for the EvtParticle EvtVector4R p4( 0.0, 0.0, 0.0, 0.0 ); if ( incoming == true ) { p4 = theParticle->getP4Restframe(); } else { p4 = theParticle->getP4(); } // Convert this to the HepMC 4-momentum double E = p4.get( 0 ); double px = p4.get( 1 ); double py = p4.get( 2 ); double pz = p4.get( 3 ); FourVector hepMC_p4( px, py, pz, E ); int PDGInt = EvtPDL::getStdHep( theParticle->getId() ); // Set the status flag for the particle. This is required, otherwise Photos++ // will crash from out-of-bounds array index problems. int status = Photospp::PhotosParticle::HISTORY; if ( incoming == false ) { status = Photospp::PhotosParticle::STABLE; } GenParticlePtr genParticle = newGenParticlePtr( hepMC_p4, PDGInt, status ); return genParticle; } int EvtPhotosEngine::getNumberOfPhotons( const GenVertexPtr theVertex ) const { // Find the number of photons from the outgoing particle list if ( !theVertex ) { return 0; } int nPhotons( 0 ); // Get the iterator of outgoing particles for this vertex #ifdef EVTGEN_HEPMC3 for ( auto outParticle : theVertex->particles_out() ) { #else HepMC::GenVertex::particles_out_const_iterator outIter; for ( outIter = theVertex->particles_out_const_begin(); outIter != theVertex->particles_out_const_end(); ++outIter ) { // Get the next HepMC GenParticle HepMC::GenParticle* outParticle = *outIter; #endif // Get the PDG id int pdgId( 0 ); - if ( outParticle != 0 ) { + if ( outParticle != nullptr ) { pdgId = outParticle->pdg_id(); } // Keep track of how many photons there are if ( pdgId == _gammaPDG ) { nPhotons++; } } return nPhotons; } #endif diff --git a/src/EvtGenExternal/EvtPythia.cpp b/src/EvtGenExternal/EvtPythia.cpp index fa003ad..c98e75b 100644 --- a/src/EvtGenExternal/EvtPythia.cpp +++ b/src/EvtGenExternal/EvtPythia.cpp @@ -1,152 +1,152 @@ /*********************************************************************** * 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 "EvtGenExternal/EvtPythia.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtSpinDensity.hh" #include "EvtGenModels/EvtAbsExternalGen.hh" #include "EvtGenExternal/EvtExternalGenFactory.hh" #include #include EvtPythia::EvtPythia() { // Set the Pythia engine to a null pointer at first. // When we do the decay, we retrieve the pointer to the Pythia engine // and use that for all decays. All clones will use the same Pythia engine. - _pythiaEngine = 0; + _pythiaEngine = nullptr; } EvtPythia::~EvtPythia() { _commandList.clear(); } std::string EvtPythia::getName() { return "PYTHIA"; } EvtDecayBase* EvtPythia::clone() { return new EvtPythia(); } void EvtPythia::init() { // Do not check for any arguments. The PythiaEngine will check // to see if there is an integer specifying the decay physics, // otherwise it just uses phase-space. } void EvtPythia::initProbMax() { noProbMax(); } void EvtPythia::decay( EvtParticle* p ) { // We have to initialise the Pythia engine after the decay.dec files have been read in, // since we will be modifying Pythia data tables, and that is only possible once we have // defined all Pythia-type decays we want to use. // We check to see if the engine has been created before doing the decay. // This should only create the full Pythia engine once, and all clones will point to the same engine. if ( !_pythiaEngine ) { _pythiaEngine = EvtExternalGenFactory::getInstance()->getGenerator( EvtExternalGenFactory::PythiaGenId ); } if ( _pythiaEngine ) { _pythiaEngine->doDecay( p ); } this->fixPolarisations( p ); } void EvtPythia::fixPolarisations( EvtParticle* p ) { // Special case to handle the J/psi polarisation if ( !p ) { return; } int nDaug = p->getNDaug(); int i( 0 ); static EvtId Jpsi = EvtPDL::getId( "J/psi" ); for ( i = 0; i < nDaug; i++ ) { EvtParticle* theDaug = p->getDaug( i ); if ( theDaug ) { if ( theDaug->getId() == Jpsi ) { EvtSpinDensity rho; rho.setDim( 3 ); rho.set( 0, 0, 0.5 ); rho.set( 0, 1, 0.0 ); rho.set( 0, 2, 0.0 ); rho.set( 1, 0, 0.0 ); rho.set( 1, 1, 1.0 ); rho.set( 1, 2, 0.0 ); rho.set( 2, 0, 0.0 ); rho.set( 2, 1, 0.0 ); rho.set( 2, 2, 0.5 ); EvtVector4R p4Psi = theDaug->getP4(); double alpha = atan2( p4Psi.get( 2 ), p4Psi.get( 1 ) ); double beta = acos( p4Psi.get( 3 ) / p4Psi.d3mag() ); theDaug->setSpinDensityForwardHelicityBasis( rho, alpha, beta, 0.0 ); setDaughterSpinDensity( i ); } } } } std::string EvtPythia::commandName() { // Allow backward compatibility for decay.dec files // having JetSetPar parameters. They are obsolete for Pythia 8, // since the JetSet-type array variables do not exist. // Need to think about including user defined parameters in // EvtPythiaEngine::updatePhysicsParameters(). return std::string( "JetSetPar" ); } void EvtPythia::command( std::string cmd ) { // Locally store commands in a vector _commandList.push_back( cmd ); } diff --git a/src/EvtGenExternal/EvtPythiaEngine.cpp b/src/EvtGenExternal/EvtPythiaEngine.cpp index 72aa46d..2333a26 100644 --- a/src/EvtGenExternal/EvtPythiaEngine.cpp +++ b/src/EvtGenExternal/EvtPythiaEngine.cpp @@ -1,853 +1,853 @@ /*********************************************************************** * 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 . * ***********************************************************************/ #ifdef EVTGEN_PYTHIA #include "EvtGenExternal/EvtPythiaEngine.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtExtGeneratorCommandsTable.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenExternal/EvtPythia6CommandConverter.hh" #include "Pythia8/Event.h" #include "Pythia8/ParticleData.h" #include #include #include #if PYTHIA_VERSION_INTEGER < 8304 typedef Pythia8::ParticleDataEntry* ParticleDataEntryPtr; #else typedef Pythia8::ParticleDataEntryPtr ParticleDataEntryPtr; #endif using std::endl; EvtPythiaEngine::EvtPythiaEngine( std::string xmlDir, bool convertPhysCodes, bool useEvtGenRandom ) { // Create two Pythia generators. One will be for generic // Pythia decays in the decay.dec file. The other one will be to // only decay aliased particles, which are in general "signal" // decays different from those in the decay.dec file. // Even though it is not possible to have two different particle // versions in one Pythia generator, we can use two generators to // get the required behaviour. EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Creating generic Pythia generator" << endl; _genericPythiaGen = std::make_unique( xmlDir ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Creating alias Pythia generator" << endl; _aliasPythiaGen = std::make_unique( xmlDir, false ); - _thePythiaGenerator = 0; + _thePythiaGenerator = nullptr; _daugPDGVector.clear(); _daugP4Vector.clear(); _convertPhysCodes = convertPhysCodes; // Specify if we are going to use the random number generator (engine) // from EvtGen for Pythia 8. _useEvtGenRandom = useEvtGenRandom; _evtgenRandom = std::make_unique(); _initialised = false; } EvtPythiaEngine::~EvtPythiaEngine() { _thePythiaGenerator = nullptr; this->clearDaughterVectors(); this->clearPythiaModeMap(); } void EvtPythiaEngine::clearDaughterVectors() { _daugPDGVector.clear(); _daugP4Vector.clear(); } void EvtPythiaEngine::clearPythiaModeMap() { PythiaModeMap::iterator iter; for ( iter = _pythiaModeMap.begin(); iter != _pythiaModeMap.end(); ++iter ) { std::vector modeVector = iter->second; modeVector.clear(); } _pythiaModeMap.clear(); } void EvtPythiaEngine::initialise() { if ( _initialised ) { return; } this->clearPythiaModeMap(); this->updateParticleLists(); // Hadron-level processes only (hadronized, string fragmentation and secondary decays). // We do not want to generate the full pp or e+e- event structure etc.. _genericPythiaGen->readString( "ProcessLevel:all = off" ); _aliasPythiaGen->readString( "ProcessLevel:all = off" ); // Turn off Pythia warnings, e.g. changes to particle properties _genericPythiaGen->readString( "Print:quiet = on" ); _aliasPythiaGen->readString( "Print:quiet = on" ); // Apply any other physics (or special particle) requirements/cuts etc.. this->updatePhysicsParameters(); // Set the random number generator if ( _useEvtGenRandom == true ) { _genericPythiaGen->setRndmEnginePtr( _evtgenRandom.get() ); _aliasPythiaGen->setRndmEnginePtr( _evtgenRandom.get() ); } _genericPythiaGen->init(); _aliasPythiaGen->init(); _initialised = true; } bool EvtPythiaEngine::doDecay( EvtParticle* theParticle ) { // Store the mother particle within a Pythia8 Event object. // Then do the hadron level decays. // The EvtParticle must be a colour singlet (meson/baryon/lepton), i.e. not a gluon or quark // We delete any daughters the particle may have, since we are asking Pythia // to generate the decay anew. Also note that _any_ Pythia decay allowed for the particle // will be generated and not the specific Pythia decay mode that EvtGen has already // specified. This is necessary since we only want to initialise the Pythia decay table // once; all Pythia branching fractions for a given mother particle are renormalised to sum to 1.0. // In EvtGen decay.dec files, it may be the case that Pythia decays are only used // for some of the particle decays (i.e. Pythia BF sum < 1.0). As we loop over many events, // the total frequency for each Pythia decay mode will normalise correctly to what // we wanted via the specifications made to the decay.dec file, even though event-by-event // the EvtGen decay channel and the Pythia decay channel may be different. if ( _initialised == false ) { this->initialise(); } - if ( theParticle == 0 ) { + if ( theParticle == nullptr ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Error in EvtPythiaEngine::doDecay. The mother particle is null. Not doing any Pythia decay." << endl; return false; } // Delete EvtParticle daughters if they already exist if ( theParticle->getNDaug() != 0 ) { bool keepChannel( false ); theParticle->deleteDaughters( keepChannel ); } EvtId particleId = theParticle->getId(); int isAlias = particleId.isAlias(); // Choose the generator depending if we have an aliased (parent) particle or not _thePythiaGenerator = ( isAlias == 1 ? _aliasPythiaGen.get() : _genericPythiaGen.get() ); // Need to use the reference to the Pythia8::Event object, // otherwise it will just return a new empty, default event object. Pythia8::Event& theEvent = _thePythiaGenerator->event; theEvent.reset(); // Initialise the event to be the particle rest frame int PDGCode = EvtPDL::getStdHep( particleId ); int status( 1 ); int colour( 0 ), anticolour( 0 ); double px( 0.0 ), py( 0.0 ), pz( 0.0 ); double m0 = theParticle->mass(); double E = m0; theEvent.append( PDGCode, status, colour, anticolour, px, py, pz, E, m0 ); // Generate the Pythia event int iTrial( 0 ); bool generatedEvent( false ); for ( iTrial = 0; iTrial < 10; iTrial++ ) { generatedEvent = _thePythiaGenerator->next(); if ( generatedEvent ) { break; } } bool success( false ); if ( generatedEvent ) { // Store the daughters for this particle from the Pythia decay tree. // This is a recursive function that will continue looping through // all available daughters until the first set of non-quark and non-gluon // particles are encountered in the Pythia Event structure. // First, clear up the internal vectors storing the daughter // EvtId types and 4-momenta. this->clearDaughterVectors(); // Now store the daughter info. Since this is a recursive function // to loop through the full Pythia decay tree, we do not want to create // EvtParticles here but in the next step. this->storeDaughterInfo( theParticle, 1 ); // Now create the EvtParticle daughters of the (parent) particle. // We need to use the EvtParticle::makeDaughters function // owing to the way EvtParticle stores parent-daughter information. this->createDaughterEvtParticles( theParticle ); //theParticle->printTree(); //theEvent.list(true, true); success = true; } return success; } void EvtPythiaEngine::storeDaughterInfo( EvtParticle* theParticle, int startInt ) { Pythia8::Event& theEvent = _thePythiaGenerator->event; std::vector daugList = theEvent.daughterList( startInt ); std::vector::iterator daugIter; for ( daugIter = daugList.begin(); daugIter != daugList.end(); ++daugIter ) { int daugInt = *daugIter; // Ask if the daughter is a quark or gluon. If so, recursively search again. Pythia8::Particle& daugParticle = theEvent[daugInt]; if ( daugParticle.isQuark() || daugParticle.isGluon() ) { // Recursively search for correct daughter type this->storeDaughterInfo( theParticle, daugInt ); } else { // We have a daughter that is not a quark nor gluon particle. // Make sure we are not double counting particles, since several quarks // and gluons make one particle. // Set the status flag for any "new" particle to say that we have stored it. // Use status flag = 1000 (within the user allowed range for Pythia codes). // Check that the status flag for the particle is not equal to 1000 int statusCode = daugParticle.status(); if ( statusCode != 1000 ) { int daugPDGInt = daugParticle.id(); double px = daugParticle.px(); double py = daugParticle.py(); double pz = daugParticle.pz(); double E = daugParticle.e(); EvtVector4R daughterP4( E, px, py, pz ); // Now store the EvtId and 4-momentum in the internal vectors _daugPDGVector.push_back( daugPDGInt ); _daugP4Vector.push_back( daughterP4 ); // Set the status flag for the Pythia particle to let us know // that we have already considered it to avoid double counting. daugParticle.status( 1000 ); } // Status code != 1000 } } } void EvtPythiaEngine::createDaughterEvtParticles( EvtParticle* theParent ) { - if ( theParent == 0 ) { + if ( theParent == nullptr ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Error in EvtPythiaEngine::createDaughterEvtParticles. The parent is null" << endl; return; } // Get the list of Pythia decay modes defined for this particle id alias. // It would be easier to just use the decay channel number that Pythia chose to use // for the particle decay, but this is not accessible from the Pythia interface at present. int nDaughters = _daugPDGVector.size(); std::vector daugAliasIdVect( 0 ); EvtId particleId = theParent->getId(); // Check to see if we have an anti-particle. If we do, charge conjugate the particle id to get the // Pythia "alias" we can compare with the defined (particle) Pythia modes. int PDGId = EvtPDL::getStdHep( particleId ); int aliasInt = particleId.getAlias(); int pythiaAliasInt( aliasInt ); if ( PDGId < 0 ) { // We have an anti-particle. EvtId conjPartId = EvtPDL::chargeConj( particleId ); pythiaAliasInt = conjPartId.getAlias(); } std::vector pythiaModes = _pythiaModeMap[pythiaAliasInt]; // Loop over all available Pythia decay modes and find the channel that matches // the daughter ids. Set each daughter id to also use the alias integer. // This will then convert the Pythia generated channel to the EvtGen alias defined one. std::vector::iterator modeIter; bool gotMode( false ); for ( modeIter = pythiaModes.begin(); modeIter != pythiaModes.end(); ++modeIter ) { // Stop the loop if we have the right decay mode channel if ( gotMode ) { break; } int pythiaModeInt = *modeIter; EvtDecayBase* decayModel = EvtDecayTable::getInstance()->findDecayModel( aliasInt, pythiaModeInt ); - if ( decayModel != 0 ) { + if ( decayModel != nullptr ) { int nModeDaug = decayModel->getNDaug(); // We need to make sure that the number of daughters match if ( nDaughters == nModeDaug ) { int iModeDaug( 0 ); for ( iModeDaug = 0; iModeDaug < nModeDaug; iModeDaug++ ) { EvtId daugId = decayModel->getDaug( iModeDaug ); int daugPDGId = EvtPDL::getStdHep( daugId ); // Pythia has used the right PDG codes for this decay mode, even for conjugate modes int pythiaPDGId = _daugPDGVector[iModeDaug]; if ( daugPDGId == pythiaPDGId ) { daugAliasIdVect.push_back( daugId ); } } // Loop over EvtGen mode daughters int daugAliasSize = daugAliasIdVect.size(); if ( daugAliasSize == nDaughters ) { // All daughter Id codes are accounted for. Set the flag to stop the loop. gotMode = true; } else { // We do not have the correct daughter ordering. Clear the id vector // and try another mode. daugAliasIdVect.clear(); } } // Same number of daughters } // decayModel != 0 } // Loop over available Pythia modes if ( gotMode == false ) { // We did not find a match for the daughter aliases. Just use the normal PDG codes // from the Pythia decay result int iPyDaug( 0 ); for ( iPyDaug = 0; iPyDaug < nDaughters; iPyDaug++ ) { int daugPDGCode = _daugPDGVector[iPyDaug]; EvtId daugPyId = EvtPDL::evtIdFromStdHep( daugPDGCode ); daugAliasIdVect.push_back( daugPyId ); } } // Make the EvtParticle daughters (with correct alias id's). Their 4-momenta are uninitialised. theParent->makeDaughters( nDaughters, daugAliasIdVect ); // Now set the 4-momenta of the daughters. int iDaug( 0 ); // Can use an iterator here, but we already had to use the vector size... for ( iDaug = 0; iDaug < nDaughters; iDaug++ ) { EvtParticle* theDaughter = theParent->getDaug( iDaug ); // Set the correct 4-momentum for each daughter particle. - if ( theDaughter != 0 ) { + if ( theDaughter != nullptr ) { EvtId theDaugId = daugAliasIdVect[iDaug]; const EvtVector4R theDaugP4 = _daugP4Vector[iDaug]; theDaughter->init( theDaugId, theDaugP4 ); } } } void EvtPythiaEngine::updateParticleLists() { // Use the EvtGen decay table (decay/user.dec) to update Pythia particle // decay modes. Also, make sure the generic and alias Pythia generators // use the same particle data entries as defined by EvtGen (evt.pdl). // Loop over all entries in the EvtPDL particle data table. // Aliases are added at the end with id numbers equal to the // original particle, but with alias integer = lastPDLEntry+1 etc.. int iPDL; int nPDL = EvtPDL::entries(); // Reset the _addedPDGCodes map that keeps track // of any new particles added to the Pythia input data stream _addedPDGCodes.clear(); for ( iPDL = 0; iPDL < nPDL; iPDL++ ) { EvtId particleId = EvtPDL::getEntry( iPDL ); int aliasInt = particleId.getAlias(); // Pythia and EvtGen should use the same PDG codes for particles int PDGCode = EvtPDL::getStdHep( particleId ); // Update pole mass, width, lifetime and mass range double mass = EvtPDL::getMeanMass( particleId ); double width = EvtPDL::getWidth( particleId ); double lifetime = EvtPDL::getctau( particleId ); double mmin = EvtPDL::getMinMass( particleId ); double mmax = EvtPDL::getMaxMass( particleId ); // Particle data pointers. The generic and alias Pythia generator pointers have // their own Pythia8::ParticleData particleData public data members which contain // the particle properties table. We can extract and change individual particle // entries using the particleDataEntryPtr() function within ParticleData. // However, we must be careful when accessing the particleData table. We must do // this directly, since assigning it to another Pythia8::ParticleData object via copying // or assignment will give it a different memory address and it will no longer refer to // the original particleData information from the generator pointer. ParticleDataEntryPtr entry_generic = _genericPythiaGen->particleData.particleDataEntryPtr( PDGCode ); ParticleDataEntryPtr entry_alias = _aliasPythiaGen->particleData.particleDataEntryPtr( PDGCode ); // Check that the PDG code is not zero/null and exclude other // special cases, e.g. those reserved for internal generator use - if ( entry_generic != 0 && this->validPDGCode( PDGCode ) ) { + if ( entry_generic != nullptr && this->validPDGCode( PDGCode ) ) { entry_generic->setM0( mass ); entry_generic->setMWidth( width ); entry_generic->setTau0( lifetime ); if ( std::fabs( width ) > 0.0 ) { entry_generic->setMMin( mmin ); entry_generic->setMMax( mmax ); } } // Check that the PDG code is not zero/null and exclude other // special cases, e.g. those reserved for internal generator use - if ( entry_alias != 0 && this->validPDGCode( PDGCode ) ) { + if ( entry_alias != nullptr && this->validPDGCode( PDGCode ) ) { entry_alias->setM0( mass ); entry_alias->setMWidth( width ); entry_alias->setTau0( lifetime ); if ( std::fabs( width ) > 0.0 ) { entry_alias->setMMin( mmin ); entry_alias->setMMax( mmax ); } } // Check which particles have a Pythia decay defined. // Get the list of all possible decays for the particle, using the alias integer. // If the particle is not actually an alias, aliasInt = idInt. bool hasPythiaDecays = EvtDecayTable::getInstance()->hasPythia( aliasInt ); if ( hasPythiaDecays ) { int isAlias = particleId.isAlias(); // Decide what generator to use depending on whether we have // an aliased particle or not _thePythiaGenerator = ( isAlias == 1 ? _aliasPythiaGen.get() : _genericPythiaGen.get() ); // Find the Pythia particle name given the standard PDG code integer std::string dataName = _thePythiaGenerator->particleData.name( PDGCode ); bool alreadyStored = ( _addedPDGCodes.find( abs( PDGCode ) ) != _addedPDGCodes.end() ); if ( dataName == " " && !alreadyStored ) { // Particle and its antiparticle do not exist in the Pythia database. // Create a new particle, then create the new decay modes. this->createPythiaParticle( particleId, PDGCode ); } // For the particle, create the Pythia decay modes. // Update Pythia data tables. this->updatePythiaDecayTable( particleId, aliasInt, PDGCode ); } // Loop over Pythia decays } // Loop over EvtPDL entries //EvtGenReport(EVTGEN_INFO,"EvtGen")<<"Writing out changed generic Pythia decay list"<particleData.listChanged(); //EvtGenReport(EVTGEN_INFO,"EvtGen")<<"Writing out changed alias Pythia decay list"<particleData.listChanged(); } bool EvtPythiaEngine::validPDGCode( int PDGCode ) { // Exclude certain PDG codes: void = 0 and special values = 81 to 100, which are reserved // for internal generator use (pseudoparticles) according to PDG guidelines. Also exclude // nu'_tau (nu_L) = 18, which has different masses: Pythia8 = 400 GeV, EvtGen = 0 GeV. bool isValid( true ); int absPDGCode = abs( PDGCode ); if ( absPDGCode == 0 || absPDGCode == 18 ) { // Void and nu_L or nu'_tau isValid = false; } else if ( absPDGCode >= 81 && absPDGCode <= 100 ) { // Pseudoparticles isValid = false; } return isValid; } void EvtPythiaEngine::updatePythiaDecayTable( EvtId& particleId, int aliasInt, int PDGCode ) { // Update the particle data table in Pythia. // The tables store information about the allowed decay modes // where the PDGId for all particles must be positive; anti-particles are stored // with the corresponding particle entry. // Since we do not want to implement CP violation here, just use the same branching // fractions for particle and anti-particle modes. int nModes = EvtDecayTable::getInstance()->getNModes( aliasInt ); int iMode( 0 ); bool firstMode( true ); // Only process positive PDG codes. if ( PDGCode < 0 ) { return; } // Keep track of which decay modes are Pythia decays for each aliasInt std::vector pythiaModes( 0 ); // Loop over the decay modes for this particle for ( iMode = 0; iMode < nModes; iMode++ ) { EvtDecayBase* decayModel = EvtDecayTable::getInstance()->findDecayModel( aliasInt, iMode ); - if ( decayModel != 0 ) { + if ( decayModel != nullptr ) { int nDaug = decayModel->getNDaug(); // If the decay mode has no daughters, then that means that there will be // no entries for any submode re-definitions for Pythia. // This sometimes occurs for any mode using non-standard Pythia 6 codes. // Do not refine the decay mode, i.e. accept the Pythia 8 default (if it exists). if ( nDaug > 0 ) { // Check to see if we have a Pythia decay mode std::string modelName = decayModel->getModelName(); if ( modelName == "PYTHIA" ) { // Keep track which decay mode is a Pythia one. We need this in order to // reassign alias Id values for particles generated in the decay. pythiaModes.push_back( iMode ); std::ostringstream oss; oss.setf( std::ios::scientific ); // Write out the absolute value of the PDG code, since // particles and anti-particles occupy the same part of the Pythia table. oss << PDGCode; if ( firstMode ) { // Create a new channel oss << ":oneChannel = "; firstMode = false; } else { // Add the channel oss << ":addChannel = "; } // Select all channels (particle and anti-particle). // For CP violation, or different BFs for particle and anti-particle, // use options 2 or 3 (not here). int onMode( 1 ); oss << onMode << " "; double BF = decayModel->getBranchingFraction(); oss << BF << " "; // Need to convert the old Pythia physics mode integers with the new ones // To do this, get the model argument and write a conversion method. int modeInt = this->getModeInt( decayModel ); oss << modeInt; int iDaug( 0 ); for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtId daugId = decayModel->getDaug( iDaug ); int daugPDG = EvtPDL::getStdHep( daugId ); oss << " " << daugPDG; } // Daughter list _thePythiaGenerator->readString( oss.str() ); } // is Pythia } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Warning in EvtPythiaEngine. Trying to redefine Pythia table for " << EvtPDL::name( particleId ) << " for a decay channel that has no daughters." << " Keeping Pythia default (if available)." << endl; } } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Error in EvtPythiaEngine. decayModel is null for particle " << EvtPDL::name( particleId ) << " mode number " << iMode << endl; } } // Loop over modes _pythiaModeMap[aliasInt] = pythiaModes; // Now, renormalise the decay branching fractions to sum to 1.0 std::ostringstream rescaleStr; rescaleStr.setf( std::ios::scientific ); rescaleStr << PDGCode << ":rescaleBR = 1.0"; _thePythiaGenerator->readString( rescaleStr.str() ); } int EvtPythiaEngine::getModeInt( EvtDecayBase* decayModel ) { int tmpModeInt( 0 ), modeInt( 0 ); - if ( decayModel != 0 ) { + if ( decayModel != nullptr ) { int nVars = decayModel->getNArg(); // Just read the first integer, which specifies the Pythia decay model. // Ignore any other values. if ( nVars > 0 ) { tmpModeInt = static_cast( decayModel->getArg( 0 ) ); } } if ( _convertPhysCodes ) { // Extra code to convert the old Pythia decay model integer MDME(ICC,2) to the new one. // This should be removed eventually after updating decay.dec files to use // the new convention. if ( tmpModeInt == 0 ) { modeInt = 0; // phase-space } else if ( tmpModeInt == 1 ) { modeInt = 1; // omega or phi -> 3pi } else if ( tmpModeInt == 2 ) { modeInt = 11; // Dalitz decay } else if ( tmpModeInt == 3 ) { modeInt = 2; // V -> PS PS } else if ( tmpModeInt == 4 ) { modeInt = 92; // onium -> ggg or gg gamma } else if ( tmpModeInt == 11 ) { modeInt = 42; // phase-space of hadrons from available quarks } else if ( tmpModeInt == 12 ) { modeInt = 42; // phase-space for onia resonances } else if ( tmpModeInt == 13 ) { modeInt = 43; // phase-space of at least 3 hadrons } else if ( tmpModeInt == 14 ) { modeInt = 44; // phase-space of at least 4 hadrons } else if ( tmpModeInt == 15 ) { modeInt = 45; // phase-space of at least 5 hadrons } else if ( tmpModeInt >= 22 && tmpModeInt <= 30 ) { modeInt = tmpModeInt + 40; // phase space of hadrons with fixed multiplicity (modeInt - 60) } else if ( tmpModeInt == 31 ) { modeInt = 42; // two or more quarks phase-space; one spectactor quark } else if ( tmpModeInt == 32 ) { modeInt = 91; // qqbar or gg pair } else if ( tmpModeInt == 33 ) { modeInt = 0; // triplet q X qbar, where X = gluon or colour singlet (superfluous, since g's are created anyway) } else if ( tmpModeInt == 41 ) { modeInt = 21; // weak decay phase space, weighting nu_tau spectrum } else if ( tmpModeInt == 42 ) { modeInt = 22; // weak decay V-A matrix element } else if ( tmpModeInt == 43 ) { modeInt = 22; // weak decay V-A matrix element, quarks as jets (superfluous) } else if ( tmpModeInt == 44 ) { modeInt = 22; // weak decay V-A matrix element, parton showers (superfluous) } else if ( tmpModeInt == 48 ) { modeInt = 23; // weak decay V-A matrix element, at least 3 decay products } else if ( tmpModeInt == 50 ) { modeInt = 0; // default behaviour } else if ( tmpModeInt == 51 ) { modeInt = 0; // step threshold (channel switched off when mass daughters > mother mass } else if ( tmpModeInt == 52 || tmpModeInt == 53 ) { modeInt = 0; // beta-factor threshold } else if ( tmpModeInt == 84 ) { modeInt = 42; // unknown physics process - just use phase-space } else if ( tmpModeInt == 101 ) { modeInt = 0; // continuation line } else if ( tmpModeInt == 102 ) { modeInt = 0; // off mass shell particles. } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Pythia mode integer " << tmpModeInt << " is not recognised. Using phase-space model" << endl; modeInt = 0; // Use phase-space for anything else } } else { // No need to convert the physics mode integer code modeInt = tmpModeInt; } return modeInt; } void EvtPythiaEngine::createPythiaParticle( EvtId& particleId, int PDGCode ) { // Use the EvtGen name, PDGId and other variables to define the new Pythia particle. EvtId antiPartId = EvtPDL::chargeConj( particleId ); std::string aliasName = EvtPDL::name( particleId ); // If not an alias, aliasName = normal name std::string antiName = EvtPDL::name( antiPartId ); EvtSpinType::spintype spinType = EvtPDL::getSpinType( particleId ); int spin = EvtSpinType::getSpin2( spinType ); int charge = EvtPDL::chg3( particleId ); // Must set the correct colour type manually here, since the evt.pdl file // does not store this information. This is required for quarks otherwise // Pythia cannot generate the decay properly. int PDGId = EvtPDL::getStdHep( particleId ); int colour( 0 ); if ( PDGId == 21 ) { colour = 2; // gluons } else if ( PDGId <= 8 && PDGId > 0 ) { colour = 1; // single quarks } double m0 = EvtPDL::getMeanMass( particleId ); double mWidth = EvtPDL::getWidth( particleId ); double mMin = EvtPDL::getMinMass( particleId ); double mMax = EvtPDL::getMaxMass( particleId ); double tau0 = EvtPDL::getctau( particleId ); std::ostringstream oss; oss.setf( std::ios::scientific ); int absPDGCode = abs( PDGCode ); oss << absPDGCode << ":new = " << aliasName << " " << antiName << " " << spin << " " << charge << " " << colour << " " << m0 << " " << mWidth << " " << mMin << " " << mMax << " " << tau0; // Pass this information to Pythia _thePythiaGenerator->readString( oss.str() ); // Also store the absolute value of the PDG entry // to keep track of which new particles have been added, // which also automatically includes the anti-particle. // We need to avoid creating new anti-particles when // they already exist when the particle was added. _addedPDGCodes[absPDGCode] = 1; } void EvtPythiaEngine::updatePhysicsParameters() { // Update any more Pythia physics (or special particle) requirements/cuts etc.. // This should be used if any of the Pythia 6 parameters like JetSetPar MSTJ(i) = x // are needed. Such commands will need to be implemented using the new interface // pythiaGenerator->readString(cmd); Here cmd is a string telling Pythia 8 // what physics parameters to change. This will need to be done for the generic and // alias generator pointers, as appropriate. // Set the multiplicity level for hadronic weak decays std::string multiWeakCut( "ParticleDecays:multIncreaseWeak = 2.0" ); _genericPythiaGen->readString( multiWeakCut ); _aliasPythiaGen->readString( multiWeakCut ); // Set the multiplicity level for all other decays std::string multiCut( "ParticleDecays:multIncrease = 4.5" ); _genericPythiaGen->readString( multiCut ); _aliasPythiaGen->readString( multiCut ); //Now read in any custom configuration entered in the XML GeneratorCommands commands = EvtExtGeneratorCommandsTable::getInstance()->getCommands( "PYTHIA" ); GeneratorCommands::iterator it = commands.begin(); for ( ; it != commands.end(); it++ ) { Command command = *it; std::vector commandStrings; if ( command["VERSION"] == "PYTHIA6" ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Converting Pythia 6 command: " << command["MODULE"] << "(" << command["PARAM"] << ")=" << command["VALUE"] << "..." << endl; commandStrings = convertPythia6Command( command ); } else if ( command["VERSION"] == "PYTHIA8" ) { commandStrings.push_back( command["MODULE"] + ":" + command["PARAM"] + " = " + command["VALUE"] ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Pythia command received by EvtPythiaEngine has bad version:" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Received " << command["VERSION"] << " but expected PYTHIA6 or PYTHIA8." << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "The error is likely to be in EvtDecayTable.cpp" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtGen will now abort." << endl; ::abort(); } std::string generator = command["GENERATOR"]; if ( generator == "GENERIC" || generator == "Generic" || generator == "generic" || generator == "BOTH" || generator == "Both" || generator == "both" ) { std::vector::iterator it2 = commandStrings.begin(); for ( ; it2 != commandStrings.end(); it2++ ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Configuring generic Pythia generator: " << ( *it2 ) << endl; _genericPythiaGen->readString( *it2 ); } } if ( generator == "ALIAS" || generator == "Alias" || generator == "alias" || generator == "BOTH" || generator == "Both" || generator == "both" ) { std::vector::iterator it2 = commandStrings.begin(); for ( ; it2 != commandStrings.end(); it2++ ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Configuring alias Pythia generator: " << ( *it2 ) << endl; _aliasPythiaGen->readString( *it2 ); } } } } #endif diff --git a/src/EvtGenExternal/EvtTauolaEngine.cpp b/src/EvtGenExternal/EvtTauolaEngine.cpp index 14e4786..256e5b2 100644 --- a/src/EvtGenExternal/EvtTauolaEngine.cpp +++ b/src/EvtGenExternal/EvtTauolaEngine.cpp @@ -1,601 +1,601 @@ /*********************************************************************** * 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 . * ***********************************************************************/ #ifdef EVTGEN_TAUOLA #include "EvtGenExternal/EvtTauolaEngine.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSymTable.hh" #include "EvtGenBase/EvtVector4R.hh" #include "Tauola/Log.h" #include "Tauola/Tauola.h" #include #include #include #include #include using std::endl; EvtTauolaEngine::EvtTauolaEngine( bool useEvtGenRandom ) { // PDG standard code integer ID for tau particle _tauPDG = 15; // Number of possible decay modes in Tauola _nTauolaModes = 22; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Setting up TAUOLA." << endl; // These three lines are not really necessary since they are the default. // But they are here so that we know what the initial conditions are. Tauolapp::Tauola::setDecayingParticle( _tauPDG ); // tau PDG code Tauolapp::Tauola::setSameParticleDecayMode( Tauolapp::Tauola::All ); // all modes allowed Tauolapp::Tauola::setOppositeParticleDecayMode( Tauolapp::Tauola::All ); // all modes allowed // Limit the number of warnings printed out. Can't choose zero here, unfortunately Tauolapp::Log::SetWarningLimit( 1 ); // Initial the Tauola external generator if ( useEvtGenRandom == true ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Using EvtGen random number engine also for Tauola++" << endl; Tauolapp::Tauola::setRandomGenerator( EvtRandom::Flat ); } // Use the BaBar-tuned chiral current calculations by default. Can be changed using the // TauolaCurrentOption keyword in decay files Tauolapp::Tauola::setNewCurrents( 1 ); Tauolapp::Tauola::initialize(); // Initialise various default parameters // Neutral and charged spin propagator choices _neutPropType = 0; _posPropType = 0; _negPropType = 0; // Set-up possible decay modes _after_ we have read the (user) decay file _initialised = false; } void EvtTauolaEngine::initialise() { // Set up all possible tau decay modes. // This should be done just before the first doDecay() call, // since we want to make sure that any decay.dec files are processed // first to get lists of particle modes and their alias definitions // (for creating EvtParticles with the right history information). if ( _initialised == false ) { this->setUpPossibleTauModes(); this->setOtherParameters(); _initialised = true; } } void EvtTauolaEngine::setUpPossibleTauModes() { // Get the decay table list defined by the decay.dec files. // Only look for the first tau particle decay mode definitions with the Tauola name, // since that generator only allows the same BFs for both tau+ and tau- decays. // We can not choose a specific tau decay event-by-event, since this is // only possible before we call Tauola::initialize(). // Otherwise, we could have selected a random mode ourselves for tau- and tau+ // separately (via selecting a random number and comparing it to be less than // the cumulative BF) for each event. int nPDL = EvtPDL::entries(); int iPDL( 0 ); bool gotAnyTauolaModes( false ); for ( iPDL = 0; iPDL < nPDL; iPDL++ ) { EvtId particleId = EvtPDL::getEntry( iPDL ); int PDGId = EvtPDL::getStdHep( particleId ); if ( abs( PDGId ) == _tauPDG && gotAnyTauolaModes == false ) { int aliasInt = particleId.getAlias(); // Get the list of decay modes for this tau particle (alias) int nModes = EvtDecayTable::getInstance()->getNModes( aliasInt ); int iMode( 0 ), iTauMode( 0 ); // Vector to store tau mode branching fractions. // The size of this vector equals the total number of possible // Tauola decay modes. Initialise all BFs to zero. std::vector tauolaModeBFs( _nTauolaModes ); for ( iTauMode = 0; iTauMode < _nTauolaModes; iTauMode++ ) { tauolaModeBFs[iTauMode] = 0.0; } double totalTauModeBF( 0.0 ); int nNonTauolaModes( 0 ); // Loop through each decay mode for ( iMode = 0; iMode < nModes; iMode++ ) { EvtDecayBase* decayModel = EvtDecayTable::getInstance()->findDecayModel( aliasInt, iMode ); if ( decayModel ) { // Check that the decay model name matches TAUOLA std::string modelName = decayModel->getName(); if ( modelName == "TAUOLA" ) { if ( gotAnyTauolaModes == false ) { gotAnyTauolaModes = true; } // Extract the decay mode integer type and branching fraction double BF = decayModel->getBranchingFraction(); int modeArrayInt = this->getModeInt( decayModel ) - 1; if ( modeArrayInt >= 0 && modeArrayInt < _nTauolaModes ) { tauolaModeBFs[modeArrayInt] = BF; totalTauModeBF += BF; } } else { nNonTauolaModes++; } } // Decay mode exists } // Loop over decay models if ( gotAnyTauolaModes == true && nNonTauolaModes > 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Please remove all non-TAUOLA decay modes for particle " << EvtPDL::name( particleId ) << endl; ::abort(); } // Normalise all (non-zero) tau mode BFs to sum up to 1.0, and // let Tauola know about these normalised branching fractions if ( totalTauModeBF > 0.0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Setting TAUOLA BF modes using the definitions for the particle " << EvtPDL::name( particleId ) << endl; for ( iTauMode = 0; iTauMode < _nTauolaModes; iTauMode++ ) { tauolaModeBFs[iTauMode] /= totalTauModeBF; double modeBF = tauolaModeBFs[iTauMode]; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Setting TAUOLA BF for mode " << iTauMode + 1 << " = " << modeBF << endl; Tauolapp::Tauola::setTauBr( iTauMode + 1, modeBF ); } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Any other TAUOLA BF modes for other tau particle decay mode definitions will be ignored!" << endl; } } // Got tau particle and have yet to get a TAUOLA mode } // Loop through PDL entries } int EvtTauolaEngine::getModeInt( EvtDecayBase* decayModel ) { int modeInt( 0 ); if ( decayModel ) { int nVars = decayModel->getNArg(); if ( nVars > 0 ) { modeInt = static_cast( decayModel->getArg( 0 ) ); } } return modeInt; } void EvtTauolaEngine::setOtherParameters() { // Set other Tauola parameters using the "Defined" keyword in the decay file. If any of // these are not found in the decay file, then default values are assumed/kept // 1) TauolaNeutralProp: Specify the neutral propagator type used for spin matrix calculations // "Z" (default), "Gamma", "Higgs" (H0), "PseudoHiggs" (A0), "MixedHiggs" (A0/H0) int iErr( 0 ); std::string neutPropName = EvtSymTable::get( "TauolaNeutralProp", iErr ); if ( neutPropName == "Z0" || neutPropName == "Z" ) { _neutPropType = Tauolapp::TauolaParticle::Z0; } else if ( neutPropName == "Gamma" ) { _neutPropType = Tauolapp::TauolaParticle::GAMMA; } else if ( neutPropName == "Higgs" ) { _neutPropType = Tauolapp::TauolaParticle::HIGGS; } else if ( neutPropName == "PseudoHiggs" ) { _neutPropType = Tauolapp::TauolaParticle::HIGGS_A; } else if ( neutPropName == "MixedHiggs" ) { _neutPropType = Tauolapp::Tauola::getHiggsScalarPseudoscalarPDG(); } if ( _neutPropType != 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "TAUOLA neutral spin propagator PDG id set to " << _neutPropType << endl; } // 2) TauolaChargedProp: Specify the charged propagator type used for spin matrix calculations // "W" (default), "Higgs" (H+/H-) std::string chargedPropName = EvtSymTable::get( "TauolaChargedProp", iErr ); if ( chargedPropName == "W" ) { _negPropType = Tauolapp::TauolaParticle::W_MINUS; _posPropType = Tauolapp::TauolaParticle::W_PLUS; } else if ( chargedPropName == "Higgs" ) { _negPropType = Tauolapp::TauolaParticle::HIGGS_MINUS; _posPropType = Tauolapp::TauolaParticle::HIGGS_PLUS; } if ( _negPropType != 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "TAUOLA negative charge spin propagator PDG id set to " << _negPropType << endl; } if ( _posPropType != 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "TAUOLA positive charge spin propagator PDG id set to " << _posPropType << endl; } // 3) TauolaHiggsMixingAngle: Specify the mixing angle between the neutral scalar & pseudoscalar Higgs // A0/H0; the default mixing angle is pi/4 radians std::string mixString = EvtSymTable::get( "TauolaHiggsMixingAngle", iErr ); // If the definition name is not found, get() just returns the first argument string if ( mixString != "TauolaHiggsMixingAngle" ) { double mixAngle = std::atof( mixString.c_str() ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "TAUOLA Higgs mixing angle set to " << mixAngle << " radians" << endl; Tauolapp::Tauola::setHiggsScalarPseudoscalarMixingAngle( mixAngle ); } // 4) TauolaBRi, where i = 1,2,3,4: Redefine sub-channel branching fractions using the setTaukle // function, after initialized() has been called. Default values = 0.5, 0.5, 0.5 and 0.6667 int j( 1 ); std::vector BRVect; BRVect.push_back( 0.5 ); BRVect.push_back( 0.5 ); BRVect.push_back( 0.5 ); BRVect.push_back( 0.6667 ); for ( j = 1; j < 5; j++ ) { std::ostringstream o; o << j; std::string BRName = "TauolaBR" + o.str(); std::string stringBR = EvtSymTable::get( BRName, iErr ); // If the definition name is not found, get() just returns the first argument string if ( stringBR != BRName ) { BRVect[j - 1] = std::atof( stringBR.c_str() ); } } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "TAUOLA::setTaukle values are " << BRVect[0] << ", " << BRVect[1] << ", " << BRVect[2] << ", " << BRVect[3] << endl; Tauolapp::Tauola::setTaukle( BRVect[0], BRVect[1], BRVect[2], BRVect[3] ); // 5) Specify the hadronic current option, e.g. orig CLEO = 0, BaBar-tuned = 1 (default), ... // No check is made by EvtGen on valid integer options - its just passed to Tauola std::string currentOption = EvtSymTable::get( "TauolaCurrentOption", iErr ); // If the definition name is not found, get() just returns the first argument string if ( currentOption != "TauolaCurrentOption" ) { int currentOpt = std::atoi( currentOption.c_str() ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "TAUOLA current option = " << currentOpt << endl; Tauolapp::Tauola::setNewCurrents( currentOpt ); } } bool EvtTauolaEngine::doDecay( EvtParticle* tauParticle ) { if ( _initialised == false ) { this->initialise(); } - if ( tauParticle == 0 ) { + if ( tauParticle == nullptr ) { return false; } // Check that we have a tau particle. EvtId partId = tauParticle->getId(); if ( abs( EvtPDL::getStdHep( partId ) ) != _tauPDG ) { return false; } int nTauDaug = tauParticle->getNDaug(); // If the number of tau daughters is not zero, then we have already decayed // it using Tauola/another decay algorithm. if ( nTauDaug > 0 ) { return true; } this->decayTauEvent( tauParticle ); return true; } void EvtTauolaEngine::decayTauEvent( EvtParticle* tauParticle ) { // Either we have a tau particle within a decay chain, or a single particle. // Create a dummy HepMC event & vertex for the parent particle, containing the tau as // one of the outgoing particles. If we have a decay chain, the parent will be the // incoming particle, while the daughters, including the tau, are outgoing particles. // For the single particle case, the incoming particle is null, while the single tau // is the only outgoing particle. // We can then pass this event to Tauola which should then decay the tau particle. // We also consider all other tau particles from the parent decay in the logic below. // Create the dummy event. auto theEvent = std::make_unique( Units::GEV, Units::MM ); // Create the decay "vertex". GenVertexPtr theVertex = newGenVertexPtr(); theEvent->add_vertex( theVertex ); // Get the parent of this tau particle EvtParticle* theParent = tauParticle->getParent(); - GenParticlePtr hepMCParent( 0 ); + GenParticlePtr hepMCParent( nullptr ); // Assign the parent particle as the incoming particle to the vertex. if ( theParent ) { hepMCParent = this->createGenParticle( theParent ); theVertex->add_particle_in( hepMCParent ); } else { // The tau particle has no parent. Set "itself" as the incoming particle for the first vertex. // This is needed, otherwise Tauola warns of momentum non-conservation for this (1st) vertex. GenParticlePtr tauGenInit = this->createGenParticle( tauParticle ); theVertex->add_particle_in( tauGenInit ); } // Find all daughter particles and assign them as outgoing particles to the vertex. // This will include the tau particle we are currently processing. // If the parent decay has more than one tau particle, we need to include them as well. // This is important since Tauola needs the correct physics correlations: we do not // want Tauola to decay each particle separately if they are from tau pair combinations. // Tauola will process the event, and we will create EvtParticles from all tau decay // products, i.e. the tau particle we currently have and any other tau particles. // EvtGen will try to decay the other tau particle(s) by calling EvtTauola and therefore // this function. However, we check to see if the tau candidate has any daughters already. // If it does, then we have already set the tau decay products from Tauola. // Map to store (HepMC,EvtParticle) pairs for each tau candidate from the parent // decay. This is needed to find out what EvtParticle corresponds to a given tau HepMC // candidate: we do not want to recreate existing EvtParticle pointers. std::map tauMap; // Keep track of the original EvtId of the parent particle, since we may need to set // the equivalent HepMCParticle has a gauge boson to let Tauola calculate spin effects EvtId origParentId( -1, -1 ); if ( theParent ) { // Original parent id origParentId = EvtPDL::getId( theParent->getName() ); // Find all tau particles in the decay tree and store them in the map. // Keep track of how many tau daughters this parent particle has int nTaus( 0 ); int nDaug( theParent->getNDaug() ); int iDaug( 0 ); for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* theDaughter = theParent->getDaug( iDaug ); if ( theDaughter ) { GenParticlePtr hepMCDaughter = this->createGenParticle( theDaughter ); theVertex->add_particle_out( hepMCDaughter ); EvtId theId = theDaughter->getId(); int PDGInt = EvtPDL::getStdHep( theId ); if ( abs( PDGInt ) == _tauPDG ) { // Delete any siblings for the tau particle if ( theDaughter->getNDaug() > 0 ) { theDaughter->deleteDaughters( false ); } tauMap[hepMCDaughter] = theDaughter; nTaus++; } else { // Treat all other particles as "stable" hepMCDaughter->set_status( Tauolapp::TauolaParticle::STABLE ); } } // theDaughter != 0 } // Loop over daughters // For the parent particle, artifically set the PDG to a boson with the same 4-momentum // so that spin correlations are calculated inside Tauola. // This leaves the original parent _EvtParticle_ unchanged if ( nTaus > 0 && hepMCParent ) { int parCharge = EvtPDL::chg3( origParentId ) / 3; // (3*particle charge)/3 = particle charge if ( parCharge == 0 && _neutPropType != 0 ) { hepMCParent->set_pdg_id( _neutPropType ); } else if ( parCharge == -1 && _negPropType != 0 ) { hepMCParent->set_pdg_id( _negPropType ); } else if ( parCharge == 1 && _posPropType != 0 ) { hepMCParent->set_pdg_id( _posPropType ); } } } else { // We only have the one tau particle. Store only this in the map. GenParticlePtr singleTau = this->createGenParticle( tauParticle ); theVertex->add_particle_out( singleTau ); tauMap[singleTau] = tauParticle; } // Now pass the event to Tauola for processing // Create a Tauola event object #ifdef EVTGEN_HEPMC3 Tauolapp::TauolaHepMC3Event tauolaEvent( theEvent.get() ); #else Tauolapp::TauolaHepMCEvent tauolaEvent( theEvent.get() ); #endif // Run the Tauola algorithm tauolaEvent.decayTaus(); // Loop over all tau particles in the HepMC event and create their EvtParticle daughters. // Store all final "stable" descendent particles as the tau daughters, i.e. // let Tauola decay any resonances such as a_1 or rho. // If there is more than one tau particle in the event, then also create the // corresponding EvtParticles for their daughters as well. They will not be // re-decayed since we check at the start of this function if the tau particle has // any daughters before running Tauola decayTaus(). #ifdef EVTGEN_HEPMC3 for ( auto aParticle : theEvent->particles() ) { #else HepMC::GenEvent::particle_iterator eventIter; for ( eventIter = theEvent->particles_begin(); eventIter != theEvent->particles_end(); ++eventIter ) { // Check to see if we have a tau particle HepMC::GenParticle* aParticle = ( *eventIter ); #endif if ( aParticle && abs( aParticle->pdg_id() ) == _tauPDG ) { // Find out what EvtParticle corresponds to the HepMC particle. // We need this to create and attach EvtParticle daughters. EvtParticle* tauEvtParticle = tauMap[aParticle]; if ( tauEvtParticle ) { // Get the tau 4-momentum in the lab (first mother) frame. We need to boost // all the tau daughters to this frame, such that daug.getP4() is in the tau restframe. EvtVector4R tauP4CM = tauEvtParticle->getP4Lab(); tauP4CM.set( tauP4CM.get( 0 ), -tauP4CM.get( 1 ), -tauP4CM.get( 2 ), -tauP4CM.get( 3 ) ); // Get the decay vertex for the tau particle GenVertexPtr endVertex = aParticle->end_vertex(); std::vector daugIdVect; std::vector daugP4Vect; // Loop through all descendants #ifdef EVTGEN_HEPMC3 for ( auto tauDaug : HepMC3::Relatives::DESCENDANTS( endVertex ) ) { #else HepMC::GenVertex::particle_iterator tauIter; // Loop through all descendants for ( tauIter = endVertex->particles_begin( HepMC::descendants ); tauIter != endVertex->particles_end( HepMC::descendants ); ++tauIter ) { HepMC::GenParticle* tauDaug = ( *tauIter ); #endif // Check to see if this descendant has its own decay vertex, e.g. rho resonance. // If so, skip this daughter and continue looping through the descendant list // until we reach the final "stable" products (e.g. pi pi from rho -> pi pi). GenVertexPtr daugDecayVtx = tauDaug->end_vertex(); if ( daugDecayVtx ) { continue; } // Store the particle id and 4-momentum int tauDaugPDG = tauDaug->pdg_id(); EvtId daugId = EvtPDL::evtIdFromStdHep( tauDaugPDG ); daugIdVect.push_back( daugId ); FourVector tauDaugP4 = tauDaug->momentum(); double tauDaug_px = tauDaugP4.px(); double tauDaug_py = tauDaugP4.py(); double tauDaug_pz = tauDaugP4.pz(); double tauDaug_E = tauDaugP4.e(); EvtVector4R daugP4( tauDaug_E, tauDaug_px, tauDaug_py, tauDaug_pz ); daugP4Vect.push_back( daugP4 ); } // Loop over HepMC tau daughters // Create the tau EvtParticle daughters and assign their ids and 4-mtm int nDaug = daugIdVect.size(); tauEvtParticle->makeDaughters( nDaug, daugIdVect ); int iDaug( 0 ); for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* theDaugPart = tauEvtParticle->getDaug( iDaug ); if ( theDaugPart ) { EvtId theDaugId = daugIdVect[iDaug]; EvtVector4R theDaugP4 = daugP4Vect[iDaug]; theDaugP4.applyBoostTo( tauP4CM ); // Boost the 4-mtm to the tau rest frame theDaugPart->init( theDaugId, theDaugP4 ); } } // Loop over tau daughters } } // We have a tau HepMC particle in the event } theEvent->clear(); } GenParticlePtr EvtTauolaEngine::createGenParticle( EvtParticle* theParticle ) { // Method to create an HepMC::GenParticle version of the given EvtParticle. - if ( theParticle == 0 ) { - return 0; + if ( theParticle == nullptr ) { + return nullptr; } // Get the 4-momentum (E, px, py, pz) for the EvtParticle EvtVector4R p4 = theParticle->getP4Lab(); // Convert this to the HepMC 4-momentum double E = p4.get( 0 ); double px = p4.get( 1 ); double py = p4.get( 2 ); double pz = p4.get( 3 ); FourVector hepMC_p4( px, py, pz, E ); int PDGInt = EvtPDL::getStdHep( theParticle->getId() ); // Set the status flag for the particle. int status = Tauolapp::TauolaParticle::HISTORY; GenParticlePtr genParticle = newGenParticlePtr( hepMC_p4, PDGInt, status ); return genParticle; } #endif diff --git a/src/EvtGenModels/EvtBtoXsgamma.cpp b/src/EvtGenModels/EvtBtoXsgamma.cpp index bb1524a..a81c4e5 100644 --- a/src/EvtGenModels/EvtBtoXsgamma.cpp +++ b/src/EvtGenModels/EvtBtoXsgamma.cpp @@ -1,130 +1,130 @@ /*********************************************************************** * 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/EvtBtoXsgamma.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtBtoXsgammaAliGreub.hh" #include "EvtGenModels/EvtBtoXsgammaFixedMass.hh" #include "EvtGenModels/EvtBtoXsgammaFlatEnergy.hh" #include "EvtGenModels/EvtBtoXsgammaKagan.hh" #include #include using std::endl; std::string EvtBtoXsgamma::getName() { return "BTOXSGAMMA"; } EvtDecayBase* EvtBtoXsgamma::clone() { return new EvtBtoXsgamma; } void EvtBtoXsgamma::init() { //Arguments: // 0: Ali-Greub model = 1, Kagan model = 2 //No more arguments for Ali-Greub model // 1: // 2: // 3: // check that at least one b->sg model has been selected if ( getNArg() == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBtoXsgamma generator expected " << " at least 1 argument but found: " << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } void EvtBtoXsgamma::initProbMax() { noProbMax(); } void EvtBtoXsgamma::decay( EvtParticle* p ) { //initialize here. -- its too damn slow otherwise. - if ( _model == 0 ) { + if ( _model == nullptr ) { if ( getArg( 0 ) == 1 ) _model = std::make_unique(); else if ( getArg( 0 ) == 2 ) _model = std::make_unique(); else if ( getArg( 0 ) == 3 ) _model = std::make_unique(); else if ( getArg( 0 ) == 4 ) _model = std::make_unique(); else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "No valid EvtBtoXsgamma generator model selected " << "Set arg(0) to 1 for Ali-Greub model or 2 for " << " Kagan model or 3 for a fixed mass" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } _model->init( getNArg(), getArgs() ); } // if ( p->getNDaug() != 0 ) { //Will end up here because maxrate multiplies by 1.2 // EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "In EvtBtoXsgamma: X_s daughters should not be here!"<makeDaughters( getNDaug(), getDaugs() ); EvtParticle* pdaug[MAX_DAUG]; for ( i = 0; i < getNDaug(); i++ ) { pdaug[i] = p->getDaug( i ); } static EvtVector4R p4[MAX_DAUG]; static double mass[MAX_DAUG]; m_b = p->mass(); mass[1] = EvtPDL::getMass( getDaug( 1 ) ); int Xscode = EvtPDL::getStdHep( getDaug( 0 ) ); mass[0] = _model->GetMass( Xscode ); EvtGenKine::PhaseSpace( getNDaug(), mass, p4, m_b ); for ( i = 0; i < getNDaug(); i++ ) { pdaug[i]->init( getDaugs()[i], p4[i] ); } } diff --git a/src/EvtGenModels/EvtD0gammaDalitz.cpp b/src/EvtGenModels/EvtD0gammaDalitz.cpp index c4810e7..3bbdc6e 100644 --- a/src/EvtGenModels/EvtD0gammaDalitz.cpp +++ b/src/EvtGenModels/EvtD0gammaDalitz.cpp @@ -1,310 +1,310 @@ /*********************************************************************** * 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/EvtD0gammaDalitz.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtFlatte.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtResonance.hh" #include "EvtGenBase/EvtResonance2.hh" #include #include #include // Initialize the static variables. const EvtSpinType::spintype& EvtD0gammaDalitz::_SCALAR = EvtSpinType::SCALAR; const EvtSpinType::spintype& EvtD0gammaDalitz::_VECTOR = EvtSpinType::VECTOR; const EvtSpinType::spintype& EvtD0gammaDalitz::_TENSOR = EvtSpinType::TENSOR; const EvtDalitzReso::CouplingType& EvtD0gammaDalitz::_EtaPic = EvtDalitzReso::EtaPic; const EvtDalitzReso::CouplingType& EvtD0gammaDalitz::_PicPicKK = EvtDalitzReso::PicPicKK; const EvtDalitzReso::NumType& EvtD0gammaDalitz::_RBW = EvtDalitzReso::RBW_CLEO_ZEMACH; const EvtDalitzReso::NumType& EvtD0gammaDalitz::_GS = EvtDalitzReso::GS_CLEO_ZEMACH; const EvtDalitzReso::NumType& EvtD0gammaDalitz::_KMAT = EvtDalitzReso::K_MATRIX; const EvtCyclic3::Pair& EvtD0gammaDalitz::_AB = EvtCyclic3::AB; const EvtCyclic3::Pair& EvtD0gammaDalitz::_AC = EvtCyclic3::AC; const EvtCyclic3::Pair& EvtD0gammaDalitz::_BC = EvtCyclic3::BC; std::string EvtD0gammaDalitz::getName() { return "D0GAMMADALITZ"; } EvtDecayBase* EvtD0gammaDalitz::clone() { return new EvtD0gammaDalitz; } void EvtD0gammaDalitz::init() { // check that there are 0 arguments checkNArg( 0 ); // Check that this model is valid for the specified decay. checkNDaug( 3 ); checkSpinParent( _SCALAR ); checkSpinDaughter( 0, _SCALAR ); checkSpinDaughter( 1, _SCALAR ); checkSpinDaughter( 2, _SCALAR ); // Get the values of the EvtId objects from the data files. readPDGValues(); // Get the EvtId of the D0 and its 3 daughters. getParentId(); EvtId dau[3]; for ( int index = 0; index < 3; index++ ) { dau[index] = getDaug( index ); } // Look for K0bar h+ h-. The order will be K[0SL] h+ h- for ( int index = 0; index < 3; index++ ) { if ( ( dau[index] == _K0B ) || ( dau[index] == _KS ) || ( dau[index] == _KL ) ) { _d1 = index; } else if ( ( dau[index] == _PIP ) || ( dau[index] == _KP ) ) { _d2 = index; } else if ( ( dau[index] == _PIM ) || ( dau[index] == _KM ) ) { _d3 = index; } else { reportInvalidAndExit(); } } // Check if we're dealing with Ks pi pi or with Ks K K. _isKsPiPi = false; if ( dau[_d2] == _PIP || dau[_d2] == _PIM ) { _isKsPiPi = true; } } void EvtD0gammaDalitz::initProbMax() { setProbMax( 5200. ); } void EvtD0gammaDalitz::decay( EvtParticle* part ) { // Check if the D is from a B+- -> D0 K+- decay with the appropriate model. EvtParticle* parent = part->getParent(); // If there are no mistakes, should be B+ or B-. - if ( parent != 0 && + if ( parent != nullptr && EvtDecayTable::getInstance()->getDecayFunc( parent )->getName() == "BTODDALITZCPK" ) { EvtId parId = parent->getId(); if ( ( parId == _BP ) || ( parId == _BM ) || ( parId == _B0 ) || ( parId == _B0B ) ) { _bFlavor = parId; } else { reportInvalidAndExit(); } } else { reportInvalidAndExit(); } // Read the D decay parameters from the B decay model. // Gamma angle in rad. double gamma = EvtDecayTable::getInstance()->getDecayFunc( parent )->getArg( 0 ); // Strong phase in rad. double delta = EvtDecayTable::getInstance()->getDecayFunc( parent )->getArg( 1 ); // Ratio between B->D0K and B->D0barK double rB = EvtDecayTable::getInstance()->getDecayFunc( parent )->getArg( 2 ); // Same structure for all of these decays. part->initializePhaseSpace( getNDaug(), getDaugs() ); EvtVector4R pA = part->getDaug( _d1 )->getP4(); EvtVector4R pB = part->getDaug( _d2 )->getP4(); EvtVector4R pC = part->getDaug( _d3 )->getP4(); // Squared invariant masses. double mSqAB = ( pA + pB ).mass2(); double mSqAC = ( pA + pC ).mass2(); double mSqBC = ( pB + pC ).mass2(); EvtComplex amp( 1.0, 0.0 ); // Direct and conjugated amplitudes. EvtComplex ampDir; EvtComplex ampCnj; if ( _isKsPiPi ) { // Direct and conjugated Dalitz points. EvtDalitzPoint pointDir( _mKs, _mPi, _mPi, mSqAB, mSqBC, mSqAC ); EvtDalitzPoint pointCnj( _mKs, _mPi, _mPi, mSqAC, mSqBC, mSqAB ); // Direct and conjugated amplitudes. ampDir = dalitzKsPiPi( pointDir ); ampCnj = dalitzKsPiPi( pointCnj ); } else { // Direct and conjugated Dalitz points. EvtDalitzPoint pointDir( _mKs, _mK, _mK, mSqAB, mSqBC, mSqAC ); EvtDalitzPoint pointCnj( _mKs, _mK, _mK, mSqAC, mSqBC, mSqAB ); // Direct and conjugated amplitudes. ampDir = dalitzKsKK( pointDir ); ampCnj = dalitzKsKK( pointCnj ); } if ( _bFlavor == _BP || _bFlavor == _B0 ) { amp = ampCnj + rB * exp( EvtComplex( 0., delta + gamma ) ) * ampDir; } else { amp = ampDir + rB * exp( EvtComplex( 0., delta - gamma ) ) * ampCnj; } vertex( amp ); return; } EvtComplex EvtD0gammaDalitz::dalitzKsPiPi( const EvtDalitzPoint& point ) const { static const EvtDalitzPlot plot( _mKs, _mPi, _mPi, _mD0 ); EvtComplex amp = 0.; // This corresponds to relativistic Breit-Wigner distributions. Not K-matrix. // Defining resonances. static EvtDalitzReso KStarm( plot, _BC, _AC, _VECTOR, 0.893606, 0.0463407, _RBW ); static EvtDalitzReso KStarp( plot, _BC, _AB, _VECTOR, 0.893606, 0.0463407, _RBW ); static EvtDalitzReso rho0( plot, _AC, _BC, _VECTOR, 0.7758, 0.1464, _GS ); static EvtDalitzReso omega( plot, _AC, _BC, _VECTOR, 0.78259, 0.00849, _RBW ); static EvtDalitzReso f0_980( plot, _AC, _BC, _SCALAR, 0.975, 0.044, _RBW ); static EvtDalitzReso f0_1370( plot, _AC, _BC, _SCALAR, 1.434, 0.173, _RBW ); static EvtDalitzReso f2_1270( plot, _AC, _BC, _TENSOR, 1.2754, 0.1851, _RBW ); static EvtDalitzReso K0Starm_1430( plot, _BC, _AC, _SCALAR, 1.459, 0.175, _RBW ); static EvtDalitzReso K0Starp_1430( plot, _BC, _AB, _SCALAR, 1.459, 0.175, _RBW ); static EvtDalitzReso K2Starm_1430( plot, _BC, _AC, _TENSOR, 1.4256, 0.0985, _RBW ); static EvtDalitzReso K2Starp_1430( plot, _BC, _AB, _TENSOR, 1.4256, 0.0985, _RBW ); static EvtDalitzReso sigma( plot, _AC, _BC, _SCALAR, 0.527699, 0.511861, _RBW ); static EvtDalitzReso sigma2( plot, _AC, _BC, _SCALAR, 1.03327, 0.0987890, _RBW ); static EvtDalitzReso KStarm_1680( plot, _BC, _AC, _VECTOR, 1.677, 0.205, _RBW ); // Adding terms to the amplitude with their corresponding amplitude and phase terms. amp += EvtComplex( .848984, .893618 ); amp += EvtComplex( -1.16356, 1.19933 ) * KStarm.evaluate( point ); amp += EvtComplex( .106051, -.118513 ) * KStarp.evaluate( point ); amp += EvtComplex( 1.0, 0.0 ) * rho0.evaluate( point ); amp += EvtComplex( -.0249569, .0388072 ) * omega.evaluate( point ); amp += EvtComplex( -.423586, -.236099 ) * f0_980.evaluate( point ); amp += EvtComplex( -2.16486, 3.62385 ) * f0_1370.evaluate( point ); amp += EvtComplex( .217748, -.133327 ) * f2_1270.evaluate( point ); amp += EvtComplex( 1.62128, 1.06816 ) * K0Starm_1430.evaluate( point ); amp += EvtComplex( .148802, .0897144 ) * K0Starp_1430.evaluate( point ); amp += EvtComplex( 1.15489, -.773363 ) * K2Starm_1430.evaluate( point ); amp += EvtComplex( .140865, -.165378 ) * K2Starp_1430.evaluate( point ); amp += EvtComplex( -1.55556, -.931685 ) * sigma.evaluate( point ); amp += EvtComplex( -.273791, -.0535596 ) * sigma2.evaluate( point ); amp += EvtComplex( -1.69720, .128038 ) * KStarm_1680.evaluate( point ); return amp; } EvtComplex EvtD0gammaDalitz::dalitzKsKK( const EvtDalitzPoint& point ) const { static const EvtDalitzPlot plot( _mKs, _mK, _mK, _mD0 ); // Defining resonances. static EvtDalitzReso a00_980( plot, _AC, _BC, _SCALAR, 0.999, _RBW, .550173, .324, _EtaPic ); static EvtDalitzReso phi( plot, _AC, _BC, _VECTOR, 1.01943, .00459319, _RBW ); static EvtDalitzReso a0p_980( plot, _AC, _AB, _SCALAR, 0.999, _RBW, .550173, .324, _EtaPic ); static EvtDalitzReso f0_1370( plot, _AC, _BC, _SCALAR, 1.350, .265, _RBW ); static EvtDalitzReso a0m_980( plot, _AB, _AC, _SCALAR, 0.999, _RBW, .550173, .324, _EtaPic ); static EvtDalitzReso f0_980( plot, _AC, _BC, _SCALAR, 0.965, _RBW, .695, .165, _PicPicKK ); static EvtDalitzReso f2_1270( plot, _AC, _BC, _TENSOR, 1.2754, .1851, _RBW ); static EvtDalitzReso a00_1450( plot, _AC, _BC, _SCALAR, 1.474, .265, _RBW ); static EvtDalitzReso a0p_1450( plot, _AC, _AB, _SCALAR, 1.474, .265, _RBW ); static EvtDalitzReso a0m_1450( plot, _AB, _AC, _SCALAR, 1.474, .265, _RBW ); // Adding terms to the amplitude with their corresponding amplitude and phase terms. EvtComplex amp( 0., 0. ); // Phase space amplitude. amp += EvtComplex( 1.0, 0.0 ) * a00_980.evaluate( point ); amp += EvtComplex( -.126314, .188701 ) * phi.evaluate( point ); amp += EvtComplex( -.561428, .0135338 ) * a0p_980.evaluate( point ); amp += EvtComplex( .035, -.00110488 ) * f0_1370.evaluate( point ); amp += EvtComplex( -.0872735, .0791190 ) * a0m_980.evaluate( point ); amp += EvtComplex( 0., 0. ) * f0_980.evaluate( point ); amp += EvtComplex( .257341, -.0408343 ) * f2_1270.evaluate( point ); amp += EvtComplex( -.0614342, -.649930 ) * a00_1450.evaluate( point ); amp += EvtComplex( -.104629, .830120 ) * a0p_1450.evaluate( point ); amp += EvtComplex( 0., 0. ) * a0m_1450.evaluate( point ); return 2.8 * amp; // Multiply by 2.8 in order to reuse the same probmax as Ks pi pi. } void EvtD0gammaDalitz::readPDGValues() { // Define the EvtIds. _BP = EvtPDL::getId( "B+" ); _BM = EvtPDL::getId( "B-" ); _B0 = EvtPDL::getId( "B0" ); _B0B = EvtPDL::getId( "anti-B0" ); _D0 = EvtPDL::getId( "D0" ); _D0B = EvtPDL::getId( "anti-D0" ); _KM = EvtPDL::getId( "K-" ); _KP = EvtPDL::getId( "K+" ); _K0 = EvtPDL::getId( "K0" ); _K0B = EvtPDL::getId( "anti-K0" ); _KL = EvtPDL::getId( "K_L0" ); _KS = EvtPDL::getId( "K_S0" ); _PIM = EvtPDL::getId( "pi-" ); _PIP = EvtPDL::getId( "pi+" ); // Read the relevant masses. _mD0 = EvtPDL::getMass( _D0 ); _mKs = EvtPDL::getMass( _KS ); _mPi = EvtPDL::getMass( _PIP ); _mK = EvtPDL::getMass( _KP ); } void EvtD0gammaDalitz::reportInvalidAndExit() const { EvtGenReport( EVTGEN_ERROR, "EvtD0gammaDalitz" ) << "EvtD0gammaDalitz: Invalid mode." << std::endl; exit( 1 ); } diff --git a/src/EvtGenModels/EvtDalitzTable.cpp b/src/EvtGenModels/EvtDalitzTable.cpp index fa90889..7d43bb9 100644 --- a/src/EvtGenModels/EvtDalitzTable.cpp +++ b/src/EvtGenModels/EvtDalitzTable.cpp @@ -1,674 +1,674 @@ /*********************************************************************** * 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/EvtDalitzTable.hh" #include "EvtGenBase/EvtCyclic3.hh" #include "EvtGenBase/EvtDalitzPlot.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParserXml.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSpinType.hh" #include #include using std::endl; using std::fstream; using std::ifstream; EvtDalitzTable::EvtDalitzTable() { _dalitztable.clear(); _readFiles.clear(); } EvtDalitzTable::~EvtDalitzTable() { _dalitztable.clear(); _readFiles.clear(); } EvtDalitzTable* EvtDalitzTable::getInstance( const std::string dec_name, bool verbose ) { - static EvtDalitzTable* theDalitzTable = 0; + static EvtDalitzTable* theDalitzTable = nullptr; - if ( theDalitzTable == 0 ) { + if ( theDalitzTable == nullptr ) { theDalitzTable = new EvtDalitzTable(); } if ( !theDalitzTable->fileHasBeenRead( dec_name ) ) { theDalitzTable->readXMLDecayFile( dec_name, verbose ); } return theDalitzTable; } bool EvtDalitzTable::fileHasBeenRead( const std::string dec_name ) { std::vector::iterator i = _readFiles.begin(); for ( ; i != _readFiles.end(); i++ ) { if ( ( *i ).compare( dec_name ) == 0 ) { return true; } } return false; } void EvtDalitzTable::readXMLDecayFile( const std::string dec_name, bool verbose ) { if ( verbose ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "EvtDalitzTable: Reading in xml parameter file " << dec_name << endl; } _readFiles.push_back( dec_name ); - EvtDalitzDecayInfo* dalitzDecay = 0; + EvtDalitzDecayInfo* dalitzDecay = nullptr; double probMax = 0; EvtId ipar; std::string decayParent = ""; std::string daugStr = ""; EvtId daughter[3]; EvtDalitzPlot dp; EvtComplex cAmp; std::vector> angAndResPairs; std::string shape( "" ); EvtSpinType::spintype spinType( EvtSpinType::SCALAR ); double mass( 0. ), width( 0. ), FFp( 0. ), FFr( 0. ); std::vector flatteParams; //Nonres parameters double alpha( 0. ); //LASS parameters double aLass( 0. ), rLass( 0. ), BLass( 0. ), phiBLass( 0. ), RLass( 0. ), phiRLass( 0. ), cutoffLass( -1. ); EvtParserXml parser; parser.open( dec_name ); bool endReached = false; while ( parser.readNextTag() ) { //TAGS FOUND UNDER DATA if ( parser.getParentTagTitle() == "data" ) { if ( parser.getTagTitle() == "dalitzDecay" ) { int nDaughters = 0; decayParent = parser.readAttribute( "particle" ); daugStr = parser.readAttribute( "daughters" ); probMax = parser.readAttributeDouble( "probMax", -1 ); checkParticle( decayParent ); ipar = EvtPDL::getId( decayParent ); std::istringstream daugStream( daugStr ); std::string daugh; while ( std::getline( daugStream, daugh, ' ' ) ) { checkParticle( daugh ); daughter[nDaughters++] = EvtPDL::getId( daugh ); } if ( nDaughters != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected to find three daughters for dalitzDecay of " << decayParent << " near line " << parser.getLineNumber() << ", " << "found " << nDaughters << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } double m_d1 = EvtPDL::getMass( daughter[0] ), m_d2 = EvtPDL::getMass( daughter[1] ), m_d3 = EvtPDL::getMass( daughter[2] ), M = EvtPDL::getMass( ipar ); dp = EvtDalitzPlot( m_d1, m_d2, m_d3, M ); dalitzDecay = new EvtDalitzDecayInfo( daughter[0], daughter[1], daughter[2] ); } else if ( parser.getTagTitle() == "copyDalitz" ) { int nDaughters = 0; EvtId daughter[3]; int nCopyDaughters = 0; EvtId copyDaughter[3]; decayParent = parser.readAttribute( "particle" ); daugStr = parser.readAttribute( "daughters" ); std::string copyParent = parser.readAttribute( "copy" ); std::string copyDaugStr = parser.readAttribute( "copyDaughters" ); checkParticle( decayParent ); ipar = EvtPDL::getId( decayParent ); checkParticle( copyParent ); EvtId copypar = EvtPDL::getId( copyParent ); std::istringstream daugStream( daugStr ); std::istringstream copyDaugStream( copyDaugStr ); std::string daugh; while ( std::getline( daugStream, daugh, ' ' ) ) { checkParticle( daugh ); daughter[nDaughters++] = EvtPDL::getId( daugh ); } while ( std::getline( copyDaugStream, daugh, ' ' ) ) { checkParticle( daugh ); copyDaughter[nCopyDaughters++] = EvtPDL::getId( daugh ); } if ( nDaughters != 3 || nCopyDaughters != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Expected to find three daughters for copyDecay of " << decayParent << " from " << copyParent << " near line " << parser.getLineNumber() << ", " << "found " << nDaughters << " and " << nCopyDaughters << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } copyDecay( ipar, daughter, copypar, copyDaughter ); } else if ( parser.getTagTitle() == "/data" ) { //end of data endReached = true; parser.close(); break; } //TAGS FOUND UNDER DALITZDECAY } else if ( parser.getParentTagTitle() == "dalitzDecay" ) { if ( parser.getTagTitle() == "resonance" ) { flatteParams.clear(); //Amplitude EvtComplex ampFactor( parser.readAttributeDouble( "ampFactorReal", 1. ), parser.readAttributeDouble( "ampFactorImag", 0. ) ); double mag = parser.readAttributeDouble( "mag", -999. ); double phase = parser.readAttributeDouble( "phase", -999. ); double real = parser.readAttributeDouble( "real", -999. ); double imag = parser.readAttributeDouble( "imag", -999. ); if ( ( real != -999. || imag != -999. ) && mag == -999. && phase == -999. ) { if ( real == -999. ) { real = 0; } if ( imag == -999. ) { imag = 0; } mag = sqrt( real * real + imag * imag ); phase = atan2( imag, real ) * EvtConst::radToDegrees; } if ( mag == -999. ) { mag = 1.; } if ( phase == -999. ) { phase = 0.; } cAmp = ampFactor * EvtComplex( cos( phase * 1.0 / EvtConst::radToDegrees ), sin( phase * 1.0 / EvtConst::radToDegrees ) ) * mag; //Resonance particle properties mass = 0.; width = 0.; spinType = EvtSpinType::SCALAR; std::string particle = parser.readAttribute( "particle" ); if ( particle != "" ) { EvtId resId = EvtPDL::getId( particle ); if ( resId == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << particle.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } else { mass = EvtPDL::getMeanMass( resId ); width = EvtPDL::getWidth( resId ); spinType = EvtPDL::getSpinType( resId ); } } width = parser.readAttributeDouble( "width", width ); mass = parser.readAttributeDouble( "mass", mass ); switch ( parser.readAttributeInt( "spin", -1 ) ) { case -1: //not set here break; case 0: spinType = EvtSpinType::SCALAR; break; case 1: spinType = EvtSpinType::VECTOR; break; case 2: spinType = EvtSpinType::TENSOR; break; default: EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unsupported spin near line " << parser.getLineNumber() << " of XML file." << endl; ::abort(); } //Shape and form factors shape = parser.readAttribute( "shape" ); FFp = parser.readAttributeDouble( "BlattWeisskopfFactorParent", 0.0 ); FFr = parser.readAttributeDouble( "BlattWeisskopfFactorResonance", 1.5 ); //Shape specific attributes if ( shape == "NonRes_Exp" ) { alpha = parser.readAttributeDouble( "alpha", 0.0 ); } if ( shape == "LASS" ) { aLass = parser.readAttributeDouble( "a", 2.07 ); rLass = parser.readAttributeDouble( "r", 3.32 ); BLass = parser.readAttributeDouble( "B", 1.0 ); phiBLass = parser.readAttributeDouble( "phiB", 0.0 ); RLass = parser.readAttributeDouble( "R", 1.0 ); phiRLass = parser.readAttributeDouble( "phiR", 0.0 ); cutoffLass = parser.readAttributeDouble( "cutoff", -1.0 ); } //Daughter pairs for resonance angAndResPairs.clear(); std::string resDaugStr = parser.readAttribute( "resDaughters" ); if ( resDaugStr != "" ) { std::istringstream resDaugStream( resDaugStr ); std::string resDaug; int nResDaug( 0 ); EvtId resDaughter[2]; while ( std::getline( resDaugStream, resDaug, ' ' ) ) { checkParticle( resDaug ); resDaughter[nResDaug++] = EvtPDL::getId( resDaug ); } if ( nResDaug != 2 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Resonance must have exactly 2 daughters near line " << parser.getLineNumber() << " of XML file." << endl; ::abort(); } int nRes = getDaughterPairs( resDaughter, daughter, angAndResPairs ); if ( nRes == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Resonance daughters must match decay daughters near line " << parser.getLineNumber() << " of XML file." << endl; ::abort(); } if ( parser.readAttributeBool( "normalise", true ) ) cAmp /= sqrt( nRes ); } if ( angAndResPairs.empty() ) { switch ( parser.readAttributeInt( "daughterPair" ) ) { case 1: angAndResPairs.push_back( std::make_pair( EvtCyclic3::BC, EvtCyclic3::AB ) ); break; case 2: angAndResPairs.push_back( std::make_pair( EvtCyclic3::CA, EvtCyclic3::BC ) ); break; case 3: angAndResPairs.push_back( std::make_pair( EvtCyclic3::AB, EvtCyclic3::CA ) ); break; default: if ( shape == "NonRes" ) { //We don't expect a pair for non-resonant terms but add dummy values for convenience angAndResPairs.push_back( std::make_pair( EvtCyclic3::AB, EvtCyclic3::AB ) ); break; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Daughter pair must be 1, 2 or 3 near line " << parser.getLineNumber() << " of XML file." << endl; ::abort(); } } if ( parser.isTagInline() ) { std::vector>::iterator it = angAndResPairs.begin(); for ( ; it != angAndResPairs.end(); it++ ) { std::pair pairs = *it; EvtDalitzReso resonance = getResonance( shape, dp, pairs.first, pairs.second, spinType, mass, width, FFp, FFr, alpha, aLass, rLass, BLass, phiBLass, RLass, phiRLass, cutoffLass ); dalitzDecay->addResonance( cAmp, resonance ); } } } else if ( parser.getTagTitle() == "/dalitzDecay" ) { if ( probMax < 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "probMax is not defined for " << decayParent << " -> " << daugStr << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Will now estimate probMax. This may take a while. Once probMax is calculated, update the XML file to skip this step in future." << endl; probMax = calcProbMax( dp, dalitzDecay ); } dalitzDecay->setProbMax( probMax ); addDecay( ipar, *dalitzDecay ); delete dalitzDecay; - dalitzDecay = 0; + dalitzDecay = nullptr; } else if ( verbose ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Unexpected tag " << parser.getTagTitle() << " found in XML decay file near line " << parser.getLineNumber() << ". Tag will be ignored." << endl; } //TAGS FOUND UNDER RESONANCE } else if ( parser.getParentTagTitle() == "resonance" ) { if ( parser.getTagTitle() == "flatteParam" ) { EvtFlatteParam param( parser.readAttributeDouble( "mass1" ), parser.readAttributeDouble( "mass2" ), parser.readAttributeDouble( "g" ) ); flatteParams.push_back( param ); } else if ( parser.getTagTitle() == "/resonance" ) { std::vector>::iterator it = angAndResPairs.begin(); for ( ; it != angAndResPairs.end(); it++ ) { std::pair pairs = *it; EvtDalitzReso resonance = getResonance( shape, dp, pairs.first, pairs.second, spinType, mass, width, FFp, FFr, alpha, aLass, rLass, BLass, phiBLass, RLass, phiRLass, cutoffLass ); std::vector::iterator flatteIt = flatteParams.begin(); for ( ; flatteIt != flatteParams.end(); flatteIt++ ) { resonance.addFlatteParam( ( *flatteIt ) ); } dalitzDecay->addResonance( cAmp, resonance ); } } } } if ( !endReached ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Either the decay file ended prematurely or the file is badly formed.\n" << "Error occured near line" << parser.getLineNumber() << endl; ::abort(); } } void EvtDalitzTable::checkParticle( std::string particle ) { if ( EvtPDL::getId( particle ) == EvtId( -1, -1 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Unknown particle name:" << particle.c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } void EvtDalitzTable::addDecay( EvtId parent, const EvtDalitzDecayInfo& dec ) { if ( _dalitztable.find( parent ) != _dalitztable.end() ) { _dalitztable[parent].push_back( dec ); } else { _dalitztable[parent].push_back( dec ); } } void EvtDalitzTable::copyDecay( EvtId parent, EvtId* daughters, EvtId copy, EvtId* copyd ) { EvtDalitzDecayInfo decay( daughters[0], daughters[1], daughters[2] ); std::vector copyTable = getDalitzTable( copy ); std::vector::iterator i = copyTable.begin(); for ( ; i != copyTable.end(); i++ ) { EvtId daughter1 = ( *i ).daughter1(); EvtId daughter2 = ( *i ).daughter2(); EvtId daughter3 = ( *i ).daughter3(); if ( ( copyd[0] == daughter1 && copyd[1] == daughter2 && copyd[2] == daughter3 ) || ( copyd[0] == daughter1 && copyd[1] == daughter3 && copyd[2] == daughter2 ) || ( copyd[0] == daughter2 && copyd[1] == daughter1 && copyd[2] == daughter3 ) || ( copyd[0] == daughter2 && copyd[1] == daughter3 && copyd[2] == daughter1 ) || ( copyd[0] == daughter3 && copyd[1] == daughter1 && copyd[2] == daughter2 ) || ( copyd[0] == daughter3 && copyd[1] == daughter2 && copyd[2] == daughter1 ) ) { decay.setProbMax( ( *i ).getProbMax() ); std::vector>::const_iterator j = ( *i ).getResonances().begin(); for ( ; j != ( *i ).getResonances().end(); j++ ) { decay.addResonance( ( *j ) ); } addDecay( parent, decay ); return; } } //if we get here then there was no match EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Did not find dalitz decays for particle:" << copy << "\n"; } std::vector EvtDalitzTable::getDalitzTable( const EvtId& parent ) { std::vector table; if ( _dalitztable.find( parent ) != _dalitztable.end() ) { table = _dalitztable[parent]; } if ( table.empty() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Did not find dalitz decays for particle:" << parent << "\n"; } return table; } EvtDalitzReso EvtDalitzTable::getResonance( std::string shape, EvtDalitzPlot dp, EvtCyclic3::Pair angPair, EvtCyclic3::Pair resPair, EvtSpinType::spintype spinType, double mass, double width, double FFp, double FFr, double alpha, double aLass, double rLass, double BLass, double phiBLass, double RLass, double phiRLass, double cutoffLass ) { if ( shape == "RBW" || shape == "RBW_CLEO" ) { return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::RBW_CLEO, FFp, FFr ); } else if ( shape == "RBW_CLEO_ZEMACH" ) { return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::RBW_CLEO_ZEMACH, FFp, FFr ); } else if ( shape == "GS" || shape == "GS_CLEO" ) { return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::GS_CLEO, FFp, FFr ); } else if ( shape == "GS_CLEO_ZEMACH" ) { return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::GS_CLEO_ZEMACH, FFp, FFr ); } else if ( shape == "GAUSS" || shape == "GAUSS_CLEO" ) { return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::GAUSS_CLEO, FFp, FFr ); } else if ( shape == "GAUSS_CLEO_ZEMACH" ) { return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::GAUSS_CLEO_ZEMACH, FFp, FFr ); } else if ( shape == "Flatte" ) { return EvtDalitzReso( dp, resPair, mass ); } else if ( shape == "LASS" ) { return EvtDalitzReso( dp, resPair, mass, width, aLass, rLass, BLass, phiBLass, RLass, phiRLass, cutoffLass, true ); } else if ( shape == "NonRes" ) { return EvtDalitzReso(); } else if ( shape == "NonRes_Linear" ) { return EvtDalitzReso( dp, resPair, EvtDalitzReso::NON_RES_LIN ); } else if ( shape == "NonRes_Exp" ) { return EvtDalitzReso( dp, resPair, EvtDalitzReso::NON_RES_EXP, alpha ); } else { //NBW if ( shape != "NBW" ) EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtDalitzTable: shape " << shape << " is unknown. Defaulting to NBW." << endl; return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width, EvtDalitzReso::NBW, FFp, FFr ); } } int EvtDalitzTable::getDaughterPairs( EvtId* resDaughter, EvtId* daughter, std::vector>& angAndResPairs ) { int n( 0 ); if ( resDaughter[0] == daughter[0] && resDaughter[1] == daughter[1] ) { angAndResPairs.push_back( std::make_pair( EvtCyclic3::BC, EvtCyclic3::AB ) ); n++; } else if ( resDaughter[0] == daughter[1] && resDaughter[1] == daughter[0] ) { angAndResPairs.push_back( std::make_pair( EvtCyclic3::CA, EvtCyclic3::AB ) ); n++; } if ( resDaughter[0] == daughter[1] && resDaughter[1] == daughter[2] ) { angAndResPairs.push_back( std::make_pair( EvtCyclic3::CA, EvtCyclic3::BC ) ); n++; } else if ( resDaughter[0] == daughter[2] && resDaughter[1] == daughter[1] ) { angAndResPairs.push_back( std::make_pair( EvtCyclic3::AB, EvtCyclic3::BC ) ); n++; } if ( resDaughter[0] == daughter[2] && resDaughter[1] == daughter[0] ) { angAndResPairs.push_back( std::make_pair( EvtCyclic3::AB, EvtCyclic3::CA ) ); n++; } else if ( resDaughter[0] == daughter[0] && resDaughter[1] == daughter[2] ) { angAndResPairs.push_back( std::make_pair( EvtCyclic3::BC, EvtCyclic3::CA ) ); n++; } return n; } double EvtDalitzTable::calcProbMax( EvtDalitzPlot dp, EvtDalitzDecayInfo* model ) { double factor = 1.2; //factor to increase our final answer by int nStep( 1000 ); //number of steps - total points will be 3*nStep*nStep double maxProb( 0 ); double min( 0 ), max( 0 ), step( 0 ), min2( 0 ), max2( 0 ), step2( 0 ); //first do AB, BC min = dp.qAbsMin( EvtCyclic3::AB ); max = dp.qAbsMax( EvtCyclic3::AB ); step = ( max - min ) / nStep; for ( int i = 0; i < nStep; ++i ) { double qAB = min + i * step; min2 = dp.qMin( EvtCyclic3::BC, EvtCyclic3::AB, qAB ); max2 = dp.qMax( EvtCyclic3::BC, EvtCyclic3::AB, qAB ); step2 = ( max2 - min2 ) / nStep; for ( int j = 0; j < nStep; ++j ) { double qBC = min2 + j * step2; EvtDalitzCoord coord( EvtCyclic3::AB, qAB, EvtCyclic3::BC, qBC ); EvtDalitzPoint point( dp, coord ); double prob = calcProb( point, model ); if ( prob > maxProb ) maxProb = prob; } } //next do BC, CA min = dp.qAbsMin( EvtCyclic3::BC ); max = dp.qAbsMax( EvtCyclic3::BC ); step = ( max - min ) / nStep; for ( int i = 0; i < nStep; ++i ) { double qBC = min + i * step; min2 = dp.qMin( EvtCyclic3::CA, EvtCyclic3::BC, qBC ); max2 = dp.qMax( EvtCyclic3::CA, EvtCyclic3::BC, qBC ); step2 = ( max2 - min2 ) / nStep; for ( int j = 0; j < nStep; ++j ) { double qCA = min2 + j * step2; EvtDalitzCoord coord( EvtCyclic3::BC, qBC, EvtCyclic3::CA, qCA ); EvtDalitzPoint point( dp, coord ); double prob = calcProb( point, model ); if ( prob > maxProb ) maxProb = prob; } } //finally do CA, AB min = dp.qAbsMin( EvtCyclic3::CA ); max = dp.qAbsMax( EvtCyclic3::CA ); step = ( max - min ) / nStep; for ( int i = 0; i < nStep; ++i ) { double qCA = min + i * step; min2 = dp.qMin( EvtCyclic3::AB, EvtCyclic3::CA, qCA ); max2 = dp.qMax( EvtCyclic3::AB, EvtCyclic3::CA, qCA ); step2 = ( max2 - min2 ) / nStep; for ( int j = 0; j < nStep; ++j ) { double qAB = min2 + j * step2; EvtDalitzCoord coord( EvtCyclic3::CA, qCA, EvtCyclic3::AB, qAB ); EvtDalitzPoint point( dp, coord ); double prob = calcProb( point, model ); if ( prob > maxProb ) maxProb = prob; } } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Largest probability found was " << maxProb << endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Setting probMax to " << factor * maxProb << endl; return factor * maxProb; } double EvtDalitzTable::calcProb( EvtDalitzPoint point, EvtDalitzDecayInfo* model ) { std::vector> resonances = model->getResonances(); EvtComplex amp( 0, 0 ); std::vector>::iterator i = resonances.begin(); for ( ; i != resonances.end(); i++ ) { std::pair res = ( *i ); amp += res.first * res.second.evaluate( point ); } return abs2( amp ); } diff --git a/src/EvtGenModels/EvtLb2Baryonlnu.cpp b/src/EvtGenModels/EvtLb2Baryonlnu.cpp index ce3e851..d03f962 100644 --- a/src/EvtGenModels/EvtLb2Baryonlnu.cpp +++ b/src/EvtGenModels/EvtLb2Baryonlnu.cpp @@ -1,225 +1,225 @@ /*********************************************************************** * 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/EvtLb2Baryonlnu.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtLb2BaryonlnuFF.hh" #include #include using namespace std; #ifdef D0 #undef D0 #endif -EvtLb2Baryonlnu::EvtLb2Baryonlnu() : ffmodel( 0 ), calcamp( 0 ) +EvtLb2Baryonlnu::EvtLb2Baryonlnu() : ffmodel( nullptr ), calcamp( nullptr ) { } EvtLb2Baryonlnu::~EvtLb2Baryonlnu() { delete ffmodel; - ffmodel = 0; + ffmodel = nullptr; delete calcamp; - calcamp = 0; + calcamp = nullptr; } std::string EvtLb2Baryonlnu::getName() { return "Lb2Baryonlnu"; } EvtDecayBase* EvtLb2Baryonlnu::clone() { return new EvtLb2Baryonlnu; } void EvtLb2Baryonlnu::decay( EvtParticle* p ) { //This is a kludge to avoid warnings because the K_2* mass becomes to large. static EvtIdSet regenerateMasses( "K_2*+", "K_2*-", "K_2*0", "anti-K_2*0", "K_1+", "K_1-", "K_10", "anti-K_10", "D'_1+", "D'_1-", "D'_10", "anti-D'_10" ); if ( regenerateMasses.contains( getDaug( 0 ) ) ) { p->resetFirstOrNot(); } p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtComplex r00( getArg( 0 ), 0.0 ); EvtComplex r01( getArg( 1 ), 0.0 ); EvtComplex r10( getArg( 2 ), 0.0 ); EvtComplex r11( getArg( 3 ), 0.0 ); calcamp->CalcAmp( p, _amp2, ffmodel, r00, r01, r10, r11 ); } void EvtLb2Baryonlnu::initProbMax() { static EvtId LAMB = EvtPDL::getId( "Lambda_b0" ); static EvtId LAMBB = EvtPDL::getId( "anti-Lambda_b0" ); static EvtId PRO = EvtPDL::getId( "p+" ); static EvtId PROB = EvtPDL::getId( "anti-p-" ); static EvtId N1440 = EvtPDL::getId( "N(1440)+" ); static EvtId N1440B = EvtPDL::getId( "anti-N(1440)-" ); static EvtId N1535 = EvtPDL::getId( "N(1535)+" ); static EvtId N1535B = EvtPDL::getId( "anti-N(1535)-" ); static EvtId N1520 = EvtPDL::getId( "N(1520)+" ); static EvtId N1520B = EvtPDL::getId( "anti-N(1520)-" ); static EvtId N1720 = EvtPDL::getId( "N(1720)+" ); static EvtId N1720B = EvtPDL::getId( "anti-N(1720)-" ); static EvtId N1650 = EvtPDL::getId( "N(1650)+" ); static EvtId N1650B = EvtPDL::getId( "anti-N(1650)-" ); static EvtId N1700 = EvtPDL::getId( "N(1700)+" ); static EvtId N1700B = EvtPDL::getId( "anti-N(1700)-" ); static EvtId N1710 = EvtPDL::getId( "N(1710)+" ); static EvtId N1710B = EvtPDL::getId( "anti-N(1710)-" ); static EvtId N1875 = EvtPDL::getId( "N(1875)+" ); static EvtId N1875B = EvtPDL::getId( "anti-N(1875)-" ); static EvtId N1900 = EvtPDL::getId( "N(1900)+" ); static EvtId N1900B = EvtPDL::getId( "anti-N(1900)-" ); static EvtId LAMCP = EvtPDL::getId( "Lambda_c+" ); static EvtId LAMCM = EvtPDL::getId( "anti-Lambda_c-" ); static EvtId LAMC1P = EvtPDL::getId( "Lambda_c(2593)+" ); static EvtId LAMC1M = EvtPDL::getId( "anti-Lambda_c(2593)-" ); static EvtId LAMC2P = EvtPDL::getId( "Lambda_c(2625)+" ); static EvtId LAMC2M = EvtPDL::getId( "anti-Lambda_c(2625)-" ); EvtId parnum, barnum; parnum = getParentId(); barnum = getDaug( 0 ); if ( ( parnum == LAMB && barnum == PRO ) || ( parnum == LAMBB && barnum == PROB ) || ( parnum == LAMB && barnum == N1440 ) || ( parnum == LAMBB && barnum == N1440B ) || ( parnum == LAMB && barnum == N1520 ) || ( parnum == LAMBB && barnum == N1520B ) || ( parnum == LAMB && barnum == N1535 ) || ( parnum == LAMBB && barnum == N1535B ) || ( parnum == LAMB && barnum == N1720 ) || ( parnum == LAMBB && barnum == N1720B ) || ( parnum == LAMB && barnum == N1650 ) || ( parnum == LAMBB && barnum == N1650B ) || ( parnum == LAMB && barnum == N1700 ) || ( parnum == LAMBB && barnum == N1700B ) || ( parnum == LAMB && barnum == N1710 ) || ( parnum == LAMBB && barnum == N1710B ) || ( parnum == LAMB && barnum == N1875 ) || ( parnum == LAMBB && barnum == N1875B ) || ( parnum == LAMB && barnum == N1900 ) || ( parnum == LAMBB && barnum == N1900B ) || ( parnum == LAMB && barnum == LAMCP ) || ( parnum == LAMBB && barnum == LAMCM ) || ( parnum == LAMB && barnum == LAMC1P ) || ( parnum == LAMBB && barnum == LAMC1M ) || ( parnum == LAMB && barnum == LAMC2P ) || ( parnum == LAMBB && barnum == LAMC2M ) ) { setProbMax( 22000.0 ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Decay does not have acceptable final state baryon for this model setting ProbMax = 0 " << endl; setProbMax( 0.0 ); } } void EvtLb2Baryonlnu::init() { if ( getNArg() != 4 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2Baryonlnu generator expected " << " 4 arguments but found:" << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( getNDaug() != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong number of daughters in EvtLb2plnu.cc " << " 3 daughters expected but found: " << getNDaug() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } //We expect the parent to be a dirac particle //and the daughters to be X lepton neutrino EvtSpinType::spintype parenttype = EvtPDL::getSpinType( getParentId() ); EvtSpinType::spintype baryontype = EvtPDL::getSpinType( getDaug( 0 ) ); EvtSpinType::spintype leptontype = EvtPDL::getSpinType( getDaug( 1 ) ); EvtSpinType::spintype neutrinotype = EvtPDL::getSpinType( getDaug( 2 ) ); if ( parenttype != EvtSpinType::DIRAC ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2Baryonlnu generator expected " << " a DIRAC parent, found:" << EvtPDL::name( getParentId() ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( leptontype != EvtSpinType::DIRAC ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2Baryonlnu generator expected " << " a DIRAC 2nd daughter, found:" << EvtPDL::name( getDaug( 1 ) ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( neutrinotype != EvtSpinType::NEUTRINO ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2Baryonlnu generator expected " << " a NEUTRINO 3rd daughter, found:" << EvtPDL::name( getDaug( 2 ) ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } //set ffmodel ffmodel = new EvtLb2BaryonlnuFF; if ( baryontype == EvtSpinType::DIRAC || baryontype == EvtSpinType::RARITASCHWINGER ) { calcamp = new EvtSLBaryonAmp; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong baryon spin type in EvtLb2Baryonlnu.cc " << "Expected spin type " << EvtSpinType::DIRAC << ", found spin type " << baryontype << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } diff --git a/src/EvtGenModels/EvtLb2plnuLCSR.cpp b/src/EvtGenModels/EvtLb2plnuLCSR.cpp index 03c9d20..94a81b4 100644 --- a/src/EvtGenModels/EvtLb2plnuLCSR.cpp +++ b/src/EvtGenModels/EvtLb2plnuLCSR.cpp @@ -1,175 +1,175 @@ /*********************************************************************** * 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/EvtLb2plnuLCSR.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtLb2plnuLCSRFF.hh" #include #include using namespace std; #ifdef D0 #undef D0 #endif -EvtLb2plnuLCSR::EvtLb2plnuLCSR() : ffmodel( 0 ), calcamp( 0 ) +EvtLb2plnuLCSR::EvtLb2plnuLCSR() : ffmodel( nullptr ), calcamp( nullptr ) { } EvtLb2plnuLCSR::~EvtLb2plnuLCSR() { delete ffmodel; - ffmodel = 0; + ffmodel = nullptr; delete calcamp; - calcamp = 0; + calcamp = nullptr; } std::string EvtLb2plnuLCSR::getName() { return "Lb2plnuLCSR"; } EvtDecayBase* EvtLb2plnuLCSR::clone() { return new EvtLb2plnuLCSR; } void EvtLb2plnuLCSR::decay( EvtParticle* p ) { //This is a kludge to avoid warnings because the K_2* mass becomes to large. static EvtIdSet regenerateMasses( "K_2*+", "K_2*-", "K_2*0", "anti-K_2*0", "K_1+", "K_1-", "K_10", "anti-K_10", "D'_1+", "D'_1-", "D'_10", "anti-D'_10" ); if ( regenerateMasses.contains( getDaug( 0 ) ) ) { p->resetFirstOrNot(); } p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtComplex r00( getArg( 0 ), 0.0 ); EvtComplex r01( getArg( 1 ), 0.0 ); EvtComplex r10( getArg( 2 ), 0.0 ); EvtComplex r11( getArg( 3 ), 0.0 ); calcamp->CalcAmp( p, _amp2, ffmodel, r00, r01, r10, r11 ); } void EvtLb2plnuLCSR::initProbMax() { static EvtId LAMB = EvtPDL::getId( "Lambda_b0" ); static EvtId LAMBB = EvtPDL::getId( "anti-Lambda_b0" ); static EvtId PRO = EvtPDL::getId( "p+" ); static EvtId PROB = EvtPDL::getId( "anti-p-" ); EvtId parnum, barnum; parnum = getParentId(); barnum = getDaug( 0 ); if ( ( parnum == LAMB && barnum == PRO ) || ( parnum == LAMBB && barnum == PROB ) ) { setProbMax( 22000.0 ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Decay does not have Lb->p setting ProbMax = 0 " << endl; setProbMax( 0.0 ); } } void EvtLb2plnuLCSR::init() { if ( getNArg() != 4 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLCSR generator expected " << " 4 arguments but found:" << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( getNDaug() != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong number of daughters in EvtLb2plnu.cc " << " 3 daughters expected but found: " << getNDaug() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } //We expect the parent to be a dirac particle //and the daughters to be X lepton neutrino EvtSpinType::spintype parenttype = EvtPDL::getSpinType( getParentId() ); EvtSpinType::spintype baryontype = EvtPDL::getSpinType( getDaug( 0 ) ); EvtSpinType::spintype leptontype = EvtPDL::getSpinType( getDaug( 1 ) ); EvtSpinType::spintype neutrinotype = EvtPDL::getSpinType( getDaug( 2 ) ); if ( parenttype != EvtSpinType::DIRAC ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLCSR generator expected " << " a DIRAC parent, found:" << EvtPDL::name( getParentId() ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( leptontype != EvtSpinType::DIRAC ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLCSR generator expected " << " a DIRAC 2nd daughter, found:" << EvtPDL::name( getDaug( 1 ) ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( neutrinotype != EvtSpinType::NEUTRINO ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLCSR generator expected " << " a NEUTRINO 3rd daughter, found:" << EvtPDL::name( getDaug( 2 ) ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } //set ffmodel ffmodel = new EvtLb2plnuLCSRFF; if ( baryontype == EvtSpinType::DIRAC ) { calcamp = new EvtSLBaryonAmp; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong baryon spin type in EvtLb2plnuLCSR.cc " << "Expected spin type " << EvtSpinType::DIRAC << ", found spin type " << baryontype << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } diff --git a/src/EvtGenModels/EvtLb2plnuLQCD.cpp b/src/EvtGenModels/EvtLb2plnuLQCD.cpp index 869fb76..3c2e8cc 100644 --- a/src/EvtGenModels/EvtLb2plnuLQCD.cpp +++ b/src/EvtGenModels/EvtLb2plnuLQCD.cpp @@ -1,175 +1,175 @@ /*********************************************************************** * 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/EvtLb2plnuLQCD.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtLb2plnuLQCDFF.hh" #include #include using namespace std; #ifdef D0 #undef D0 #endif -EvtLb2plnuLQCD::EvtLb2plnuLQCD() : ffmodel( 0 ), calcamp( 0 ) +EvtLb2plnuLQCD::EvtLb2plnuLQCD() : ffmodel( nullptr ), calcamp( nullptr ) { } EvtLb2plnuLQCD::~EvtLb2plnuLQCD() { delete ffmodel; - ffmodel = 0; + ffmodel = nullptr; delete calcamp; - calcamp = 0; + calcamp = nullptr; } std::string EvtLb2plnuLQCD::getName() { return "Lb2plnuLQCD"; } EvtDecayBase* EvtLb2plnuLQCD::clone() { return new EvtLb2plnuLQCD; } void EvtLb2plnuLQCD::decay( EvtParticle* p ) { //This is a kludge to avoid warnings because the K_2* mass becomes to large. static EvtIdSet regenerateMasses( "K_2*+", "K_2*-", "K_2*0", "anti-K_2*0", "K_1+", "K_1-", "K_10", "anti-K_10", "D'_1+", "D'_1-", "D'_10", "anti-D'_10" ); if ( regenerateMasses.contains( getDaug( 0 ) ) ) { p->resetFirstOrNot(); } p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtComplex r00( getArg( 0 ), 0.0 ); EvtComplex r01( getArg( 1 ), 0.0 ); EvtComplex r10( getArg( 2 ), 0.0 ); EvtComplex r11( getArg( 3 ), 0.0 ); calcamp->CalcAmp( p, _amp2, ffmodel, r00, r01, r10, r11 ); } void EvtLb2plnuLQCD::initProbMax() { static EvtId LAMB = EvtPDL::getId( "Lambda_b0" ); static EvtId LAMBB = EvtPDL::getId( "anti-Lambda_b0" ); static EvtId PRO = EvtPDL::getId( "p+" ); static EvtId PROB = EvtPDL::getId( "anti-p-" ); EvtId parnum, barnum; parnum = getParentId(); barnum = getDaug( 0 ); if ( ( parnum == LAMB && barnum == PRO ) || ( parnum == LAMBB && barnum == PROB ) ) { setProbMax( 22000.0 ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Decay does not have Lb->p setting ProbMax = 0 " << endl; setProbMax( 0.0 ); } } void EvtLb2plnuLQCD::init() { if ( getNArg() != 4 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLQCD generator expected " << " 4 arguments but found:" << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( getNDaug() != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong number of daughters in EvtLb2plnu.cc " << " 3 daughters expected but found: " << getNDaug() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } //We expect the parent to be a dirac particle //and the daughters to be X lepton neutrino EvtSpinType::spintype parenttype = EvtPDL::getSpinType( getParentId() ); EvtSpinType::spintype baryontype = EvtPDL::getSpinType( getDaug( 0 ) ); EvtSpinType::spintype leptontype = EvtPDL::getSpinType( getDaug( 1 ) ); EvtSpinType::spintype neutrinotype = EvtPDL::getSpinType( getDaug( 2 ) ); if ( parenttype != EvtSpinType::DIRAC ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLQCD generator expected " << " a DIRAC parent, found:" << EvtPDL::name( getParentId() ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( leptontype != EvtSpinType::DIRAC ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLQCD generator expected " << " a DIRAC 2nd daughter, found:" << EvtPDL::name( getDaug( 1 ) ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( neutrinotype != EvtSpinType::NEUTRINO ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtLb2plnuLQCD generator expected " << " a NEUTRINO 3rd daughter, found:" << EvtPDL::name( getDaug( 2 ) ) << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } //set ffmodel ffmodel = new EvtLb2plnuLQCDFF; if ( baryontype == EvtSpinType::DIRAC ) { calcamp = new EvtSLBaryonAmp; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong baryon spin type in EvtLb2plnuLQCD.cc " << "Expected spin type " << EvtSpinType::DIRAC << ", found spin type " << baryontype << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } } diff --git a/src/EvtGenModels/EvtMultibody.cpp b/src/EvtGenModels/EvtMultibody.cpp index 2defab6..35aad34 100644 --- a/src/EvtGenModels/EvtMultibody.cpp +++ b/src/EvtGenModels/EvtMultibody.cpp @@ -1,94 +1,94 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenModels/EvtMultibody.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtResonance.hh" #include "EvtGenBase/EvtResonance2.hh" #include "EvtGenBase/EvtdFunction.hh" EvtMultibody::~EvtMultibody() { - if ( _decayTree != NULL ) + if ( _decayTree != nullptr ) delete _decayTree; - _decayTree = NULL; - if ( _ilist != NULL ) + _decayTree = nullptr; + if ( _ilist != nullptr ) delete[] _ilist; - _ilist = NULL; + _ilist = nullptr; } std::string EvtMultibody::getName() { return "D_MULTIBODY"; } EvtDecayBase* EvtMultibody::clone() { return new EvtMultibody; } void EvtMultibody::init() { int N = getNArg(); _decayTree = new EvtMTree( getDaugs(), getNDaug() ); _ilist = new int[getNDaug() + 1]; for ( int i = 0; i < N - 1; ++i ) { if ( getArgStr( i ) == "RESONANCE" ) { _decayTree->addtree( getArgStr( ++i ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Syntax error at " << getArgStr( i ) << std::endl; ::abort(); } } } void EvtMultibody::initProbMax() { setProbMax(1.0); } void EvtMultibody::decay( EvtParticle* p ) { // Initialize the phase space before doing anything else! p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtSpinAmp amp = _decayTree->amplitude( p ); vector index = amp.iterallowedinit(); vector spins = amp.dims(); do { for ( size_t i = 0; i < index.size(); ++i ) { _ilist[i] = index[i] + spins[i]; } vertex( _ilist, amp( index ) ); } while ( amp.iterateallowed( index ) ); } diff --git a/src/EvtGenModels/EvtPropSLPole.cpp b/src/EvtGenModels/EvtPropSLPole.cpp index 5ae069d..247ba50 100644 --- a/src/EvtGenModels/EvtPropSLPole.cpp +++ b/src/EvtGenModels/EvtPropSLPole.cpp @@ -1,559 +1,559 @@ /*********************************************************************** * 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/EvtPropSLPole.hh" #include "EvtGenBase/EvtAmpPdf.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtIntervalFlatPdf.hh" #include "EvtGenBase/EvtMassAmp.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPropBreitWignerRel.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtSemiLeptonicScalarAmp.hh" #include "EvtGenBase/EvtSemiLeptonicTensorAmp.hh" #include "EvtGenBase/EvtSemiLeptonicVectorAmp.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtTensorParticle.hh" #include "EvtGenBase/EvtTwoBodyVertex.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include "EvtGenModels/EvtSLPoleFF.hh" #include #include std::string EvtPropSLPole::getName() { return "PROPSLPOLE"; } EvtDecayBase* EvtPropSLPole::clone() { return new EvtPropSLPole; } void EvtPropSLPole::decay( EvtParticle* p ) { if ( !_isProbMaxSet ) { EvtId parnum, mesnum, lnum, nunum; parnum = getParentId(); mesnum = getDaug( 0 ); lnum = getDaug( 1 ); nunum = getDaug( 2 ); double mymaxprob = calcMaxProb( parnum, mesnum, lnum, nunum, SLPoleffmodel.get() ); setProbMax( mymaxprob ); _isProbMaxSet = true; } double minKstMass = EvtPDL::getMinMass( p->getDaug( 0 )->getId() ); double maxKstMass = EvtPDL::getMaxMass( p->getDaug( 0 )->getId() ); EvtIntervalFlatPdf flat( minKstMass, maxKstMass ); EvtPdfGen gen( flat ); EvtPoint1D point = gen(); double massKst = point.value(); p->getDaug( 0 )->setMass( massKst ); p->initializePhaseSpace( getNDaug(), getDaugs() ); // EvtVector4R p4meson = p->getDaug(0)->getP4(); calcamp->CalcAmp( p, _amp2, SLPoleffmodel.get() ); EvtParticle* mesonPart = p->getDaug( 0 ); double meson_BWAmp = calBreitWigner( mesonPart, point ); int list[2]; list[0] = 0; list[1] = 0; _amp2.vertex( 0, 0, _amp2.getAmp( list ) * meson_BWAmp ); list[0] = 0; list[1] = 1; _amp2.vertex( 0, 1, _amp2.getAmp( list ) * meson_BWAmp ); list[0] = 1; list[1] = 0; _amp2.vertex( 1, 0, _amp2.getAmp( list ) * meson_BWAmp ); list[0] = 1; list[1] = 1; _amp2.vertex( 1, 1, _amp2.getAmp( list ) * meson_BWAmp ); list[0] = 2; list[1] = 0; _amp2.vertex( 2, 0, _amp2.getAmp( list ) * meson_BWAmp ); list[0] = 2; list[1] = 1; _amp2.vertex( 2, 1, _amp2.getAmp( list ) * meson_BWAmp ); return; } void EvtPropSLPole::initProbMax() { _isProbMaxSet = false; return; } void EvtPropSLPole::init() { checkNDaug( 3 ); //We expect the parent to be a scalar //and the daughters to be X lepton neutrino checkSpinParent( EvtSpinType::SCALAR ); checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::NEUTRINO ); EvtSpinType::spintype mesontype = EvtPDL::getSpinType( getDaug( 0 ) ); SLPoleffmodel = std::make_unique( getNArg(), getArgs() ); switch ( mesontype ) { case EvtSpinType::SCALAR: calcamp = std::make_unique(); break; case EvtSpinType::VECTOR: calcamp = std::make_unique(); break; case EvtSpinType::TENSOR: calcamp = std::make_unique(); break; default:; } } double EvtPropSLPole::calBreitWignerBasic( double maxMass ) { if ( _width < 0.0001 ) return 1.0; //its not flat - but generated according to a BW double mMin = _massMin; double mMax = _massMax; if ( maxMass > -0.5 && maxMass < mMax ) mMax = maxMass; double massGood = EvtRandom::Flat( mMin, mMax ); double ampVal = sqrt( 1.0 / ( pow( massGood - _mass, 2.0 ) + pow( _width, 2.0 ) / 4.0 ) ); return ampVal; } double EvtPropSLPole::calBreitWigner( EvtParticle* pmeson, EvtPoint1D point ) { EvtId mesnum = pmeson->getId(); _mass = EvtPDL::getMeanMass( mesnum ); _width = EvtPDL::getWidth( mesnum ); _maxRange = EvtPDL::getMaxRange( mesnum ); EvtSpinType::spintype mesontype = EvtPDL::getSpinType( mesnum ); _includeDecayFact = true; _includeBirthFact = true; _spin = mesontype; _blatt = 3.0; double maxdelta = 15.0 * _width; if ( _maxRange > 0.00001 ) { _massMax = _mass + maxdelta; _massMin = _mass - _maxRange; } else { _massMax = _mass + maxdelta; _massMin = _mass - 15.0 * _width; } _massMax = _mass + maxdelta; if ( _massMin < 0. ) _massMin = 0.; EvtParticle* par = pmeson->getParent(); double maxMass = -1.; - if ( par != 0 ) { + if ( par != nullptr ) { if ( par->hasValidP4() ) maxMass = par->mass(); for ( size_t i = 0; i < par->getNDaug(); i++ ) { EvtParticle* tDaug = par->getDaug( i ); if ( pmeson != tDaug ) maxMass -= EvtPDL::getMinMass( tDaug->getId() ); } } - EvtId* dauId = 0; - double* dauMasses = 0; + EvtId* dauId = nullptr; + double* dauMasses = nullptr; size_t nDaug = pmeson->getNDaug(); if ( nDaug > 0 ) { dauId = new EvtId[nDaug]; dauMasses = new double[nDaug]; for ( size_t j = 0; j < nDaug; j++ ) { dauId[j] = pmeson->getDaug( j )->getId(); dauMasses[j] = pmeson->getDaug( j )->mass(); } } - EvtId* parId = 0; - EvtId* othDaugId = 0; + EvtId* parId = nullptr; + EvtId* othDaugId = nullptr; EvtParticle* tempPar = pmeson->getParent(); if ( tempPar ) { parId = new EvtId( tempPar->getId() ); if ( tempPar->getNDaug() == 2 ) { if ( tempPar->getDaug( 0 ) == pmeson ) othDaugId = new EvtId( tempPar->getDaug( 1 )->getId() ); else othDaugId = new EvtId( tempPar->getDaug( 0 )->getId() ); } } if ( nDaug != 2 ) return calBreitWignerBasic( maxMass ); if ( _width < 0.00001 ) return 1.0; //first figure out L - take the lowest allowed. EvtSpinType::spintype spinD1 = EvtPDL::getSpinType( dauId[0] ); EvtSpinType::spintype spinD2 = EvtPDL::getSpinType( dauId[1] ); int t1 = EvtSpinType::getSpin2( spinD1 ); int t2 = EvtSpinType::getSpin2( spinD2 ); int t3 = EvtSpinType::getSpin2( _spin ); int Lmin = -10; // allow for special cases. if ( Lmin < -1 ) { //There are some things I don't know how to deal with if ( t3 > 4 ) return calBreitWignerBasic( maxMass ); if ( t1 > 4 ) return calBreitWignerBasic( maxMass ); if ( t2 > 4 ) return calBreitWignerBasic( maxMass ); //figure the min and max allowwed "spins" for the daughters state Lmin = std::max( t3 - t2 - t1, std::max( t2 - t3 - t1, t1 - t3 - t2 ) ); if ( Lmin < 0 ) Lmin = 0; assert( Lmin == 0 || Lmin == 2 || Lmin == 4 ); } //double massD1=EvtPDL::getMeanMass(dauId[0]); //double massD2=EvtPDL::getMeanMass(dauId[1]); double massD1 = dauMasses[0]; double massD2 = dauMasses[1]; // I'm not sure how to define the vertex factor here - so retreat to nonRel code. if ( ( massD1 + massD2 ) > _mass ) return calBreitWignerBasic( maxMass ); //parent vertex factor not yet implemented double massOthD = -10.; double massParent = -10.; int birthl = -10; if ( othDaugId ) { EvtSpinType::spintype spinOth = EvtPDL::getSpinType( *othDaugId ); EvtSpinType::spintype spinPar = EvtPDL::getSpinType( *parId ); int tt1 = EvtSpinType::getSpin2( spinOth ); int tt2 = EvtSpinType::getSpin2( spinPar ); int tt3 = EvtSpinType::getSpin2( _spin ); //figure the min and max allowwed "spins" for the daughters state if ( ( tt1 <= 4 ) && ( tt2 <= 4 ) ) { birthl = std::max( tt3 - tt2 - tt1, std::max( tt2 - tt3 - tt1, tt1 - tt3 - tt2 ) ); if ( birthl < 0 ) birthl = 0; massOthD = EvtPDL::getMeanMass( *othDaugId ); massParent = EvtPDL::getMeanMass( *parId ); } } double massM = _massMax; if ( ( maxMass > -0.5 ) && ( maxMass < massM ) ) massM = maxMass; //special case... if the parent mass is _fixed_ we can do a little better //and only for a two body decay as that seems to be where we have problems // Define relativistic propagator amplitude EvtTwoBodyVertex vd( massD1, massD2, _mass, Lmin / 2 ); vd.set_f( _blatt ); EvtPropBreitWignerRel bw( _mass, _width ); EvtMassAmp amp( bw, vd ); // if ( _fixMassForMax) amp.fixUpMassForMax(); // else std::cout << "problem problem\n"; if ( _includeDecayFact ) { amp.addDeathFact(); amp.addDeathFactFF(); } if ( massParent > -1. ) { if ( _includeBirthFact ) { EvtTwoBodyVertex vb( _mass, massOthD, massParent, birthl / 2 ); amp.setBirthVtx( vb ); amp.addBirthFact(); amp.addBirthFactFF(); } } EvtAmpPdf pdf( amp ); double ampVal = sqrt( pdf.evaluate( point ) ); if ( parId ) delete parId; if ( othDaugId ) delete othDaugId; if ( dauId ) delete[] dauId; if ( dauMasses ) delete[] dauMasses; return ampVal; } double EvtPropSLPole::calcMaxProb( EvtId parent, EvtId meson, EvtId lepton, EvtId nudaug, EvtSemiLeptonicFF* FormFactors ) { //This routine takes the arguements parent, meson, and lepton //number, and a form factor model, and returns a maximum //probability for this semileptonic form factor model. A //brute force method is used. The 2D cos theta lepton and //q2 phase space is probed. //Start by declaring a particle at rest. //It only makes sense to have a scalar parent. For now. //This should be generalized later. EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; //cludge to avoid generating random numbers! scalar_part->noLifeTime(); EvtVector4R p_init; p_init.set( EvtPDL::getMass( parent ), 0.0, 0.0, 0.0 ); scalar_part->init( parent, p_init ); root_part = (EvtParticle*)scalar_part; // root_part->set_type(EvtSpinType::SCALAR); root_part->setDiagonalSpinDensity(); EvtParticle *daughter, *lep, *trino; EvtAmp amp; EvtId listdaug[3]; listdaug[0] = meson; listdaug[1] = lepton; listdaug[2] = nudaug; amp.init( parent, 3, listdaug ); root_part->makeDaughters( 3, listdaug ); daughter = root_part->getDaug( 0 ); lep = root_part->getDaug( 1 ); trino = root_part->getDaug( 2 ); EvtDecayBase* decayer; decayer = EvtDecayTable::getInstance()->getDecayFunc( daughter ); if ( decayer ) { daughter->makeDaughters( decayer->nRealDaughters(), decayer->getDaugs() ); for ( int ii = 0; ii < decayer->nRealDaughters(); ii++ ) { daughter->getDaug( ii )->setMass( EvtPDL::getMeanMass( daughter->getDaug( ii )->getId() ) ); } } //cludge to avoid generating random numbers! daughter->noLifeTime(); lep->noLifeTime(); trino->noLifeTime(); //Initial particle is unpolarized, well it is a scalar so it is //trivial EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); double mass[3]; double m = root_part->mass(); EvtVector4R p4meson, p4lepton, p4nu, p4w; double q2max; double q2, elepton, plepton; int i, j; double erho, prho, costl; double maxfoundprob = 0.0; double prob = -10.0; int massiter; for ( massiter = 0; massiter < 3; massiter++ ) { mass[0] = EvtPDL::getMeanMass( meson ); mass[1] = EvtPDL::getMeanMass( lepton ); mass[2] = EvtPDL::getMeanMass( nudaug ); if ( massiter == 1 ) { mass[0] = EvtPDL::getMinMass( meson ); } if ( massiter == 2 ) { mass[0] = EvtPDL::getMaxMass( meson ); if ( ( mass[0] + mass[1] + mass[2] ) > m ) mass[0] = m - mass[1] - mass[2] - 0.00001; } q2max = ( m - mass[0] ) * ( m - mass[0] ); //loop over q2 for ( i = 0; i < 25; i++ ) { q2 = ( ( i + 0.5 ) * q2max ) / 25.0; erho = ( m * m + mass[0] * mass[0] - q2 ) / ( 2.0 * m ); prho = sqrt( erho * erho - mass[0] * mass[0] ); p4meson.set( erho, 0.0, 0.0, -1.0 * prho ); p4w.set( m - erho, 0.0, 0.0, prho ); //This is in the W rest frame elepton = ( q2 + mass[1] * mass[1] ) / ( 2.0 * sqrt( q2 ) ); plepton = sqrt( elepton * elepton - mass[1] * mass[1] ); double probctl[3]; for ( j = 0; j < 3; j++ ) { costl = 0.99 * ( j - 1.0 ); //These are in the W rest frame. Need to boost out into //the B frame. p4lepton.set( elepton, 0.0, plepton * sqrt( 1.0 - costl * costl ), plepton * costl ); p4nu.set( plepton, 0.0, -1.0 * plepton * sqrt( 1.0 - costl * costl ), -1.0 * plepton * costl ); EvtVector4R boost( ( m - erho ), 0.0, 0.0, 1.0 * prho ); p4lepton = boostTo( p4lepton, boost ); p4nu = boostTo( p4nu, boost ); //Now initialize the daughters... daughter->init( meson, p4meson ); lep->init( lepton, p4lepton ); trino->init( nudaug, p4nu ); calcamp->CalcAmp( root_part, amp, FormFactors ); EvtPoint1D* point = new EvtPoint1D( mass[0] ); double meson_BWAmp = calBreitWigner( daughter, *point ); int list[2]; list[0] = 0; list[1] = 0; amp.vertex( 0, 0, amp.getAmp( list ) * meson_BWAmp ); list[0] = 0; list[1] = 1; amp.vertex( 0, 1, amp.getAmp( list ) * meson_BWAmp ); list[0] = 1; list[1] = 0; amp.vertex( 1, 0, amp.getAmp( list ) * meson_BWAmp ); list[0] = 1; list[1] = 1; amp.vertex( 1, 1, amp.getAmp( list ) * meson_BWAmp ); list[0] = 2; list[1] = 0; amp.vertex( 2, 0, amp.getAmp( list ) * meson_BWAmp ); list[0] = 2; list[1] = 1; amp.vertex( 2, 1, amp.getAmp( list ) * meson_BWAmp ); //Now find the probability at this q2 and cos theta lepton point //and compare to maxfoundprob. //Do a little magic to get the probability!! prob = rho.normalizedProb( amp.getSpinDensity() ); probctl[j] = prob; } //probclt contains prob at ctl=-1,0,1. //prob=a+b*ctl+c*ctl^2 double a = probctl[1]; double b = 0.5 * ( probctl[2] - probctl[0] ); double c = 0.5 * ( probctl[2] + probctl[0] ) - probctl[1]; prob = probctl[0]; if ( probctl[1] > prob ) prob = probctl[1]; if ( probctl[2] > prob ) prob = probctl[2]; if ( fabs( c ) > 1e-20 ) { double ctlx = -0.5 * b / c; if ( fabs( ctlx ) < 1.0 ) { double probtmp = a + b * ctlx + c * ctlx * ctlx; if ( probtmp > prob ) prob = probtmp; } } //EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "prob,probctl:"< maxfoundprob ) { maxfoundprob = prob; } } if ( EvtPDL::getWidth( meson ) <= 0.0 ) { //if the particle is narrow dont bother with changing the mass. massiter = 4; } } root_part->deleteTree(); maxfoundprob *= 1.1; return maxfoundprob; } diff --git a/src/EvtGenModels/EvtRareLbToLll.cpp b/src/EvtGenModels/EvtRareLbToLll.cpp index 121a02e..f1e7600 100644 --- a/src/EvtGenModels/EvtRareLbToLll.cpp +++ b/src/EvtGenModels/EvtRareLbToLll.cpp @@ -1,506 +1,506 @@ /*********************************************************************** * 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( 0, 1 ); // check that there are 3 daughters checkNDaug( 3 ); // Parent should be spin 1/2 Lambda_b0 const EvtSpinType::spintype spin = EvtPDL::getSpinType( getDaug( 0 ) ); if ( !( spin == EvtSpinType::DIRAC || spin == EvtSpinType::RARITASCHWINGER ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll expects DIRAC or RARITASWINGER daughter " << std::endl; } // We expect that the second and third daughters // are the ell+ and ell- checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::DIRAC ); // Work out whether we have electron mode const EvtIdSet leptons{ "e-", "e+" }; if ( leptons.contains( getDaug( 1 ) ) ) { m_electronMode = true; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll has dielectron final state" << std::endl; } std::string model{ "LQCD" }; if ( getNArg() == 1) { model = getArgStr( 0 ); } if ( model == "Gutsche" ) { ffmodel_ = std::make_unique(); } else if ( model == "LQCD" ) { ffmodel_ = std::make_unique(); } else if ( model == "MR" ) { ffmodel_ = std::make_unique(); } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " Unknown form-factor model, valid options are MR, LQCD, Gutsche." << " Assuming LQCD form-factors... " << std::endl; ffmodel_ = std::make_unique(); } wcmodel_ = std::make_unique(); ffmodel_->init(); return; } void EvtRareLbToLll::initProbMax() { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is finding maximum probability ... " << std::endl; m_maxProbability = 0; if ( m_maxProbability == 0 ) { EvtDiracParticle parent{}; parent.noLifeTime(); parent.init( getParentId(), EvtVector4R( EvtPDL::getMass( getParentId() ), 0, 0, 0 ) ); parent.setDiagonalSpinDensity(); EvtAmp amp; EvtId daughters[3] = {getDaug( 0 ), getDaug( 1 ), getDaug( 2 )}; amp.init( getParentId(), 3, daughters ); parent.makeDaughters( 3, daughters ); EvtParticle* lambda = parent.getDaug( 0 ); EvtParticle* lep1 = parent.getDaug( 1 ); EvtParticle* lep2 = parent.getDaug( 2 ); lambda->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); EvtSpinDensity rho; rho.setDiag( parent.getSpinStates() ); const double M0 = EvtPDL::getMass( getParentId() ); const double mL = EvtPDL::getMass( getDaug( 0 ) ); const double m1 = EvtPDL::getMass( getDaug( 1 ) ); const double m2 = EvtPDL::getMass( getDaug( 2 ) ); const double q2min = ( m1 + m2 ) * ( m1 + m2 ); const double q2max = ( M0 - mL ) * ( M0 - mL ); EvtVector4R p4lambda, p4lep1, p4lep2, boost; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is probing whole phase space ..." << std::endl; double prob = 0; const int nsteps = 5000; for ( int i = 0; i <= nsteps; i++ ) { const double q2 = q2min + i * ( q2max - q2min ) / nsteps; const double elambda = ( M0 * M0 + mL * mL - q2 ) / 2 / M0; double pstar{0}; if ( i != 0 ) { pstar = sqrt( q2 - ( m1 + m2 ) * ( m1 + m2 ) ) * sqrt( q2 - ( m1 - m2 ) * ( m1 - m2 ) ) / 2 / sqrt( q2 ); } boost.set( M0 - elambda, 0, 0, +sqrt( elambda * elambda - mL * mL ) ); if ( i != nsteps ) { p4lambda.set( elambda, 0, 0, -sqrt( elambda * elambda - mL * mL ) ); } else { p4lambda.set( mL, 0, 0, 0 ); } for ( int j = 0; j <= 45; j++ ) { const double theta = j * EvtConst::pi / 45; p4lep1.set( sqrt( pstar * pstar + m1 * m1 ), 0, +pstar * sin( theta ), +pstar * cos( theta ) ); p4lep2.set( sqrt( pstar * pstar + m2 * m2 ), 0, -pstar * sin( theta ), -pstar * cos( theta ) ); if ( i != nsteps) // At maximal q2 we are already in correct frame as Lambda and W/Zvirtual are at rest { p4lep1 = boostTo( p4lep1, boost ); p4lep2 = boostTo( p4lep2, boost ); } lambda->init( getDaug( 0 ), p4lambda ); lep1->init( getDaug( 1 ), p4lep1 ); lep2->init( getDaug( 2 ), p4lep2 ); calcAmp( amp, parent ); prob = rho.normalizedProb( amp.getSpinDensity() ); // In case of electron mode add pole if ( m_electronMode ) { prob /= 1.0 + m_poleSize / ( q2*q2 ); } if ( prob > m_maxProbability ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " - probability " << prob << " found at q2 = " << q2 << " (" << nsteps * ( q2 - q2min ) / ( q2max - q2min ) << " %) and theta = " << theta * 180 / EvtConst::pi << std::endl; m_maxProbability = prob; } } } m_maxProbability *= 1.05; } setProbMax( m_maxProbability ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll set up maximum probability to " << m_maxProbability << std::endl; } void EvtRareLbToLll::decay( EvtParticle* parent ) { // Phase space initialization depends on what leptons are if ( m_electronMode ) { setWeight( parent->initializePhaseSpace( getNDaug(), getDaugs(), false, m_poleSize, 1, 2 ) ); } else { parent->initializePhaseSpace( getNDaug(), getDaugs() ); } calcAmp( _amp2, *parent ); } bool EvtRareLbToLll::isParticle( const EvtParticle& parent ) const { const EvtIdSet partlist{ "Lambda_b0" }; return partlist.contains( parent.getId() ); } void EvtRareLbToLll::calcAmp( EvtAmp& amp, const EvtParticle& parent ) { //parent->setDiagonalSpinDensity(); const EvtParticle* lambda = parent.getDaug( 0 ); const EvtIdSet leptons{ "e-", "mu-", "tau-" }; const bool isparticle = isParticle( parent ); - const EvtParticle* lp = 0; - const EvtParticle* lm = 0; + const EvtParticle* lp = nullptr; + const EvtParticle* lm = nullptr; if ( leptons.contains( parent.getDaug( 1 )->getId() ) ) { lp = parent.getDaug( 1 ); lm = parent.getDaug( 2 ); } else { lp = parent.getDaug( 2 ); lm = parent.getDaug( 1 ); } EvtVector4R P; P.set( parent.mass(), 0.0, 0.0, 0.0 ); EvtVector4R q = lp->getP4() + lm->getP4(); const double qsq = q.mass2(); // Leptonic currents EvtVector4C LV[2][2]; // \bar{\ell} \gamma^{\mu} \ell EvtVector4C LA[2][2]; // \bar{\ell} \gamma^{\mu} \gamma^{5} \ell for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { if ( isparticle ) { LV[i][j] = EvtLeptonVCurrent( lp->spParent( i ), lm->spParent( j ) ); LA[i][j] = EvtLeptonACurrent( lp->spParent( i ), lm->spParent( j ) ); } else { LV[i][j] = EvtLeptonVCurrent( lp->spParent( 1 - i ), lm->spParent( 1 - j ) ); LA[i][j] = EvtLeptonACurrent( lp->spParent( 1 - i ), lm->spParent( 1 - j ) ); } } } EvtRareLbToLllFF::FormFactors FF; //F, G, FT and GT ffmodel_->getFF( parent, *lambda, FF ); EvtComplex C7eff = wcmodel_->GetC7Eff( qsq ); EvtComplex C9eff = wcmodel_->GetC9Eff( qsq ); EvtComplex C10eff = wcmodel_->GetC10Eff( qsq ); EvtComplex AC[4]; EvtComplex BC[4]; EvtComplex DC[4]; EvtComplex EC[4]; // check to see if particle is same or opposite parity to Lb const int parity = ffmodel_->isNatural( *lambda ) ? 1 : -1; // Lambda spin type const EvtSpinType::spintype spin = EvtPDL::getSpinType( lambda->getId() ); const double mb = 5.209; // Eq. 48 + 49 for ( unsigned int i = 0; i < 4; ++i ) { if ( parity > 0 ) { AC[i] = -2. * mb * C7eff * FF.FT_[i] / qsq + C9eff * FF.F_[i]; BC[i] = -2. * mb * C7eff * FF.GT_[i] / qsq - C9eff * FF.G_[i]; DC[i] = C10eff * FF.F_[i]; EC[i] = -C10eff * FF.G_[i]; } else { AC[i] = -2. * mb * C7eff * FF.GT_[i] / qsq - C9eff * FF.G_[i]; BC[i] = -2. * mb * C7eff * FF.FT_[i] / qsq + C9eff * FF.F_[i]; DC[i] = -C10eff * FF.G_[i]; EC[i] = C10eff * FF.F_[i]; } } // handle particle -> antiparticle in Hadronic currents const double cv = ( isparticle > 0 ) ? 1.0 : -1.0 * parity; const double ca = ( isparticle > 0 ) ? 1.0 : +1.0 * parity; const double cs = ( isparticle > 0 ) ? 1.0 : +1.0 * parity; const double cp = ( isparticle > 0 ) ? 1.0 : -1.0 * parity; if ( EvtSpinType::DIRAC == spin ) { EvtVector4C H1[2][2]; // vector current EvtVector4C H2[2][2]; // axial-vector EvtVector4C T[6]; // Hadronic currents for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { HadronicAmp( parent, *lambda, T, i, j ); H1[i][j] = ( cv * AC[0] * T[0] + ca * BC[0] * T[1] + cs * AC[1] * T[2] + cp * BC[1] * T[3] + cs * AC[2] * T[4] + cp * BC[2] * T[5] ); H2[i][j] = ( cv * DC[0] * T[0] + ca * EC[0] * T[1] + cs * DC[1] * T[2] + cp * EC[1] * T[3] + cs * DC[2] * T[4] + cp * EC[2] * T[5] ); } } // Spin sums int spins[4]; for ( int i = 0; i < 2; ++i ) { for ( int ip = 0; ip < 2; ++ip ) { for ( int j = 0; j < 2; ++j ) { for ( int jp = 0; jp < 2; ++jp ) { spins[0] = i; spins[1] = ip; spins[2] = j; spins[3] = jp; EvtComplex M = H1[i][ip] * LV[j][jp] + H2[i][ip] * LA[j][jp]; amp.vertex( spins, M ); } } } } } else if ( EvtSpinType::RARITASCHWINGER == spin ) { EvtVector4C T[8]; EvtVector4C H1[2][4]; // vector current // swaped EvtVector4C H2[2][4]; // axial-vector // Build hadronic amplitude for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 4; ++j ) { HadronicAmpRS( parent, *lambda, T, i, j ); H1[i][j] = ( cv * AC[0] * T[0] + ca * BC[0] * T[1] + cs * AC[1] * T[2] + cp * BC[1] * T[3] + cs * AC[2] * T[4] + cp * BC[2] * T[5] + cs * AC[3] * T[6] + cp * BC[3] * T[7] ); H2[i][j] = ( cv * DC[0] * T[0] + ca * EC[0] * T[1] + cs * DC[1] * T[2] + cp * EC[1] * T[3] + cs * DC[2] * T[4] + cp * EC[2] * T[5] + cs * DC[3] * T[6] + cp * EC[3] * T[7] ); } } // Spin sums int spins[4]; for ( int i = 0; i < 2; ++i ) { for ( int ip = 0; ip < 4; ++ip ) { for ( int j = 0; j < 2; ++j ) { for ( int jp = 0; jp < 2; ++jp ) { spins[0] = i; spins[1] = ip; spins[2] = j; spins[3] = jp; EvtComplex M = H1[i][ip] * LV[j][jp] + H2[i][ip] * LA[j][jp]; amp.vertex( spins, M ); } } } } } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll expects DIRAC or RARITASWINGER daughter " << std::endl; } return; } // spin 1/2 daughters void EvtRareLbToLll::HadronicAmp( const EvtParticle& parent, const EvtParticle& lambda, EvtVector4C* T, const int i, const int j ) { const EvtDiracSpinor Sfinal = lambda.spParent( j ); const EvtDiracSpinor Sinit = parent.sp( i ); const EvtVector4R L = lambda.getP4(); EvtVector4R P; P.set( parent.mass(), 0.0, 0.0, 0.0 ); const double Pm = parent.mass(); const double Lm = lambda.mass(); // \bar{u} \gamma^{\mu} u T[0] = EvtLeptonVCurrent( Sfinal, Sinit ); // \bar{u} \gamma^{\mu}\gamma^{5} u T[1] = EvtLeptonACurrent( Sfinal, Sinit ); // \bar{u} v^{\mu} u T[2] = EvtLeptonSCurrent( Sfinal, Sinit ) * ( P / Pm ); // \bar{u} v^{\mu} \gamma^{5} u T[3] = EvtLeptonPCurrent( Sfinal, Sinit ) * ( P / Pm ); // \bar{u} v^{\prime\mu} u T[4] = EvtLeptonSCurrent( Sfinal, Sinit ) * ( L / Lm ); // \bar{u} v^{\prime\mu} \gamma^{5} T[5] = EvtLeptonPCurrent( Sfinal, Sinit ) * ( L / Lm ); // Where: // v = p_{\Lambda_b}/m_{\Lambda_b} // v^{\prime} = p_{\Lambda}/m_{\Lambda} return; } // spin 3/2 daughters void EvtRareLbToLll::HadronicAmpRS( const EvtParticle& parent, const EvtParticle& lambda, EvtVector4C* T, const int i, const int j ) { const EvtRaritaSchwinger Sfinal = lambda.spRSParent( j ); const EvtDiracSpinor Sinit = parent.sp( i ); EvtVector4R P; P.set( parent.mass(), 0.0, 0.0, 0.0 ); const EvtVector4R L = lambda.getP4(); EvtTensor4C ID; ID.setdiag( 1.0, 1.0, 1.0, 1.0 ); EvtDiracSpinor Sprime; for ( int i = 0; i < 4; i++ ) { Sprime.set_spinor( i, Sfinal.getVector( i ) * P ); } const double Pmsq = P.mass2(); const double Pm = parent.mass(); const double PmLm = Pm * lambda.mass(); EvtVector4C V1, V2; for ( int i = 0; i < 4; i++ ) { V1.set( i, EvtLeptonSCurrent( Sfinal.getSpinor( i ), Sinit ) ); V2.set( i, EvtLeptonPCurrent( Sfinal.getSpinor( i ), Sinit ) ); } // \bar{u}_{alpha} v^{\alpha} \gamma^{\mu} u T[0] = EvtLeptonVCurrent( Sprime, Sinit ) * ( 1 / Pm ); // \bar{u}_{alpha} v^{\alpha} \gamma^{\mu} \gamma^{5} u T[1] = EvtLeptonACurrent( Sprime, Sinit ) * ( 1 / Pm ); // \bar{u}_{\alpha} v^{\alpha} v^{\mu} u T[2] = EvtLeptonSCurrent( Sprime, Sinit ) * ( P / Pmsq ); // \bar{u}_{\alpha} v^{\alpha} v^{\mu} \gamma^{5} u T[3] = EvtLeptonPCurrent( Sprime, Sinit ) * ( P / Pmsq ); // \bar{u}_{\alpha} v^{\alpha} v^{\prime \mu} u T[4] = EvtLeptonSCurrent( Sprime, Sinit ) * ( L / PmLm ); // \bar{u}_{\alpha} v^{\alpha} v^{\prime \mu} \gamma^{5} u T[5] = EvtLeptonPCurrent( Sprime, Sinit ) * ( L / PmLm ); // \bar{u}_{\alpha} g^{\alpha\mu} u T[6] = ID.cont2( V1 ); // \bar{u}_{\alpha} g^{\alpha\mu} \gamma^{5} u T[7] = ID.cont2( V2 ); // Where: // v = p_{\Lambda_b}/m_{\Lambda_b} // v^{\prime} = p_{\Lambda}/m_{\Lambda} return; } diff --git a/src/EvtGenModels/EvtVub.cpp b/src/EvtGenModels/EvtVub.cpp index e58184e..026a282 100644 --- a/src/EvtGenModels/EvtVub.cpp +++ b/src/EvtGenModels/EvtVub.cpp @@ -1,406 +1,406 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenModels/EvtVub.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtPFermi.hh" #include #include using std::endl; std::string EvtVub::getName() { return "VUB"; } EvtDecayBase* EvtVub::clone() { return new EvtVub; } void EvtVub::init() { // check that there are at least 6 arguments if ( getNArg() < 6 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << " at least 6 arguments (mb,a,alpha_s,Nbins,m1,w1,...) but found: " << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } _mb = getArg( 0 ); _a = getArg( 1 ); _alphas = getArg( 2 ); _nbins = abs( (int)getArg( 3 ) ); _storeQplus = ( getArg( 3 ) < 0 ? 1 : 0 ); _masses = std::vector( _nbins ); _weights = std::vector( _nbins ); if ( getNArg() - 4 != 2 * _nbins ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << _nbins << " masses and weights but found: " << ( getNArg() - 4 ) / 2 << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } int i, j = 4; double maxw = 0.; for ( i = 0; i < _nbins; i++ ) { _masses[i] = getArg( j++ ); if ( i > 0 && _masses[i] <= _masses[i - 1] ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << " mass bins in ascending order!" << "Will terminate execution!" << endl; ::abort(); } _weights[i] = getArg( j++ ); if ( _weights[i] < 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << " weights >= 0, but found: " << _weights[i] << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _weights[i] > maxw ) maxw = _weights[i]; } if ( maxw == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected at least one " << " weight > 0, but found none! " << "Will terminate execution!" << endl; ::abort(); } for ( i = 0; i < _nbins; i++ ) _weights[i] /= maxw; // the maximum dGamma*p2 value depends on alpha_s only: const double dGMax0 = 3.; _dGMax = 0.21344 + 8.905 * _alphas; if ( _dGMax < dGMax0 ) _dGMax = dGMax0; // for the Fermi Motion we need a B-Meson mass - but it's not critical // to get an exact value; in order to stay in the phase space for // B+- and B0 use the smaller mass EvtId BP = EvtPDL::getId( "B+" ); EvtId B0 = EvtPDL::getId( "B0" ); double mB0 = EvtPDL::getMaxMass( B0 ); double mBP = EvtPDL::getMaxMass( BP ); double mB = ( mB0 < mBP ? mB0 : mBP ); const double xlow = -_mb; const double xhigh = mB - _mb; const int aSize = 10000; EvtPFermi pFermi( _a, mB, _mb ); // pf is the cumulative distribution // normalized to 1. _pf.resize( aSize ); for ( i = 0; i < aSize; i++ ) { double kplus = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getFPFermi( kplus ); else _pf[i] = _pf[i - 1] + pFermi.getFPFermi( kplus ); } for ( size_t index = 0; index < _pf.size(); index++ ) { _pf[index] /= _pf[_pf.size() - 1]; } // static EvtHepRandomEngine myEngine; // _pFermi = new RandGeneral(myEngine,pf,aSize,0); _dGamma = std::make_unique( _alphas ); // check that there are 3 daughters checkNDaug( 3 ); } void EvtVub::initProbMax() { noProbMax(); } void EvtVub::decay( EvtParticle* p ) { int j; // B+ -> u-bar specflav l+ nu - EvtParticle *xuhad( 0 ), *lepton( 0 ), *neutrino( 0 ); + EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; // R. Faccini 21/02/03 // move the reweighting up , before also shooting the fermi distribution double x, z, p2; double sh = 0.0; double mB, ml, xlow, xhigh, qplus; double El = 0.0; double Eh = 0.0; double kplus; const double lp2epsilon = -10; bool rew( true ); while ( rew ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = p->getDaug( 0 ); lepton = p->getDaug( 1 ); neutrino = p->getDaug( 2 ); mB = p->mass(); ml = lepton->mass(); xlow = -_mb; xhigh = mB - _mb; // Fermi motion does not need to be computed inside the // tryit loop as m_b in Gamma0 does not need to be replaced by (m_b+kplus). // The difference however should be of the Order (lambda/m_b)^2 which is // beyond the considered orders in the paper anyway ... // for alpha_S = 0 and a mass cut on X_u not all values of kplus are // possible. The maximum value is mB/2-_mb + sqrt(mB^2/4-_masses[0]^2) kplus = 2 * xhigh; while ( kplus >= xhigh || kplus <= xlow || ( _alphas == 0 && kplus >= mB / 2 - _mb + sqrt( mB * mB / 4 - _masses[0] * _masses[0] ) ) ) { kplus = findPFermi(); //_pFermi->shoot(); kplus = xlow + kplus * ( xhigh - xlow ); } qplus = mB - _mb - kplus; if ( ( mB - qplus ) / 2. <= ml ) continue; int tryit = 1; while ( tryit ) { x = EvtRandom::Flat(); z = EvtRandom::Flat( 0, 2 ); p2 = EvtRandom::Flat(); p2 = pow( 10.0, lp2epsilon * p2 ); El = x * ( mB - qplus ) / 2; if ( El > ml && El < mB / 2 ) { Eh = z * ( mB - qplus ) / 2 + qplus; if ( Eh > 0 && Eh < mB ) { sh = p2 * pow( mB - qplus, 2 ) + 2 * qplus * ( Eh - qplus ) + qplus * qplus; if ( sh > _masses[0] * _masses[0] && mB * mB + sh - 2 * mB * Eh > ml * ml ) { double xran = EvtRandom::Flat(); double y = _dGamma->getdGdxdzdp( x, z, p2 ) / _dGMax * p2; if ( y > 1 ) EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtVub decay probability > 1 found: " << y << endl; if ( y >= xran ) tryit = 0; } } } } // reweight the Mx distribution if ( _nbins > 0 ) { double xran1 = EvtRandom::Flat(); double m = sqrt( sh ); j = 0; while ( j < _nbins && m > _masses[j] ) j++; double w = _weights[j - 1]; if ( w >= xran1 ) rew = false; } else { rew = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * EvtConst::pi ); double phL = EvtRandom::Flat( 0, 2 * EvtConst::pi ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( Eh * Eh - sh ); double pHB[4] = {Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), ptmp * ctH}; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); if ( _storeQplus ) { // cludge to store the hidden parameter q+ with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take q+/(10000 GeV) which // goes up to 0.0005 in the most extreme cases as ctau in mm. // To extract q+ back from the StdHepTrk its necessary to get // delta_ctau = Xu->anyDaughter->getVertexTime()-Xu->getVertexTime() // where these pseudo calls refere to the StdHep time stored at // the production vertex in the lab for each particle. The boost // has to be reversed and the result is: // // q+ = delta_ctau * 10000 GeV/mm * Mass_Xu/Energy_Xu // xuhad->setLifetime( qplus / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; double pWB[4] = {mB - Eh, -pHB[1], -pHB[2], -pHB[3]}; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mB * mB + sh - 2 * mB * Eh; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW double xW[3] = {-pWB[2], pWB[1], 0}; // eZ' = eW double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], pWB[1] * pWB[1] + pWB[2] * pWB[2]}; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; double pLB[4] = {El, 0, 0, 0}; double pNB[4] = {pWB[0] - El, 0, 0, 0}; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVub::findPFermi() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } diff --git a/src/EvtGenModels/EvtVubBLNP.cpp b/src/EvtGenModels/EvtVubBLNP.cpp index 9bbd16b..e819bdf 100644 --- a/src/EvtGenModels/EvtVubBLNP.cpp +++ b/src/EvtGenModels/EvtVubBLNP.cpp @@ -1,1051 +1,1051 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenModels/EvtVubBLNP.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtItgPtrFunction.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenModels/EvtPFermi.hh" #include #include // For incomplete gamma function #include "math.h" #include "signal.h" #define ITMAX 100 #define EPS 3.0e-7 #define FPMIN 1.0e-30 using std::cout; using std::endl; std::string EvtVubBLNP::getName() { return "VUB_BLNP"; } EvtDecayBase* EvtVubBLNP::clone() { return new EvtVubBLNP; } void EvtVubBLNP::init() { // get parameters (declared in the header file) // Input parameters mBB = 5.2792; lambda2 = 0.12; // Shape function parameters b = getArg( 0 ); Lambda = getArg( 1 ); Ecut = 1.8; wzero = mBB - 2 * Ecut; // SF and SSF modes itype = (int)getArg( 5 ); dtype = getArg( 5 ); isubl = (int)getArg( 6 ); // flags flag1 = (int)getArg( 7 ); flag2 = (int)getArg( 8 ); flag3 = (int)getArg( 9 ); // Quark mass mb = 4.61; // hidden parameter what and SF stuff const double xlow = 0; const double xhigh = mBB; const int aSize = 10000; EvtPFermi pFermi( Lambda, b ); // pf is the cumulative distribution normalized to 1. _pf.resize( aSize ); for ( int i = 0; i < aSize; i++ ) { double what = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getSFBLNP( what ); else _pf[i] = _pf[i - 1] + pFermi.getSFBLNP( what ); } for ( size_t i = 0; i < _pf.size(); i++ ) { _pf[i] /= _pf[_pf.size() - 1]; } // Matching scales muh = mBB * getArg( 2 ); // 0.5 mui = getArg( 3 ); // 1.5 mubar = getArg( 4 ); // 1.5 // Perturbative quantities CF = 4.0 / 3.0; CA = 3.0; double nf = 4.0; beta0 = 11.0 / 3.0 * CA - 2.0 / 3.0 * nf; beta1 = 34.0 / 3.0 * CA * CA - 10.0 / 3.0 * CA * nf - 2.0 * CF * nf; beta2 = 2857.0 / 54.0 * CA * CA * CA + ( CF * CF - 205.0 / 18.0 * CF * CA - 1415.0 / 54.0 * CA * CA ) * nf + ( 11.0 / 9.0 * CF + 79.0 / 54.0 * CA ) * nf * nf; zeta3 = 1.0 + 1 / 8.0 + 1 / 27.0 + 1 / 64.0; Gamma0 = 4 * CF; Gamma1 = CF * ( ( 268.0 / 9.0 - 4.0 * M_PI * M_PI / 3.0 ) * CA - 40.0 / 9.0 * nf ); Gamma2 = 16 * CF * ( ( 245.0 / 24.0 - 67.0 / 54.0 * M_PI * M_PI + +11.0 / 180.0 * pow( M_PI, 4 ) + 11.0 / 6.0 * zeta3 ) * CA * CA * +( -209.0 / 108.0 + 5.0 / 27.0 * M_PI * M_PI - 7.0 / 3.0 * zeta3 ) * CA * nf + ( -55.0 / 24.0 + 2 * zeta3 ) * CF * nf - nf * nf / 27.0 ); gp0 = -5.0 * CF; gp1 = -8.0 * CF * ( ( 3.0 / 16.0 - M_PI * M_PI / 4.0 + 3 * zeta3 ) * CF + ( 1549.0 / 432.0 + 7.0 / 48.0 * M_PI * M_PI - 11.0 / 4.0 * zeta3 ) * CA - ( 125.0 / 216.0 + M_PI * M_PI / 24.0 ) * nf ); // Lbar and mupisq Lbar = Lambda; // all models mupisq = 3 * Lambda * Lambda / b; if ( itype == 1 ) mupisq = 3 * Lambda * Lambda / b; if ( itype == 2 ) mupisq = 3 * Lambda * Lambda * ( Gamma( 1 + 0.5 * b ) * Gamma( 0.5 * b ) / pow( Gamma( 0.5 + 0.5 * b ), 2 ) - 1 ); // moment2 for SSFs moment2 = pow( 0.3, 3 ); // inputs for total rate (T for Total); use BLNP notebook defaults flagpower = 1; flag2loop = 1; // stuff for the integrator maxLoop = 20; //precision = 1.0e-3; precision = 2.0e-2; // vector of global variables, to pass to static functions (which can't access globals); gvars.push_back( 0.0 ); // 0 gvars.push_back( 0.0 ); // 1 gvars.push_back( mui ); // 2 gvars.push_back( b ); // 3 gvars.push_back( Lambda ); // 4 gvars.push_back( mBB ); // 5 gvars.push_back( mb ); // 6 gvars.push_back( wzero ); // 7 gvars.push_back( beta0 ); // 8 gvars.push_back( beta1 ); // 9 gvars.push_back( beta2 ); // 10 gvars.push_back( dtype ); // 11 // check that there are 3 daughters and 10 arguments checkNDaug( 3 ); checkNArg( 10 ); } void EvtVubBLNP::initProbMax() { noProbMax(); } void EvtVubBLNP::decay( EvtParticle* Bmeson ) { int j; - EvtParticle *xuhad( 0 ), *lepton( 0 ), *neutrino( 0 ); + EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; double Pp, Pm, Pl, pdf, EX, sh, ml, mpi, ratemax; double El( 0. ); double xhigh, xlow, what; Bmeson->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = Bmeson->getDaug( 0 ); lepton = Bmeson->getDaug( 1 ); neutrino = Bmeson->getDaug( 2 ); mBB = Bmeson->mass(); ml = lepton->mass(); // get SF value xlow = 0; xhigh = mBB; // the case for alphas = 0 is not considered what = 2 * xhigh; while ( what > xhigh || what < xlow ) { what = findBLNPWhat(); what = xlow + what * ( xhigh - xlow ); } bool tryit = true; while ( tryit ) { // generate pp between 0 and // Flat(min, max) gives R(max - min) + min, where R = random btwn 0 and 1 Pp = EvtRandom::Flat( 0, mBB ); // P+ = EX - |PX| Pl = EvtRandom::Flat( 0, mBB ); // mBB - 2El Pm = EvtRandom::Flat( 0, mBB ); // P- = EX + |PX| sh = Pm * Pp; EX = 0.5 * ( Pm + Pp ); El = 0.5 * ( mBB - Pl ); // Need maximum rate. Waiting for Mr. Paz to give it to me. // Meanwhile, use this. ratemax = 3.0; // From trial and error - most events below 3.0 // kinematic bounds (Eq. 2) mpi = 0.14; if ( ( Pp > 0 ) && ( Pp <= Pl ) && ( Pl <= Pm ) && ( Pm < mBB ) && ( El > ml ) && ( sh > 4 * mpi * mpi ) ) { // Probability of pass proportional to PDF pdf = rate3( Pp, Pl, Pm ); double testRan = EvtRandom::Flat( 0., ratemax ); if ( pdf >= testRan ) tryit = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * M_PI ); double phL = EvtRandom::Flat( 0, 2 * M_PI ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( EX * EX - sh ); double pHB[4] = {EX, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), ptmp * ctH}; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); bool _storeWhat( true ); if ( _storeWhat ) { // cludge to store the hidden parameter what with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take what/(10000 GeV). // To extract what back from the StdHepTrk its necessary to get // delta_ctau = Xu->decayVtx()->point().distanceTo(XuDaughter->decayVtx()->point()); // // what = delta_ctau * 100000 * Mass_Xu/Momentum_Xu // xuhad->setLifetime( what / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; double pWB[4] = {mBB - EX, -pHB[1], -pHB[2], -pHB[3]}; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mBB * mBB + sh - 2 * mBB * EX; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW double xW[3] = {-pWB[2], pWB[1], 0}; // eZ' = eW double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], pWB[1] * pWB[1] + pWB[2] * pWB[2]}; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; double pLB[4] = {El, 0, 0, 0}; double pNB[4] = {pWB[0] - El, 0, 0, 0}; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVubBLNP::rate3( double Pp, double Pl, double Pm ) { // rate3 in units of GF^2*Vub^2/pi^3 double factor = 1.0 / 16 * ( mBB - Pp ) * U1lo( muh, mui ) * pow( ( Pm - Pp ) / ( mBB - Pp ), alo( muh, mui ) ); double doneJS = DoneJS( Pp, Pm, mui ); double done1 = Done1( Pp, Pm, mui ); double done2 = Done2( Pp, Pm, mui ); double done3 = Done3( Pp, Pm, mui ); // The EvtSimpsonIntegrator returns zero for bad integrals. // So if any of the integrals are zero (ie bad), return zero. // This will cause pdf = 0, so the event will not pass. // I hope this will not introduce a bias. if ( doneJS * done1 * done2 * done3 == 0.0 ) { //cout << "Integral failed: (Pp, Pm, Pl) = (" << Pp << ", " << Pm << ", " << Pl << ")" << endl; return 0.0; } // if (doneJS*done1*done2*done3 != 0.0) { // cout << "Integral OK: (Pp, Pm, Pl) = (" << Pp << ", " << Pm << ", " << Pl << ")" << endl; //} double f1 = F1( Pp, Pm, muh, mui, mubar, doneJS, done1 ); double f2 = F2( Pp, Pm, muh, mui, mubar, done3 ); double f3 = F3( Pp, Pm, muh, mui, mubar, done2 ); double answer = factor * ( ( mBB + Pl - Pp - Pm ) * ( Pm - Pl ) * f1 + 2 * ( Pl - Pp ) * ( Pm - Pl ) * f2 + ( mBB - Pm ) * ( Pm - Pp ) * f3 ); return answer; } double EvtVubBLNP::F1( double Pp, double Pm, double muh, double mui, double mubar, double doneJS, double done1 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double ah = CF * alphas( muh, vars ) / 4 / M_PI; double ai = CF * alphas( mui, vars ) / 4 / M_PI; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double lambda1 = -mupisq; double t1 = -4 * ai / ( Pp - Lbar ) * ( 2 * log( ( Pp - Lbar ) / mui ) + 1 ); double t2 = 1 + dU1nlo( muh, mui ) + anlo( muh, mui ) * log( y ); double t3 = -4.0 * pow( log( y * mb / muh ), 2 ) + 10.0 * log( y * mb / muh ) - 4.0 * log( y ) - 2.0 * log( y ) / ( 1 - y ) - 4.0 * PolyLog( 2, 1 - y ) - M_PI * M_PI / 6.0 - 12.0; double t4 = 2 * pow( log( y * mb * Pp / ( mui * mui ) ), 2 ) - 3 * log( y * mb * Pp / ( mui * mui ) ) + 7 - M_PI * M_PI; double t5 = -wS( Pp ) + 2 * t( Pp ) + ( 1.0 / y - 1.0 ) * ( u( Pp ) - v( Pp ) ); double t6 = -( lambda1 + 3.0 * lambda2 ) / 3.0 + 1.0 / pow( y, 2 ) * ( 4.0 / 3.0 * lambda1 - 2.0 * lambda2 ); double shapePp = Shat( Pp, vars ); double answer = ( t2 + ah * t3 + ai * t4 ) * shapePp + ai * doneJS + 1 / ( mBB - Pp ) * ( flag2 * abar * done1 + flag1 * t5 ) + 1 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t6; if ( Pp > Lbar + mui / exp( 0.5 ) ) answer = answer + t1; return answer; } double EvtVubBLNP::F2( double Pp, double Pm, double muh, double /*mui*/, double mubar, double done3 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double lambda1 = -mupisq; double ah = CF * alphas( muh, vars ) / 4 / M_PI; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double t6 = -wS( Pp ) - 2 * t( Pp ) + 1.0 / y * ( t( Pp ) + v( Pp ) ); double t7 = 1 / pow( y, 2 ) * ( 2.0 / 3.0 * lambda1 + 4.0 * lambda2 ) - 1 / y * ( 2.0 / 3.0 * lambda1 + 3.0 / 2.0 * lambda2 ); double shapePp = Shat( Pp, vars ); double answer = ah * log( y ) / ( 1 - y ) * shapePp + 1 / ( mBB - Pp ) * ( flag2 * abar * 0.5 * done3 + flag1 / y * t6 ) + 1.0 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t7; return answer; } double EvtVubBLNP::F3( double Pp, double Pm, double /*muh*/, double /*mui*/, double mubar, double done2 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double lambda1 = -mupisq; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double t7 = 1.0 / pow( y, 2 ) * ( -2.0 / 3.0 * lambda1 + lambda2 ); double shapePp = Shat( Pp, vars ); double answer = 1.0 / ( Pm - Pp ) * flag2 * 0.5 * y * abar * done2 + 1.0 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t7; return answer; } double EvtVubBLNP::DoneJS( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; auto func = EvtItgPtrFunction{&IntJS, lowerlim, upperlim, vars}; auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Done1( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; auto func = EvtItgPtrFunction{&Int1, lowerlim, upperlim, vars}; auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Done2( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; auto func = EvtItgPtrFunction{&Int2, lowerlim, upperlim, vars}; auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Done3( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; auto func = EvtItgPtrFunction{&Int3, lowerlim, upperlim, vars}; auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Int1( double what, const std::vector& vars ) { return Shat( what, vars ) * g1( what, vars ); } double EvtVubBLNP::Int2( double what, const std::vector& vars ) { return Shat( what, vars ) * g2( what, vars ); } double EvtVubBLNP::Int3( double what, const std::vector& vars ) { return Shat( what, vars ) * g3( what, vars ); } double EvtVubBLNP::IntJS( double what, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mui = vars[2]; double mBB = vars[5]; double mb = vars[6]; double y = ( Pm - Pp ) / ( mBB - Pp ); return 1 / ( Pp - what ) * ( Shat( what, vars ) - Shat( Pp, vars ) ) * ( 4 * log( y * mb * ( Pp - what ) / ( mui * mui ) ) - 3 ); } double EvtVubBLNP::g1( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * y * ( x + y ); double q2 = y * ( -9 + 10 * y ) + x * x * ( -12.0 + 13.0 * y ) + 2 * x * ( -8.0 + 6 * y + 3 * y * y ); double q3 = 4 / x * log( y + y / x ); double q4 = 3.0 * pow( x, 4 ) * ( -2.0 + y ) - 2 * pow( y, 3 ) - 4 * pow( x, 3 ) * ( 2.0 + y ) - 2 * x * y * y * ( 4 + y ) - x * x * y * ( 12 + 4 * y + y * y ); double q5 = log( 1 + y / x ); double answer = q2 / q1 - q3 - 2 * q4 * q5 / ( q1 * y * x ); return answer; } double EvtVubBLNP::g2( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * pow( y, 3 ) * ( x + y ); double q2 = 10.0 * pow( x, 4 ) + y * y + 3.0 * pow( x, 2 ) * y * ( 10.0 + y ) + pow( x, 3 ) * ( 12.0 + 19.0 * y ) + x * y * ( 8.0 + 4.0 * y + y * y ); double q3 = 5 * pow( x, 4 ) + 2.0 * y * y + 6.0 * pow( x, 3 ) * ( 1.0 + 2.0 * y ) + 4.0 * x * y * ( 1 + 2.0 * y ) + x * x * y * ( 18.0 + 5.0 * y ); double q4 = log( 1 + y / x ); double answer = 2.0 / q1 * ( y * q2 - 2 * x * q3 * q4 ); return answer; } double EvtVubBLNP::g3( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * pow( y, 3 ) * ( x + y ); double q2 = 2.0 * pow( y, 3 ) * ( -11.0 + 2.0 * y ) - 10.0 * pow( x, 4 ) * ( 6 - 6 * y + y * y ) + x * y * y * ( -94.0 + 29.0 * y + 2.0 * y * y ) + 2.0 * x * x * y * ( -72.0 + 18.0 * y + 13.0 * y * y ) - x * x * x * ( 72.0 + 42.0 * y - 70.0 * y * y + 3.0 * y * y * y ); double q3 = -6.0 * x * ( -5.0 + y ) * pow( y, 3 ) + 4 * pow( y, 4 ) + 5 * pow( x, 5 ) * ( 6 - 6 * y + y * y ) - 4 * x * x * y * y * ( -20.0 + 6 * y + y * y ) + pow( x, 3 ) * y * ( 90.0 - 10.0 * y - 28.0 * y * y + y * y * y ) + pow( x, 4 ) * ( 36.0 + 36.0 * y - 50.0 * y * y + 4 * y * y * y ); double q4 = log( 1 + y / x ); double answer = q2 / q1 + 2 / q1 / y * q3 * q4; return answer; } double EvtVubBLNP::Shat( double w, const std::vector& vars ) { double mui = vars[2]; double b = vars[3]; double Lambda = vars[4]; double wzero = vars[7]; int itype = (int)vars[11]; double norm = 0.0; double shape = 0.0; if ( itype == 1 ) { double Lambar = ( Lambda / b ) * ( Gamma( 1 + b ) - Gamma( 1 + b, b * wzero / Lambda ) ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ); double muf = wzero - Lambar; double mupisq = 3 * pow( Lambda, 2 ) / pow( b, 2 ) * ( Gamma( 2 + b ) - Gamma( 2 + b, b * wzero / Lambda ) ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ) - 3 * Lambar * Lambar; norm = Mzero( muf, mui, mupisq, vars ) * Gamma( b ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ); shape = pow( b, b ) / Lambda / Gamma( b ) * pow( w / Lambda, b - 1 ) * exp( -b * w / Lambda ); } if ( itype == 2 ) { double dcoef = pow( Gamma( 0.5 * ( 1 + b ) ) / Gamma( 0.5 * b ), 2 ); double t1 = wzero * wzero * dcoef / ( Lambda * Lambda ); double Lambar = Lambda * ( Gamma( 0.5 * ( 1 + b ) ) - Gamma( 0.5 * ( 1 + b ), t1 ) ) / pow( dcoef, 0.5 ) / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, t1 ) ); double muf = wzero - Lambar; double mupisq = 3 * Lambda * Lambda * ( Gamma( 1 + 0.5 * b ) - Gamma( 1 + 0.5 * b, t1 ) ) / dcoef / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, t1 ) ) - 3 * Lambar * Lambar; norm = Mzero( muf, mui, mupisq, vars ) * Gamma( 0.5 * b ) / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, wzero * wzero * dcoef / ( Lambda * Lambda ) ) ); shape = 2 * pow( dcoef, 0.5 * b ) / Lambda / Gamma( 0.5 * b ) * pow( w / Lambda, b - 1 ) * exp( -dcoef * w * w / ( Lambda * Lambda ) ); } double answer = norm * shape; return answer; } double EvtVubBLNP::Mzero( double muf, double mu, double mupisq, const std::vector& vars ) { double CF = 4.0 / 3.0; double amu = CF * alphas( mu, vars ) / M_PI; double answer = 1 - amu * ( pow( log( muf / mu ), 2 ) + log( muf / mu ) + M_PI * M_PI / 24.0 ) + amu * ( log( muf / mu ) - 0.5 ) * mupisq / ( 3 * muf * muf ); return answer; } double EvtVubBLNP::wS( double w ) { double answer = ( Lbar - w ) * Shat( w, gvars ); return answer; } double EvtVubBLNP::t( double w ) { double t1 = -3 * lambda2 / mupisq * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = t1; if ( isubl == 1 ) answer = t1; if ( isubl == 3 ) answer = t1 - myf; if ( isubl == 4 ) answer = t1 + myf; if ( isubl == 5 ) answer = t1 - myBIK; if ( isubl == 6 ) answer = t1 + myBIK; return answer; } double EvtVubBLNP::u( double w ) { double u1 = -2 * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = u1; if ( isubl == 1 ) answer = u1; if ( isubl == 3 ) answer = u1 + myf; if ( isubl == 4 ) answer = u1 - myf; if ( isubl == 5 ) answer = u1 + myBIK; if ( isubl == 6 ) answer = u1 - myBIK; return answer; } double EvtVubBLNP::v( double w ) { double v1 = 3 * lambda2 / mupisq * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = v1; if ( isubl == 1 ) answer = v1; if ( isubl == 3 ) answer = v1 - myf; if ( isubl == 4 ) answer = v1 + myf; if ( isubl == 5 ) answer = v1 - myBIK; if ( isubl == 6 ) answer = v1 + myBIK; return answer; } double EvtVubBLNP::myfunction( double w, double Lbar, double mom2 ) { double bval = 5.0; double x = w / Lbar; double factor = 0.5 * mom2 * pow( bval / Lbar, 3 ); double answer = factor * exp( -bval * x ) * ( 1 - 2 * bval * x + 0.5 * bval * bval * x * x ); return answer; } double EvtVubBLNP::myfunctionBIK( double w, double Lbar, double /*mom2*/ ) { double aval = 10.0; double normBIK = ( 4 - M_PI ) * M_PI * M_PI / 8 / ( 2 - M_PI ) / aval + 1; double z = 3 * M_PI * w / 8 / Lbar; double q = M_PI * M_PI * 2 * pow( M_PI * aval, 0.5 ) * exp( -aval * z * z ) / ( 4 * M_PI - 8 ) * ( 1 - 2 * pow( aval / M_PI, 0.5 ) * z ) + 8 / pow( 1 + z * z, 4 ) * ( z * log( z ) + 0.5 * z * ( 1 + z * z ) - M_PI / 4 * ( 1 - z * z ) ); double answer = q / normBIK; return answer; } double EvtVubBLNP::dU1nlo( double muh, double mui ) { double ai = alphas( mui, gvars ); double ah = alphas( muh, gvars ); double q1 = ( ah - ai ) / ( 4 * M_PI * beta0 ); double q2 = log( mb / muh ) * Gamma1 + gp1; double q3 = 4 * beta1 * ( log( mb / muh ) * Gamma0 + gp0 ) + Gamma2 * ( 1 - ai / ah ); double q4 = beta1 * beta1 * Gamma0 * ( -1.0 + ai / ah ) / ( 4 * pow( beta0, 3 ) ); double q5 = -beta2 * Gamma0 * ( 1.0 + ai / ah ) + beta1 * Gamma1 * ( 3 - ai / ah ); double q6 = beta1 * beta1 * Gamma0 * ( ah - ai ) / beta0 - beta2 * Gamma0 * ah + beta1 * Gamma1 * ai; double answer = q1 * ( q2 - q3 / 4 / beta0 + q4 + q5 / ( 4 * beta0 * beta0 ) ) + 1 / ( 8 * M_PI * beta0 * beta0 * beta0 ) * log( ai / ah ) * q6; return answer; } double EvtVubBLNP::U1lo( double muh, double mui ) { double epsilon = 0.0; double answer = pow( mb / muh, -2 * aGamma( muh, mui, epsilon ) ) * exp( 2 * Sfun( muh, mui, epsilon ) - 2 * agp( muh, mui, epsilon ) ); return answer; } double EvtVubBLNP::Sfun( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ) / 4 / M_PI; double a2 = alphas( mu2, gvars ) / alphas( mu1, gvars ); double answer = S0( a1, a2 ) + S1( a1, a2 ) + epsilon * S2( a1, a2 ); return answer; } double EvtVubBLNP::S0( double a1, double r ) { double answer = -Gamma0 / ( 4.0 * beta0 * beta0 * a1 ) * ( -1.0 + 1.0 / r + log( r ) ); return answer; } double EvtVubBLNP::S1( double /*a1*/, double r ) { double answer = Gamma0 / ( 4 * beta0 * beta0 ) * ( 0.5 * log( r ) * log( r ) * beta1 / beta0 + ( Gamma1 / Gamma0 - beta1 / beta0 ) * ( 1 - r + log( r ) ) ); return answer; } double EvtVubBLNP::S2( double a1, double r ) { double w1 = pow( beta1, 2 ) / pow( beta0, 2 ) - beta2 / beta0 - beta1 * Gamma1 / ( beta0 * Gamma0 ) + Gamma2 / Gamma0; double w2 = pow( beta1, 2 ) / pow( beta0, 2 ) - beta2 / beta0; double w3 = beta1 * Gamma1 / ( beta0 * Gamma0 ) - beta2 / beta0; double w4 = a1 * Gamma0 / ( 4 * beta0 * beta0 ); double answer = w4 * ( -0.5 * pow( 1 - r, 2 ) * w1 + w2 * ( 1 - r ) * log( r ) + w3 * ( 1 - r + r * log( r ) ) ); return answer; } double EvtVubBLNP::aGamma( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ); double a2 = alphas( mu2, gvars ); double answer = Gamma0 / ( 2 * beta0 ) * log( a2 / a1 ) + epsilon * ( a2 - a1 ) / ( 8.0 * M_PI ) * ( Gamma1 / beta0 - beta1 * Gamma0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNP::agp( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ); double a2 = alphas( mu2, gvars ); double answer = gp0 / ( 2 * beta0 ) * log( a2 / a1 ) + epsilon * ( a2 - a1 ) / ( 8.0 * M_PI ) * ( gp1 / beta0 - beta1 * gp0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNP::alo( double muh, double mui ) { return -2.0 * aGamma( muh, mui, 0 ); } double EvtVubBLNP::anlo( double muh, double mui ) { // d/depsilon of aGamma double ah = alphas( muh, gvars ); double ai = alphas( mui, gvars ); double answer = ( ah - ai ) / ( 8.0 * M_PI ) * ( Gamma1 / beta0 - beta1 * Gamma0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNP::alphas( double mu, const std::vector& vars ) { // Note: Lambda4 and Lambda5 depend on mbMS = 4.25 // So if you change mbMS, then you will have to recalculate them. double beta0 = vars[8]; double beta1 = vars[9]; double beta2 = vars[10]; double Lambda4 = 0.298791; double lg = 2 * log( mu / Lambda4 ); double answer = 4 * M_PI / ( beta0 * lg ) * ( 1 - beta1 * log( lg ) / ( beta0 * beta0 * lg ) + beta1 * beta1 / ( beta0 * beta0 * beta0 * beta0 * lg * lg ) * ( ( log( lg ) - 0.5 ) * ( log( lg ) - 0.5 ) - 5.0 / 4.0 + beta2 * beta0 / ( beta1 * beta1 ) ) ); return answer; } double EvtVubBLNP::PolyLog( double v, double z ) { if ( z >= 1 ) cout << "Error in EvtVubBLNP: 2nd argument to PolyLog is >= 1." << endl; double sum = 0.0; for ( int k = 1; k < 101; k++ ) { sum = sum + pow( z, k ) / pow( k, v ); } return sum; } double EvtVubBLNP::Gamma( double z ) { if ( z <= 0 ) return 0; double v = lgamma( z ); return exp( v ); } double EvtVubBLNP::Gamma( double a, double x ) { double LogGamma; /* if (x<0.0 || a<= 0.0) raise(SIGFPE);*/ if ( x < 0.0 ) x = 0.0; if ( a <= 0.0 ) a = 1.e-50; LogGamma = lgamma( a ); if ( x < ( a + 1.0 ) ) return gamser( a, x, LogGamma ); else return 1.0 - gammcf( a, x, LogGamma ); } /* ------------------Incomplete gamma function-----------------*/ /* ------------------via its series representation-------------*/ double EvtVubBLNP::gamser( double a, double x, double LogGamma ) { double n; double ap, del, sum; ap = a; del = sum = 1.0 / a; for ( n = 1; n < ITMAX; n++ ) { ++ap; del *= x / ap; sum += del; if ( fabs( del ) < fabs( sum ) * EPS ) return sum * exp( -x + a * log( x ) - LogGamma ); } raise( SIGFPE ); return 0.0; } /* ------------------Incomplete gamma function complement------*/ /* ------------------via its continued fraction representation-*/ double EvtVubBLNP::gammcf( double a, double x, double LogGamma ) { double an, b, c, d, del, h; int i; b = x + 1.0 - a; c = 1.0 / FPMIN; d = 1.0 / b; h = d; for ( i = 1; i < ITMAX; i++ ) { an = -i * ( i - a ); b += 2.0; d = an * d + b; if ( fabs( d ) < FPMIN ) d = FPMIN; c = b + an / c; if ( fabs( c ) < FPMIN ) c = FPMIN; d = 1.0 / d; del = d * c; h *= del; if ( fabs( del - 1.0 ) < EPS ) return exp( -x + a * log( x ) - LogGamma ) * h; } raise( SIGFPE ); return 0.0; } double EvtVubBLNP::findBLNPWhat() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } diff --git a/src/EvtGenModels/EvtVubHybrid.cpp b/src/EvtGenModels/EvtVubHybrid.cpp index 694a4a2..7658f3e 100644 --- a/src/EvtGenModels/EvtVubHybrid.cpp +++ b/src/EvtGenModels/EvtVubHybrid.cpp @@ -1,465 +1,465 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "EvtGenModels/EvtVubHybrid.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtPFermi.hh" #include "EvtGenModels/EvtVubdGamma.hh" #include #include #include #include using std::cout; using std::endl; using std::ifstream; std::string EvtVubHybrid::getName() { return "VUBHYBRID"; } EvtDecayBase* EvtVubHybrid::clone() { return new EvtVubHybrid; } void EvtVubHybrid::init() { // check that there are at least 3 arguments if ( getNArg() < EvtVubHybrid::nParameters ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "EvtVub generator expected " << "at least " << EvtVubHybrid::nParameters << " arguments but found: " << getNArg() << "\nWill terminate execution!" << endl; ::abort(); } else if ( getNArg() == EvtVubHybrid::nParameters ) { EvtGenReport( EVTGEN_WARNING, "EvtVubHybrid" ) << "EvtVub: generate B -> Xu l nu events " << "without using the hybrid reweighting." << endl; _noHybrid = true; } else if ( getNArg() < EvtVubHybrid::nParameters + EvtVubHybrid::nVariables ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "EvtVub could not read number of bins for " << "all variables used in the reweighting\n" << "Will terminate execution!" << endl; ::abort(); } // check that there are 3 daughters checkNDaug( 3 ); // read minimum required parameters from decay.dec _mb = getArg( 0 ); _a = getArg( 1 ); _alphas = getArg( 2 ); // the maximum dGamma*p2 value depends on alpha_s only: const double dGMax0 = 3.; _dGMax = 0.21344 + 8.905 * _alphas; if ( _dGMax < dGMax0 ) _dGMax = dGMax0; // for the Fermi Motion we need a B-Meson mass - but it's not critical // to get an exact value; in order to stay in the phase space for // B+- and B0 use the smaller mass static double mB0 = EvtPDL::getMaxMass( EvtPDL::getId( "B0" ) ); static double mBP = EvtPDL::getMaxMass( EvtPDL::getId( "B+" ) ); static double mB = ( mB0 < mBP ? mB0 : mBP ); const double xlow = -_mb; const double xhigh = mB - _mb; const int aSize = 10000; EvtPFermi pFermi( _a, mB, _mb ); // pf is the cumulative distribution normalized to 1. _pf.resize( aSize ); for ( int i = 0; i < aSize; i++ ) { double kplus = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getFPFermi( kplus ); else _pf[i] = _pf[i - 1] + pFermi.getFPFermi( kplus ); } for ( size_t index = 0; index < _pf.size(); index++ ) { _pf[index] /= _pf[_pf.size() - 1]; } _dGamma = std::make_unique( _alphas ); if ( _noHybrid ) return; // Without hybrid weighting, nothing else to do _bins_mX.resize( abs( (int)getArg( 3 ) ) ); _bins_q2.resize( abs( (int)getArg( 4 ) ) ); _bins_El.resize( abs( (int)getArg( 5 ) ) ); int nextArg = EvtVubHybrid::nParameters + EvtVubHybrid::nVariables; _nbins = _bins_mX.size() * _bins_q2.size() * _bins_El.size(); // Binning of weight table int expectArgs = nextArg + _bins_mX.size() + _bins_q2.size() + _bins_El.size() + _nbins; if ( getNArg() < expectArgs ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << " finds " << getNArg() << " arguments, expected " << expectArgs << ". Something is wrong with the tables of weights or thresholds." << "\nWill terminate execution!" << endl; ::abort(); } // read bin boundaries from decay.dec for ( auto& b : _bins_mX ) b = getArg( nextArg++ ); _masscut = _bins_mX[0]; for ( auto& b : _bins_q2 ) b = getArg( nextArg++ ); for ( auto& b : _bins_El ) b = getArg( nextArg++ ); // read in weights (and rescale to range 0..1) readWeights( nextArg ); } void EvtVubHybrid::initProbMax() { noProbMax(); } void EvtVubHybrid::decay( EvtParticle* p ) { int j; // B+ -> u-bar specflav l+ nu - EvtParticle *xuhad( 0 ), *lepton( 0 ), *neutrino( 0 ); + EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; // R. Faccini 21/02/03 // move the reweighting up , before also shooting the fermi distribution double x, z, p2; double sh = 0.0; double mB, ml, xlow, xhigh, qplus; double El = 0.0; double Eh = 0.0; double kplus; double q2, mX; const double lp2epsilon = -10; bool rew( true ); while ( rew ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = p->getDaug( 0 ); lepton = p->getDaug( 1 ); neutrino = p->getDaug( 2 ); mB = p->mass(); ml = lepton->mass(); xlow = -_mb; xhigh = mB - _mb; // Fermi motion does not need to be computed inside the // tryit loop as m_b in Gamma0 does not need to be replaced by (m_b+kplus). // The difference however should be of the Order (lambda/m_b)^2 which is // beyond the considered orders in the paper anyway ... // for alpha_S = 0 and a mass cut on X_u not all values of kplus are // possible. The maximum value is mB/2-_mb + sqrt(mB^2/4-_masscut^2) kplus = 2 * xhigh; while ( kplus >= xhigh || kplus <= xlow || ( _alphas == 0 && kplus >= mB / 2 - _mb + sqrt( mB * mB / 4 - _masscut * _masscut ) ) ) { kplus = findPFermi(); //_pFermi->shoot(); kplus = xlow + kplus * ( xhigh - xlow ); } qplus = mB - _mb - kplus; if ( ( mB - qplus ) / 2. <= ml ) continue; int tryit = 1; while ( tryit ) { x = EvtRandom::Flat(); z = EvtRandom::Flat( 0, 2 ); p2 = EvtRandom::Flat(); p2 = pow( 10, lp2epsilon * p2 ); El = x * ( mB - qplus ) / 2; if ( El > ml && El < mB / 2 ) { Eh = z * ( mB - qplus ) / 2 + qplus; if ( Eh > 0 && Eh < mB ) { sh = p2 * pow( mB - qplus, 2 ) + 2 * qplus * ( Eh - qplus ) + qplus * qplus; if ( sh > _masscut * _masscut && mB * mB + sh - 2 * mB * Eh > ml * ml ) { double xran = EvtRandom::Flat(); double y = _dGamma->getdGdxdzdp( x, z, p2 ) / _dGMax * p2; if ( y > 1 ) EvtGenReport( EVTGEN_WARNING, "EvtVubHybrid" ) << "EvtVubHybrid decay probability > 1 found: " << y << endl; if ( y >= xran ) tryit = 0; } } } } // compute all kinematic variables needed for reweighting (J. Dingfelder) mX = sqrt( sh ); q2 = mB * mB + sh - 2 * mB * Eh; // Reweighting in bins of mX, q2, El (J. Dingfelder) if ( !_weights.empty() ) { double xran1 = EvtRandom::Flat(); double w = 1.0; if ( !_noHybrid ) w = getWeight( mX, q2, El ); if ( w >= xran1 ) rew = false; } else { rew = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * M_PI ); double phL = EvtRandom::Flat( 0, 2 * M_PI ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( Eh * Eh - sh ); double pHB[4] = {Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), ptmp * ctH}; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); if ( _storeQplus ) { // cludge to store the hidden parameter q+ with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take q+/(10000 GeV) which // goes up to 0.0005 in the most extreme cases as ctau in mm. // To extract q+ back from the StdHepTrk its necessary to get // delta_ctau = Xu->anyDaughter->getVertexTime()-Xu->getVertexTime() // where these pseudo calls refere to the StdHep time stored at // the production vertex in the lab for each particle. The boost // has to be reversed and the result is: // // q+ = delta_ctau * 10000 GeV/mm * Mass_Xu/Energy_Xu // xuhad->setLifetime( qplus / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; double pWB[4] = {mB - Eh, -pHB[1], -pHB[2], -pHB[3]}; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mB * mB + sh - 2 * mB * Eh; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW double xW[3] = {-pWB[2], pWB[1], 0}; // eZ' = eW double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], pWB[1] * pWB[1] + pWB[2] * pWB[2]}; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // calculate the neutrino 4 vector in the W restframe //double pNW[4] = {sqrt(mW2)-pLW[0],-pLW[1],-pLW[2],-pLW[3]}; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; double pLB[4] = {El, 0, 0, 0}; double pNB[4] = {pWB[0] - El, 0, 0, 0}; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVubHybrid::findPFermi() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } double EvtVubHybrid::getWeight( double mX, double q2, double El ) { int ibin_mX = -1; int ibin_q2 = -1; int ibin_El = -1; for ( unsigned i = 0; i < _bins_mX.size(); i++ ) { if ( mX >= _bins_mX[i] ) ibin_mX = i; } for ( unsigned i = 0; i < _bins_q2.size(); i++ ) { if ( q2 >= _bins_q2[i] ) ibin_q2 = i; } for ( unsigned i = 0; i < _bins_El.size(); i++ ) { if ( El >= _bins_El[i] ) ibin_El = i; } int ibin = ibin_mX + ibin_q2 * _bins_mX.size() + ibin_El * _bins_mX.size() * _bins_q2.size(); if ( ( ibin_mX < 0 ) || ( ibin_q2 < 0 ) || ( ibin_El < 0 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "Cannot determine hybrid weight " << "for this event " << "-> assign weight = 0" << endl; return 0.0; } return _weights[ibin]; } void EvtVubHybrid::readWeights( int startArg ) { _weights.resize( _nbins ); double maxw = 0.0; for ( auto& w : _weights ) { w = getArg( startArg++ ); if ( w > maxw ) maxw = w; } if ( maxw == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "EvtVub generator expected at least one " << " weight > 0, but found none! " << "Will terminate execution!" << endl; ::abort(); } // rescale weights (to be in range 0..1) for ( auto& w : _weights ) w /= maxw; } diff --git a/src/EvtGenModels/EvtbTosllScalarAmpNew.cpp b/src/EvtGenModels/EvtbTosllScalarAmpNew.cpp index 97cf870..c3f2de7 100644 --- a/src/EvtGenModels/EvtbTosllScalarAmpNew.cpp +++ b/src/EvtGenModels/EvtbTosllScalarAmpNew.cpp @@ -1,938 +1,938 @@ /*********************************************************************** * 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/EvtbTosllScalarAmpNew.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenModels/EvtbTosllAmpNew.hh" #include "EvtGenModels/EvtbTosllFFNew.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include // // The main functiom for the amplitude calculation // // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllFFNew class object; // *WilsCoeff - the pointer to // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta // // return: amp - amplitude for the decay B -> P ell^+ ell^- // // Note: in our calculations we assume, that pseudoscalar meson is the first // daughter particle (iP=0) and leptons are the second and thirds // daughter particles (il1=1 and il2=2). // void EvtbTosllScalarAmpNew::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { // FILE *mytest; EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit int iP = 0; // pseudoscalar meson is the first daughter particle int il1 = 1, il2 = 2; // leptons are the second and thirds daughter particles // transition momentum of the leptonic pair q=k1+k2 or q=p1-p2 EvtVector4R q = parent->getDaug( il1 )->getP4() + parent->getDaug( il2 )->getP4(); // Mandelstam variable t=q^2 double q2 = q.mass2(); double M1 = parent->mass(); // B - meson mass double M2 = parent->getDaug( iP )->mass(); // pseudoscalar meson mass double ml = parent->getDaug( il1 )->mass(); // leptonic mass double ms = 0.0; // light quark mass from the dispersion QM double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM // double Mw = EvtPDL::getNominalMass("W+"); // W-boson mass // double mt = EvtPDL::getNominalMass("t"); // t-quark mass double Mw = 80.403; // GeV W-boson mass double mt = 174.2; // GeV t-quark mass EvtComplex Vtb, Vtq, Vub, Vuq; // V_{tb}, V_{tq}, V_{ub} and V_{uq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; EvtId idparent = parent->getId(); // B-meson Id EvtId iddaught = parent->getDaug( iP )->getId(); // The pseudoscalar meson Id // set of the light quark mass value if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "f_0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "f_0" ) ) ) ) { ms = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; // EvtGenReport(EVTGEN_ERROR,"EvtGen") // << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" // << "\n ms = " << ms // << "\n idparent = " << idparent << ", " << EvtPDL::getId(std::string("B_s0")) // << "\n iddaught = " << iddaught << ", " << EvtPDL::getId(std::string("f_0")) // << std::endl; } if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "pi+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "pi-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "pi0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "pi0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) ) { ms = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); } if ( ms < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllScalarAmpNew::CalcAmp(...)" << "\n Error in the model set!" << " ms = " << ms << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); double fp, f0, ft; // B -> P transition form-factors // To get the B -> P transition form-factors formFactors->getScalarFF( parent->getId(), parent->getDaug( iP )->getId(), q2, fp, f0, ft ); // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) EvtComplex c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); EvtComplex c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c10a = WilsCoeff->GetC10Eff( mt, Mw ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n\n The function EvtbTosllScalarAmpNew::CalcAmp(...) passed." // << "\n Particle masses:" // << "\n B - meson mass M1 = " << M1 // << "\n P - meson mass M2 = " << M2 // << "\n leptonic mass ml = " << ml // << "\n light quark mass = " << ms // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << mb // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ============================================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n resonant switching = " << res_swch // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n ============================================================================" // << "\n Vector form-factors at q^2 = " << q2 // << " for B -> P transition:" // << "\n fp = " << fp // << "\n f0 = " << f0 // << "\n ft = " << ft // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Re(c7gam) = " << real(c7gam) << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) << " Im(c10a) = " << imag(c10a) // << std::endl; // mytest = fopen("scalaroutput.txt","a"); // if(mytest != NULL){ // fprintf(mytest,"%lf\n",q2); // fclose(mytest); // } // else{ // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n Error in writing to file.\n" // << std::endl; // return; // } // 4- momentum of the B-meson in the the B-meson rest frame EvtVector4R p1 = parent->getP4Restframe(); EvtVector4R hatp1 = p1 / M1; // 4-momentum of the pseudoscalar meson in the B-meson rest frame EvtVector4R p2 = parent->getDaug( 0 )->getP4(); EvtVector4R hatp2 = p2 / M1; // 4-vector \hat q = q/M1 EvtVector4R hatq = q / M1; // 4-vector \hat P= (p1 + p2)/M1 EvtVector4R hatP = hatp1 + hatp2; double hats = q2 / pow( M1, 2 ); double hatM2 = M2 / M1; double hatmb = mb / M1; double hatms = ms / M1; // Hadronic matrix element with m_s.NE.0 EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, c, d; a_b2q = c9eff_b2q * fp - 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ); a_barb2barq = c9eff_barb2barq * fp - 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ); b_b2q = ( c9eff_b2q * ( f0 - fp ) + 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ) ) * ( 1 - pow( hatM2, 2.0 ) ) / hats; b_barb2barq = ( c9eff_barb2barq * ( f0 - fp ) + 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ) ) * ( 1 - pow( hatM2, 2.0 ) ) / hats; c = c10a * fp; d = c10a * ( 1.0 - pow( hatM2, 2 ) ) * ( f0 - fp ) / hats; // to find ell^+ and ell^- in the B-meson daughters int charge1 = EvtPDL::chg3( parent->getDaug( 1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( 2 )->getId() ); - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; lepPlus = ( charge1 > charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); lepMinus = ( charge1 < charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); EvtVector4C T1, T2; // hadronic matrix element vector structures EvtVector4C lvc11, lvc12; // spin structures for EvtVector4C lvc21, lvc22; // the leptonic vector current EvtVector4C lac11, lac12; // spin structures for EvtVector4C lac21, lac22; // the leptonic axial current // B - and barB - mesons descriptors EvtIdSet bmesons( "B-", "anti-B0", "anti-B_s0", "B_c-" ); EvtIdSet bbarmesons( "B+", "B0", "B_s0", "B_c+" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> barP ell^+ ell^- // (b -> q ell^+ ell^- transition) T1 = a_b2q * hatP + b_b2q * hatq; T2 = c * hatP + d * hatq; lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); amp.vertex( 0, 0, CKM_factor * ( lvc11 * T1 + lac11 * T2 ) ); amp.vertex( 0, 1, CKM_factor * ( lvc12 * T1 + lac12 * T2 ) ); amp.vertex( 1, 0, CKM_factor * ( lvc21 * T1 + lac21 * T2 ) ); amp.vertex( 1, 1, CKM_factor * ( lvc22 * T1 + lac22 * T2 ) ); } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> K* ell^+ ell^- // (barb -> barq ell^+ ell^- transition) T1 = a_barb2barq * hatP + b_barb2barq * hatq; T2 = c * hatP + d * hatq; lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); amp.vertex( 0, 0, conj( CKM_factor ) * ( lvc11 * T1 + lac11 * T2 ) ); amp.vertex( 0, 1, conj( CKM_factor ) * ( lvc12 * T1 + lac12 * T2 ) ); amp.vertex( 1, 0, conj( CKM_factor ) * ( lvc21 * T1 + lac21 * T2 ) ); amp.vertex( 1, 1, conj( CKM_factor ) * ( lvc22 * T1 + lac22 * T2 ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllScalarAmpNew::CalcAmp(...)" << "\n Wrong B-meson number" << std::endl; ::abort(); } } } // // The decays B -> P ell^+ ell^- maximum probability calculation for the // d^2\Gamma/dq^2 d\cos\theta distribution. // // \theta - the angle between the final P-meson and ell^- directions in the // B-meson rest frame. // // If ias=0 (nonresonant case), the maximum is achieved at (s,t) plane! // If ias=1 (resonant case), the maximum is achieved at q2=M^2_{J/\psi}. // double EvtbTosllScalarAmpNew::CalcMaxProb( EvtId parnum, EvtId mesnum, EvtId l1num, EvtId l2num, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { double maxfoundprob = -100.0; // maximum of the probability double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass double M2 = EvtPDL::getMeanMass( mesnum ); // P - meson mass double ml = EvtPDL::getMeanMass( l1num ); // leptonic mass if ( res_swch == 0 ) { double s, t_for_s; // Mandelstam variables double s_min, s_max; // s-variable boundaries double t_plus, t_minus; // t-variable boundaries for current s-variable double ds, dt; int j, k; int max_j, max_k; s_min = 4.0 * pow( ml, 2.0 ); // minimum value of s-variable s_max = pow( ( M1 - M2 ), 2.0 ); // maximum value of s-variable max_j = 1000; ds = ( s_max - s_min ) / ( (double)max_j ); if ( ds < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" << "\n ds = " << ds << " < 0." << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // The maximum probability calculation // from s_min to s_max for ( j = max_j / 3; j < max_j; j++ ) { s = s_min + ds * ( (double)j ); t_plus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_minus *= 0.5; max_k = 1000; dt = ( t_plus - t_minus ) / ( (double)max_k ); if ( fabs( dt ) < 0.00001 ) dt = 0.0; if ( dt <= ( -0.00001 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" << "\n dt = " << dt << " < 0." << "\n s = " << s << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n ds = " << ds << "\n j = " << j << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // from t_minus to t_plus for ( k = 0; k < max_k; k++ ) { t_for_s = t_minus + dt * ( (double)k ); if ( ( t_for_s > t_plus ) && ( t_for_s <= ( 1.0001 * t_plus ) ) ) { t_for_s = t_plus; } if ( t_for_s > ( 1.0001 * t_plus ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" << "\n t_for_s = " << t_for_s << " > t_plus = " << t_plus << " ! " << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n k = " << k << "\n s = " << s << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // B-meson rest frame particles and they kinematics inicialization double EV, El1, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s ) / ( 2.0 * M1 ); // P-meson energy if ( EV < M2 ) { EV = 1.0000001 * M2; } El1 = ( pow( M1, 2.0 ) + pow( ml, 2.0 ) - t_for_s ) / ( 2.0 * M1 ); // ell^+ energy if ( El1 < ml ) { El1 = 1.0000001 * ml; } El2 = ( s + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy if ( El2 < ml ) { El2 = 1.0000001 * ml; } double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the P-meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n modV = " << modV // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n s_min = " << s_min // << "\n s_max = " << s_max // << "\n t_plus = " << t_plus // << "\n t_minus = " << t_minus // << "\n dt = " << dt // << "\n EV = " << EV // << "\n El2 = " << El2 // << "\n M2 = " << M2 // << "\n ml = " << ml // << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } double sin2Vellminus = 1.0 - pow( cosVellminus, 2.0 ); if ( ( sin2Vellminus < 0.0 ) && ( sin2Vellminus >= -0.0001 ) ) { sin2Vellminus = 0.0; } if ( sin2Vellminus <= -0.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n cos^2(theta) = " << sin2Vellminus << " < -0.001" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( sin2Vellminus ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); // EvtGenReport(EVTGEN_ERROR,"EvtGen") // << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n p1 = " << p1 // << "\n p2 = " << p2 // << "\n k1 = " << k1 // << "\n k2 = " << k2 // << "\n mesnum = " << mesnum // << "\n l1num = " << l1num // << "\n l2num = " << l2num // << std::endl; vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); // EvtGenReport(EVTGEN_ERROR,"EvtGen") // << "\n vect = " << vect // << "\n lep1 = " << lep1 // << "\n lep2 = " << lep2 // << std::endl; EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " // << maxfoundprob // << "\n k =" << k // << std::endl; } delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // for(k=0; k<=max_k; k++) } // for(j=0; j t_plus ) && ( t_for_s <= ( 1.0001 * t_plus ) ) ) { t_for_s = t_plus; } if ( t_for_s > ( 1.0001 * t_plus ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n t_for_s = " << t_for_s << " > t_plus = " << t_plus << " ! " << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n k = " << k << "\n s = " << s << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // B-meson rest frame particles and they kinematics inicialization double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s ) / ( 2.0 * M1 ); // V-meson energy El2 = ( s + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the vector meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n modV = " << modV // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n t_plus = " << t_plus // << "\n t_minus = " << t_minus // << "\n dt = " << dt // << "\n EV = " << EV // << "\n El2 = " << El2 // << "\n M2 = " << M2 // << "\n ml = " << ml // << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } double sin2Vellminus = 1.0 - pow( cosVellminus, 2.0 ); if ( ( sin2Vellminus < 0.0 ) && ( sin2Vellminus >= -0.0001 ) ) { sin2Vellminus = 0.0; } if ( sin2Vellminus <= -0.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n cos^2(theta) = " << sin2Vellminus << " < -0.001" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( sin2Vellminus ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " // << maxfoundprob // << "\n k =" << k // << std::endl; } delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // for(k=0; k<=1000; k++) } // if(res_swch==1) if ( maxfoundprob <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob (...) = " << maxfoundprob << std::endl; maxfoundprob *= 1.01; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ***************************************************************************" // << "\n The function EvtbTosllScalarAmpNew::CalcMaxProb(...) passed with arguments:" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << " \n s_at_max = " << s_at_max // << " t_at_max = " << t_at_max // << "\n The distribution maximum maxfoundprob =" << maxfoundprob // << "\n ***************************************************************************" // << std::endl; return maxfoundprob; } // Triangular function double EvtbTosllScalarAmpNew::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/EvtbTosllScalarAmpNewExt.cpp b/src/EvtGenModels/EvtbTosllScalarAmpNewExt.cpp index 104b3e1..e7455cb 100644 --- a/src/EvtGenModels/EvtbTosllScalarAmpNewExt.cpp +++ b/src/EvtGenModels/EvtbTosllScalarAmpNewExt.cpp @@ -1,871 +1,871 @@ /*********************************************************************** * 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/EvtbTosllScalarAmpNewExt.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenModels/EvtbTosllAmpNewExt.hh" #include "EvtGenModels/EvtbTosllFFNew.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include // // The main functiom for the amplitude calculation // // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllFFNew class object; // *WilsCoeff - the pointer to // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta // // return: amp - amplitude for the decay B -> P ell^+ ell^- // // Note: in our calculations we assume, that pseudoscalar meson is the first // daughter particle (iP=0) and leptons are the second and thirds // daughter particles (il1=1 and il2=2). // void EvtbTosllScalarAmpNewExt::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta, double ReA7, double ImA7, double ReA10, double ImA10 ) { // FILE *mytest; EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit EvtComplex A7 = ReA7 * unit1 + ImA7 * uniti; EvtComplex A10 = ReA10 * unit1 + ImA10 * uniti; int iP = 0; // pseudoscalar meson is the first daughter particle int il1 = 1, il2 = 2; // leptons are the second and thirds daughter particles // transition momentum of the leptonic pair q=k1+k2 or q=p1-p2 EvtVector4R q = parent->getDaug( il1 )->getP4() + parent->getDaug( il2 )->getP4(); // Mandelstam variable t=q^2 double q2 = q.mass2(); double M1 = parent->mass(); // B - meson mass double M2 = parent->getDaug( iP )->mass(); // pseudoscalar meson mass double ml = parent->getDaug( il1 )->mass(); // leptonic mass double ms = 0.0; // light quark mass from the dispersion QM double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM // double Mw = EvtPDL::getNominalMass("W+"); // W-boson mass // double mt = EvtPDL::getNominalMass("t"); // t-quark mass double Mw = 80.403; // GeV W-boson mass double mt = 174.2; // GeV t-quark mass EvtComplex Vtb, Vtq, Vub, Vuq; // V_{tb}, V_{tq}, V_{ub} and V_{uq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; EvtId idparent = parent->getId(); // B-meson Id EvtId iddaught = parent->getDaug( iP )->getId(); // The pseudoscalar meson Id // set of the light quark mass value if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "f_0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "f_0" ) ) ) ) { ms = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; } if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "pi+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "pi-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "pi0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "pi0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "eta'" ) ) ) ) { ms = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); } if ( ms < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllScalarAmpNew::CalcAmp(...)" << "\n Error in the model set!" << " ms = " << ms << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); double fp, f0, ft; // B -> P transition form-factors // To get the B -> P transition form-factors formFactors->getScalarFF( parent->getId(), parent->getDaug( iP )->getId(), q2, fp, f0, ft ); // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) EvtComplex c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); c7gam = c7gam * A7; EvtComplex c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c10a = WilsCoeff->GetC10Eff( mt, Mw ); c10a = c10a * A10; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n\n The function EvtbTosllScalarAmpNew::CalcAmp(...) passed." // << "\n Particle masses:" // << "\n B - meson mass M1 = " << M1 // << "\n P - meson mass M2 = " << M2 // << "\n leptonic mass ml = " << ml // << "\n light quark mass = " << ms // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << mb // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ============================================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n resonant switching = " << res_swch // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n ============================================================================" // << "\n Vector form-factors at q^2 = " << q2 // << " for B -> P transition:" // << "\n fp = " << fp // << "\n f0 = " << f0 // << "\n ft = " << ft // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Re(c7gam) = " << real(c7gam) << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) << " Im(c10a) = " << imag(c10a) // << std::endl; // mytest = fopen("scalaroutput.txt","a"); // if(mytest != NULL){ // fprintf(mytest,"%lf\n",q2); // fclose(mytest); // } // else{ // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n Error in writing to file.\n" // << std::endl; // return; // } // 4- momentum of the B-meson in the the B-meson rest frame EvtVector4R p1 = parent->getP4Restframe(); EvtVector4R hatp1 = p1 / M1; // 4-momentum of the pseudoscalar meson in the B-meson rest frame EvtVector4R p2 = parent->getDaug( 0 )->getP4(); EvtVector4R hatp2 = p2 / M1; // 4-vector \hat q = q/M1 EvtVector4R hatq = q / M1; // 4-vector \hat P= (p1 + p2)/M1 EvtVector4R hatP = hatp1 + hatp2; double hats = q2 / pow( M1, 2 ); double hatM2 = M2 / M1; double hatmb = mb / M1; double hatms = ms / M1; // Hadronic matrix element with m_s.NE.0 EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, c, d; a_b2q = c9eff_b2q * fp - 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ); a_barb2barq = c9eff_barb2barq * fp - 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ); b_b2q = ( c9eff_b2q * ( f0 - fp ) + 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ) ) * ( 1 - pow( hatM2, 2.0 ) ) / hats; b_barb2barq = ( c9eff_barb2barq * ( f0 - fp ) + 2.0 * c7gam * ( hatmb + hatms ) * ft / ( 1.0 + hatM2 ) ) * ( 1 - pow( hatM2, 2.0 ) ) / hats; c = c10a * fp; d = c10a * ( 1.0 - pow( hatM2, 2 ) ) * ( f0 - fp ) / hats; // to find ell^+ and ell^- in the B-meson daughters int charge1 = EvtPDL::chg3( parent->getDaug( 1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( 2 )->getId() ); - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; lepPlus = ( charge1 > charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); lepMinus = ( charge1 < charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); EvtVector4C T1, T2; // hadronic matrix element vector structures EvtVector4C lvc11, lvc12; // spin structures for EvtVector4C lvc21, lvc22; // the leptonic vector current EvtVector4C lac11, lac12; // spin structures for EvtVector4C lac21, lac22; // the leptonic axial current // B - and barB - mesons descriptors EvtIdSet bmesons( "B-", "anti-B0", "anti-B_s0", "B_c-" ); EvtIdSet bbarmesons( "B+", "B0", "B_s0", "B_c+" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> barP ell^+ ell^- // (b -> q ell^+ ell^- transition) T1 = a_b2q * hatP + b_b2q * hatq; T2 = c * hatP + d * hatq; lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); amp.vertex( 0, 0, CKM_factor * ( lvc11 * T1 + lac11 * T2 ) ); amp.vertex( 0, 1, CKM_factor * ( lvc12 * T1 + lac12 * T2 ) ); amp.vertex( 1, 0, CKM_factor * ( lvc21 * T1 + lac21 * T2 ) ); amp.vertex( 1, 1, CKM_factor * ( lvc22 * T1 + lac22 * T2 ) ); } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> K* ell^+ ell^- // (barb -> barq ell^+ ell^- transition) T1 = a_barb2barq * hatP + b_barb2barq * hatq; T2 = c * hatP + d * hatq; lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); amp.vertex( 0, 0, conj( CKM_factor ) * ( lvc11 * T1 + lac11 * T2 ) ); amp.vertex( 0, 1, conj( CKM_factor ) * ( lvc12 * T1 + lac12 * T2 ) ); amp.vertex( 1, 0, conj( CKM_factor ) * ( lvc21 * T1 + lac21 * T2 ) ); amp.vertex( 1, 1, conj( CKM_factor ) * ( lvc22 * T1 + lac22 * T2 ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllScalarAmpNew::CalcAmp(...)" << "\n Wrong B-meson number" << std::endl; ::abort(); } } } // // The decays B -> P ell^+ ell^- maximum probability calculation for the // d^2\Gamma/dq^2 d\cos\theta distribution. // // \theta - the angle between the final P-meson and ell^- directions in the // B-meson rest frame. // // If ias=0 (nonresonant case), the maximum is achieved at (s,t) plane! // If ias=1 (resonant case), the maximum is achieved at q2=M^2_{J/\psi}. // double EvtbTosllScalarAmpNewExt::CalcMaxProb( EvtId parnum, EvtId mesnum, EvtId l1num, EvtId l2num, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta, double ReA7, double ImA7, double ReA10, double ImA10 ) { double maxfoundprob = -100.0; // maximum of the probability double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass double M2 = EvtPDL::getMeanMass( mesnum ); // P - meson mass double ml = EvtPDL::getMeanMass( l1num ); // leptonic mass if ( res_swch == 0 ) { double s, t_for_s; // Mandelstam variables double s_min, s_max; // s-variable boundaries double t_plus, t_minus; // t-variable boundaries for current s-variable double ds, dt; int j, k; int max_j, max_k; s_min = 4.0 * pow( ml, 2.0 ); // minimum value of s-variable s_max = pow( ( M1 - M2 ), 2.0 ); // maximum value of s-variable max_j = 1000; ds = ( s_max - s_min ) / ( (double)max_j ); if ( ds < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" << "\n ds = " << ds << " < 0." << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // The maximum probability calculation // from s_min to s_max for ( j = max_j / 3; j < max_j; j++ ) { s = s_min + ds * ( (double)j ); t_plus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_minus *= 0.5; max_k = 1000; dt = ( t_plus - t_minus ) / ( (double)max_k ); if ( fabs( dt ) < 0.00001 ) dt = 0.0; if ( dt <= ( -0.00001 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" << "\n dt = " << dt << " < 0." << "\n s = " << s << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n ds = " << ds << "\n j = " << j << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // from t_minus to t_plus for ( k = 0; k < max_k; k++ ) { t_for_s = t_minus + dt * ( (double)k ); if ( ( t_for_s > t_plus ) && ( t_for_s <= ( 1.0001 * t_plus ) ) ) { t_for_s = t_plus; } if ( t_for_s > ( 1.0001 * t_plus ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcScalarMaxProb(...)" << "\n t_for_s = " << t_for_s << " > t_plus = " << t_plus << " ! " << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n k = " << k << "\n s = " << s << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // B-meson rest frame particles and they kinematics inicialization double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s ) / ( 2.0 * M1 ); // P-meson energy El2 = ( s + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the P-meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n modV = " << modV // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n s_min = " << s_min // << "\n s_max = " << s_max // << "\n t_plus = " << t_plus // << "\n t_minus = " << t_minus // << "\n dt = " << dt // << "\n EV = " << EV // << "\n El2 = " << El2 // << "\n M2 = " << M2 // << "\n ml = " << ml // << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n s_min = " << s_min << "\n s_max = " << s_max << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( 1.0 - pow( cosVellminus, 2.0 ) ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta, ReA7, ImA7, ReA10, ImA10 ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " // << maxfoundprob // << "\n k =" << k // << std::endl; } delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // for(k=0; k<=max_k; k++) } // for(j=0; j<=max_j; j++) } // if(res_swch==0) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if ( res_swch == 1 ) { double s, t_for_s; // Mandelstam variables double t_plus, t_minus; // t-variable boundaries for current s-variable double dt; int k; s = pow( 3.09688, 2.0 ); // s = (M_{J/\psi})^2 t_plus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_minus *= 0.5; dt = ( t_plus - t_minus ) / 1000.0; // The maximum probability calculation for ( k = 0; k < 1000; k++ ) { t_for_s = t_minus + dt * ( (double)k ); if ( ( t_for_s > t_plus ) && ( t_for_s <= ( 1.0001 * t_plus ) ) ) { t_for_s = t_plus; } if ( t_for_s > ( 1.0001 * t_plus ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n t_for_s = " << t_for_s << " > t_plus = " << t_plus << " ! " << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n k = " << k << "\n s = " << s << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // B-meson rest frame particles and they kinematics inicialization double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s ) / ( 2.0 * M1 ); // V-meson energy El2 = ( s + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the vector meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n modV = " << modV // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n t_plus = " << t_plus // << "\n t_minus = " << t_minus // << "\n dt = " << dt // << "\n EV = " << EV // << "\n El2 = " << El2 // << "\n M2 = " << M2 // << "\n ml = " << ml // << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( 1.0 - pow( cosVellminus, 2.0 ) ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n Debug in the function EvtbTosllScalarAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta, ReA7, ImA7, ReA10, ImA10 ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " // << maxfoundprob // << "\n k =" << k // << std::endl; } delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // for(k=0; k<=1000; k++) } // if(res_swch==1) if ( maxfoundprob <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllScalarAmpNew::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob (...) = " << maxfoundprob << std::endl; maxfoundprob *= 1.01; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ***************************************************************************" // << "\n The function EvtbTosllScalarAmpNew::CalcMaxProb(...) passed with arguments:" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << " \n s_at_max = " << s_at_max // << " t_at_max = " << t_at_max // << "\n The distribution maximum maxfoundprob =" << maxfoundprob // << "\n ***************************************************************************" // << std::endl; return maxfoundprob; } // Triangular function double EvtbTosllScalarAmpNewExt::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/EvtbTosllVectorAmp.cpp b/src/EvtGenModels/EvtbTosllVectorAmp.cpp index 3790f96..e4fe67e 100644 --- a/src/EvtGenModels/EvtbTosllVectorAmp.cpp +++ b/src/EvtGenModels/EvtbTosllVectorAmp.cpp @@ -1,215 +1,215 @@ /*********************************************************************** * 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/EvtbTosllVectorAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenModels/EvtbTosllAmp.hh" #include "EvtGenModels/EvtbTosllFF.hh" void EvtbTosllVectorAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtbTosllFF* formFactors ) { //Add the lepton and neutrino 4 momenta to find q2 EvtVector4R q = parent->getDaug( 1 )->getP4() + parent->getDaug( 2 )->getP4(); double q2 = ( q.mass2() ); double a1, a2, a0, v, t1, t2, t3; double mesonmass = parent->getDaug( 0 )->mass(); double parentmass = parent->mass(); formFactors->getVectorFF( parent->getId(), parent->getDaug( 0 )->getId(), q2, mesonmass, a1, a2, a0, v, t1, t2, t3 ); EvtId daught = parent->getDaug( 0 )->getId(); EvtId parentId = parent->getId(); bool btod = false; bool nnlo = true; if ( ( parentId == EvtPDL::getId( "B0" ) || parentId == EvtPDL::getId( "anti-B0" ) || parentId == EvtPDL::getId( "B+" ) || parentId == EvtPDL::getId( "B-" ) ) && ( daught == EvtPDL::getId( std::string( "rho+" ) ) || daught == EvtPDL::getId( std::string( "rho-" ) ) || daught == EvtPDL::getId( std::string( "rho0" ) ) || daught == EvtPDL::getId( std::string( "omega" ) ) ) ) { btod = true; } if ( ( parentId == EvtPDL::getId( "B_s0" ) || parentId == EvtPDL::getId( "anti-B_s0" ) ) && ( daught == EvtPDL::getId( std::string( "K*0" ) ) || daught == EvtPDL::getId( std::string( "anti-K*0" ) ) || daught == EvtPDL::getId( std::string( "K*+" ) ) || daught == EvtPDL::getId( std::string( "K*-" ) ) ) ) { btod = true; } EvtVector4R p4b; p4b.set( parent->mass(), 0.0, 0.0, 0.0 ); EvtVector4R p4meson = parent->getDaug( 0 )->getP4(); EvtVector4C l11, l12; EvtVector4C l21, l22; EvtVector4C a11, a12; EvtVector4C a21, a22; EvtId parentID = parent->getId(); //EvtId l_num = parent->getDaug(1)->getId(); EvtVector4R pbhat = p4b / parentmass; EvtVector4R qhat = q / parentmass; EvtVector4R pkstarhat = p4meson / parentmass; EvtVector4R phat = pbhat + pkstarhat; EvtComplex c7eff = EvtbTosllAmp::GetC7Eff( q2, nnlo ); EvtComplex c9eff = EvtbTosllAmp::GetC9Eff( q2, nnlo, btod ); EvtComplex c10eff = EvtbTosllAmp::GetC10Eff( q2, nnlo ); EvtComplex uniti( 0.0, 1.0 ); double mhatb = 4.4 / ( parentmass ); double mhatkstar = mesonmass / ( parentmass ); double shat = q2 / ( parentmass * parentmass ); EvtComplex a; a = c9eff * v * 2 / ( 1 + mhatkstar ) + 4 * mhatb * c7eff * t1 / shat; EvtComplex b; b = ( 1 + mhatkstar ) * ( c9eff * a1 + 2 * mhatb * ( 1 - mhatkstar ) * c7eff * t2 / shat ); EvtComplex c; c = ( ( 1 - mhatkstar ) * c9eff * a2 + 2 * mhatb * c7eff * ( t3 + ( 1 - mhatkstar * mhatkstar ) * t2 / shat ) ) / ( 1 - mhatkstar * mhatkstar ); EvtComplex d; d = ( c9eff * ( ( 1 + mhatkstar ) * a1 - ( 1 - mhatkstar ) * a2 - 2 * mhatkstar * a0 ) - 2 * mhatb * c7eff * t3 ) / shat; EvtComplex e; e = 2 * c10eff * v / ( 1 + mhatkstar ); EvtComplex f; f = ( 1 + mhatkstar ) * c10eff * a1; EvtComplex g; g = c10eff * a2 / ( 1 + mhatkstar ); EvtComplex h; h = c10eff * ( ( 1 + mhatkstar ) * a1 - ( 1 - mhatkstar ) * a2 - 2 * mhatkstar * a0 ) / shat; EvtTensor4C T1, T2; static EvtIdSet bmesons( "B-", "anti-B0", "anti-B_s0" ); static EvtIdSet bbarmesons( "B+", "B0", "B_s0" ); - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; int charge1 = EvtPDL::chg3( parent->getDaug( 1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( 2 )->getId() ); lepPlus = ( charge1 > charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); lepMinus = ( charge1 < charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); if ( bmesons.contains( parentID ) ) { T1 = a * dual( EvtGenFunctions::directProd( pbhat, pkstarhat ) ) - b * uniti * EvtTensor4C::g() + c * uniti * EvtGenFunctions::directProd( pbhat, phat ) + d * uniti * EvtGenFunctions::directProd( pbhat, qhat ); T2 = e * dual( EvtGenFunctions::directProd( pbhat, pkstarhat ) ) - f * uniti * EvtTensor4C::g() + g * uniti * EvtGenFunctions::directProd( pbhat, phat ) + h * uniti * EvtGenFunctions::directProd( pbhat, qhat ); l11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); l21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); l12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); l22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); a11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); a21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); a12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); a22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); } else { if ( bbarmesons.contains( parentID ) ) { T1 = -a * dual( EvtGenFunctions::directProd( pbhat, pkstarhat ) ) - b * uniti * EvtTensor4C::g() + c * uniti * EvtGenFunctions::directProd( pbhat, phat ) + d * uniti * EvtGenFunctions::directProd( pbhat, qhat ); T2 = -e * dual( EvtGenFunctions::directProd( pbhat, pkstarhat ) ) - f * uniti * EvtTensor4C::g() + g * uniti * EvtGenFunctions::directProd( pbhat, phat ) + h * uniti * EvtGenFunctions::directProd( pbhat, qhat ); l11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); l21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); l12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); l22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); a11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); a21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); a12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); a22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong lepton number\n"; T1.zero(); T2.zero(); // Set all tensor terms to zero. } } int i; for ( i = 0; i < 3; i++ ) { EvtVector4C eps = parent->getDaug( 0 )->epsParent( i ).conj(); EvtVector4C E1 = T1.cont1( eps ); EvtVector4C E2 = T2.cont1( eps ); amp.vertex( i, 0, 0, l11 * E1 + a11 * E2 ); amp.vertex( i, 0, 1, l12 * E1 + a12 * E2 ); amp.vertex( i, 1, 0, l21 * E1 + a21 * E2 ); amp.vertex( i, 1, 1, l22 * E1 + a22 * E2 ); } } diff --git a/src/EvtGenModels/EvtbTosllVectorAmpNew.cpp b/src/EvtGenModels/EvtbTosllVectorAmpNew.cpp index 47a1e3a..ccefe64 100644 --- a/src/EvtGenModels/EvtbTosllVectorAmpNew.cpp +++ b/src/EvtGenModels/EvtbTosllVectorAmpNew.cpp @@ -1,872 +1,872 @@ /*********************************************************************** * 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/EvtbTosllVectorAmpNew.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include "EvtGenModels/EvtbTosllAmpNew.hh" #include "EvtGenModels/EvtbTosllFFNew.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include // // The main functiom for the amplitude calculation // // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllFFNew class object; // *WilsCoeff - the pointer to the Standart Model Wilson Coefficients class; // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta // // return: amp - amplitude for the decay B -> V ell^+ ell^- // // Note: in our calculations we assume, that V-meson is the first // daughter particle (iV=0) and leptons are the second and thirds // daughter particles (il1=1 and il2=2). // void EvtbTosllVectorAmpNew::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { // FILE *mytest; EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit int iV = 0; // V-meson is the first daughter particle int il1 = 1, il2 = 2; // leptons are the second and thirds daughter particles // transition momentum of the leptonic pair q=k1+k2 or q=p1-p2 EvtVector4R q = parent->getDaug( il1 )->getP4() + parent->getDaug( il2 )->getP4(); // Mandelstam variable t=q^2 double q2 = q.mass2(); double M1 = parent->mass(); // B - meson mass double M2 = parent->getDaug( iV )->mass(); // V - meson mass double ml = parent->getDaug( il1 )->mass(); // leptonic mass double ms = 0.0; // light quark mass from the dispersion QM double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM // double Mw = EvtPDL::getNominalMass("W+"); // W-boson mass // double mt = EvtPDL::getNominalMass("t"); // t-quark mass double Mw = 80.403; // GeV W-boson mass double mt = 174.2; // GeV t-quark mass EvtComplex Vtb, Vtq, Vub, Vuq; // V_{tb}, V_{tq}, V_{ub} and V_{uq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; EvtId idparent = parent->getId(); // B-meson Id EvtId iddaught = parent->getDaug( iV )->getId(); // The vector meson Id // set of the light quark mass value if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K*+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K*-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K*0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K*0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "phi" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "phi" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K_1+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K_1-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K_10" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K_10" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K'_1+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K'_1-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K'_10" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K'_10" ) ) ) ) { ms = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; } if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "rho+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "rho-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "rho0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "rho0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "omega" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "omega" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K*0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "K*0" ) ) ) ) { ms = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); } if ( ms < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllVectorAmpNew::CalcAmp(...)" << "\n Error in the model set!" << " ms = " << ms << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); double a1, a2, a0, v, t1, t2, t3; // B -> V transition form-factors // To get the B -> V transition form-factors formFactors->getVectorFF( parent->getId(), parent->getDaug( iV )->getId(), q2, a1, a2, a0, v, t1, t2, t3 ); // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) EvtComplex c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); EvtComplex c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c10a = WilsCoeff->GetC10Eff( mt, Mw ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n\n The function EvtbTosllVectorAmpNew::CalcAmp(...) passed." // << "\n Particle masses:" // << "\n B - meson mass M1 = " << M1 // << "\n V - meson mass M2 = " << M2 // << "\n leptonic mass ml = " << ml // << "\n light quark mass = " << ms // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << mb // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ============================================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n resonant switching = " << res_swch // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n ============================================================================" // << "\n Vector form-factors at q^2 = " << q2 // << " for B -> V transition:" // << "\n v = " << v // << "\n a0 = " << a0 // << "\n a1 = " << a1 // << "\n a2 = " << a2 // << "\n t1 = " << t1 // << "\n t2 = " << t2 // << "\n t3 = " << t3 // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Re(c7gam) = " << real(c7gam) << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) << " Im(c10a) = " << imag(c10a) // << std::endl; // mytest = fopen("output.txt","a"); // // if(mytest != NULL){ // fprintf(mytest,"%lf\n",q2); // fclose(mytest); // } // else{ // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n Error in writing to file.\n" // << std::endl; // return; // } // 4- momentum of the B-meson in the the B-meson rest frame EvtVector4R p1 = parent->getP4Restframe(); EvtVector4R hatp1 = p1 / M1; // 4-momentum of the V-meson in the B-meson rest frame EvtVector4R p2 = parent->getDaug( 0 )->getP4(); EvtVector4R hatp2 = p2 / M1; double hats = q2 / pow( M1, 2 ); double hatM2 = M2 / M1; double hatmb = mb / M1; double hatms = ms / M1; // Hadronic matrix element coefficients according to the paper // A. Ali, A. Salim Safir, Eur.Phys.J.C25, pp.583-601 (2002) // with m_s.NE.0 EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, c_b2q, c_barb2barq, e, f, g, h; a_b2q = 2.0 * c9eff_b2q * v / ( 1.0 + hatM2 ) + 4.0 * ( hatmb + hatms ) * c7gam * t1 / hats; a_barb2barq = 2.0 * c9eff_barb2barq * v / ( 1.0 + hatM2 ) + 4.0 * ( hatmb + hatms ) * c7gam * t1 / hats; b_b2q = ( c9eff_b2q * a1 + 2.0 * ( hatmb - hatms ) * ( 1.0 - hatM2 ) * c7gam * t2 / hats ) * ( 1.0 + hatM2 ); b_barb2barq = ( c9eff_barb2barq * a1 + 2.0 * ( hatmb - hatms ) * ( 1.0 - hatM2 ) * c7gam * t2 / hats ) * ( 1.0 + hatM2 ); c_b2q = ( c9eff_b2q * ( 1.0 - hatM2 ) * a2 + 2.0 * ( hatmb - hatms ) * ( 1.0 - pow( hatM2, 2 ) ) * c7gam * t2 / hats + 2.0 * ( hatmb - hatms ) * c7gam * t3 ) / ( 1 - pow( hatM2, 2 ) ); c_barb2barq = ( c9eff_barb2barq * ( 1.0 - hatM2 ) * a2 + 2.0 * ( hatmb - hatms ) * ( 1.0 - pow( hatM2, 2 ) ) * c7gam * t2 / hats + 2.0 * ( hatmb - hatms ) * c7gam * t3 ) / ( 1 - pow( hatM2, 2 ) ); e = 2.0 * c10a * v / ( 1 + hatM2 ); f = ( 1.0 + hatM2 ) * c10a * a1; g = c10a * a2 / ( 1 + hatM2 ); h = ( ( 1.0 + hatM2 ) * a1 - ( 1.0 - hatM2 ) * a2 - 2.0 * hatM2 * a0 ) * c10a / hats; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " a_b2q = " << a_b2q // << " a_barb2barq = " << a_barb2barq // << " b_b2q = " << b_b2q // << " b_barb2barq = " << b_barb2barq // << " c_b2q = " << c_b2q // << " c_barb2barq = " << c_barb2barq // << " e = " << e // << " f = " << f // << " g = " << g // << " h = " << h // << std::endl; // to find ell^+ and ell^- in the B-meson daughters int charge1 = EvtPDL::chg3( parent->getDaug( 1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( 2 )->getId() ); - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; lepPlus = ( charge1 > charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); lepMinus = ( charge1 < charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); EvtTensor4C T1, T2; // hadronic matrix element tensor structures EvtVector4C epsV; // vector meson polarisation vector int i; // vector meson polarisations counter EvtVector4C lvc11, lvc12; // spin structures for EvtVector4C lvc21, lvc22; // the leptonic vector current EvtVector4C lac11, lac12; // spin structures for EvtVector4C lac21, lac22; // the leptonic axial current // B - and barB - mesons descriptors EvtIdSet bmesons( "B-", "anti-B0", "anti-B_s0", "B_c-" ); EvtIdSet bbarmesons( "B+", "B0", "B_s0", "B_c+" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> barV ell^+ ell^- // (b -> q ell^+ ell^- transition) T1 = -a_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - b_b2q * uniti * EvtTensor4C::g() + c_b2q * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ); T2 = -e * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - f * uniti * EvtTensor4C::g() + g * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ) + h * uniti * EvtGenFunctions::directProd( ( hatp1 - hatp2 ), hatp1 ); lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); // summing up vector meson polarisations \epsilon^*_{\nu}(i) for ( i = 0; i < 3; i++ ) { EvtVector4C epsV = parent->getDaug( 0 )->epsParent( i ).conj(); EvtVector4C E1 = M1 * T1.cont2( epsV ); EvtVector4C E2 = M1 * T2.cont2( epsV ); amp.vertex( i, 0, 0, CKM_factor * ( lvc11 * E1 + lac11 * E2 ) ); amp.vertex( i, 0, 1, CKM_factor * ( lvc12 * E1 + lac12 * E2 ) ); amp.vertex( i, 1, 0, CKM_factor * ( lvc21 * E1 + lac21 * E2 ) ); amp.vertex( i, 1, 1, CKM_factor * ( lvc22 * E1 + lac22 * E2 ) ); } } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> V ell^+ ell^- // (barb -> barq ell^+ ell^- transition) T1 = a_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - b_barb2barq * uniti * EvtTensor4C::g() + c_barb2barq * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ); T2 = e * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - f * uniti * EvtTensor4C::g() + g * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ) + h * uniti * EvtGenFunctions::directProd( ( hatp1 - hatp2 ), hatp1 ); lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); // summing up vector meson polarisations \epsilon^*_{\nu}(i) for ( i = 0; i < 3; i++ ) { EvtVector4C barepsV = parent->getDaug( 0 )->epsParent( i ).conj(); EvtVector4C E3 = M1 * T1.cont2( barepsV ); EvtVector4C E4 = M1 * T2.cont2( barepsV ); amp.vertex( i, 0, 0, conj( CKM_factor ) * ( lvc11 * E3 + lac11 * E4 ) ); amp.vertex( i, 0, 1, conj( CKM_factor ) * ( lvc12 * E3 + lac12 * E4 ) ); amp.vertex( i, 1, 0, conj( CKM_factor ) * ( lvc21 * E3 + lac21 * E4 ) ); amp.vertex( i, 1, 1, conj( CKM_factor ) * ( lvc22 * E3 + lac22 * E4 ) ); } } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllVectorAmpNew::CalcAmp(...)" << "\n Wrong B-meson number" << std::endl; ::abort(); } } // Test of the signature for Levi-Civita tensor // EvtVector4C Vec0, Vec1, Vec2, Vec3; // EvtTensor4C Ttest; // Vec0.set(1.0,0.0,0.0,0.0); // Vec1.set(0.0,1.0,0.0,0.0); // Vec2.set(0.0,0.0,1.0,0.0); // Vec3.set(0.0,0.0,0.0,1.0); // Ttest=dual(directProd(Vec2,Vec3)); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n\n\n e^{0123} =" << Ttest.get(0,1) << std::endl; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " e^{1023} =" << Ttest.get(1,0) << std::endl; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " e^{1123} =" << Ttest.get(1,1) << "\n" << std::endl; // EvtVector4C Vtest=Ttest.cont2(Vec1); // for(i=0;i<=3;i++){ // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " Vtest =" << Vtest.get(i) << std::endl; // } // EvtComplex Atest; // Atest=Vec0*Vtest; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n Atest =" << Atest << "\n\n\n" << std::endl; } // // The decays B -> V ell^+ ell^- maximum probability calculation for the // d^2\Gamma/dq^2 d\cos\theta distribution. // // \theta - the angle between the vector meson and ell^- directions in the // B-meson rest frame. // // If ias=0 (nonresonant case), the maximum is achieved at q2=q2_min=4*ml^2. // If ias=1 (resonant case), the maximum is achieved at q2=M^2_{J/\psi}. // double EvtbTosllVectorAmpNew::CalcMaxProb( EvtId parnum, EvtId mesnum, EvtId l1num, EvtId l2num, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { double maxfoundprob = -100.0; // maximum of the probability int katmax = 0; double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass double M2 = EvtPDL::getMeanMass( mesnum ); // V - meson mass double ml = EvtPDL::getMeanMass( l1num ); // leptonic mass if ( res_swch == 0 ) { // B-meson rest frame particles and they kinematics inicialization double s_min, t_for_s; s_min = 4.0 * pow( ml, 2.0 ); t_for_s = 0.5 * ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - 2.0 * pow( ml, 2.0 ) ); double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s_min ) / ( 2.0 * M1 ); // V-meson energy El2 = ( s_min + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the vector meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n cos(theta) = " << cosVellminus << "\n t_for_s = " << t_for_s << "\n s_min = " << s_min << "\n EV = " << EV << "\n El2 = " << El2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s_min = " << s_min << "\n t_for_s = " << t_for_s << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( 1.0 - pow( cosVellminus, 2.0 ) ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s_min = " << s_min // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta ); // Now find the probability at this q2 and cos theta lepton point maxfoundprob = rho.normalizedProb( amp.getSpinDensity() ); delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // if(res_swch==0) if ( res_swch == 1 ) { double s, t_for_s; // Mandelstam variables double t_plus, t_minus; // t-variable boundaries for current s-variable double dt; int k; s = pow( 3.09688, 2.0 ); // s = (M_{J/\psi})^2 t_plus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_minus *= 0.5; dt = ( t_plus - t_minus ) / 1000.0; // The maximum probability calculation for ( k = 0; k <= 1000; k++ ) { t_for_s = t_plus - dt * ( (double)k ); if ( ( t_for_s < t_minus ) && ( t_for_s >= ( 0.9999 * t_minus ) ) ) { t_for_s = t_minus; } if ( t_for_s < ( 0.9999 * t_minus ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n t_for_s = " << t_for_s << " < t_minus = " << t_minus << " ! " << "\n t_plus = " << t_plus << "\n dt = " << dt << "\n k = " << k << "\n s = " << s << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // B-meson rest frame particles and they kinematics inicialization double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s ) / ( 2.0 * M1 ); // V-meson energy El2 = ( s + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the vector meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n cos(theta) = " << cosVellminus << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( 1.0 - pow( cosVellminus, 2.0 ) ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; katmax = k; EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " << maxfoundprob << "\n k =" << katmax << std::endl; } delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // for(k=0; k<=1000; k++) } // if(res_swch==1) if ( maxfoundprob <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob (...) = " << maxfoundprob << std::endl; maxfoundprob *= 1.01; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ***************************************************************************" // << "\n The function EvtbTosllVectorAmpNew::CalcMaxProb(...) passed with arguments:" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n The distribution maximum maxfoundprob =" << maxfoundprob // << "\n k = " << katmax // << "\n ***************************************************************************" // << std::endl; return maxfoundprob; } // Triangular function double EvtbTosllVectorAmpNew::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/EvtbTosllVectorAmpNewExt.cpp b/src/EvtGenModels/EvtbTosllVectorAmpNewExt.cpp index 200e24b..650278e 100644 --- a/src/EvtGenModels/EvtbTosllVectorAmpNewExt.cpp +++ b/src/EvtGenModels/EvtbTosllVectorAmpNewExt.cpp @@ -1,882 +1,882 @@ /*********************************************************************** * 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/EvtbTosllVectorAmpNewExt.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include "EvtGenModels/EvtbTosllAmpNewExt.hh" #include "EvtGenModels/EvtbTosllFFNew.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include // // The main functiom for the amplitude calculation // // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllFFNew class object; // *WilsCoeff - the pointer to the Standart Model Wilson Coefficients class; // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta // Multiplication coefficients // A7 = ReA7 + i*ImA7 // A10 = ReA10 + i*ImA10 // // return: amp - amplitude for the decay B -> V ell^+ ell^- // // Note: in our calculations we assume, that V-meson is the first // daughter particle (iV=0) and leptons are the second and thirds // daughter particles (il1=1 and il2=2). // void EvtbTosllVectorAmpNewExt::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta, double ReA7, double ImA7, double ReA10, double ImA10 ) { // FILE *mytest; EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit EvtComplex A7 = ReA7 * unit1 + ImA7 * uniti; EvtComplex A10 = ReA10 * unit1 + ImA10 * uniti; int iV = 0; // V-meson is the first daughter particle int il1 = 1, il2 = 2; // leptons are the second and thirds daughter particles // transition momentum of the leptonic pair q=k1+k2 or q=p1-p2 EvtVector4R q = parent->getDaug( il1 )->getP4() + parent->getDaug( il2 )->getP4(); // Mandelstam variable t=q^2 double q2 = q.mass2(); double M1 = parent->mass(); // B - meson mass double M2 = parent->getDaug( iV )->mass(); // V - meson mass double ml = parent->getDaug( il1 )->mass(); // leptonic mass double ms = 0.0; // light quark mass from the dispersion QM double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM // double Mw = EvtPDL::getNominalMass("W+"); // W-boson mass // double mt = EvtPDL::getNominalMass("t"); // t-quark mass double Mw = 80.403; // GeV W-boson mass double mt = 174.2; // GeV t-quark mass EvtComplex Vtb, Vtq, Vub, Vuq; // V_{tb}, V_{tq}, V_{ub} and V_{uq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; EvtId idparent = parent->getId(); // B-meson Id EvtId iddaught = parent->getDaug( iV )->getId(); // The vector meson Id // set of the light quark mass value if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K*+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K*-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K*0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K*0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "phi" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "phi" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K_1+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K_1-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K_10" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K_10" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "K'_1+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "K'_1-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "K'_10" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K'_10" ) ) ) ) { ms = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; } if ( ( idparent == EvtPDL::getId( std::string( "B+" ) ) && iddaught == EvtPDL::getId( std::string( "rho+" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B-" ) ) && iddaught == EvtPDL::getId( std::string( "rho-" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "rho0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "rho0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B0" ) ) && iddaught == EvtPDL::getId( std::string( "omega" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) && iddaught == EvtPDL::getId( std::string( "omega" ) ) ) || ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "anti-K*0" ) ) ) || ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && iddaught == EvtPDL::getId( std::string( "K*0" ) ) ) ) { ms = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); } if ( ms < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllVectorAmpNew::CalcAmp(...)" << "\n Error in the model set!" << " ms = " << ms << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); double a1, a2, a0, v, t1, t2, t3; // B -> V transition form-factors // To get the B -> V transition form-factors formFactors->getVectorFF( parent->getId(), parent->getDaug( iV )->getId(), q2, a1, a2, a0, v, t1, t2, t3 ); // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) EvtComplex c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); c7gam = c7gam * A7; EvtComplex c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, ms, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); EvtComplex c10a = WilsCoeff->GetC10Eff( mt, Mw ); c10a = c10a * A10; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n\n The function EvtbTosllVectorAmpNew::CalcAmp(...) passed." // << "\n Particle masses:" // << "\n B - meson mass M1 = " << M1 // << "\n V - meson mass M2 = " << M2 // << "\n leptonic mass ml = " << ml // << "\n light quark mass = " << ms // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << mb // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ============================================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n resonant switching = " << res_swch // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n ============================================================================" // << "\n Vector form-factors at q^2 = " << q2 // << " for B -> V transition:" // << "\n v = " << v // << "\n a0 = " << a0 // << "\n a1 = " << a1 // << "\n a2 = " << a2 // << "\n t1 = " << t1 // << "\n t2 = " << t2 // << "\n t3 = " << t3 // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Re(c7gam) = " << real(c7gam) << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) << " Im(c10a) = " << imag(c10a) // << std::endl; // mytest = fopen("output.txt","a"); // // if(mytest != NULL){ // fprintf(mytest,"%lf\n",q2); // fclose(mytest); // } // else{ // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n Error in writing to file.\n" // << std::endl; // return; // } // 4- momentum of the B-meson in the the B-meson rest frame EvtVector4R p1 = parent->getP4Restframe(); EvtVector4R hatp1 = p1 / M1; // 4-momentum of the V-meson in the B-meson rest frame EvtVector4R p2 = parent->getDaug( 0 )->getP4(); EvtVector4R hatp2 = p2 / M1; double hats = q2 / pow( M1, 2 ); double hatM2 = M2 / M1; double hatmb = mb / M1; double hatms = ms / M1; // Hadronic matrix element coefficients according to the paper // A. Ali, A. Salim Safir, Eur.Phys.J.C25, pp.583-601 (2002) // with m_s.NE.0 EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, c_b2q, c_barb2barq, e, f, g, h; a_b2q = 2.0 * c9eff_b2q * v / ( 1.0 + hatM2 ) + 4.0 * ( hatmb + hatms ) * c7gam * t1 / hats; a_barb2barq = 2.0 * c9eff_barb2barq * v / ( 1.0 + hatM2 ) + 4.0 * ( hatmb + hatms ) * c7gam * t1 / hats; b_b2q = ( c9eff_b2q * a1 + 2.0 * ( hatmb - hatms ) * ( 1.0 - hatM2 ) * c7gam * t2 / hats ) * ( 1.0 + hatM2 ); b_barb2barq = ( c9eff_barb2barq * a1 + 2.0 * ( hatmb - hatms ) * ( 1.0 - hatM2 ) * c7gam * t2 / hats ) * ( 1.0 + hatM2 ); c_b2q = ( c9eff_b2q * ( 1.0 - hatM2 ) * a2 + 2.0 * ( hatmb - hatms ) * ( 1.0 - pow( hatM2, 2 ) ) * c7gam * t2 / hats + 2.0 * ( hatmb - hatms ) * c7gam * t3 ) / ( 1 - pow( hatM2, 2 ) ); c_barb2barq = ( c9eff_barb2barq * ( 1.0 - hatM2 ) * a2 + 2.0 * ( hatmb - hatms ) * ( 1.0 - pow( hatM2, 2 ) ) * c7gam * t2 / hats + 2.0 * ( hatmb - hatms ) * c7gam * t3 ) / ( 1 - pow( hatM2, 2 ) ); e = 2.0 * c10a * v / ( 1 + hatM2 ); f = ( 1.0 + hatM2 ) * c10a * a1; g = c10a * a2 / ( 1 + hatM2 ); h = ( ( 1.0 + hatM2 ) * a1 - ( 1.0 - hatM2 ) * a2 - 2.0 * hatM2 * a0 ) * c10a / hats; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " a_b2q = " << a_b2q // << " a_barb2barq = " << a_barb2barq // << " b_b2q = " << b_b2q // << " b_barb2barq = " << b_barb2barq // << " c_b2q = " << c_b2q // << " c_barb2barq = " << c_barb2barq // << " e = " << e // << " f = " << f // << " g = " << g // << " h = " << h // << std::endl; // to find ell^+ and ell^- in the B-meson daughters int charge1 = EvtPDL::chg3( parent->getDaug( 1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( 2 )->getId() ); - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; lepPlus = ( charge1 > charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); lepMinus = ( charge1 < charge2 ) ? parent->getDaug( 1 ) : parent->getDaug( 2 ); EvtTensor4C T1, T2; // hadronic matrix element tensor structures EvtVector4C epsV; // vector meson polarisation vector int i; // vector meson polarisations counter EvtVector4C lvc11, lvc12; // spin structures for EvtVector4C lvc21, lvc22; // the leptonic vector current EvtVector4C lac11, lac12; // spin structures for EvtVector4C lac21, lac22; // the leptonic axial current // B - and barB - mesons descriptors EvtIdSet bmesons( "B-", "anti-B0", "anti-B_s0", "B_c-" ); EvtIdSet bbarmesons( "B+", "B0", "B_s0", "B_c+" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> barV ell^+ ell^- // (b -> q ell^+ ell^- transition) T1 = -a_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - b_b2q * uniti * EvtTensor4C::g() + c_b2q * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ); T2 = -e * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - f * uniti * EvtTensor4C::g() + g * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ) + h * uniti * EvtGenFunctions::directProd( ( hatp1 - hatp2 ), hatp1 ); lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); // summing up vector meson polarisations \epsilon^*_{\nu}(i) for ( i = 0; i < 3; i++ ) { EvtVector4C epsV = parent->getDaug( 0 )->epsParent( i ).conj(); EvtVector4C E1 = M1 * T1.cont2( epsV ); EvtVector4C E2 = M1 * T2.cont2( epsV ); amp.vertex( i, 0, 0, CKM_factor * ( lvc11 * E1 + lac11 * E2 ) ); amp.vertex( i, 0, 1, CKM_factor * ( lvc12 * E1 + lac12 * E2 ) ); amp.vertex( i, 1, 0, CKM_factor * ( lvc21 * E1 + lac21 * E2 ) ); amp.vertex( i, 1, 1, CKM_factor * ( lvc22 * E1 + lac22 * E2 ) ); } } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> V ell^+ ell^- // (barb -> barq ell^+ ell^- transition) T1 = a_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - b_barb2barq * uniti * EvtTensor4C::g() + c_barb2barq * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ); T2 = e * unit1 * dual( EvtGenFunctions::directProd( hatp1, hatp2 ) ) - f * uniti * EvtTensor4C::g() + g * uniti * EvtGenFunctions::directProd( ( hatp1 + hatp2 ), hatp1 ) + h * uniti * EvtGenFunctions::directProd( ( hatp1 - hatp2 ), hatp1 ); lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); // summing up vector meson polarisations \epsilon^*_{\nu}(i) for ( i = 0; i < 3; i++ ) { EvtVector4C barepsV = parent->getDaug( 0 )->epsParent( i ).conj(); EvtVector4C E3 = M1 * T1.cont2( barepsV ); EvtVector4C E4 = M1 * T2.cont2( barepsV ); amp.vertex( i, 0, 0, conj( CKM_factor ) * ( lvc11 * E3 + lac11 * E4 ) ); amp.vertex( i, 0, 1, conj( CKM_factor ) * ( lvc12 * E3 + lac12 * E4 ) ); amp.vertex( i, 1, 0, conj( CKM_factor ) * ( lvc21 * E3 + lac21 * E4 ) ); amp.vertex( i, 1, 1, conj( CKM_factor ) * ( lvc22 * E3 + lac22 * E4 ) ); } } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbTosllVectorAmpNew::CalcAmp(...)" << "\n Wrong B-meson number" << std::endl; ::abort(); } } // Test of the signature for Levi-Civita tensor // EvtVector4C Vec0, Vec1, Vec2, Vec3; // EvtTensor4C Ttest; // Vec0.set(1.0,0.0,0.0,0.0); // Vec1.set(0.0,1.0,0.0,0.0); // Vec2.set(0.0,0.0,1.0,0.0); // Vec3.set(0.0,0.0,0.0,1.0); // Ttest=dual(directProd(Vec2,Vec3)); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n\n\n e^{0123} =" << Ttest.get(0,1) << std::endl; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " e^{1023} =" << Ttest.get(1,0) << std::endl; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " e^{1123} =" << Ttest.get(1,1) << "\n" << std::endl; // EvtVector4C Vtest=Ttest.cont2(Vec1); // for(i=0;i<=3;i++){ // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << " Vtest =" << Vtest.get(i) << std::endl; // } // EvtComplex Atest; // Atest=Vec0*Vtest; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n Atest =" << Atest << "\n\n\n" << std::endl; } // // The decays B -> V ell^+ ell^- maximum probability calculation for the // d^2\Gamma/dq^2 d\cos\theta distribution. // // \theta - the angle between the vector meson and ell^- directions in the // B-meson rest frame. // // If ias=0 (nonresonant case), the maximum is achieved at q2=q2_min=4*ml^2. // If ias=1 (resonant case), the maximum is achieved at q2=M^2_{J/\psi}. // double EvtbTosllVectorAmpNewExt::CalcMaxProb( EvtId parnum, EvtId mesnum, EvtId l1num, EvtId l2num, EvtbTosllFFNew* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta, double ReA7, double ImA7, double ReA10, double ImA10 ) { double maxfoundprob = -100.0; // maximum of the probability int katmax = 0; double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass double M2 = EvtPDL::getMeanMass( mesnum ); // V - meson mass double ml = EvtPDL::getMeanMass( l1num ); // leptonic mass if ( res_swch == 0 ) { // B-meson rest frame particles and they kinematics inicialization double s_min, t_for_s; s_min = 4.0 * pow( ml, 2.0 ); t_for_s = 0.5 * ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - 2.0 * pow( ml, 2.0 ) ); double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s_min ) / ( 2.0 * M1 ); // V-meson energy El2 = ( s_min + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the vector meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n cos(theta) = " << cosVellminus << "\n t_for_s = " << t_for_s << "\n s_min = " << s_min << "\n EV = " << EV << "\n El2 = " << El2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s_min = " << s_min << "\n t_for_s = " << t_for_s << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( 1.0 - pow( cosVellminus, 2.0 ) ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s_min = " << s_min // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta, ReA7, ImA7, ReA10, ImA10 ); // Now find the probability at this q2 and cos theta lepton point maxfoundprob = rho.normalizedProb( amp.getSpinDensity() ); delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // if(res_swch==0) if ( res_swch == 1 ) { double s, t_for_s; // Mandelstam variables double t_plus, t_minus; // t-variable boundaries for current s-variable double dt; int k; s = pow( 3.09688, 2.0 ); // s = (M_{J/\psi})^2 t_plus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + pow( M2, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * sqrt( lambda( s, pow( M1, 2.0 ), pow( M2, 2.0 ) ) ); t_minus *= 0.5; dt = ( t_plus - t_minus ) / 1000.0; // The maximum probability calculation for ( k = 0; k <= 1000; k++ ) { t_for_s = t_plus - dt * ( (double)k ); if ( ( t_for_s < t_minus ) && ( t_for_s >= ( 0.9999 * t_minus ) ) ) { t_for_s = t_minus; } if ( t_for_s < ( 0.9999 * t_minus ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n t_for_s = " << t_for_s << " < t_minus = " << t_minus << " ! " << "\n t_plus = " << t_plus << "\n dt = " << dt << "\n k = " << k << "\n s = " << s << "\n M1 = " << M1 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } // B-meson rest frame particles and they kinematics inicialization double EV, El2; EV = ( pow( M1, 2.0 ) + pow( M2, 2.0 ) - s ) / ( 2.0 * M1 ); // V-meson energy El2 = ( s + t_for_s - pow( M2, 2.0 ) - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modV, modl2; modV = sqrt( pow( EV, 2.0 ) - pow( M2, 2.0 ) ); modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosVellminus; // angle between the vector meson and ell^- directions cosVellminus = ( pow( M2, 2.0 ) + pow( ml, 2.0 ) + 2.0 * EV * El2 - t_for_s ) / ( 2.0 * modV * modl2 ); if ( ( fabs( cosVellminus ) > 1.0 ) && ( fabs( cosVellminus ) <= 1.0001 ) ) { // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n cos(theta) = " << cosVellminus // << std::endl; cosVellminus = cosVellminus / fabs( cosVellminus ); } if ( ( modV <= 0.000001 ) || ( modl2 <= 0.000001 ) ) { cosVellminus = cosVellminus / fabs( cosVellminus ); EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n cos(theta) = " << cosVellminus << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n EV = " << EV << "\n El2 = " << El2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; } if ( fabs( cosVellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosVellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n EV = " << EV << "\n El2 = " << El2 << "\n modV = " << modV << "\n modl2 = " << modl2 << "\n M2 = " << M2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p1, p2, k1, k2; p1.set( M1, 0.0, 0.0, 0.0 ); p2.set( EV, modV, 0.0, 0.0 ); k2.set( El2, modl2 * cosVellminus, -modl2 * sqrt( 1.0 - pow( cosVellminus, 2.0 ) ), 0.0 ); k1 = p1 - p2 - k2; // EvtGenReport(EVTGEN_DEBUG,"EvtGen") // << "\n Debug in the function EvtbTosllVectorAmpNew::CalcMaxProb(...):" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n M1 = " << M1 // << "\n M2 = " << M2 // << "\n ml = " << ml // << "\n s = " << s // << "\n t_for_s = " << t_for_s // << "\n EV = " << EV // << "\n El1 = " << El1 // << "\n El2 = " << El2 // << "\n modV = " << modV // << "\n modl1 = " << modl1 // << "\n modl2 = " << modl2 // << "\n cos(theta) = " << cosVellminus // << "\n p1 =" << p1 // << "\n p2 =" << p2 // << "\n k1 =" << k1 // << "\n k2 =" << k2 // << std::endl; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p1 ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = mesnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *vect, *lep1, *lep2; vect = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); vect->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); vect->init( mesnum, p2 ); lep1->init( l1num, k1 ); lep2->init( l2num, k2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta, ReA7, ImA7, ReA10, ImA10 ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; katmax = k; EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " << maxfoundprob << "\n k =" << katmax << std::endl; } delete scalar_part; // delete root_part; delete vect; delete lep1; delete lep2; } // for(k=0; k<=1000; k++) } // if(res_swch==1) if ( maxfoundprob <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbTosllVectorAmpNew::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob (...) = " << maxfoundprob << std::endl; maxfoundprob *= 1.01; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ***************************************************************************" // << "\n The function EvtbTosllVectorAmpNew::CalcMaxProb(...) passed with arguments:" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n The distribution maximum maxfoundprob =" << maxfoundprob // << "\n k = " << katmax // << "\n ***************************************************************************" // << std::endl; return maxfoundprob; } // Triangular function double EvtbTosllVectorAmpNewExt::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/Evtbs2llGammaAmp.cpp b/src/EvtGenModels/Evtbs2llGammaAmp.cpp index b95923a..8ea28c9 100644 --- a/src/EvtGenModels/Evtbs2llGammaAmp.cpp +++ b/src/EvtGenModels/Evtbs2llGammaAmp.cpp @@ -1,856 +1,856 @@ /*********************************************************************** * 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/Evtbs2llGammaAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include "EvtGenModels/Evtbs2llGammaFFMNT.hh" #include // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllGammaFF class object; // *WilsCoeff - the pointer to the Standart Model Wilson Coefficients class; // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Egamma_min - photon energy cut, GeV; // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta void Evtbs2llGammaAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, Evtbs2llGammaFF* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double Egamma_min, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { // FILE *mytest; int iG = 0; // photon is the first daughter particle int il1 = 1, il2 = 2; // leptons are the second and thirds daughter particles EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit double M1 = parent->mass(); // B - meson mass, GeV double ml = parent->getDaug( il1 )->mass(); // leptonic mass, GeV double mq = 0.0; // light quark mass from the dispersion QM, GeV double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM, GeV double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM, GeV double Mw = 80.403; // GeV W-boson mass, GeV double mt = 174.2; // GeV t-quark mass, GeV double fb = 0.0; // leptonic decay constant of B-meson, Gev EvtComplex Vtb, Vtq, Vub, Vuq, Vcb, Vcq; // V_{tb}, V_{tq}, V_{ub}, V_{uq}, V_{cb}, V_{cq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qc; // V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; // to find charges of ell^+ and ell^- in the B-meson daughters int charge1 = EvtPDL::chg3( parent->getDaug( il1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( il2 )->getId() ); if ( charge1 == 0 || charge2 == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsTollGammaAmp::CalcAmp(...)" << "\n Error in the leptonic charge getting!" << "\n charge1 =" << charge1 << "\n charge2 =" << charge2 << "\n charge gamma =" << EvtPDL::chg3( parent->getDaug( iG )->getId() ) << "\n number of daughters =" << parent->getNDaug() << std::endl; ::abort(); } - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; lepPlus = ( charge1 > charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); // positive charged lepMinus = ( charge1 < charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); // negative charged EvtVector4R p = parent->getP4Restframe(); // B-meson momentum in the B-rest frame EvtVector4R k = parent->getDaug( iG )->getP4(); // 4-momentum of photon in the B-rest frame EvtVector4R q = p - k; // transition 4-momentum q=p-k in the B-rest frame EvtVector4R p_1; // 4-momentum of ell^+ in the B-rest frame EvtVector4R p_2; // 4-momentum of ell^- in the B-rest frame // the preparation of the leptonic 4-momentums in the B-rest frame if ( charge1 > charge2 ) { p_1 = parent->getDaug( il1 )->getP4(); p_2 = parent->getDaug( il2 )->getP4(); } else { p_1 = parent->getDaug( il2 )->getP4(); p_2 = parent->getDaug( il1 )->getP4(); } EvtVector4R p_minus_p_1 = p - p_1; // transition momentum of the B-meson and antilepton p-p_1 EvtVector4R p_minus_p_2 = p - p_2; // transition momentum of the B-meson and lepton p-p_2 double q2 = q.mass2(); // Mandelstam variable s=q^2 double p2 = p.mass2(); // p^2=M1^2 double t = p_minus_p_1.mass2(); // Mandelstam variable t=(p-p_1)^2 double u = p_minus_p_2.mass2(); // Mandelstam variable u=(p-p_2)^2 // scalar products double pk = 0.5 * ( p2 - q2 ); // (p*k) double p1k = 0.5 * ( pow( ml, 2.0 ) - u ); // (p1*k) double p2k = 0.5 * ( pow( ml, 2.0 ) - t ); // (p2*k) double hatq2 = q2 / ( M1 * M1 ); // \hat s = q^2/M_1^2 double Egam = 0.5 * M1 * ( 1 - hatq2 ); // photon energy in the B-meson rest frame EvtVector4R hatp = p / M1; EvtVector4R hatk = k / M1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n\n The function EvtbsTollGammaAmp::CalcAmp(...)" // << "\n q = p-k =" << p-k << " q^2 = " << (p-k).mass2() // << "\n q = p1+p2 =" << p_1+p_2 << " q^2 = " << (p_1+p_2).mass2() // << "\n m_ell =" << parent->getDaug(il1)->mass() // << "\n m_ell =" << parent->getDaug(il2)->mass() // << "\n m_gamma =" << parent->getDaug(iG)->mass() // << std::endl; EvtId idparent = parent->getId(); // B-meson Id if ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) || idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) ) { mq = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM fb = 0.24; // leptonic decay constant // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; // V_{cs} Vcq = unit1 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) * ( 1.0 + 4.0 * pow( CKM_A, 2.0 ) ); } if ( idparent == EvtPDL::getId( std::string( "B0" ) ) || idparent == EvtPDL::getId( std::string( "anti-B0" ) ) ) { mq = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM fb = 0.20; // leptonic decay constant // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); // V_{cd} Vcq = unit1 * ( -CKM_lambda + 0.5 * pow( CKM_A, 2.0 ) * pow( CKM_lambda, 5.0 ) * ( 1.0 - 2.0 * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ) ) ); } if ( mq < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsTollGammaAmp::CalcAmp(..// 4-momentum of ell^+.)" << "\n Error in the model set!" << " mq = " << mq << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} Vcb = unit1 * CKM_A * pow( CKM_lambda, 2.0 ); // V_{cb} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); lambda_qc = conj( Vcq ) * Vcb / CKM_factor; // V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb} // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) double c1, c2; EvtComplex a1, c7gam, c9eff_b2q, c9eff_barb2barq, c10a; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) ) { c1 = 0.0; c2 = 0.0; a1 = unit1 * 0.0; c7gam = unit1 * 0.0; c9eff_b2q = unit1 * 0.0; c9eff_barb2barq = unit1 * 0.0; c10a = unit1 * 0.0; } else { c1 = WilsCoeff->C1( mu, Mw, Nf, ias ); c2 = WilsCoeff->C2( mu, Mw, Nf, ias ); a1 = unit1 * ( c1 + c2 / 3.0 ); c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c10a = WilsCoeff->GetC10Eff( mt, Mw ); } EvtComplex Fv, Fa; // The change of the sign is included in the amplitudes definition! EvtComplex Ftv_b2q, Ftv_barb2barq; EvtComplex Fta_b2q, Fta_barb2barq; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) ) { fb = 0.0; Fa = unit1 * 0.0; Fv = unit1 * 0.0; Fta_b2q = unit1 * 0.0; Fta_barb2barq = unit1 * 0.0; Ftv_b2q = unit1 * 0.0; Ftv_barb2barq = unit1 * 0.0; } else { if ( fb < 0.01 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsTollGammaAmp::CalcAmp(...)" << "\n Leptonic decay constant fb is not uninitialized in this function!" << " fb = " << fb << std::endl; ::abort(); } // For \bar B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 0, fb, parent->getId(), q2, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_b2q, Fta_b2q ); // For B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 1, fb, parent->getId(), q2, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_barb2barq, Fta_barb2barq ); } // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ============================================================================" // << "\n ============================================================================" // << "\n\n The function Evtbs2llGammaAmp::CalcAmp(...) passed." // << "\n Particle masses:" // << "\n B - meson mass M1 = " << M1 // << "\n photon minimum E = " << Egamma_min // << "\n q2 = " << q2 // << "\n leptonic mass ml = " << ml // << "\n light quark mass = " << mq // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << mb // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ============================================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n resonant switching = " << res_swch // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n photon energy cut (GeV) = " << Egamma_min // << "\n ============================================================================" // << "\n Form-factors" // << "\n Egam = " << Egam // << "\n Egamma_min = " << Egamma_min // << "\n Fv = " << Fv // << "\n Fa = " << Fa // << "\n Ftv_b2q = " << Ftv_b2q // << "\n Fta_b2q = " << Fta_b2q // << "\n Ftv_barb2barq = " << Ftv_barb2barq // << "\n Fta_barb2barq = " << Fta_barb2barq // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Egam = " << Egam // << "\n Egamma_min = " << Egamma_min // << "\n Re(c7gam) = " << real(c7gam) // << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) // << " Im(c10a) = " << imag(c10a) // << std::endl; // Hadronic matrix element coefficients EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, e_b2q, e_barb2barq, f_b2q, f_barb2barq; EvtComplex brammS, brammT; a_b2q = c9eff_b2q * Fv + 2.0 * c7gam * Ftv_b2q * mb * M1 / q2; a_barb2barq = c9eff_barb2barq * Fv + 2.0 * c7gam * Ftv_barb2barq * mb * M1 / q2; b_b2q = ( c9eff_b2q * Fa + 2.0 * c7gam * Fta_b2q * mb * M1 / q2 ) * pk / ( M1 * M1 ); b_barb2barq = ( c9eff_barb2barq * Fa + 2.0 * c7gam * Fta_barb2barq * mb * M1 / q2 ) * pk / ( M1 * M1 ); e_b2q = c10a * Fv; e_barb2barq = e_b2q; f_b2q = c10a * Fa * pk / ( M1 * M1 ); f_barb2barq = f_b2q; brammS = 0.0; // in the Bq-meson rest frame! brammT = 0.5 * c10a * ml * fb * ( 1.0 / p2k + 1.0 / p1k ); // for Bramsstrahlung EvtTensor4C T1, T2; // hadronic matrix element tensor structures EvtVector4C E1, E2; EvtComplex E3; EvtVector4C epsG; // photon polarisation vector int i; // photon polarisations counter EvtVector4C lvc11, lvc12; // spin structures for EvtVector4C lvc21, lvc22; // the leptonic vector current EvtVector4C lac11, lac12; // spin structures for EvtVector4C lac21, lac22; // the leptonic axial current EvtComplex lsc11, lsc12; // spin structures for EvtComplex lsc21, lsc22; // the leptonic scalar current EvtTensor4C ltc11, ltc12; // spin structures for EvtTensor4C ltc21, ltc22; // the leptonic tensor current // B - and barB - mesons descriptors static EvtIdSet bmesons( "anti-B0", "anti-B_s0" ); static EvtIdSet bbarmesons( "B0", "B_s0" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> gamma ell^+ ell^- or // b \bar q -> gamma ell^+ ell^- T1 = -a_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) - b_b2q * uniti * EvtTensor4C::g(); T2 = -e_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) - f_b2q * uniti * EvtTensor4C::g(); // spin combinations for vector lepton current lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lsc11 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lsc21 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lsc12 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lsc22 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); // \epsilon^{\alpha\beta\mu\nu}*TCurrent_{\mu\nu} ltc11 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ) ); ltc21 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ) ); ltc12 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ) ); ltc22 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ) ); // summing up photon polarisations for ( i = 0; i < 2; i++ ) { // conjaction of epsG (photon polarization vector) EvtVector4C epsG = parent->getDaug( 0 )->epsParentPhoton( i ).conj(); // de-escalation T with epsG E1 = T1.cont2( epsG ); E2 = T2.cont2( epsG ); E3 = ( epsG * hatp ) * brammS; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) ) { CKM_factor = 0.0 * unit1; } // 1 amp.vertex( i, 0, 0, CKM_factor * ( lvc11 * E1 + lac11 * E2 + uniti * lsc11 * E3 + uniti * ( ( ltc11.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 1" << CKM_factor*(lvc11*E1+lac11*E2+uniti*lsc11*E3+uniti*((ltc11.cont2(hatp))*epsG)*brammT) // << std::endl; // 2 amp.vertex( i, 0, 1, CKM_factor * ( lvc12 * E1 + lac12 * E2 + uniti * lsc12 * E3 + uniti * ( ( ltc12.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 2" << CKM_factor*(lvc12*E1+lac12*E2+uniti*lsc12*E3+uniti*((ltc12.cont2(hatp))*epsG)*brammT) // << std::endl; // 3 amp.vertex( i, 1, 0, CKM_factor * ( lvc21 * E1 + lac21 * E2 + uniti * lsc21 * E3 + uniti * ( ( ltc21.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 3" << CKM_factor*(lvc21*E1+lac21*E2+uniti*lsc21*E3+uniti*((ltc21.cont2(hatp))*epsG)*brammT) // << std::endl; // 4 amp.vertex( i, 1, 1, CKM_factor * ( lvc22 * E1 + lac22 * E2 + uniti * lsc22 * E3 + uniti * ( ( ltc22.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 4" << CKM_factor*(lvc22*E1+lac22*E2+uniti*lsc22*E3+uniti*((ltc22.cont2(hatp))*epsG)*brammT) // << std::endl; } } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> gamma ell^+ ell^- or // q bar b -> gamma ell^+ ell^- T1 = -a_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) + b_barb2barq * uniti * EvtTensor4C::g(); T2 = -e_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) + f_barb2barq * uniti * EvtTensor4C::g(); lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lsc11 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lsc21 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lsc12 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lsc22 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); // \epsilon^{\alpha\beta\mu\nu}*TCurrent_{\mu\nu} ltc11 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ) ); ltc21 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ) ); ltc12 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ) ); ltc22 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ) ); // summing up photon polarisations for ( i = 0; i < 2; i++ ) { EvtVector4C barepsG = parent->getDaug( 0 )->epsParentPhoton( i ); E1 = T1.cont2( barepsG ); E2 = T2.cont2( barepsG ); E3 = ( barepsG * hatp ) * brammS; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) ) { CKM_factor = 0.0 * unit1; } amp.vertex( i, 1, 1, conj( CKM_factor ) * ( lvc11 * E1 + lac11 * E2 + uniti * lsc11 * E3 + // -? uniti * ( ( ltc11.cont2( hatp ) ) * epsG ) * brammT ) ); amp.vertex( i, 1, 0, conj( CKM_factor ) * ( lvc12 * E1 + lac12 * E2 + uniti * lsc12 * E3 + // -? uniti * ( ( ltc12.cont2( hatp ) ) * epsG ) * brammT ) ); amp.vertex( i, 0, 1, conj( CKM_factor ) * ( lvc21 * E1 + lac21 * E2 + uniti * lsc21 * E3 + // -? uniti * ( ( ltc21.cont2( hatp ) ) * epsG ) * brammT ) ); amp.vertex( i, 0, 0, conj( CKM_factor ) * ( lvc22 * E1 + lac22 * E2 + uniti * lsc22 * E3 + // -? uniti * ( ( ltc22.cont2( hatp ) ) * epsG ) * brammT ) ); } } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function Evtbs2llGammaAmp::CalcAmp(...)" << "\n Wrong B-meson number" << std::endl; ::abort(); } } } // // The decays B -> Gamma ell^+ ell^- maximum probability calculation for the // d^2\Gamma/dq^2 d\cos\theta distribution. // // \theta - the angle between the photon and ell^- directions in the // B-meson rest frame. // // If ias=0 (nonresonant case), the maximum is achieved at q2 // B0s: q2 = 4*ml^2, Mphi^2, q_max^2; // B0d: q2 = 4*ml^2, Mrho^2, Momega^2, q_max^2; // If ias=1 (resonant case), the maximum in the same points, because the // resonat area is remove // double Evtbs2llGammaAmp::CalcMaxProb( EvtId parnum, EvtId photnum, EvtId l1num, EvtId l2num, Evtbs2llGammaFF* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double Egamma_min, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { double maxfoundprob = -100.0; // maximum of the probability // int ijk_atmax = 1000000; double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass double ml = EvtPDL::getMeanMass( l1num ); // leptonic mass double Mrho = EvtPDL::getMeanMass( EvtPDL::getId( std::string( "rho0" ) ) ); // mass of the rho-meson, MeV double Momega = EvtPDL::getMeanMass( EvtPDL::getId( std::string( "omega" ) ) ); // mass of the omega-meson, MeV double Mphi = EvtPDL::getMeanMass( EvtPDL::getId( std::string( "phi" ) ) ); // mass of the phi-meson, MeV // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n M1 = " << M1 // << "\n ml = " << ml // << "\n Mrho = " << Mrho // << "\n Momega = " << Momega // << "\n Mphi = " << Mphi // << "\n Egamma_min = " << Egamma_min // << std::endl; double list_of_max_q2_points[5]; list_of_max_q2_points[0] = pow( 2.0 * ml, 2.0 ); list_of_max_q2_points[1] = pow( Mrho, 2.0 ); list_of_max_q2_points[2] = pow( Momega, 2.0 ); list_of_max_q2_points[3] = pow( Mphi, 2.0 ); list_of_max_q2_points[4] = pow( M1, 2.0 ) - 2.0 * M1 * Egamma_min; // q^2_max at photon energy cut // if(list_of_max_points[4]<0){ // EvtGenReport(EVTGEN_ERROR,"EvtGen") // << "\n\n In the function EvtbsTollGammaAmp::CalcScalarMaxProb(...)" // << "\n Bad photon energy cut: Egamma_min > M1 in the rest frame of B-meson!" // << "\n q2_max = " << list_of_max_points[4] // << "\n M1 = " << M1 // << "\n Egamma_min = " << Egamma_min // << std::endl; // ::abort(); // } if ( Egamma_min > Mrho ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollGammaAmp::CalcScalarMaxProb(...)" << "\n Bad photon energy cut: Egamma_min > M_rho0 in the rest frame of B-meson." << "\n Mrho = " << Mrho << "\n Egamma_min = " << Egamma_min << std::endl; ::abort(); } if ( Egamma_min <= 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollGammaAmp::CalcScalarMaxProb(...)" << "\n Bad photon energy cut: Egamma_min <= 0 in the rest frame of B-meson." << "\n Egamma_min = " << Egamma_min << std::endl; ::abort(); } if ( res_swch == 0 || res_swch == 1 ) { int i_list; for ( i_list = 0; i_list <= 4; i_list++ ) { double s; // mandelstam variable "s"; double t_minus; // minimum and maximum of the mandelstam variable "t" double t_plus; // as function of the mandelstam variable "s=q2"; double t_for_s; int ijk; // counter for variable "t"; int max_ijk; // maximal value of this counter; s = list_of_max_q2_points[i_list]; t_plus = pow( M1, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * ( pow( M1, 2.0 ) - s ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * ( pow( M1, 2.0 ) - s ); t_minus *= 0.5; if ( fabs( t_plus - t_minus ) < 0.000001 ) t_minus = t_plus; max_ijk = 1000; double dt = ( t_plus - t_minus ) / ( (double)max_ijk ); if ( fabs( dt ) < 0.00001 ) dt = 0.0; if ( dt < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollGammaAmp::CalcScalarMaxProb(...)" << "\n dt = " << dt << " < 0." << "\n s = " << s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n M1 = " << M1 << "\n ml = " << ml << std::endl; ::abort(); } for ( ijk = 0; ijk <= max_ijk; ijk++ ) { t_for_s = t_minus + dt * ( (double)ijk ); // B-meson rest frame particles and they kinematics inicialization double Eg, El2; Eg = ( pow( M1, 2.0 ) - s ) / ( 2.0 * M1 ); // photon energy El2 = ( s + t_for_s - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modl2; modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosBellminus; // angle between the B-meson and ell^- directions cosBellminus = ( pow( ml, 2.0 ) + 2.0 * Eg * El2 - t_for_s ) / ( 2.0 * Eg * modl2 ); if ( ( fabs( cosBellminus ) > 1.0 ) && ( fabs( cosBellminus ) <= 1.0001 ) ) { EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n Debug in the function EvtbsTollGammaAmp::CalcMaxProb(...):" << "\n cos(theta) = " << cosBellminus << std::endl; cosBellminus = cosBellminus / fabs( cosBellminus ); } if ( fabs( cosBellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollGammaAmp::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosBellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n Eg = " << Eg << "\n El2 = " << El2 << "\n modl2 = " << modl2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p, k, p1, p2; p.set( M1, 0.0, 0.0, 0.0 ); k.set( Eg, Eg, 0.0, 0.0 ); p2.set( El2, modl2 * cosBellminus, -modl2 * sqrt( 1.0 - pow( cosBellminus, 2.0 ) ), 0.0 ); p1 = p - k - p2; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = photnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *gamm, *lep1, *lep2; gamm = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); gamm->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); gamm->init( photnum, k ); lep1->init( l1num, p1 ); lep2->init( l2num, p2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, res_swch, ias, Egamma_min, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { maxfoundprob = nikmax; EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " << maxfoundprob << "\n ijk =" << ijk << std::endl; } delete scalar_part; // delete root_part; delete gamm; delete lep1; delete lep2; } // for(ijk=0; ijk<=max_ijk; ijk++) } // i_list - variable loop } // if(res_swch==0||res_swch==1) else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollVectorAmpNew::CalcMaxProb(...)" << "\n Unexpected value of the variable res_swch !!!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } if ( maxfoundprob <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollVectorAmpNew::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } maxfoundprob *= 1.01; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n **********************************************************************" // << "\n The function Evtbs2llGammaAmp::CalcMaxProb(...) passed with arguments:" // << "\n mu =" << mu << " Nf =" << Nf // << " res_swch =" << res_swch // << " ias =" << ias // << "\n CKM_A = " << CKM_A // << " CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << " CKM_bareta = " << CKM_bareta // << "\n The distribution maximum maxfoundprob =" << maxfoundprob // << "\n ijk = " << ijk_atmax // << "\n **********************************************************************" // << std::endl; return maxfoundprob; } // Triangular function double Evtbs2llGammaAmp::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/Evtbs2llGammaISRFSRAmp.cpp b/src/EvtGenModels/Evtbs2llGammaISRFSRAmp.cpp index d237d25..e23e02f 100644 --- a/src/EvtGenModels/Evtbs2llGammaISRFSRAmp.cpp +++ b/src/EvtGenModels/Evtbs2llGammaISRFSRAmp.cpp @@ -1,895 +1,895 @@ /*********************************************************************** * 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/Evtbs2llGammaISRFSRAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include "EvtGenModels/Evtbs2llGammaFFMNT.hh" #include // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllGammaFF class object; // *WilsCoeff - the pointer to the Standart Model Wilson Coefficients class; // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // sr - state radiation type: // = 0 the ISR only, // = 1 the FSR only, // = 2 both ISR + FSR (== BSTOGLLMNT model); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Egamma_min - photon energy cut, GeV; // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta void Evtbs2llGammaISRFSRAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, Evtbs2llGammaFF* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int sr, int res_swch, int ias, double Egamma_min, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta, double mumumass_min ) { // FILE *mytest; int iG = 0; // photon is the first daughter particle int il1 = 1, il2 = 2; // leptons are the second and thirds daughter particles EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit double M1 = parent->mass(); // B - meson mass, GeV double ml = parent->getDaug( il1 )->mass(); // leptonic mass, GeV double mq = 0.0; // light quark mass from the dispersion QM, GeV double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM, GeV double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM, GeV double Mw = 80.403; // GeV W-boson mass, GeV double mt = 174.2; // GeV t-quark mass, GeV double fb = 0.0; // leptonic decay constant of B-meson, Gev EvtComplex Vtb, Vtq, Vub, Vuq, Vcb, Vcq; // V_{tb}, V_{tq}, V_{ub}, V_{uq}, V_{cb}, V_{cq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qc; // V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; // to find charges of ell^+ and ell^- in the B-meson daughters int charge1 = EvtPDL::chg3( parent->getDaug( il1 )->getId() ); int charge2 = EvtPDL::chg3( parent->getDaug( il2 )->getId() ); if ( charge1 == 0 || charge2 == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsTollGammaAmp::CalcAmp(...)" << "\n Error in the leptonic charge getting!" << "\n charge1 =" << charge1 << "\n charge2 =" << charge2 << "\n charge gamma =" << EvtPDL::chg3( parent->getDaug( iG )->getId() ) << "\n number of daughters =" << parent->getNDaug() << std::endl; ::abort(); } - EvtParticle* lepPlus = 0; - EvtParticle* lepMinus = 0; + EvtParticle* lepPlus = nullptr; + EvtParticle* lepMinus = nullptr; lepPlus = ( charge1 > charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); // positive charged lepMinus = ( charge1 < charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); // negative charged EvtVector4R p = parent->getP4Restframe(); // B-meson momentum in the B-rest frame EvtVector4R k = parent->getDaug( iG )->getP4(); // 4-momentum of photon in the B-rest frame EvtVector4R q = p - k; // transition 4-momentum q=p-k in the B-rest frame EvtVector4R p_1; // 4-momentum of ell^+ in the B-rest frame EvtVector4R p_2; // 4-momentum of ell^- in the B-rest frame // the preparation of the leptonic 4-momentums in the B-rest frame if ( charge1 > charge2 ) { p_1 = parent->getDaug( il1 )->getP4(); p_2 = parent->getDaug( il2 )->getP4(); } else { p_1 = parent->getDaug( il2 )->getP4(); p_2 = parent->getDaug( il1 )->getP4(); } EvtVector4R p_minus_p_1 = p - p_1; // transition momentum of the B-meson and antilepton p-p_1 EvtVector4R p_minus_p_2 = p - p_2; // transition momentum of the B-meson and lepton p-p_2 double q2 = q.mass2(); // Mandelstam variable s=q^2 double p2 = p.mass2(); // p^2=M1^2 double t = p_minus_p_1.mass2(); // Mandelstam variable t=(p-p_1)^2 double u = p_minus_p_2.mass2(); // Mandelstam variable u=(p-p_2)^2 // scalar products double pk = 0.5 * ( p2 - q2 ); // (p*k) double p1k = 0.5 * ( pow( ml, 2.0 ) - u ); // (p1*k) double p2k = 0.5 * ( pow( ml, 2.0 ) - t ); // (p2*k) double hatq2 = q2 / ( M1 * M1 ); // \hat s = q^2/M_1^2 double Egam = 0.5 * M1 * ( 1 - hatq2 ); // photon energy in the B-meson rest frame EvtVector4R hatp = p / M1; EvtVector4R hatk = k / M1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n\n The function EvtbsTollGammaISRFSRAmp::CalcAmp(...)" // << "\n q = p-k =" << p-k << " q^2 = " << (p-k).mass2() // << "\n q = p1+p2 =" << p_1+p_2 << " q^2 = " << (p_1+p_2).mass2() // << "\n m_ell =" << parent->getDaug(il1)->mass() // << "\n m_ell =" << parent->getDaug(il2)->mass() // << "\n m_gamma =" << parent->getDaug(iG)->mass() // << std::endl; EvtId idparent = parent->getId(); // B-meson Id if ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) || idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) ) { mq = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM fb = 0.24; // leptonic decay constant // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; // V_{cs} Vcq = unit1 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) * ( 1.0 + 4.0 * pow( CKM_A, 2.0 ) ); } if ( idparent == EvtPDL::getId( std::string( "B0" ) ) || idparent == EvtPDL::getId( std::string( "anti-B0" ) ) ) { mq = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM fb = 0.20; // leptonic decay constant // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); // V_{cd} Vcq = unit1 * ( -CKM_lambda + 0.5 * pow( CKM_A, 2.0 ) * pow( CKM_lambda, 5.0 ) * ( 1.0 - 2.0 * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ) ) ); } if ( mq < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsTollGammaISRFSRAmp::CalcAmp(..// 4-momentum of ell^+.)" << "\n Error in the model set!" << " mq = " << mq << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} Vcb = unit1 * CKM_A * pow( CKM_lambda, 2.0 ); // V_{cb} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); lambda_qc = conj( Vcq ) * Vcb / CKM_factor; // V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb} // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) double c1, c2; EvtComplex a1, c7gam, c9eff_b2q, c9eff_barb2barq, c10a; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) || ( q2 <= mumumass_min * mumumass_min ) ) { c1 = 0.0; c2 = 0.0; a1 = unit1 * 0.0; c7gam = unit1 * 0.0; c9eff_b2q = unit1 * 0.0; c9eff_barb2barq = unit1 * 0.0; c10a = unit1 * 0.0; } else { c1 = WilsCoeff->C1( mu, Mw, Nf, ias ); c2 = WilsCoeff->C2( mu, Mw, Nf, ias ); a1 = unit1 * ( c1 + c2 / 3.0 ); c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c10a = WilsCoeff->GetC10Eff( mt, Mw ); } EvtComplex Fv, Fa; // The change of the sign is included in the amplitudes definition! EvtComplex Ftv_b2q, Ftv_barb2barq; EvtComplex Fta_b2q, Fta_barb2barq; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) || ( q2 <= mumumass_min * mumumass_min ) ) { fb = 0.0; Fa = unit1 * 0.0; Fv = unit1 * 0.0; Fta_b2q = unit1 * 0.0; Fta_barb2barq = unit1 * 0.0; Ftv_b2q = unit1 * 0.0; Ftv_barb2barq = unit1 * 0.0; } else { if ( fb < 0.01 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsTollGammaISRFSRAmp::CalcAmp(...)" << "\n Leptonic decay constant fb is not uninitialized in this function!" << " fb = " << fb << std::endl; ::abort(); } // For \bar B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 0, fb, parent->getId(), q2, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_b2q, Fta_b2q ); // For B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 1, fb, parent->getId(), q2, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_barb2barq, Fta_barb2barq ); } // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ============================================================================" // << "\n ============================================================================" // << "\n\n The function Evtbs2llGammaISRFSRAmp::CalcAmp(...) passed." // << "\n Particle masses:" // << "\n B - meson mass M1 = " << M1 // << "\n photon minimum E = " << Egamma_min // << "\n q2 = " << q2 // << "\n leptonic mass ml = " << ml // << "\n light quark mass = " << mq // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << mb // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ============================================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n state radiation switching = " << sr // << "\n resonant switching = " << res_swch // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n photon energy cut (GeV) = " << Egamma_min // << "\n ============================================================================" // << "\n Form-factors" // << "\n Egam = " << Egam // << "\n Egamma_min = " << Egamma_min // << "\n Fv = " << Fv // << "\n Fa = " << Fa // << "\n Ftv_b2q = " << Ftv_b2q // << "\n Fta_b2q = " << Fta_b2q // << "\n Ftv_barb2barq = " << Ftv_barb2barq // << "\n Fta_barb2barq = " << Fta_barb2barq // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Egam = " << Egam // << "\n Egamma_min = " << Egamma_min // << "\n Re(c7gam) = " << real(c7gam) // << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) // << " Im(c10a) = " << imag(c10a) // << std::endl; // Hadronic matrix element coefficients EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, e_b2q, e_barb2barq, f_b2q, f_barb2barq; EvtComplex brammS, brammT; a_b2q = c9eff_b2q * Fv + 2.0 * c7gam * Ftv_b2q * mb * M1 / q2; a_barb2barq = c9eff_barb2barq * Fv + 2.0 * c7gam * Ftv_barb2barq * mb * M1 / q2; b_b2q = ( c9eff_b2q * Fa + 2.0 * c7gam * Fta_b2q * mb * M1 / q2 ) * pk / ( M1 * M1 ); b_barb2barq = ( c9eff_barb2barq * Fa + 2.0 * c7gam * Fta_barb2barq * mb * M1 / q2 ) * pk / ( M1 * M1 ); e_b2q = c10a * Fv; e_barb2barq = e_b2q; f_b2q = c10a * Fa * pk / ( M1 * M1 ); f_barb2barq = f_b2q; brammS = 0.0; // in the Bq-meson rest frame! brammT = 0.5 * c10a * ml * fb * ( 1.0 / p2k + 1.0 / p1k ); // for Bramsstrahlung // The separation of the ISR and FSR contributions if ( sr == 0 ) { // ISR only brammS = 0.0; brammT = 0.0; } if ( sr == 1 ) { // FSR only a_b2q = 0.0; a_barb2barq = 0.0; b_b2q = 0.0; b_barb2barq = 0.0; e_b2q = 0.0; e_barb2barq = 0.0; f_b2q = 0.0; f_barb2barq = 0.0; } EvtTensor4C T1, T2; // hadronic matrix element tensor structures EvtVector4C E1, E2; EvtComplex E3; EvtVector4C epsG; // photon polarisation vector int i; // photon polarisations counter EvtVector4C lvc11, lvc12; // spin structures for EvtVector4C lvc21, lvc22; // the leptonic vector current EvtVector4C lac11, lac12; // spin structures for EvtVector4C lac21, lac22; // the leptonic axial current EvtComplex lsc11, lsc12; // spin structures for EvtComplex lsc21, lsc22; // the leptonic scalar current EvtTensor4C ltc11, ltc12; // spin structures for EvtTensor4C ltc21, ltc22; // the leptonic tensor current // B - and barB - mesons descriptors static EvtIdSet bmesons( "anti-B0", "anti-B_s0" ); static EvtIdSet bbarmesons( "B0", "B_s0" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> gamma ell^+ ell^- or // b \bar q -> gamma ell^+ ell^- T1 = -a_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) - b_b2q * uniti * EvtTensor4C::g(); T2 = -e_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) - f_b2q * uniti * EvtTensor4C::g(); // spin combinations for vector lepton current lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lsc11 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lsc21 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lsc12 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lsc22 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); // \epsilon^{\alpha\beta\mu\nu}*TCurrent_{\mu\nu} ltc11 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ) ); ltc21 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ) ); ltc12 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ) ); ltc22 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ) ); // summing up photon polarisations for ( i = 0; i < 2; i++ ) { // conjaction of epsG (photon polarization vector) EvtVector4C epsG = parent->getDaug( 0 )->epsParentPhoton( i ).conj(); // de-escalation T with epsG E1 = T1.cont2( epsG ); E2 = T2.cont2( epsG ); E3 = ( epsG * hatp ) * brammS; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) || ( q2 <= mumumass_min * mumumass_min ) ) { CKM_factor = 0.0 * unit1; } // 1 amp.vertex( i, 0, 0, CKM_factor * ( lvc11 * E1 + lac11 * E2 + uniti * lsc11 * E3 + uniti * ( ( ltc11.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 1" << CKM_factor*(lvc11*E1+lac11*E2+uniti*lsc11*E3+uniti*((ltc11.cont2(hatp))*epsG)*brammT) // << std::endl; // 2 amp.vertex( i, 0, 1, CKM_factor * ( lvc12 * E1 + lac12 * E2 + uniti * lsc12 * E3 + uniti * ( ( ltc12.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 2" << CKM_factor*(lvc12*E1+lac12*E2+uniti*lsc12*E3+uniti*((ltc12.cont2(hatp))*epsG)*brammT) // << std::endl; // 3 amp.vertex( i, 1, 0, CKM_factor * ( lvc21 * E1 + lac21 * E2 + uniti * lsc21 * E3 + uniti * ( ( ltc21.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 3" << CKM_factor*(lvc21*E1+lac21*E2+uniti*lsc21*E3+uniti*((ltc21.cont2(hatp))*epsG)*brammT) // << std::endl; // 4 amp.vertex( i, 1, 1, CKM_factor * ( lvc22 * E1 + lac22 * E2 + uniti * lsc22 * E3 + uniti * ( ( ltc22.cont2( hatp ) ) * epsG ) * brammT ) ); // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n 4" << CKM_factor*(lvc22*E1+lac22*E2+uniti*lsc22*E3+uniti*((ltc22.cont2(hatp))*epsG)*brammT) // << std::endl; } } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> gamma ell^+ ell^- or // q bar b -> gamma ell^+ ell^- T1 = -a_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) + b_barb2barq * uniti * EvtTensor4C::g(); T2 = -e_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) + f_barb2barq * uniti * EvtTensor4C::g(); lvc11 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lvc21 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lvc12 = EvtLeptonVCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lvc22 = EvtLeptonVCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lac11 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lac21 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lac12 = EvtLeptonACurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lac22 = EvtLeptonACurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); lsc11 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ); lsc21 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ); lsc12 = EvtLeptonSCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ); lsc22 = EvtLeptonSCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ); // \epsilon^{\alpha\beta\mu\nu}*TCurrent_{\mu\nu} ltc11 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 1 ) ) ); ltc21 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 1 ) ) ); ltc12 = dual( EvtLeptonTCurrent( lepPlus->spParent( 1 ), lepMinus->spParent( 0 ) ) ); ltc22 = dual( EvtLeptonTCurrent( lepPlus->spParent( 0 ), lepMinus->spParent( 0 ) ) ); // summing up photon polarisations for ( i = 0; i < 2; i++ ) { EvtVector4C barepsG = parent->getDaug( 0 )->epsParentPhoton( i ); E1 = T1.cont2( barepsG ); E2 = T2.cont2( barepsG ); E3 = ( barepsG * hatp ) * brammS; // foton energy cut and removal of the J/psi amd psi' resonant area if ( Egam < Egamma_min || ( res_swch == 1 && q2 >= 9.199 && q2 <= 15.333 ) || ( q2 <= mumumass_min * mumumass_min ) ) { CKM_factor = 0.0 * unit1; } amp.vertex( i, 1, 1, conj( CKM_factor ) * ( lvc11 * E1 + lac11 * E2 + uniti * lsc11 * E3 + // -? uniti * ( ( ltc11.cont2( hatp ) ) * epsG ) * brammT ) ); amp.vertex( i, 1, 0, conj( CKM_factor ) * ( lvc12 * E1 + lac12 * E2 + uniti * lsc12 * E3 + // -? uniti * ( ( ltc12.cont2( hatp ) ) * epsG ) * brammT ) ); amp.vertex( i, 0, 1, conj( CKM_factor ) * ( lvc21 * E1 + lac21 * E2 + uniti * lsc21 * E3 + // -? uniti * ( ( ltc21.cont2( hatp ) ) * epsG ) * brammT ) ); amp.vertex( i, 0, 0, conj( CKM_factor ) * ( lvc22 * E1 + lac22 * E2 + uniti * lsc22 * E3 + // -? uniti * ( ( ltc22.cont2( hatp ) ) * epsG ) * brammT ) ); } } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function Evtbs2llGammaISRFSRAmp::CalcAmp(...)" << "\n Wrong B-meson number" << std::endl; ::abort(); } } } // // The decays B -> Gamma ell^+ ell^- maximum probability calculation for the // d^2\Gamma/dq^2 d\cos\theta distribution. // // \theta - the angle between the photon and ell^- directions in the // B-meson rest frame. // // If ias=0 (nonresonant case), the maximum is achieved at q2 // B0s: q2 = 4*ml^2, Mphi^2, q_max^2; // B0d: q2 = 4*ml^2, Mrho^2, Momega^2, q_max^2; // If ias=1 (resonant case), the maximum in the same points, because the // resonat area is remove // double Evtbs2llGammaISRFSRAmp::CalcMaxProb( EvtId parnum, EvtId photnum, EvtId l1num, EvtId l2num, Evtbs2llGammaFF* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int sr, int res_swch, int ias, double Egamma_min, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta, double mumumass_min ) { double maxfoundprob = -100.0; // maximum of the probability double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass double ml = EvtPDL::getMeanMass( l1num ); // leptonic mass double Mrho = EvtPDL::getMeanMass( EvtPDL::getId( std::string( "rho0" ) ) ); // mass of the rho-meson, MeV double Momega = EvtPDL::getMeanMass( EvtPDL::getId( std::string( "omega" ) ) ); // mass of the omega-meson, MeV double Mphi = EvtPDL::getMeanMass( EvtPDL::getId( std::string( "phi" ) ) ); // mass of the phi-meson, MeV // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n M1 = " << M1 // << "\n ml = " << ml // << "\n Mrho = " << Mrho // << "\n Momega = " << Momega // << "\n Mphi = " << Mphi // << "\n Egamma_min = " << Egamma_min // << std::endl; double list_of_max_q2_points[5]; list_of_max_q2_points[0] = pow( 2.0 * ml, 2.0 ); list_of_max_q2_points[1] = pow( Mrho, 2.0 ); list_of_max_q2_points[2] = pow( Momega, 2.0 ); list_of_max_q2_points[3] = pow( Mphi, 2.0 ); list_of_max_q2_points[4] = pow( M1, 2.0 ) - 2.0 * M1 * Egamma_min; // q^2_max at photon energy cut // if(list_of_max_points[4]<0){ // EvtGenReport(EVTGEN_ERROR,"EvtGen") // << "\n\n In the function EvtbsTollGammaAmp::CalcScalarMaxProb(...)" // << "\n Bad photon energy cut: Egamma_min > M1 in the rest frame of B-meson!" // << "\n q2_max = " << list_of_max_points[4] // << "\n M1 = " << M1 // << "\n Egamma_min = " << Egamma_min // << std::endl; // ::abort(); // } if ( Egamma_min > Mrho ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function Evtbs2llGammaISRFSRAmp::CalcMaxProb(...)" << "\n Bad photon energy cut: Egamma_min > M_rho0 in the rest frame of B-meson." << "\n Mrho = " << Mrho << "\n Egamma_min = " << Egamma_min << std::endl; ::abort(); } if ( Egamma_min <= 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function Evtbs2llGammaISRFSRAmp::CalcMaxProb(...)" << "\n Bad photon energy cut: Egamma_min <= 0 in the rest frame of B-meson." << "\n Egamma_min = " << Egamma_min << std::endl; ::abort(); } if ( res_swch == 0 || res_swch == 1 ) { int i_list; for ( i_list = 0; i_list <= 4; i_list++ ) { double s; // mandelstam variable "s"; double t_minus; // minimum and maximum of the mandelstam variable "t" double t_plus; // as function of the mandelstam variable "s=q2"; double t_for_s; int ijk; // counter for variable "t"; int max_ijk; // maximal value of this counter; s = list_of_max_q2_points[i_list]; t_plus = pow( M1, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_plus = t_plus + sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * ( pow( M1, 2.0 ) - s ); t_plus *= 0.5; t_minus = pow( M1, 2.0 ) + 2.0 * pow( ml, 2.0 ) - s; t_minus = t_minus - sqrt( 1.0 - 4.0 * pow( ml, 2.0 ) / s ) * ( pow( M1, 2.0 ) - s ); t_minus *= 0.5; if ( fabs( t_plus - t_minus ) < 0.000001 ) t_minus = t_plus; max_ijk = 1000; double dt = ( t_plus - t_minus ) / ( (double)max_ijk ); if ( fabs( dt ) < 0.00001 ) dt = 0.0; if ( dt < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollGammaISRFSRAmp::CalcScalarMaxProb(...)" << "\n dt = " << dt << " < 0." << "\n s = " << s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n M1 = " << M1 << "\n ml = " << ml << std::endl; ::abort(); } for ( ijk = 0; ijk <= max_ijk; ijk++ ) { t_for_s = t_minus + dt * ( (double)ijk ); // B-meson rest frame particles and they kinematics inicialization double Eg, El2; Eg = ( pow( M1, 2.0 ) - s ) / ( 2.0 * M1 ); // photon energy El2 = ( s + t_for_s - pow( ml, 2.0 ) ) / ( 2.0 * M1 ); // ell^- energy double modl2; modl2 = sqrt( pow( El2, 2.0 ) - pow( ml, 2.0 ) ); double cosBellminus; // angle between the B-meson and ell^- directions cosBellminus = ( pow( ml, 2.0 ) + 2.0 * Eg * El2 - t_for_s ) / ( 2.0 * Eg * modl2 ); if ( ( fabs( cosBellminus ) > 1.0 ) && ( fabs( cosBellminus ) <= 1.0001 ) ) { EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n Debug in the function EvtbsTollGammaISRFSRAmp::CalcMaxProb(...):" << "\n cos(theta) = " << cosBellminus << std::endl; cosBellminus = cosBellminus / fabs( cosBellminus ); } if ( fabs( cosBellminus ) > 1.0001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsTollGammaISRFSRAmp::CalcMaxProb(...)" << "\n |cos(theta)| = " << fabs( cosBellminus ) << " > 1" << "\n s = " << s << "\n t_for_s = " << t_for_s << "\n t_plus = " << t_plus << "\n t_minus = " << t_minus << "\n dt = " << dt << "\n Eg = " << Eg << "\n El2 = " << El2 << "\n modl2 = " << modl2 << "\n ml = " << ml << std::endl; ::abort(); } EvtVector4R p, k, p1, p2; p.set( M1, 0.0, 0.0, 0.0 ); k.set( Eg, Eg, 0.0, 0.0 ); p2.set( El2, modl2 * cosBellminus, -modl2 * sqrt( 1.0 - pow( cosBellminus, 2.0 ) ), 0.0 ); p1 = p - k - p2; // B-meson state preparation at the rest frame of B-meson EvtScalarParticle* scalar_part; EvtParticle* root_part; scalar_part = new EvtScalarParticle; scalar_part->noLifeTime(); scalar_part->init( parnum, p ); root_part = (EvtParticle*)scalar_part; root_part->setDiagonalSpinDensity(); // Amplitude initialization EvtId listdaug[3]; listdaug[0] = photnum; listdaug[1] = l1num; listdaug[2] = l2num; EvtAmp amp; amp.init( parnum, 3, listdaug ); // Daughters states preparation at the rest frame of B-meson root_part->makeDaughters( 3, listdaug ); EvtParticle *gamm, *lep1, *lep2; gamm = root_part->getDaug( 0 ); lep1 = root_part->getDaug( 1 ); lep2 = root_part->getDaug( 2 ); gamm->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); gamm->init( photnum, k ); lep1->init( l1num, p1 ); lep2->init( l2num, p2 ); EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); // The amplitude calculation at the // "maximum amplitude" kinematical configuration CalcAmp( root_part, amp, formFactors, WilsCoeff, mu, Nf, sr, res_swch, ias, Egamma_min, CKM_A, CKM_lambda, CKM_barrho, CKM_bareta, mumumass_min ); // Now find the probability at this q2 and cos theta lepton point double nikmax = rho.normalizedProb( amp.getSpinDensity() ); if ( nikmax > maxfoundprob ) { double maxfoundprob_old; maxfoundprob_old = maxfoundprob; maxfoundprob = nikmax; EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob ( s =" << s << ", t = " << t_for_s << " ) = " << maxfoundprob << "\n maxfoundprob_old = " << maxfoundprob_old << "\n ijk =" << ijk << std::endl; } delete scalar_part; // delete root_part; delete gamm; delete lep1; delete lep2; } // for(ijk=0; ijk<=max_ijk; ijk++) } // i_list - variable loop } // if(res_swch==0||res_swch==1) else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function Evtbs2llGammaISRFSRAmp::CalcMaxProb(...)" << "\n Unexpected value of the variable res_swch !!!" << "\n res_swch = " << res_swch << std::endl; ::abort(); } if ( maxfoundprob < 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function Evtbs2llGammaISRFSRAmp::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n mu =" << mu << " Nf =" << Nf << "\n sr =" << sr << " res_swch =" << res_swch << " ias =" << ias << "\n Egamma_min =" << Egamma_min << "\n CKM_A = " << CKM_A << " CKM_lambda = " << CKM_lambda << "\n CKM_barrho = " << CKM_barrho << " CKM_bareta = " << CKM_bareta << std::endl; ::abort(); } if ( maxfoundprob == 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function Evtbs2llGammaISRFSRAmp::CalcMaxProb(...)" << "\n maxfoundprob = " << maxfoundprob << " <0 or =0!" << "\n mu =" << mu << " Nf =" << Nf << "\n sr =" << sr << " res_swch =" << res_swch << " ias =" << ias << "\n Egamma_min =" << Egamma_min << "\n CKM_A = " << CKM_A << " CKM_lambda = " << CKM_lambda << "\n CKM_barrho = " << CKM_barrho << " CKM_bareta = " << CKM_bareta << std::endl; maxfoundprob = 0.00000001; } maxfoundprob *= 1.01; EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n **********************************************************************" << "\n The function Evtbs2llGammaISRFSRAmp::CalcMaxProb(...) passed with arguments:" << "\n mu =" << mu << " Nf =" << Nf << "\n sr =" << sr << " res_swch =" << res_swch << " ias =" << ias << "\n CKM_A = " << CKM_A << " CKM_lambda = " << CKM_lambda << "\n Egamma_min =" << Egamma_min << "\n CKM_barrho = " << CKM_barrho << " CKM_bareta = " << CKM_bareta << "\n The distribution maximum maxfoundprob =" << maxfoundprob << "\n **********************************************************************" << std::endl; return maxfoundprob; } // Triangular function double Evtbs2llGammaISRFSRAmp::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/EvtbsToLLLLAmp.cpp b/src/EvtGenModels/EvtbsToLLLLAmp.cpp index ad1412b..51717b7 100644 --- a/src/EvtGenModels/EvtbsToLLLLAmp.cpp +++ b/src/EvtGenModels/EvtbsToLLLLAmp.cpp @@ -1,822 +1,822 @@ /*********************************************************************** * 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/EvtbsToLLLLAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenModels/EvtbTosllWilsCoeffNLO.hh" #include "EvtGenModels/Evtbs2llGammaFFMNT.hh" #include // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // *formFactors - the pointer to instance of EvtbTosllGammaFF class object; // *WilsCoeff - the pointer to the Standart Model Wilson Coefficients class; // mu - the scale parameter, GeV; // Nf - number of "effective" flavors (for b-quark Nf=5); // res_swch - resonant switching parameter: // = 0 the resonant contribution switched OFF, // = 1 the resonant contribution switched ON; // ias - switching parameter for \alpha_s(M_Z) value: // = 0 PDG 1sigma minimal alpha_s(M_Z), // = 1 PDG average value alpha_s(M_Z), // = 2 PDG 1sigma maximal alpha_s(M_Z). // Wolfenstein parameterization for CKM matrix // CKM_A, CKM_lambda, CKM_barrho, CKM_bareta void EvtbsToLLLLAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, Evtbs2llGammaFF* formFactors, EvtbTosllWilsCoeffNLO* WilsCoeff, double mu, int Nf, int res_swch, int ias, double CKM_A, double CKM_lambda, double CKM_barrho, double CKM_bareta ) { // FILE *mytest; int il1 = 0, il2 = 1, il3 = 2, il4 = 3; // leptons are the first, second, thirds // and fourth daughter particles EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit double M1 = parent->mass(); // B - meson mass, GeV double ml = parent->getDaug( il1 )->mass(); // leptonic mass, GeV double mq = 0.0; // light quark mass from the dispersion QM, GeV double mc = formFactors->getQuarkMass( 4 ); // m_c mass from the dispersion QM, GeV double mb = formFactors->getQuarkMass( 5 ); // m_b mass from the dispersion QM, GeV double Mw = 80.403; // GeV W-boson mass, GeV double mt = 174.2; // GeV t-quark mass, GeV double fb = 0.0; // leptonic decay constant of B-meson, Gev EvtComplex Vtb, Vtq, Vub, Vuq, Vcb, Vcq; // V_{tb}, V_{tq}, V_{ub}, V_{uq}, V_{cb}, V_{cq} EvtComplex CKM_factor; // V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qu; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s} EvtComplex lambda_qc; // V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb}, where q={d,s} double Relambda_qu, Imlambda_qu; // // Setting of the mq and CKM matrix elements for different Bq-mesons tipes // EvtId idparent = parent->getId(); // Bq-meson Id EvtId IdMu1, IdMu2, IdMu3, IdMu4; if ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) || idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) ) { mq = formFactors->getQuarkMass( 3 ); // m_s mass from the dispersion QM fb = 0.24; // leptonic decay constant // V_{ts} Vtq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) + pow( CKM_lambda, 2.0 ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = -CKM_A * pow( CKM_lambda, 2.0 ) * Vtq; // V_{us} Vuq = CKM_lambda * unit1; // V_{cs} Vcq = unit1 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) * ( 1.0 + 4.0 * pow( CKM_A, 2.0 ) ); } if ( idparent == EvtPDL::getId( std::string( "B0" ) ) || idparent == EvtPDL::getId( std::string( "anti-B0" ) ) ) { mq = formFactors->getQuarkMass( 2 ); // m_d mass from the dispersion QM fb = 0.20; // leptonic decay constant // V_{td} Vtq = unit1 - ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) ) * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); Vtq = CKM_A * pow( CKM_lambda, 3.0 ) * Vtq; // V_{ud} Vuq = unit1 * ( 1.0 - 0.5 * pow( CKM_lambda, 2.0 ) - 0.125 * pow( CKM_lambda, 4.0 ) ); // V_{cd} Vcq = unit1 * ( -CKM_lambda + 0.5 * pow( CKM_A, 2.0 ) * pow( CKM_lambda, 5.0 ) * ( 1.0 - 2.0 * ( CKM_barrho * unit1 + CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ) ) ); } if ( mq < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLAmp::CalcAmp(...)" << "\n Error in the mq setting!" << "\n mq = " << mq << "< 0.001" << "\n idparent = " << idparent << std::endl; ::abort(); } Vtb = unit1 * ( 1.0 - 0.5 * pow( CKM_A * CKM_lambda * CKM_lambda, 2.0 ) ); // V_{tb} Vub = CKM_A * pow( CKM_lambda, 3.0 ) * ( CKM_barrho * unit1 - CKM_bareta * uniti ) / sqrt( 1.0 - pow( CKM_lambda, 2.0 ) ); // V_{ub} Vcb = unit1 * CKM_A * pow( CKM_lambda, 2.0 ); // V_{cb} CKM_factor = conj( Vtq ) * Vtb; // V^*_{tq}*V_{tb} lambda_qu = conj( Vuq ) * Vub / CKM_factor; // V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb} Relambda_qu = real( lambda_qu ); Imlambda_qu = imag( lambda_qu ); lambda_qc = conj( Vcq ) * Vcb / CKM_factor; // V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb} // // Setting the leptonic kinematical properties // // to find charges of ell^+ and ell^- in the B-meson daughters int charge1 = ( EvtPDL::chg3( parent->getDaug( il1 )->getId() ) ) / 3; int charge2 = ( EvtPDL::chg3( parent->getDaug( il2 )->getId() ) ) / 3; int charge3 = ( EvtPDL::chg3( parent->getDaug( il3 )->getId() ) ) / 3; int charge4 = ( EvtPDL::chg3( parent->getDaug( il4 )->getId() ) ) / 3; if ( ( abs( charge1 ) != 1 ) || ( abs( charge2 ) != 1 ) || ( abs( charge3 ) != 1 ) || ( abs( charge4 ) != 1 ) || ( charge1 + charge2 + charge3 + charge4 != 0 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLAmp::CalcAmp(...)" << "\n Error in the leptonic charge definition!" << "\n charge1 =" << charge1 << "\n charge2 =" << charge2 << "\n charge3 =" << charge3 << "\n charge4 =" << charge4 << "\n number of daughters =" << parent->getNDaug() << std::endl; ::abort(); } - EvtParticle* lep1Plus = 0; - EvtParticle* lep1Minus = 0; - EvtParticle* lep2Plus = 0; - EvtParticle* lep2Minus = 0; + EvtParticle* lep1Plus = nullptr; + EvtParticle* lep1Minus = nullptr; + EvtParticle* lep2Plus = nullptr; + EvtParticle* lep2Minus = nullptr; EvtVector4R p; // B-meson momentum in the B-rest frame EvtVector4R q; // first transition 4-momentum in the B-rest frame EvtVector4R k; // second transition 4-momentum in the B-rest frame double q2; // Mandelstam variable s=q^2 // Nondimentional 4-momentums EvtVector4R hatp; EvtVector4R hatq; EvtVector4R hatk; EvtVector4R qsecond; // first transition 4-momentum in the B-rest frame EvtVector4R ksecond; // second transition 4-momentum in the B-rest frame double q2second; // Mandelstam variable s=q^2 // Nondimentional 4-momentums EvtVector4R hatpsecond; EvtVector4R hatqsecond; EvtVector4R hatksecond; EvtVector4R k_1; // 4-momentum of ell^+ in the B-rest frame EvtVector4R k_2; // 4-momentum of ell^- in the B-rest frame EvtVector4R k_3; // 4-momentum of ell^+ in the B-rest frame EvtVector4R k_4; // 4-momentum of ell^- in the B-rest frame k_1.set( 0.0, 0.0, 0.0, 0.0 ); k_2.set( 0.0, 0.0, 0.0, 0.0 ); k_3.set( 0.0, 0.0, 0.0, 0.0 ); k_4.set( 0.0, 0.0, 0.0, 0.0 ); if ( ( charge1 + charge2 == 0 ) && ( charge3 + charge4 == 0 ) ) { // positive charged lepton 1 lep1Plus = ( charge1 > charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); // negative charged lepton 1 lep1Minus = ( charge1 < charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); if ( charge1 > charge2 ) { k_1 = parent->getDaug( il1 )->getP4(); k_2 = parent->getDaug( il2 )->getP4(); IdMu1 = parent->getDaug( il1 )->getId(); IdMu2 = parent->getDaug( il2 )->getId(); } else { k_1 = parent->getDaug( il2 )->getP4(); k_2 = parent->getDaug( il1 )->getP4(); IdMu1 = parent->getDaug( il2 )->getId(); IdMu2 = parent->getDaug( il1 )->getId(); } // positive charged lepton 2 lep2Plus = ( charge3 > charge4 ) ? parent->getDaug( il3 ) : parent->getDaug( il4 ); // negative charged lepton 2 lep2Minus = ( charge3 < charge4 ) ? parent->getDaug( il3 ) : parent->getDaug( il4 ); if ( charge3 > charge4 ) { k_3 = parent->getDaug( il3 )->getP4(); k_4 = parent->getDaug( il4 )->getP4(); IdMu3 = parent->getDaug( il3 )->getId(); IdMu4 = parent->getDaug( il4 )->getId(); } else { k_3 = parent->getDaug( il4 )->getP4(); k_4 = parent->getDaug( il3 )->getP4(); IdMu3 = parent->getDaug( il4 )->getId(); IdMu4 = parent->getDaug( il3 )->getId(); } } if ( ( charge1 + charge3 == 0 ) && ( charge2 + charge4 == 0 ) ) { // positive charged lepton 1 lep1Plus = ( charge1 > charge3 ) ? parent->getDaug( il1 ) : parent->getDaug( il3 ); // negative charged lepton 1 lep1Minus = ( charge1 < charge3 ) ? parent->getDaug( il1 ) : parent->getDaug( il3 ); if ( charge1 > charge3 ) { k_1 = parent->getDaug( il1 )->getP4(); k_2 = parent->getDaug( il3 )->getP4(); IdMu1 = parent->getDaug( il1 )->getId(); IdMu2 = parent->getDaug( il3 )->getId(); } else { k_1 = parent->getDaug( il3 )->getP4(); k_2 = parent->getDaug( il1 )->getP4(); IdMu1 = parent->getDaug( il3 )->getId(); IdMu2 = parent->getDaug( il1 )->getId(); } // positive charged lepton 2 lep2Plus = ( charge2 > charge4 ) ? parent->getDaug( il2 ) : parent->getDaug( il4 ); // negative charged lepton 2 lep2Minus = ( charge2 < charge4 ) ? parent->getDaug( il2 ) : parent->getDaug( il4 ); if ( charge2 > charge4 ) { k_3 = parent->getDaug( il2 )->getP4(); k_4 = parent->getDaug( il4 )->getP4(); IdMu3 = parent->getDaug( il2 )->getId(); IdMu4 = parent->getDaug( il4 )->getId(); } else { k_3 = parent->getDaug( il4 )->getP4(); k_4 = parent->getDaug( il2 )->getP4(); IdMu3 = parent->getDaug( il4 )->getId(); IdMu4 = parent->getDaug( il2 )->getId(); } } p = parent->getP4Restframe(); hatp = p / M1; // // The calculation of the FIRST part of the amplitude // q = k_1 + k_2; k = k_3 + k_4; q2 = q.mass2(); // Mandelstam variable s=q^2 hatq = q / M1; hatk = k / M1; // The Wilson Coefficients preparation according to the paper // A.J.Buras, M.Munz, Phys.Rev.D52, p.189 (1995) double c1, c2; EvtComplex a1, c7gam, c9eff_b2q, c9eff_barb2barq, c10a; // Excluded of the J/psi and psi' resonant area if ( ( res_swch == 1 ) && ( q2 >= 9.199 ) && ( q2 <= 15.333 ) ) { c1 = 0.0; c2 = 0.0; a1 = unit1 * 0.0; c7gam = unit1 * 0.0; c9eff_b2q = unit1 * 0.0; c9eff_barb2barq = unit1 * 0.0; c10a = unit1 * 0.0; } else { c1 = WilsCoeff->C1( mu, Mw, Nf, ias ); c2 = WilsCoeff->C2( mu, Mw, Nf, ias ); a1 = unit1 * ( c1 + c2 / 3.0 ); c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c10a = WilsCoeff->GetC10Eff( mt, Mw ); } EvtComplex Fv, Fa; // The change of the sign is included in the amplitudes definition! EvtComplex Ftv_b2q, Ftv_barb2barq; EvtComplex Fta_b2q, Fta_barb2barq; // Excluded of the J/psi and psi' resonant area if ( ( res_swch == 1 ) && ( q2 >= 9.199 ) && ( q2 <= 15.333 ) ) { fb = 0.0; Fa = unit1 * 0.0; Fv = unit1 * 0.0; Fta_b2q = unit1 * 0.0; Fta_barb2barq = unit1 * 0.0; Ftv_b2q = unit1 * 0.0; Ftv_barb2barq = unit1 * 0.0; } else { if ( fb < 0.01 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLAmp::CalcAmp(...)" << "\n Leptonic decay constant fb is not uninitialized in this function!" << " fb = " << fb << std::endl; ::abort(); } // For \bar B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 0, fb, parent->getId(), q2, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_b2q, Fta_b2q ); // For B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 1, fb, parent->getId(), q2, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_barb2barq, Fta_barb2barq ); } // The functions for the hadronic matrix element calculation EvtComplex a_b2q, a_barb2barq, b_b2q, b_barb2barq, c_b2q, c_barb2barq; EvtComplex e_b2q, e_barb2barq, f_b2q, f_barb2barq, g_b2q, g_barb2barq; a_b2q = c9eff_b2q * Fv + 2.0 * c7gam * Ftv_b2q * mb * M1 / q2; a_barb2barq = c9eff_barb2barq * Fv + 2.0 * c7gam * Ftv_barb2barq * mb * M1 / q2; b_b2q = ( c9eff_b2q * Fa + 2.0 * c7gam * Fta_b2q * mb * M1 / q2 ) * ( hatp * hatk ); b_barb2barq = ( c9eff_barb2barq * Fa + 2.0 * c7gam * Fta_barb2barq * mb * M1 / q2 ) * ( hatp * hatk ); c_b2q = c9eff_b2q * Fa + 2.0 * c7gam * Fta_b2q * mb * M1 / q2; c_barb2barq = c9eff_barb2barq * Fa + 2.0 * c7gam * Fta_barb2barq * mb * M1 / q2; e_b2q = c10a * Fv; e_barb2barq = e_b2q; f_b2q = c10a * Fa * ( hatp * hatk ); f_barb2barq = f_b2q; g_b2q = c10a * Fa; g_barb2barq = g_b2q; // // The calculation of the SECOND part of the amplitude // qsecond = k_1 + k_4; ksecond = k_3 + k_2; q2second = qsecond.mass2(); // Mandelstam variable s=q^2 hatqsecond = qsecond / M1; hatksecond = ksecond / M1; // Excluded of the J/psi and psi' resonant area if ( ( res_swch == 1 ) && ( q2second >= 9.199 ) && ( q2second <= 15.333 ) ) { c1 = 0.0; c2 = 0.0; a1 = unit1 * 0.0; c7gam = unit1 * 0.0; c9eff_b2q = unit1 * 0.0; c9eff_barb2barq = unit1 * 0.0; c10a = unit1 * 0.0; } else { c1 = WilsCoeff->C1( mu, Mw, Nf, ias ); c2 = WilsCoeff->C2( mu, Mw, Nf, ias ); a1 = unit1 * ( c1 + c2 / 3.0 ); c7gam = WilsCoeff->GetC7Eff( mu, Mw, mt, Nf, ias ); c9eff_b2q = WilsCoeff->GetC9Eff( 0, res_swch, ias, Nf, q2second, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c9eff_barb2barq = WilsCoeff->GetC9Eff( 1, res_swch, ias, Nf, q2second, mb, mq, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); c10a = WilsCoeff->GetC10Eff( mt, Mw ); } // Excluded of the J/psi and psi' resonant area if ( ( res_swch == 1 ) && ( q2second >= 9.199 ) && ( q2second <= 15.333 ) ) { fb = 0.0; Fa = unit1 * 0.0; Fv = unit1 * 0.0; Fta_b2q = unit1 * 0.0; Fta_barb2barq = unit1 * 0.0; Ftv_b2q = unit1 * 0.0; Ftv_barb2barq = unit1 * 0.0; } else { if ( fb < 0.01 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLAmp::CalcAmp(...)" << "\n Leptonic decay constant fb is not uninitialized in this function!" << " fb = " << fb << std::endl; ::abort(); } // For \bar B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 0, fb, parent->getId(), q2second, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_b2q, Fta_b2q ); // For B^0_q -> l^+ l^- gamma formFactors->getPhotonFF( 1, fb, parent->getId(), q2second, M1, mb, mq, c7gam, a1, lambda_qu, lambda_qc, Fv, Fa, Ftv_barb2barq, Fta_barb2barq ); } // The functions for the hadronic matrix element calculation EvtComplex a_b2qsecond, a_barb2barqsecond, b_b2qsecond, b_barb2barqsecond, c_b2qsecond, c_barb2barqsecond; EvtComplex e_b2qsecond, e_barb2barqsecond, f_b2qsecond, f_barb2barqsecond, g_b2qsecond, g_barb2barqsecond; a_b2qsecond = c9eff_b2q * Fv + 2.0 * c7gam * Ftv_b2q * mb * M1 / q2second; a_barb2barqsecond = c9eff_barb2barq * Fv + 2.0 * c7gam * Ftv_barb2barq * mb * M1 / q2second; b_b2qsecond = ( c9eff_b2q * Fa + 2.0 * c7gam * Fta_b2q * mb * M1 / q2second ) * ( hatpsecond * hatksecond ); b_barb2barqsecond = ( c9eff_barb2barq * Fa + 2.0 * c7gam * Fta_barb2barq * mb * M1 / q2second ) * ( hatpsecond * hatksecond ); c_b2qsecond = c9eff_b2q * Fa + 2.0 * c7gam * Fta_b2q * mb * M1 / q2second; c_barb2barqsecond = c9eff_barb2barq * Fa + 2.0 * c7gam * Fta_barb2barq * mb * M1 / q2second; e_b2qsecond = c10a * Fv; e_barb2barqsecond = e_b2qsecond; f_b2qsecond = c10a * Fa * ( hatpsecond * hatksecond ); f_barb2barqsecond = f_b2qsecond; g_b2qsecond = c10a * Fa; g_barb2barqsecond = g_b2qsecond; EvtTensor4C T1, T2; // Tensor structures for EvtTensor4C T1second, T2second; // the hadronic matrix element calculation // B - and barB - mesons descriptors static EvtIdSet bmesons( "anti-B0", "anti-B_s0" ); static EvtIdSet bbarmesons( "B0", "B_s0" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> gamma ell^+ ell^- or // b \bar q -> gamma ell^+ ell^- T1 = a_b2q * unit1 * dual( EvtGenFunctions::directProd( hatq, hatk ) ) - b_b2q * uniti * EvtTensor4C::g() + c_b2q * uniti * EvtGenFunctions::directProd( hatk, hatq ); T2 = e_b2q * unit1 * dual( EvtGenFunctions::directProd( hatp, hatk ) ) - f_b2q * uniti * EvtTensor4C::g() + g_b2q * uniti * EvtGenFunctions::directProd( hatk, hatq ); T1second = a_b2qsecond * unit1 * dual( EvtGenFunctions::directProd( hatqsecond, hatksecond ) ) - b_b2qsecond * uniti * EvtTensor4C::g() + c_b2qsecond * uniti * EvtGenFunctions::directProd( hatksecond, hatqsecond ); T2second = e_b2qsecond * unit1 * dual( EvtGenFunctions::directProd( hatpsecond, hatksecond ) ) - f_b2qsecond * uniti * EvtTensor4C::g() + g_b2qsecond * uniti * EvtGenFunctions::directProd( hatksecond, hatqsecond ); int i1, i2, i3, i4; // leptonic spin structures counters int leptonicspin[4]; // array for the saving of the leptonic spin configuration // Tables for correspondings // l^+(k_1) && lep1Plus && k_1 && i1 // l^-(k_2) && lep1Minus && k_2 && i2 // l^+(k_3) && lep2Plus && k_3 && i3 // l^-(k_4) && lep2Minus && k_4 && i4 for ( i2 = 0; i2 < 2; i2++ ) { leptonicspin[0] = i2; for ( i1 = 0; i1 < 2; i1++ ) { leptonicspin[1] = i1; for ( i4 = 0; i4 < 2; i4++ ) { leptonicspin[2] = i4; for ( i3 = 0; i3 < 2; i3++ ) { leptonicspin[3] = i3; EvtVector4C VL2L1, AL2L1, VL4L3; EvtVector4C E1, E2; EvtVector4C VL2L1second, AL2L1second, VL4L3second; EvtVector4C E1second, E2second; VL2L1 = EvtLeptonVCurrent( lep1Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); AL2L1 = EvtLeptonACurrent( lep1Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); VL4L3 = EvtLeptonVCurrent( lep2Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); E1 = T1.cont2( VL4L3 ); E2 = T2.cont2( VL4L3 ); VL2L1second = EvtLeptonVCurrent( lep2Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); AL2L1second = EvtLeptonACurrent( lep2Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); VL4L3second = EvtLeptonVCurrent( lep1Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); E1second = T1second.cont2( VL4L3second ); E2second = T2second.cont2( VL4L3second ); amp.vertex( leptonicspin, CKM_factor * ( VL2L1 * E1 + AL2L1 * E2 + VL2L1second * E1second + AL2L1second * E2second ) ); // EvtGenReport(EVTGEN_ERROR,"EvtGen") // << "\n\n ============================================================================" // << "\n The matrix element (first + second) = " // << CKM_factor*(VL2L1*E1+AL2L1*E2+VL2L1second*E1second+AL2L1second*E2second) // << "\n The matrix element (only first) = " // << CKM_factor*(VL2L1*E1+AL2L1*E2) // << "============================================================================\n\n" // << std::endl; } } } } // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n The function EvtbsToLLLLAmp::CalcAmp(...) passed with arguments:" // << "\n ============================================================================" // << "\n Input parameters:" // << "\n mu = " << mu // << "\n Nf =" << Nf // << "\n res_swch = " << res_swch // << "\n ias = " << ias // << "\n CKM_A = " << CKM_A // << "\n CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << "\n CKM_bareta = " << CKM_bareta // << "\n CKM_factor = " << CKM_factor // << "\n ============================================================================" // << "\n Kinematics:" // << "\n k_1 = " << k_1 // << "\n m_ell_1 =" << parent->getDaug(il1)->mass() // << "\n k_2 = " << k_2 // << "\n m_ell_2 =" << parent->getDaug(il2)->mass() // << "\n k_3 = " << k_3 // << "\n m_ell_3 =" << parent->getDaug(il3)->mass() // << "\n k_4 = " << k_4 // << "\n m_ell_4 =" << parent->getDaug(il4)->mass() // << "\n p = " << p // << "\n q = " << q // << "\n k = " << k // << "\n ============================================================================" // << "\n Form-factors" // << "\n Fv = " << Fv // << "\n Fa = " << Fa // << "\n Ftv_b2q = " << Ftv_b2q // << "\n Fta_b2q = " << Fta_b2q // << "\n Ftv_barb2barq = " << Ftv_barb2barq // << "\n Fta_barb2barq = " << Fta_barb2barq // << "\n fb = " << fb // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Re(c7gam) = " << real(c7gam) // << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) // << " Im(c10a) = " << imag(c10a) // << "\n ============================================================================" // << "\n Functions in the matrix element:" // << "\n a_b2q = " << a_b2q // << "\n b_b2q = " << b_b2q // << "\n c_b2q = " << c_b2q // << "\n e_b2q = " << e_b2q // << "\n f_b2q = " << f_b2q // << "\n g_b2q = " << g_b2q // << "\n ============================================================================" // << "\n Partical Properties:" // << "\n IdB = " << idparent << " == " << EvtPDL::getId(std::string("anti-B_s0")) // << "\n IdMu1 = " << IdMu1 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu2 = " << IdMu2 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n IdMu3 = " << IdMu3 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu4 = " << IdMu4 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n\n\n\n" // << std::endl; } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> gamma ell^+ ell^- or // q bar b -> gamma ell^+ ell^- T1 = -a_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatq, hatk ) ) - b_barb2barq * uniti * EvtTensor4C::g() + c_barb2barq * uniti * EvtGenFunctions::directProd( hatk, hatq ); T2 = -e_barb2barq * unit1 * dual( EvtGenFunctions::directProd( hatq, hatk ) ) - f_barb2barq * uniti * EvtTensor4C::g() + g_barb2barq * uniti * EvtGenFunctions::directProd( hatk, hatq ); T1second = -a_barb2barqsecond * unit1 * dual( EvtGenFunctions::directProd( hatqsecond, hatksecond ) ) - b_barb2barqsecond * uniti * EvtTensor4C::g() + c_barb2barqsecond * uniti * EvtGenFunctions::directProd( hatksecond, hatqsecond ); T2second = -e_barb2barqsecond * unit1 * dual( EvtGenFunctions::directProd( hatpsecond, hatksecond ) ) - f_barb2barqsecond * uniti * EvtTensor4C::g() + g_barb2barqsecond * uniti * EvtGenFunctions::directProd( hatksecond, hatqsecond ); int i1, i2, i3, i4; // leptonic spin structures counters int leptonicspin[4]; // array for the saving of the leptonic spin configuration // Tables for correspondings // l^+(k_1) && lep1Plus && k_1 && i1 // l^-(k_2) && lep1Minus && k_2 && i2 // l^+(k_3) && lep2Plus && k_3 && i3 // l^-(k_4) && lep2Minus && k_4 && i4 for ( i2 = 1; i2 > -1; i2-- ) { leptonicspin[0] = i2; for ( i1 = 1; i1 > -1; i1-- ) { leptonicspin[1] = i1; for ( i4 = 1; i4 > -1; i4-- ) { leptonicspin[2] = i4; for ( i3 = 1; i3 > -1; i3-- ) { leptonicspin[3] = i3; EvtVector4C VL2L1, AL2L1, VL4L3; EvtVector4C E1, E2; EvtVector4C VL2L1second, AL2L1second, VL4L3second; EvtVector4C E1second, E2second; VL2L1 = EvtLeptonVCurrent( lep1Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); AL2L1 = EvtLeptonACurrent( lep1Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); VL4L3 = EvtLeptonVCurrent( lep2Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); E1 = T1.cont2( VL4L3 ); E2 = T2.cont2( VL4L3 ); VL2L1second = EvtLeptonVCurrent( lep2Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); AL2L1second = EvtLeptonACurrent( lep2Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); VL4L3second = EvtLeptonVCurrent( lep1Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); E1second = T1second.cont2( VL4L3second ); E2second = T2second.cont2( VL4L3second ); amp.vertex( leptonicspin, conj( CKM_factor ) * ( VL2L1 * E1 + AL2L1 * E2 + VL2L1second * E1second + AL2L1second * E2second ) ); } } } } // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n The function EvtbsToLLLLAmp::CalcAmp(...) passed with arguments:" // << "\n ============================================================================" // << "\n Input parameters:" // << "\n mu = " << mu // << "\n Nf =" << Nf // << "\n res_swch = " << res_swch // << "\n ias = " << ias // << "\n CKM_A = " << CKM_A // << "\n CKM_lambda = " << CKM_lambda // << "\n CKM_barrho = " << CKM_barrho // << "\n CKM_bareta = " << CKM_bareta // << "\n CKM_factor = " << CKM_factor // << "\n ============================================================================" // << "\n Kinematics:" // << "\n k_1 = " << k_1 // << "\n m_ell_1 =" << parent->getDaug(il1)->mass() // << "\n k_2 = " << k_2 // << "\n m_ell_2 =" << parent->getDaug(il2)->mass() // << "\n k_3 = " << k_3 // << "\n m_ell_3 =" << parent->getDaug(il3)->mass() // << "\n k_4 = " << k_4 // << "\n m_ell_4 =" << parent->getDaug(il4)->mass() // << "\n p = " << p // << "\n q = " << q // << "\n k = " << k // << "\n ============================================================================" // << "\n Form-factors" // << "\n Fv = " << Fv // << "\n Fa = " << Fa // << "\n Ftv_b2q = " << Ftv_b2q // << "\n Fta_b2q = " << Fta_b2q // << "\n Ftv_barb2barq = " << Ftv_barb2barq // << "\n Fta_barb2barq = " << Fta_barb2barq // << "\n fb = " << fb // << "\n ============================================================================" // << "\n Wilson Coefficients:" // << "\n Re(c7gam) = " << real(c7gam) // << " Im(c7gam) = " << imag(c7gam) // << "\n Re(c9eff_b2q) = " << real(c9eff_b2q) // << " Im(c9eff_b2q) = " << imag(c9eff_b2q) // << "\n Re(c9eff_barb2barq) = " << real(c9eff_barb2barq) // << " Im(c9eff_barb2barq) = " << imag(c9eff_barb2barq) // << "\n Re(c10a) = " << real(c10a) // << " Im(c10a) = " << imag(c10a) // << "\n ============================================================================" // << "\n Functions in the matrix element:" // << "\n a_barb2barq = " << a_barb2barq // << "\n b_barb2barq = " << b_barb2barq // << "\n c_barb2barq = " << c_barb2barq // << "\n e_barb2barq = " << e_barb2barq // << "\n f_barb2barq = " << f_barb2barq // << "\n g_barb2barq = " << g_barb2barq // << "\n ============================================================================" // << "\n Partical Properties:" // << "\n IdB = " << idparent << " == " << EvtPDL::getId(std::string("B_s0")) // << "\n IdMu1 = " << IdMu1 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu2 = " << IdMu2 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n IdMu3 = " << IdMu3 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu4 = " << IdMu4 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n\n\n\n" // << std::endl; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLAmp::CalcAmp(...)" << "\n Wrong Bq-meson number" << std::endl; ::abort(); } } } // // The decays Bq -> ell^+ ell^- ell^+ ell^- maximum probability calculation // double EvtbsToLLLLAmp::CalcMaxProb( // EvtId parnum, // EvtId l1num, EvtId l2num, // EvtId l3num, EvtId l4num, // Evtbs2llGammaFF *formFactors, // EvtbTosllWilsCoeffNLO *WilsCoeff, // double mu, int Nf, // int res_swch, int ias, // double CKM_A, double CKM_lambda, // double CKM_barrho, double CKM_bareta ) { double maxfoundprob = 10.0; // maximum of the probability return maxfoundprob; } // Triangular function double EvtbsToLLLLAmp::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/src/EvtGenModels/EvtbsToLLLLHyperCPAmp.cpp b/src/EvtGenModels/EvtbsToLLLLHyperCPAmp.cpp index 40b090e..756b5ae 100644 --- a/src/EvtGenModels/EvtbsToLLLLHyperCPAmp.cpp +++ b/src/EvtGenModels/EvtbsToLLLLHyperCPAmp.cpp @@ -1,605 +1,605 @@ /*********************************************************************** * 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/EvtbsToLLLLHyperCPAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include // input: *parent - the pointer to the parent particle (B-meson, the // object of the EvtParticle class); // mS - the mass of the scalar sgoldstino "S" (GeV); // mP - the mass of the pseudoscalar sgoldstino "P" (GeV); // gammaS - the decay width of the scalar sgoldstino "S" (GeV); // gammaP - the decay width of the pseudoscalar sgoldstino "P" (GeV); // mLiiLR - // Fc - coupling constant (GeV^2); // mDijLL(RR) - parameters for \bar Bq-decays // mDjiLL(RR) - parameters for Bq-decays (i <-> j!) // d==1, s==2, b==3 // void EvtbsToLLLLHyperCPAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, double mS, double mP, double gammaS, double gammaP, double mLiiLR, double Fc, double mD23LL, double mD23RR, double mD32LL, double mD32RR, double mD13LL, double mD13RR, double mD31LL, double mD31RR ) { // FILE *mytest; int il1 = 0, il2 = 1, il3 = 2, il4 = 3; // leptons are the first, second, thirds // and fourth daughter particles EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit parent->mass(); // B - meson mass, GeV double fb = 0.0; // leptonic decay constant of B-meson, GeV double Cl = 0.0; // LPL and LSL - vertexes if ( Fc != 0.0 ) { Cl = mLiiLR * mLiiLR / ( sqrt( 2 ) * Fc ); } if ( Cl == 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcAmp(...)" << "\n Error in the Cl setting!" << "\n Cl = " << Cl << "\n mLiiLR = " << mLiiLR << "\n Fc = " << Fc << std::endl; ::abort(); } EvtComplex MS = unit1 * mS - uniti * gammaS / 2.0; // complex mass of the scalar sgoldstino EvtComplex MP = unit1 * mP - uniti * gammaP / 2.0; // complex mass of the pseudoscalar sgoldstino // // Setting of the different Bq-mesons tipes // EvtId idparent = parent->getId(); // Bq-meson Id EvtId IdMu1, IdMu2, IdMu3, IdMu4; double CB = 0.0; if ( idparent == EvtPDL::getId( std::string( "B_s0" ) ) ) { fb = 0.24; // leptonic decay constant CB = mD32LL * mD32LL + mD32RR * mD32RR; } if ( idparent == EvtPDL::getId( std::string( "anti-B_s0" ) ) ) { fb = 0.24; // leptonic decay constant CB = mD23LL * mD23LL + mD23RR * mD23RR; } if ( idparent == EvtPDL::getId( std::string( "B0" ) ) ) { fb = 0.20; // leptonic decay constant CB = mD31LL * mD31LL + mD31RR * mD31RR; } if ( idparent == EvtPDL::getId( std::string( "anti-B0" ) ) ) { fb = 0.20; // leptonic decay constant CB = mD13LL * mD13LL + mD13RR * mD13RR; } if ( CB == 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcAmp(...)" << "\n Error in the CB setting!" << "\n CB = " << CB << "\n mD32LL = " << mD32LL << "\n mD32RR = " << mD32RR << "\n mD23LL = " << mD23LL << "\n mD23RR = " << mD23RR << "\n mD31LL = " << mD31LL << "\n mD31RR = " << mD31RR << "\n mD13LL = " << mD13LL << "\n mD13RR = " << mD13RR << "\n idparent = " << idparent << std::endl; ::abort(); } // // Setting the leptonic kinematical properties // // to find charges of ell^+ and ell^- in the B-meson daughters int charge1 = ( EvtPDL::chg3( parent->getDaug( il1 )->getId() ) ) / 3; int charge2 = ( EvtPDL::chg3( parent->getDaug( il2 )->getId() ) ) / 3; int charge3 = ( EvtPDL::chg3( parent->getDaug( il3 )->getId() ) ) / 3; int charge4 = ( EvtPDL::chg3( parent->getDaug( il4 )->getId() ) ) / 3; if ( ( abs( charge1 ) != 1 ) || ( abs( charge2 ) != 1 ) || ( abs( charge3 ) != 1 ) || ( abs( charge4 ) != 1 ) || ( charge1 + charge2 + charge3 + charge4 != 0 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcAmp(...)" << "\n Error in the leptonic charge definition!" << "\n charge1 =" << charge1 << "\n charge2 =" << charge2 << "\n charge3 =" << charge3 << "\n charge4 =" << charge4 << "\n number of daughters =" << parent->getNDaug() << std::endl; ::abort(); } - EvtParticle* lep1Plus = 0; - EvtParticle* lep1Minus = 0; - EvtParticle* lep2Plus = 0; - EvtParticle* lep2Minus = 0; + EvtParticle* lep1Plus = nullptr; + EvtParticle* lep1Minus = nullptr; + EvtParticle* lep2Plus = nullptr; + EvtParticle* lep2Minus = nullptr; EvtVector4R p; // B-meson momentum in the B-rest frame EvtVector4R q; // first transition 4-momentum in the B-rest frame EvtVector4R k; // second transition 4-momentum in the B-rest frame double q2; // Mandelstam variable s=q^2 double k2; // Mandelstam variable t=k^2 EvtVector4R qsecond; // first transition 4-momentum in the B-rest frame EvtVector4R ksecond; // second transition 4-momentum in the B-rest frame double q2second; // Mandelstam variable s=q^2 double k2second; // Mandelstam variable t=k^2 EvtVector4R k_1; // 4-momentum of ell^+ in the B-rest frame EvtVector4R k_2; // 4-momentum of ell^- in the B-rest frame EvtVector4R k_3; // 4-momentum of ell^+ in the B-rest frame EvtVector4R k_4; // 4-momentum of ell^- in the B-rest frame k_1.set( 0.0, 0.0, 0.0, 0.0 ); k_2.set( 0.0, 0.0, 0.0, 0.0 ); k_3.set( 0.0, 0.0, 0.0, 0.0 ); k_4.set( 0.0, 0.0, 0.0, 0.0 ); if ( ( charge1 + charge2 == 0 ) && ( charge3 + charge4 == 0 ) ) { // positive charged lepton 1 lep1Plus = ( charge1 > charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); // negative charged lepton 1 lep1Minus = ( charge1 < charge2 ) ? parent->getDaug( il1 ) : parent->getDaug( il2 ); if ( charge1 > charge2 ) { k_1 = parent->getDaug( il1 )->getP4(); k_2 = parent->getDaug( il2 )->getP4(); IdMu1 = parent->getDaug( il1 )->getId(); IdMu2 = parent->getDaug( il2 )->getId(); } else { k_1 = parent->getDaug( il2 )->getP4(); k_2 = parent->getDaug( il1 )->getP4(); IdMu1 = parent->getDaug( il2 )->getId(); IdMu2 = parent->getDaug( il1 )->getId(); } // positive charged lepton 2 lep2Plus = ( charge3 > charge4 ) ? parent->getDaug( il3 ) : parent->getDaug( il4 ); // negative charged lepton 2 lep2Minus = ( charge3 < charge4 ) ? parent->getDaug( il3 ) : parent->getDaug( il4 ); if ( charge3 > charge4 ) { k_3 = parent->getDaug( il3 )->getP4(); k_4 = parent->getDaug( il4 )->getP4(); IdMu3 = parent->getDaug( il3 )->getId(); IdMu4 = parent->getDaug( il4 )->getId(); } else { k_3 = parent->getDaug( il4 )->getP4(); k_4 = parent->getDaug( il3 )->getP4(); IdMu3 = parent->getDaug( il4 )->getId(); IdMu4 = parent->getDaug( il3 )->getId(); } } if ( ( charge1 + charge3 == 0 ) && ( charge2 + charge4 == 0 ) ) { // positive charged lepton 1 lep1Plus = ( charge1 > charge3 ) ? parent->getDaug( il1 ) : parent->getDaug( il3 ); // negative charged lepton 1 lep1Minus = ( charge1 < charge3 ) ? parent->getDaug( il1 ) : parent->getDaug( il3 ); if ( charge1 > charge3 ) { k_1 = parent->getDaug( il1 )->getP4(); k_2 = parent->getDaug( il3 )->getP4(); IdMu1 = parent->getDaug( il1 )->getId(); IdMu2 = parent->getDaug( il3 )->getId(); } else { k_1 = parent->getDaug( il3 )->getP4(); k_2 = parent->getDaug( il1 )->getP4(); IdMu1 = parent->getDaug( il3 )->getId(); IdMu2 = parent->getDaug( il1 )->getId(); } // positive charged lepton 2 lep2Plus = ( charge2 > charge4 ) ? parent->getDaug( il2 ) : parent->getDaug( il4 ); // negative charged lepton 2 lep2Minus = ( charge2 < charge4 ) ? parent->getDaug( il2 ) : parent->getDaug( il4 ); if ( charge2 > charge4 ) { k_3 = parent->getDaug( il2 )->getP4(); k_4 = parent->getDaug( il4 )->getP4(); IdMu3 = parent->getDaug( il2 )->getId(); IdMu4 = parent->getDaug( il4 )->getId(); } else { k_3 = parent->getDaug( il4 )->getP4(); k_4 = parent->getDaug( il2 )->getP4(); IdMu3 = parent->getDaug( il4 )->getId(); IdMu4 = parent->getDaug( il2 )->getId(); } } p = parent->getP4Restframe(); // // The calculation of the FIRST part of the amplitude // q = k_1 + k_2; k = k_3 + k_4; q2 = q.mass2(); // Mandelstam variable s=q^2 k2 = k.mass2(); // Mandelstam variable t=k^2 // // The calculation of the SECOND part of the amplitude // qsecond = k_1 + k_4; ksecond = k_3 + k_2; q2second = qsecond.mass2(); // Mandelstam variable s=q^2 k2second = ksecond.mass2(); // Mandelstam variable t=k^2 // B - and barB - mesons descriptors static EvtIdSet bmesons( "anti-B0", "anti-B_s0" ); static EvtIdSet bbarmesons( "B0", "B_s0" ); EvtId parentID = parent->getId(); if ( bmesons.contains( parentID ) ) { // The amplitude for the decay barB -> ell^+ ell^- ell^+ ell^- or // b \bar q -> ell^+ ell^- ell^+ ell^- int i1, i2, i3, i4; // leptonic spin structures counters int leptonicspin[4]; // array for the saving of the leptonic spin configuration // Tables for correspondings // l^+(k_1) && lep1Plus && k_1 && i1 // l^-(k_2) && lep1Minus && k_2 && i2 // l^+(k_3) && lep2Plus && k_3 && i3 // l^-(k_4) && lep2Minus && k_4 && i4 for ( i2 = 0; i2 < 2; i2++ ) { leptonicspin[0] = i2; for ( i1 = 0; i1 < 2; i1++ ) { leptonicspin[1] = i1; for ( i4 = 0; i4 < 2; i4++ ) { leptonicspin[2] = i4; for ( i3 = 0; i3 < 2; i3++ ) { leptonicspin[3] = i3; EvtComplex SL2L1, PL4L3; EvtComplex SL2L1second, PL4L3second; SL2L1 = EvtLeptonSCurrent( lep1Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); PL4L3 = EvtLeptonPCurrent( lep2Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); SL2L1second = EvtLeptonSCurrent( lep2Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); PL4L3second = EvtLeptonPCurrent( lep1Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); amp.vertex( leptonicspin, Cl * Cl * CB * fb * ( SL2L1 * PL4L3 * ( q2 - k2 ) / ( ( q2 - MS * MS ) * ( k2 - MP * MP ) ) - SL2L1second * PL4L3second * ( q2second - k2second ) / ( ( q2second - MS * MS ) * ( k2second - MP * MP ) ) ) / ( 4.0 * Fc * Fc ) ); } } } } // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n The function EvtbsToLLLLHyperCPAmp::CalcAmp(...) passed with arguments:" // << "\n ============================================================================" // << "\n Input parameters:" // << "\n mS = " << mS // << "\n mP = " << mP // << "\n gammaS = " << gammaS // << "\n gammaP = " << gammaP // << "\n mLiiLR = " << mLiiLR // << "\n Fc = " << Fc // << "\n mD23LL = " << mD23LL // << "\n mD23RR = " << mD23RR // << "\n mD32LL = " << mD32LL // << "\n mD32RR = " << mD32RR // << "\n mD13LL = " << mD13LL // << "\n mD13RR = " << mD13RR // << "\n mD31LL = " << mD31LL // << "\n mD31RR = " << mD31RR // << "\n ============================================================================" // << "\n Kinematics:" // << "\n k_1 = " << k_1 // << "\n m_ell_1 =" << parent->getDaug(il1)->mass() // << "\n k_2 = " << k_2 // << "\n m_ell_2 =" << parent->getDaug(il2)->mass() // << "\n k_3 = " << k_3 // << "\n m_ell_3 =" << parent->getDaug(il3)->mass() // << "\n k_4 = " << k_4 // << "\n m_ell_4 =" << parent->getDaug(il4)->mass() // << "\n p = " << p // << "\n q = " << q // << "\n k = " << k // << "\n qsecond = " << qsecond // << "\n ksecond = " << ksecond // << "\n ============================================================================" // << "\n Form-factors" // << "\n fb = " << fb // << "\n ============================================================================" // << "\n Coefficients:" // << "\n Cl = " << Cl // << "\n CB = " << CB // << "\n ============================================================================" // << "\n Partical Properties:" // << "\n IdB = " << idparent << " == " << EvtPDL::getId(std::string("anti-B_s0")) // << "\n IdMu1 = " << IdMu1 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu2 = " << IdMu2 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n IdMu3 = " << IdMu3 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu4 = " << IdMu4 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n\n\n\n" // << std::endl; } else { if ( bbarmesons.contains( parentID ) ) { // The amplitude for the decay B -> ell^+ ell^- ell^+ ell^- or // q bar b -> ell^+ ell^- ell^+ ell^- int i1, i2, i3, i4; // leptonic spin structures counters int leptonicspin[4]; // array for the saving of the leptonic spin configuration // Tables for correspondings // l^+(k_1) && lep1Plus && k_1 && i1 // l^-(k_2) && lep1Minus && k_2 && i2 // l^+(k_3) && lep2Plus && k_3 && i3 // l^-(k_4) && lep2Minus && k_4 && i4 for ( i2 = 1; i2 > -1; i2-- ) { leptonicspin[0] = i2; for ( i1 = 1; i1 > -1; i1-- ) { leptonicspin[1] = i1; for ( i4 = 1; i4 > -1; i4-- ) { leptonicspin[2] = i4; for ( i3 = 1; i3 > -1; i3-- ) { leptonicspin[3] = i3; EvtComplex SL2L1, PL4L3; EvtComplex SL2L1second, PL4L3second; SL2L1 = EvtLeptonSCurrent( lep1Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); PL4L3 = EvtLeptonPCurrent( lep2Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); SL2L1second = EvtLeptonSCurrent( lep2Minus->spParent( i2 ), lep1Plus->spParent( i1 ) ); PL4L3second = EvtLeptonPCurrent( lep1Minus->spParent( i4 ), lep2Plus->spParent( i3 ) ); amp.vertex( leptonicspin, Cl * Cl * CB * fb * ( SL2L1 * PL4L3 * ( q2 - k2 ) / ( ( q2 - MS * MS ) * ( k2 - MP * MP ) ) - SL2L1second * PL4L3second * ( q2second - k2second ) / ( ( q2second - MS * MS ) * ( k2second - MP * MP ) ) ) / ( 4.0 * Fc * Fc ) ); } } } } // EvtGenReport(EVTGEN_ERROR,"EvtGen") << "\n The function EvtbsToLLLLHyperCPAmp::CalcAmp(...) passed with arguments:" // << "\n ============================================================================" // << "\n Input parameters:" // << "\n mS = " << mS // << "\n mP = " << mP // << "\n gammaS = " << gammaS // << "\n gammaP = " << gammaP // << "\n mLiiLR = " << mLiiLR // << "\n Fc = " << Fc // << "\n mD23LL = " << mD23LL // << "\n mD23RR = " << mD23RR // << "\n mD32LL = " << mD32LL // << "\n mD32RR = " << mD32RR // << "\n mD13LL = " << mD13LL // << "\n mD13RR = " << mD13RR // << "\n mD31LL = " << mD31LL // << "\n mD31RR = " << mD31RR // << "\n ============================================================================" // << "\n Kinematics:" // << "\n k_1 = " << k_1 // << "\n m_ell_1 =" << parent->getDaug(il1)->mass() // << "\n k_2 = " << k_2 // << "\n m_ell_2 =" << parent->getDaug(il2)->mass() // << "\n k_3 = " << k_3 // << "\n m_ell_3 =" << parent->getDaug(il3)->mass() // << "\n k_4 = " << k_4 // << "\n m_ell_4 =" << parent->getDaug(il4)->mass() // << "\n p = " << p // << "\n q = " << q // << "\n k = " << k // << "\n qsecond = " << qsecond // << "\n ksecond = " << ksecond // << "\n ============================================================================" // << "\n Form-factors" // << "\n fb = " << fb // << "\n ============================================================================" // << "\n Coefficients:" // << "\n Cl = " << Cl // << "\n CB = " << CB // << "\n ============================================================================" // << "\n Partical Properties:" // << "\n IdB = " << idparent << " == " << EvtPDL::getId(std::string("anti-B_s0")) // << "\n IdMu1 = " << IdMu1 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu2 = " << IdMu2 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n IdMu3 = " << IdMu3 << " == " << EvtPDL::getId(std::string("mu+")) // << "\n IdMu4 = " << IdMu4 << " == " << EvtPDL::getId(std::string("mu-")) // << "\n\n\n\n" // << std::endl; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcAmp(...)" << "\n Wrong Bq-meson number" << std::endl; ::abort(); } } } // // The decays Bq -> ell^+ ell^- ell^+ ell^- maximum probability calculation // double EvtbsToLLLLHyperCPAmp::CalcMaxProb( EvtId parnum, EvtId l1num, EvtId /*l2num*/, EvtId /*l3num*/, EvtId /*l4num*/, double mS, double mP, double gammaS, double gammaP, double mLiiLR, double Fc, double mD23LL, double mD23RR, double mD32LL, double mD32RR, double mD13LL, double mD13RR, double mD31LL, double mD31RR ) { if ( Fc == 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcMaxProb" << "\n Error in the Fc setting!" << "\n Fc = " << Fc << "\n mD32LL = " << mD32LL << "\n mD32RR = " << mD32RR << "\n mD23LL = " << mD23LL << "\n mD23RR = " << mD23RR << "\n mD31LL = " << mD31LL << "\n mD31RR = " << mD31RR << "\n mD13LL = " << mD13LL << "\n mD13RR = " << mD13RR << "\n parnum = " << parnum << std::endl; ::abort(); } double Cl = 0.0; // LPL and LSL - vertexes if ( Fc != 0.0 ) { Cl = mLiiLR * mLiiLR / ( sqrt( 2 ) * Fc ); } if ( Cl == 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcMaxProb" << "\n Error in the Cl setting!" << "\n Cl = " << Cl << "\n mLiiLR = " << mLiiLR << "\n Fc = " << Fc << std::endl; ::abort(); } // // Setting of the different Bq-mesons tipes // double fb = 0.0; double CB = 0.0; if ( parnum == EvtPDL::getId( std::string( "B_s0" ) ) ) { fb = 0.24; // leptonic decay constant CB = mD32LL * mD32LL + mD32RR * mD32RR; } if ( parnum == EvtPDL::getId( std::string( "anti-B_s0" ) ) ) { fb = 0.24; // leptonic decay constant CB = mD23LL * mD23LL + mD23RR * mD23RR; } if ( parnum == EvtPDL::getId( std::string( "B0" ) ) ) { fb = 0.20; // leptonic decay constant CB = mD31LL * mD31LL + mD31RR * mD31RR; } if ( parnum == EvtPDL::getId( std::string( "anti-B0" ) ) ) { fb = 0.20; // leptonic decay constant CB = mD13LL * mD13LL + mD13RR * mD13RR; } if ( CB == 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function EvtbsToLLLLHyperCPAmp::CalcMaxProb" << "\n Error in the CB setting!" << "\n CB = " << CB << "\n mD32LL = " << mD32LL << "\n mD32RR = " << mD32RR << "\n mD23LL = " << mD23LL << "\n mD23RR = " << mD23RR << "\n mD31LL = " << mD31LL << "\n mD31RR = " << mD31RR << "\n mD13LL = " << mD13LL << "\n mD13RR = " << mD13RR << "\n parnum = " << parnum << std::endl; ::abort(); } double M1 = EvtPDL::getMeanMass( parnum ); // B - meson mass EvtPDL::getMeanMass( l1num ); // leptonic mass // We find the maximum amplitude probability double maxfoundprob = Cl * Cl * CB * fb * fabs( mS * mS + mP * mP + M1 * M1 ) * 10000000.0 / ( 4.0 * Fc * Fc * mS * gammaS * mP * gammaP ); if ( maxfoundprob <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n In the function EvtbsToLLLLHyperCPAmp::CalcMaxProb" << "\n maxfoundprob = " << maxfoundprob << " < 0 or =0!" << "\n mS = " << mS << "\n mP = " << mP << "\n gammaS = " << gammaS << "\n gammaP = " << gammaP << "\n mLiiLR = " << mLiiLR << "\n Fc = " << Fc << "\n mD32LL = " << mD32LL << "\n mD32RR = " << mD32RR << "\n mD23LL = " << mD23LL << "\n mD23RR = " << mD23RR << "\n mD31LL = " << mD31LL << "\n mD31RR = " << mD31RR << "\n mD13LL = " << mD13LL << "\n mD13RR = " << mD13RR << "\n parnum = " << parnum << std::endl; ::abort(); } EvtGenReport( EVTGEN_NOTICE, "EvtGen" ) << "\n maxfoundprob (...) = " << maxfoundprob << std::endl; maxfoundprob *= 1.01; return maxfoundprob; } // Triangular function double EvtbsToLLLLHyperCPAmp::lambda( double a, double b, double c ) { double l; l = pow( a, 2.0 ) + pow( b, 2.0 ) + pow( c, 2.0 ) - 2.0 * a * b - 2.0 * a * c - 2.0 * b * c; return l; } diff --git a/test/evt_dalitz.cc b/test/evt_dalitz.cc index 5876043..c2fdf6b 100644 --- a/test/evt_dalitz.cc +++ b/test/evt_dalitz.cc @@ -1,172 +1,172 @@ /*********************************************************************** * 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 . * ***********************************************************************/ /* * Generate the kinematics of a Dalitz decay * according to a decay file. */ #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtVector4R.hh" #include #include #include #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include #include #include using std::endl; using std::fstream; using std::ifstream; using std::ofstream; void usage( const char* cmd ) { printf( "Usage: %s -d -m -n -f -r \n", cmd ); } int main( int argc, char* argv[] ) { std::string mother( "B+" ); int N = 10; std::string datfile( "output.dat" ); std::string decfile = ( "../DECAY.DEC" ); // Get options extern char* optarg; int c; while ( ( c = getopt( argc, argv, "d:m:n:f:" ) ) != EOF ) { switch ( c ) { case 'm': mother = std::string( optarg ); break; case 'n': N = atoi( optarg ); break; case 'f': datfile = std::string( optarg ); break; case 'd': decfile = std::string( optarg ); break; } } // Initialize EvtGen // Define the random number generator - EvtRandomEngine* eng = 0; + EvtRandomEngine* eng = nullptr; #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) eng = new EvtMTRandomEngine(); #else eng = new EvtSimpleRandomEngine(); #endif EvtRandom::setRandomEngine( eng ); - EvtAbsRadCorr* radCorrEngine = 0; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); bool useEvtGenRandom( true ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif EvtGen myGenerator( decfile.c_str(), "../evt.pdl", eng, radCorrEngine, &extraModels ); // Initialize decay EvtId id = EvtPDL::getId( mother ); // generate ofstream df( datfile.c_str() ); int count = 1; do { EvtVector4R p_init( EvtPDL::getMass( id ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( id, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); int nDaug = root_part->getNDaug(); if ( nDaug == 3 ) { EvtVector4R p0 = root_part->getDaug( 0 )->getP4Lab(); EvtVector4R p1 = root_part->getDaug( 1 )->getP4Lab(); EvtVector4R p2 = root_part->getDaug( 2 )->getP4Lab(); double qAB = ( p0 + p1 ).mass2(); double qBC = ( p1 + p2 ).mass2(); double qCA = ( p2 + p0 ).mass2(); df << qAB << " " << qBC << " " << qCA << " " << endl; } root_part->deleteTree(); } while ( count++ < N ); delete eng; } // Macro for displaying resutls /* TTree* readTree(const char* file, int N) { double qAB,qBC,qCA; TTree* t = new TTree(); t->Branch("qAB",&qAB,"qAB/D"); t->Branch("qBC",&qBC,"qBC/D"); t->Branch("qCA",&qCA,"qCA/D"); ifstream f(file); int i=0; while(i < N) { i++; f >> qAB >> qBC >> qCA; t->Fill(); } return t; } */ diff --git a/test/evtgenlhc_test1.cc b/test/evtgenlhc_test1.cc index 279d92f..84885a0 100644 --- a/test/evtgenlhc_test1.cc +++ b/test/evtgenlhc_test1.cc @@ -1,5885 +1,5885 @@ /*********************************************************************** * 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 . * ***********************************************************************/ //#@# Dalitz plot for D0 --> K- pi+ pi0 decay: //#@# 1: Mass(K-, pi+) //#@# 2: Mass(pi+,pi0) // // Description: // // This program invokes the EvtGen event generator package // for testing various decay models that are implemented. #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGammaMatrix.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParser.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtRadCorr.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtRandomEngine.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSecondary.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtStdHep.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenBase/EvtVectorParticle.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include "TApplication.h" #include "TFile.h" #include "TH1.h" #include "TH2.h" #include "TROOT.h" #include "TString.h" #include "TTree.h" #include #include #include #include #include #include #include using std::vector; void runFile( int nevent, char* fname, EvtGen& myGenerator ); void runPrint( int nevent, char* fname, EvtGen& myGenerator ); void runFileVpho( int nevent, char* fname, EvtGen& myGenerator ); void runTest1( int nevent, EvtGen& myGenerator ); void runTest2( int nevent, EvtGen& myGenerator ); void runOmega( int nevent, EvtGen& myGenerator ); void runChi1Kstar( int nevent, EvtGen& myGenerator ); void runPi0Dalitz( int nevent, EvtGen& myGenerator ); void runMix( int nevent, EvtGen& myGenerator ); void runBMix( int nevent, EvtGen& myGenerator, std::string userFile, std::string rootFile ); void runDDalitz( int nevent, EvtGen& myGenerator ); void runPiPiCPT( int nevent, EvtGen& myGenerator ); void runPiPiPiPi( int nevent, EvtGen& myGenerator ); void runD2Pi( int nevent, EvtGen& myGenerator ); void runJetsetTab3( int nevent, EvtGen& myGenerator ); void runHelAmp( int nevent, EvtGen& myGenerator, std::string userFile, std::string rootFile ); void runHelAmp2( int nevent, EvtGen& myGenerator ); void runJpsiKs( int nevent, EvtGen& myGenerator ); void runDump( int nevent, EvtGen& myGenerator ); void runD1( int nevent, EvtGen& myGenerator ); void runGenericCont( int nevent, EvtGen& myGenerator ); void runPiPiPi( int nevent, EvtGen& myGenerator ); void runBHadronic( int nevent, EvtGen& myGenerator ); void runSingleB( int nevent, EvtGen& myGenerator ); void runA2Pi( int nevent, EvtGen& myGenerator ); void runAlias(); void runRepeat( int nevent ); void runPhotos( int nevent, EvtGen& myGenerator ); void runTrackMult( int nevent, EvtGen& myGenerator ); void runGeneric( int neventOrig, EvtGen& myGenerator, std::string listfile ); void runFinalStates( int nevent, EvtGen& myGenerator ); std::vector findFinalState( EvtParticle* p ); void runKstarnunu( int nevent, EvtGen& myGenerator ); void runBsmix( int nevent, EvtGen& myGenerator ); void runTauTauPiPi( int nevent, EvtGen& myGenerator ); void runTauTauEE( int nevent, EvtGen& myGenerator ); void runTauTau2Pi2Pi( int nevent, EvtGen& myGenerator ); void runTauTau3Pi3Pi( int nevent, EvtGen& myGenerator ); void runJPsiKstar( int nevent, EvtGen& myGenerator, int modeInt ); void runSVVCPLH( int nevent, EvtGen& myGenerator ); void runSVSCPLH( int nevent, EvtGen& myGenerator ); void runSSDCP( int nevent, EvtGen& myGenerator ); void runKstarstargamma( int nevent, EvtGen& myGenerator ); void runDSTARPI( int nevent, EvtGen& myGenerator ); void runETACPHIPHI( int nevent, EvtGen& myGenerator ); void runVVPiPi( int nevent, EvtGen& myGenerator ); void runSVVHelAmp( int nevent, EvtGen& myGenerator ); void runSVVHelAmp2( int nevent, EvtGen& myGenerator ); void runPartWave( int nevent, EvtGen& myGenerator ); void runPartWave2( int nevent, EvtGen& myGenerator ); void runTwoBody( int nevent, EvtGen& myGenerator, std::string decfile, std::string rootFile ); void runPiPi( int nevent, EvtGen& myGenerator ); void runA1Pi( int nevent, EvtGen& myGenerator ); void runCPTest( int nevent, EvtGen& myGenerator ); void runSemic( int nevent, EvtGen& myGenerator ); void runKstarll( int nevent, EvtGen& myGenerator ); void runKll( int nevent, EvtGen& myGenerator ); void runHll( int nevent, EvtGen& myGenerator, char* mode ); void runVectorIsr( int nevent, EvtGen& myGenerator ); void runBsquark( int nevent, EvtGen& myGenerator ); void runK3gamma( int nevent, EvtGen& myGenerator ); void runLambda( int nevent, EvtGen& myGenerator ); void runBtoXsgamma( int nevent, EvtGen& myGenerator ); void runBtoK1273gamma( int nevent, EvtGen& myGenerator ); void runCheckRotBoost(); void runMassCheck( int nevent, EvtGen& myGenerator, int partnum ); void runJpsiPolarization( int nevent, EvtGen& myGenerator ); void runDDK( int nevent, EvtGen& myGenerator ); void runPhspDecaytimeCut( int nevent, EvtGen& myGenerator ); -int countInclusive( std::string name, EvtParticle* root, TH1F* mom = 0, - TH1F* mass = 0 ); +int countInclusive( std::string name, EvtParticle* root, TH1F* mom = nullptr, + TH1F* mass = nullptr ); int countInclusiveParent( std::string name, EvtParticle* root, EvtIdSet setIds, - TH1F* mom = 0 ); + TH1F* mom = nullptr ); int countInclusiveSubTree( std::string name, EvtParticle* root, EvtIdSet setIds, - TH1F* mom = 0 ); + TH1F* mom = nullptr ); void runBaryonic( int nEvent, EvtGen& myGenerator ); void run3BPhspRegion( int nEvent, EvtGen& myGenerator ); void runFourBody( int nevent, EvtGen& myGenerator ); int main( int argc, char* argv[] ) { // Define the random number generator - EvtRandomEngine* myRandomEngine = 0; + EvtRandomEngine* myRandomEngine = nullptr; #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) myRandomEngine = new EvtMTRandomEngine(); #else myRandomEngine = new EvtSimpleRandomEngine(); #endif if ( !TROOT::Initialized() ) { static TROOT root( "RooTuple", "RooTuple ROOT in EvtGen" ); } if ( argc == 1 ) { EvtVector4R p( 0.0, 1.0, 0.0, 0.0 ); EvtVector4R k( 0.0, 0.0, 1.0, 0.0 ); EvtTensor4C T = dual( EvtGenFunctions::directProd( p, k ) ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "p:" << p << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "k:" << k << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "T=dual(directProd(p,k)):" << T << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "T03:" << T.get( 0, 3 ) << std::endl; return 1; } - EvtAbsRadCorr* radCorrEngine = 0; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); bool useEvtGenRandom( true ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif EvtGen myGenerator( "../DECAY.DEC", "../evt.pdl", myRandomEngine, radCorrEngine, &extraModels ); if ( !strcmp( argv[1], "file" ) ) { int nevent = atoi( argv[2] ); runFile( nevent, argv[3], myGenerator ); } if ( !strcmp( argv[1], "print" ) ) { int nevent = atoi( argv[2] ); runPrint( nevent, argv[3], myGenerator ); } if ( !strcmp( argv[1], "filevpho" ) ) { int nevent = atoi( argv[2] ); runFileVpho( nevent, argv[3], myGenerator ); } if ( !strcmp( argv[1], "test1" ) ) { int nevent = atoi( argv[2] ); runTest1( nevent, myGenerator ); } if ( !strcmp( argv[1], "chi1kstar" ) ) { int nevent = atoi( argv[2] ); runChi1Kstar( nevent, myGenerator ); } if ( !strcmp( argv[1], "test2" ) ) { int nevent = atoi( argv[2] ); runTest2( nevent, myGenerator ); } if ( !strcmp( argv[1], "omega" ) ) { int nevent = atoi( argv[2] ); runOmega( nevent, myGenerator ); } if ( !strcmp( argv[1], "alias" ) ) { runAlias(); } if ( !strcmp( argv[1], "repeat" ) ) { int nevent = atoi( argv[2] ); runRepeat( nevent ); } if ( !strcmp( argv[1], "photos" ) ) { int nevent = atoi( argv[2] ); runPhotos( nevent, myGenerator ); } if ( !strcmp( argv[1], "trackmult" ) ) { int nevent = atoi( argv[2] ); runTrackMult( nevent, myGenerator ); } if ( !strcmp( argv[1], "generic" ) ) { int nevent = atoi( argv[2] ); std::string listfile( "" ); if ( argc == 4 ) listfile = argv[3]; runGeneric( nevent, myGenerator, listfile ); } if ( !strcmp( argv[1], "finalstates" ) ) { int nevent = atoi( argv[2] ); runFinalStates( nevent, myGenerator ); } if ( !strcmp( argv[1], "kstarnunu" ) ) { int nevent = atoi( argv[2] ); runKstarnunu( nevent, myGenerator ); } if ( !strcmp( argv[1], "bsmix" ) ) { int nevent = atoi( argv[2] ); runBsmix( nevent, myGenerator ); } if ( !strcmp( argv[1], "BtoXsgamma" ) ) { int nevent = atoi( argv[2] ); runBtoXsgamma( nevent, myGenerator ); } if ( !strcmp( argv[1], "BtoK1273gamma" ) ) { int nevent = atoi( argv[2] ); runBtoK1273gamma( nevent, myGenerator ); } if ( !strcmp( argv[1], "pi0dalitz" ) ) { int nevent = atoi( argv[2] ); runPi0Dalitz( nevent, myGenerator ); } if ( !strcmp( argv[1], "ddalitz" ) ) { int nevent = atoi( argv[2] ); runDDalitz( nevent, myGenerator ); } if ( !strcmp( argv[1], "kstarll" ) ) { int nevent = atoi( argv[2] ); runKstarll( nevent, myGenerator ); } if ( !strcmp( argv[1], "kll" ) ) { int nevent = atoi( argv[2] ); runKll( nevent, myGenerator ); } if ( !strcmp( argv[1], "hll" ) ) { int nevent = atoi( argv[2] ); runHll( nevent, myGenerator, argv[3] ); } if ( !strcmp( argv[1], "vectorisr" ) ) { int nevent = atoi( argv[2] ); runVectorIsr( nevent, myGenerator ); } if ( !strcmp( argv[1], "bsquark" ) ) { int nevent = atoi( argv[2] ); runBsquark( nevent, myGenerator ); } if ( !strcmp( argv[1], "k3gamma" ) ) { int nevent = atoi( argv[2] ); runK3gamma( nevent, myGenerator ); } if ( !strcmp( argv[1], "lambda" ) ) { int nevent = atoi( argv[2] ); runLambda( nevent, myGenerator ); } if ( !strcmp( argv[1], "tautaupipi" ) ) { int nevent = atoi( argv[2] ); runTauTauPiPi( nevent, myGenerator ); } if ( !strcmp( argv[1], "tautauee" ) ) { int nevent = atoi( argv[2] ); runTauTauEE( nevent, myGenerator ); } if ( !strcmp( argv[1], "tautau2pi2pi" ) ) { int nevent = atoi( argv[2] ); runTauTau2Pi2Pi( nevent, myGenerator ); } if ( !strcmp( argv[1], "tautau3pi3pi" ) ) { int nevent = atoi( argv[2] ); runTauTau3Pi3Pi( nevent, myGenerator ); } if ( !strcmp( argv[1], "jpsikstar" ) ) { int nevent = atoi( argv[2] ); int modeInt = atoi( argv[3] ); runJPsiKstar( nevent, myGenerator, modeInt ); } if ( !strcmp( argv[1], "svvcplh" ) ) { int nevent = atoi( argv[2] ); runSVVCPLH( nevent, myGenerator ); } if ( !strcmp( argv[1], "svscplh" ) ) { int nevent = atoi( argv[2] ); runSVSCPLH( nevent, myGenerator ); } if ( !strcmp( argv[1], "ssdcp" ) ) { int nevent = atoi( argv[2] ); runSSDCP( nevent, myGenerator ); } if ( !strcmp( argv[1], "kstarstargamma" ) ) { int nevent = atoi( argv[2] ); runKstarstargamma( nevent, myGenerator ); } if ( !strcmp( argv[1], "dstarpi" ) ) { int nevent = atoi( argv[2] ); runDSTARPI( nevent, myGenerator ); } if ( !strcmp( argv[1], "etacphiphi" ) ) { int nevent = atoi( argv[2] ); runETACPHIPHI( nevent, myGenerator ); } if ( !strcmp( argv[1], "vvpipi" ) ) { int nevent = atoi( argv[2] ); runVVPiPi( nevent, myGenerator ); } if ( !strcmp( argv[1], "svvhelamp" ) ) { int nevent = atoi( argv[2] ); runSVVHelAmp( nevent, myGenerator ); } if ( !strcmp( argv[1], "partwave" ) ) { int nevent = atoi( argv[2] ); runPartWave( nevent, myGenerator ); } if ( !strcmp( argv[1], "partwave2" ) ) { int nevent = atoi( argv[2] ); runPartWave2( nevent, myGenerator ); } if ( !strcmp( argv[1], "twobody" ) ) { int nevent = atoi( argv[2] ); runTwoBody( nevent, myGenerator, argv[3], argv[4] ); } if ( !strcmp( argv[1], "pipipi" ) ) { int nevent = atoi( argv[2] ); runPiPiPi( nevent, myGenerator ); } if ( !strcmp( argv[1], "bhadronic" ) ) { int nevent = atoi( argv[2] ); runBHadronic( nevent, myGenerator ); } if ( !strcmp( argv[1], "singleb" ) ) { int nevent = atoi( argv[2] ); runSingleB( nevent, myGenerator ); } if ( !strcmp( argv[1], "pipi" ) ) { int nevent = atoi( argv[2] ); runPiPi( nevent, myGenerator ); } if ( !strcmp( argv[1], "pipipipi" ) ) { int nevent = atoi( argv[2] ); runPiPiPiPi( nevent, myGenerator ); } if ( !strcmp( argv[1], "a2pi" ) ) { int nevent = atoi( argv[2] ); runA2Pi( nevent, myGenerator ); } if ( !strcmp( argv[1], "helamp" ) ) { int nevent = atoi( argv[2] ); runHelAmp( nevent, myGenerator, argv[3], argv[4] ); } if ( !strcmp( argv[1], "helamp2" ) ) { int nevent = atoi( argv[2] ); runHelAmp2( nevent, myGenerator ); } if ( !strcmp( argv[1], "d2pi" ) ) { int nevent = atoi( argv[2] ); runD2Pi( nevent, myGenerator ); } if ( !strcmp( argv[1], "a1pi" ) ) { int nevent = atoi( argv[2] ); runA1Pi( nevent, myGenerator ); } if ( !strcmp( argv[1], "cptest" ) ) { int nevent = atoi( argv[2] ); runCPTest( nevent, myGenerator ); } if ( !strcmp( argv[1], "pipicpt" ) ) { int nevent = atoi( argv[2] ); runPiPiCPT( nevent, myGenerator ); } if ( !strcmp( argv[1], "jpsiks" ) ) { int nevent = atoi( argv[2] ); runJpsiKs( nevent, myGenerator ); } if ( !strcmp( argv[1], "dump" ) ) { int nevent = atoi( argv[2] ); runDump( nevent, myGenerator ); } if ( !strcmp( argv[1], "genericcont" ) ) { int nevent = atoi( argv[2] ); runGenericCont( nevent, myGenerator ); } if ( !strcmp( argv[1], "d1" ) ) { int nevent = atoi( argv[2] ); runD1( nevent, myGenerator ); } if ( !strcmp( argv[1], "mix" ) ) { int nevent = atoi( argv[2] ); runMix( nevent, myGenerator ); } if ( !strcmp( argv[1], "bmix" ) ) { int nevent = atoi( argv[2] ); runBMix( nevent, myGenerator, argv[3], argv[4] ); } if ( !strcmp( argv[1], "semic" ) ) { int nevent = atoi( argv[2] ); runSemic( nevent, myGenerator ); } if ( !strcmp( argv[1], "ddk" ) ) { int nevent = atoi( argv[2] ); runDDK( nevent, myGenerator ); } if ( !strcmp( argv[1], "checkmass" ) ) { int nevent = atoi( argv[2] ); int partnum = atoi( argv[3] ); runMassCheck( nevent, myGenerator, partnum ); } if ( !strcmp( argv[1], "jpsipolarization" ) ) { int nevent = atoi( argv[2] ); runJpsiPolarization( nevent, myGenerator ); } if ( !strcmp( argv[1], "phspdecaytimecut" ) ) { int nevent = atoi( argv[2] ); runPhspDecaytimeCut( nevent, myGenerator ); } if ( !strcmp( argv[1], "3bodyPhsp" ) ) { int nevent = atoi( argv[2] ); EvtRadCorr::setNeverRadCorr(); run3BPhspRegion( nevent, myGenerator ); } if ( !strcmp( argv[1], "4bodyPhsp" ) ) { int nevent = atoi( argv[2] ); EvtRadCorr::setNeverRadCorr(); runFourBody( nevent, myGenerator ); } //******************************************************* //test of the rotations and boosts performed in EvtGen. // Added by Lange and Ryd Jan 5,2000. //******************************************************* if ( !strcmp( argv[1], "checkrotboost" ) ) { runCheckRotBoost(); } if ( !strcmp( argv[1], "baryonic" ) ) { runBaryonic( atoi( argv[2] ), myGenerator ); } delete myRandomEngine; return 0; } void runFile( int nevent, char* fname, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); int count; char udecay_name[100]; strcpy( udecay_name, fname ); myGenerator.readUDecay( udecay_name ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); root_part->deleteTree(); } while ( count++ < nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPrint( int nevent, char* fname, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); int count; char udecay_name[100]; strcpy( udecay_name, fname ); myGenerator.readUDecay( udecay_name ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); root_part->printTree(); root_part->deleteTree(); } while ( count++ < nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runFileVpho( int nevent, char* fname, EvtGen& myGenerator ) { static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); int count; char udecay_name[100]; strcpy( udecay_name, fname ); myGenerator.readUDecay( udecay_name ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); root_part->deleteTree(); } while ( count++ < nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } /////////////// void runJpsiPolarization( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId JPSI = EvtPDL::getId( std::string( "J/psi" ) ); int count; myGenerator.readUDecay( "exampleFiles/GENERIC.DEC" ); myGenerator.readUDecay( "exampleFiles/JPSITOLL.DEC" ); TFile* file = new TFile( "jpsipolar.root", "RECREATE" ); TH1F* coshel = new TH1F( "h1", "cos hel", 50, -1.0, 1.0 ); TH1F* coshelHigh = new TH1F( "h2", "cos hel pstar gt 1.1", 50, -1.0, 1.0 ); TH1F* coshelLow = new TH1F( "h3", "cos hel pstar lt 1.1", 50, -1.0, 1.0 ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* p = root_part; do { if ( p->getId() == JPSI ) { EvtVector4R p4psi = p->getP4Lab(); EvtVector4R p4Daug = p->getDaug( 0 )->getP4Lab(); double dcostheta = EvtDecayAngle( p_init, p4psi, p4Daug ); coshel->Fill( dcostheta ); if ( p4psi.d3mag() > 1.1 ) { coshelHigh->Fill( dcostheta ); } else { coshelLow->Fill( dcostheta ); } } p = p->nextIter( root_part ); - } while ( p != 0 ); + } while ( p != nullptr ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runMassCheck( int nevent, EvtGen& /*myGenerator*/, int partnum ) { int count; static EvtId myPart = EvtPDL::evtIdFromStdHep( partnum ); TFile* file = new TFile( "checkmass.root", "RECREATE" ); TH1F* mass = new TH1F( "h1", "Mass", 500, 0.0, 2.5 ); count = 1; do { mass->Fill( EvtPDL::getMass( myPart ) ); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPi0Dalitz( int nevent, EvtGen& myGenerator ) { static EvtId PI0 = EvtPDL::getId( std::string( "pi0" ) ); TFile* file = new TFile( "pi0dalitz.root", "RECREATE" ); TH1F* q2 = new TH1F( "h1", "q2", 50, 0.0, 0.02 ); int count; myGenerator.readUDecay( "exampleFiles/PI0DALITZ.DEC" ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( PI0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( PI0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtVector4R ep = root_part->getDaug( 0 )->getP4Lab(); EvtVector4R em = root_part->getDaug( 1 )->getP4Lab(); //EvtVector4R gamma=root_part->getDaug(2)->getP4Lab(); q2->Fill( ( ep + em ).mass2() ); // EvtGenReport(EVTGEN_INFO,"EvtGen") << ep << em << gamma <deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } //******************************************************************************* void runTest1( int nevent, EvtGen& myGenerator ) { // TFile *file=new TFile("test1.root", "RECREATE"); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); // int first=0; // char **second; // TApplication *theApp = new TApplication("App", &first, second); TFile* file = new TFile( "test1.root", "RECREATE", "Example" ); TH1F* costhetaB = new TH1F( "hcosthetaB", "costhetaB", 50, -1.0, 1.0 ); TH1F* phiB = new TH1F( "hphiB", "phiB", 50, -EvtConst::pi, EvtConst::pi ); TH1F* Elep = new TH1F( "hEl", "E?l!", 50, 0.0, 2.5 ); TH1F* q2 = new TH1F( "hq2", "q^2!", 44, 0.0, 11.0 ); TH1F* ctv = new TH1F( "hctv", "ctv", 50, -1.0, 1.0 ); TH1F* chi_low_ctv = new TH1F( "hcostv1", "[h] for cos[Q]?V!\"L#0", 50, 0.0, EvtConst::twoPi ); TH1F* chi_high_ctv = new TH1F( "hcostv2", "[h] for cos[Q]?V!\"G#0", 50, 0.0, EvtConst::twoPi ); TH1F* dt = new TH1F( "hdt", "dt", 50, -5.0, 5.0 ); int count; EvtVector4R p4b0, p4b0b, p4dstar, p4e, p4nu, p4d, p4pi, p4pip, p4pim; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/TEST1.DEC" ); // EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); double costhetaV; count = 1; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); p4b0 = root_part->getDaug( 0 )->getP4Lab(); p4b0b = root_part->getDaug( 1 )->getP4Lab(); p4dstar = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4e = root_part->getDaug( 0 )->getDaug( 1 )->getP4Lab(); p4nu = root_part->getDaug( 0 )->getDaug( 2 )->getP4Lab(); p4d = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4pi = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 1 )->getP4Lab(); p4pip = root_part->getDaug( 1 )->getDaug( 0 )->getP4Lab(); p4pim = root_part->getDaug( 1 )->getDaug( 1 )->getP4Lab(); costhetaB->Fill( p4b0.get( 3 ) / p4b0.d3mag() ); phiB->Fill( atan2( p4b0.get( 1 ), p4b0.get( 2 ) ) ); Elep->Fill( p4b0 * p4e / p4b0.mass() ); q2->Fill( ( p4e + p4nu ).mass2() ); dt->Fill( root_part->getDaug( 1 )->getLifetime() - root_part->getDaug( 0 )->getLifetime() ); costhetaV = EvtDecayAngle( p4b0, p4d + p4pi, p4d ); ctv->Fill( costhetaV ); if ( costhetaV < 0.0 ) { chi_low_ctv->Fill( EvtDecayAngleChi( p4b0, p4d, p4pi, p4e, p4nu ) ); } else { chi_high_ctv->Fill( EvtDecayAngleChi( p4b0, p4d, p4pi, p4e, p4nu ) ); } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); // delete theApp; // hfile.write(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } //******************************************************************************* void runDDK( int nevent, EvtGen& myGenerator ) { // TFile *file=new TFile("test1.root", "RECREATE"); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); int count; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/GENERIC.DEC" ); myGenerator.readUDecay( udecay_name ); count = 1; static EvtId kp = EvtPDL::getId( std::string( "K+" ) ); static EvtId km = EvtPDL::getId( std::string( "K-" ) ); static EvtId ks = EvtPDL::getId( std::string( "K_S0" ) ); static EvtId kl = EvtPDL::getId( std::string( "K_L0" ) ); static EvtId k0 = EvtPDL::getId( std::string( "K0" ) ); static EvtId kb = EvtPDL::getId( std::string( "anti-K0" ) ); static EvtId d0 = EvtPDL::getId( std::string( "D0" ) ); static EvtId dp = EvtPDL::getId( std::string( "D+" ) ); static EvtId dm = EvtPDL::getId( std::string( "D-" ) ); static EvtId db = EvtPDL::getId( std::string( "anti-D0" ) ); static EvtIdSet theKs( kp, km, ks, kl, k0, kb ); static EvtIdSet theDs( d0, dp, dm, db ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); static EvtId BP = EvtPDL::getId( std::string( "B+" ) ); static EvtId BM = EvtPDL::getId( std::string( "B-" ) ); static EvtIdSet theBs( B0B, B0, BP, BM ); int nDDK = 0; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* theB01 = root_part->getDaug( 0 ); EvtParticle* theB02 = root_part->getDaug( 1 ); int nD = 0; int nK = 0; EvtParticle* p = theB01; do { EvtId type = p->getId(); EvtId typePar = p->getParent()->getId(); if ( theDs.contains( type ) ) nD++; if ( theKs.contains( type ) && theBs.contains( typePar ) ) nK++; p = p->nextIter( theB01 ); - } while ( p != 0 ); + } while ( p != nullptr ); if ( nD == 2 && nK == 1 ) nDDK++; nD = 0; nK = 0; p = theB02; do { EvtId type = p->getId(); EvtId typePar = p->getParent()->getId(); if ( theDs.contains( type ) ) nD++; if ( theKs.contains( type ) && theBs.contains( typePar ) ) nK++; p = p->nextIter( theB02 ); - } while ( p != 0 ); + } while ( p != nullptr ); if ( nD == 2 && nK == 1 ) nDDK++; root_part->deleteTree(); } while ( count++ < nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << nDDK << " " << ( count - 1 ) << " " << nDDK / float( 2 * ( count - 1 ) ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } //******************************************************************************* void runTest2( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "test2.root", "RECREATE" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); TH1F* costhetaB = new TH1F( "h1", "cos[Q]?B!", 50, -1.0, 1.0 ); TH1F* phiB = new TH1F( "h2", "[f]?B!", 50, -EvtConst::pi, EvtConst::pi ); TH1F* dt = new TH1F( "h3", "[D]t", 100, -5.0, 5.0 ); TH1F* costhetaJpsi = new TH1F( "h4", "cos[Q]?J/[y]!", 50, -1.0, 1.0 ); TH1F* costhetaKstar = new TH1F( "h5", "cos[Q]?K*!", 50, -1.0, 1.0 ); TH1F* chi = new TH1F( "h6", "[h]", 50, 0.0, EvtConst::twoPi ); TH1F* chi1 = new TH1F( "h26", "[h] [D]t\"L#0", 50, 0.0, EvtConst::twoPi ); TH1F* chi2 = new TH1F( "h27", "[h] [D]t\"G#0", 50, 0.0, EvtConst::twoPi ); TH1F* costhetaomega = new TH1F( "h7", "costhetaomega", 50, -1.0, 1.0 ); TH1F* costhetaomega1 = new TH1F( "h20", "costhetaomega1", 50, -1.0, 1.0 ); TH1F* costhetaomega2 = new TH1F( "h21", "costhetaomega2", 50, -1.0, 1.0 ); TH1F* costhetaomega3 = new TH1F( "h22", "costhetaomega3", 50, -1.0, 1.0 ); TH1F* omegaamp = new TH1F( "h8", "omegaamp", 50, 0.0, 0.05 ); TH1F* omegaamp1 = new TH1F( "h9", "omegaamp1", 50, 0.0, 0.05 ); TH1F* omegaamp2 = new TH1F( "h10", "omegaamp2", 50, 0.0, 0.05 ); TH1F* omegaamp3 = new TH1F( "h11", "omegaamp3", 50, 0.0, 0.05 ); TH2F* chi1vscoskstarl = new TH2F( "h30", "[h] vs. cos[Q]?J/[y]! [D]t\"L#0", 20, 0.0, EvtConst::twoPi, 20, -1.0, 1.0 ); TH2F* chi1vscoskstarg = new TH2F( "h31", "[h] vs. cos[Q]?J/[y]! [D]t\"G#0", 20, 0.0, EvtConst::twoPi, 20, -1.0, 1.0 ); int count = 1; EvtVector4R p4_b0, p4_b0b, p4_psi, p4_kstar, p4_mup, p4_mum; EvtVector4R p4_kz, p4_pi0, p4_pi1, p4_pi2, p4_pi3, p4_omega; EvtVector4R p4_pi1_omega, p4_pi2_omega, p4_pi3_omega; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/TEST2.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); p4_b0 = root_part->getDaug( 0 )->getP4Lab(); p4_b0b = root_part->getDaug( 1 )->getP4Lab(); p4_psi = root_part->getDaug( 1 )->getDaug( 0 )->getP4Lab(); p4_kstar = root_part->getDaug( 1 )->getDaug( 1 )->getP4Lab(); p4_mup = root_part->getDaug( 1 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4_mum = root_part->getDaug( 1 )->getDaug( 0 )->getDaug( 1 )->getP4Lab(); p4_kz = root_part->getDaug( 1 )->getDaug( 1 )->getDaug( 0 )->getP4Lab(); p4_pi0 = root_part->getDaug( 1 )->getDaug( 1 )->getDaug( 1 )->getP4Lab(); p4_omega = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4_pi1 = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4_pi2 = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 1 )->getP4Lab(); p4_pi3 = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 2 )->getP4Lab(); //get momentum in the omega restframe p4_pi1_omega = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4(); p4_pi2_omega = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 1 )->getP4(); p4_pi3_omega = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 2 )->getP4(); EvtVector3R p3_perp = cross( EvtVector3R( p4_pi2_omega.get( 0 ), p4_pi2_omega.get( 1 ), p4_pi2_omega.get( 2 ) ), EvtVector3R( p4_pi3_omega.get( 0 ), p4_pi3_omega.get( 1 ), p4_pi3_omega.get( 2 ) ) ); EvtVector4R p4_perp( p3_perp.d3mag(), p3_perp.get( 0 ), p3_perp.get( 1 ), p3_perp.get( 2 ) ); root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->setP4( p4_perp ); p4_perp = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); EvtVector4R p4_perpprime = p4_omega - p4_perp; double d_omegaamp = EvtVector3R( p4_pi1_omega.get( 0 ), p4_pi1_omega.get( 1 ), p4_pi1_omega.get( 2 ) ) * p3_perp; d_omegaamp *= d_omegaamp; d_omegaamp *= 20.0; double d_dt = root_part->getDaug( 1 )->getLifetime() - root_part->getDaug( 0 )->getLifetime(); double d_costhetaJpsi = EvtDecayAngle( p4_b0b, p4_mup + p4_mum, p4_mup ); double d_costhetaKstar = EvtDecayAngle( p4_b0b, p4_pi0 + p4_kz, p4_pi0 ); double d_chi = EvtDecayAngleChi( p4_b0b, p4_pi0, p4_kz, p4_mup, p4_mum ); costhetaB->Fill( p4_b0.get( 3 ) / p4_b0.d3mag() ); phiB->Fill( atan2( p4_b0.get( 1 ), p4_b0.get( 2 ) ) ); dt->Fill( d_dt ); costhetaJpsi->Fill( d_costhetaJpsi ); costhetaKstar->Fill( d_costhetaKstar ); chi->Fill( d_chi ); if ( d_dt < 0.0 ) { chi1->Fill( d_chi ); chi1vscoskstarl->Fill( d_chi, d_costhetaJpsi, 1.0 ); } if ( d_dt > 0.0 ) { chi2->Fill( d_chi ); chi1vscoskstarg->Fill( d_chi, d_costhetaJpsi, 1.0 ); } double d_costhetaomega = EvtDecayAngle( p4_b0b, p4_perp + p4_perpprime, p4_perp ); costhetaomega->Fill( d_costhetaomega ); if ( d_omegaamp < 0.001 ) costhetaomega1->Fill( d_costhetaomega ); if ( d_omegaamp > 0.02 ) costhetaomega2->Fill( d_costhetaomega ); if ( std::fabs( d_omegaamp - 0.015 ) < 0.005 ) costhetaomega3->Fill( d_costhetaomega ); omegaamp->Fill( d_omegaamp ); if ( d_costhetaomega < -0.5 ) omegaamp1->Fill( d_omegaamp ); if ( d_costhetaomega > 0.5 ) omegaamp2->Fill( d_omegaamp ); if ( std::fabs( d_costhetaomega ) < 0.5 ) omegaamp3->Fill( d_omegaamp ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runOmega( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "omega.root", "RECREATE" ); static EvtId OMEGA = EvtPDL::getId( std::string( "omega" ) ); TH2F* dalitz = new TH2F( "h1", "E1 vs E2", 50, 0.0, 0.5, 50, 0.0, 0.5 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/OMEGA.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMeanMass( OMEGA ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( OMEGA, p_init ); //root_part->setDiagonalSpinDensity(); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); dalitz->Fill( root_part->getDaug( 0 )->getP4().get( 0 ), root_part->getDaug( 1 )->getP4().get( 0 ), 1.0 ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runChi1Kstar( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "chi1kstar.root", "RECREATE" ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); TH1F* costhetaChi1 = new TH1F( "h1", "cos[Q]?J/[x]!", 50, -1.0, 1.0 ); TH1F* costhetaKstar = new TH1F( "h2", "cos[Q]?K*!", 50, -1.0, 1.0 ); TH1F* chi = new TH1F( "h3", "[x]", 50, -EvtConst::pi, EvtConst::pi ); int count = 1; EvtVector4R p4_b, p4_chi, p4_kstar, p4_gamma, p4_psi, p4_k, p4_p; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/CHI1KSTAR.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); myGenerator.generateDecay( root_part ); p4_b = root_part->getP4Lab(); p4_chi = root_part->getDaug( 0 )->getP4Lab(); p4_kstar = root_part->getDaug( 1 )->getP4Lab(); p4_psi = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4_gamma = root_part->getDaug( 0 )->getDaug( 1 )->getP4Lab(); p4_k = root_part->getDaug( 1 )->getDaug( 0 )->getP4Lab(); p4_p = root_part->getDaug( 1 )->getDaug( 1 )->getP4Lab(); double d_costhetaChi1 = EvtDecayAngle( p4_b, p4_chi, p4_psi ); double d_costhetaKstar = EvtDecayAngle( p4_b, p4_kstar, p4_k ); double d_chi = EvtDecayAngleChi( p4_b, p4_k, p4_p, p4_psi, p4_gamma ); if ( d_chi > EvtConst::pi ) d_chi -= EvtConst::twoPi; costhetaChi1->Fill( d_costhetaChi1 ); costhetaKstar->Fill( d_costhetaKstar ); chi->Fill( d_chi ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runAlias() { EvtId idpip = EvtPDL::getId( std::string( "pi+" ) ); EvtPDL::alias( idpip, std::string( "my_pi+" ) ); EvtId myidpip = EvtPDL::getId( std::string( "my_pi+" ) ); EvtId idpim = EvtPDL::getId( std::string( "pi-" ) ); EvtPDL::alias( idpim, std::string( "my_pi-" ) ); EvtId myidpim = EvtPDL::getId( std::string( "my_pi-" ) ); EvtId idpi0 = EvtPDL::getId( std::string( "pi0" ) ); EvtPDL::alias( idpi0, std::string( "my_pi0" ) ); EvtId myidpi0 = EvtPDL::getId( std::string( "my_pi0" ) ); EvtPDL::aliasChgConj( myidpip, myidpim ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Id pi+:" << idpip << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Id pi-:" << idpim << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Id pi0:" << idpi0 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Id my_pi+:" << myidpip << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Id my_pi-:" << myidpim << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Id my_pi0:" << myidpi0 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Chg conj pi+:" << EvtPDL::chargeConj( idpip ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Chg conj pi-:" << EvtPDL::chargeConj( idpim ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Chg conj pi0:" << EvtPDL::chargeConj( idpi0 ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Chg conj my_pi+:" << EvtPDL::chargeConj( myidpip ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Chg conj my_pi-:" << EvtPDL::chargeConj( myidpim ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Chg conj my_pi0:" << EvtPDL::chargeConj( myidpi0 ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runRepeat( int nevent ) { int i; for ( i = 0; i < nevent; i++ ) { EvtDecayTable::getInstance()->readDecayFile( std::string( "../DECAY.DEC" ) ); } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPhotos( int nevent, EvtGen& myGenerator ) { static EvtId PSI = EvtPDL::getId( std::string( "J/psi" ) ); TFile* file = new TFile( "photos.root", "RECREATE" ); TH1F* mee = new TH1F( "h1", "mee", 60, 3.0, 3.12 ); int count = 1; EvtVector4R e1, e2; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/PHOTOS.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( PSI ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( PSI, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); e1 = root_part->getDaug( 0 )->getP4Lab(); e2 = root_part->getDaug( 1 )->getP4Lab(); mee->Fill( ( e1 + e2 ).mass() ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runFinalStates( int nevent, EvtGen& myGenerator ) { //Parse the table of particles to find.. EvtParser parser; parser.read( std::string( "exampleFiles/finalstates.list" ) ); std::vector dList[20]; int dListNum[20]; - std::vector* dListItem = 0; + std::vector* dListItem = nullptr; std::string dListName[20]; int ik, lk; std::string tk = ""; int tline = -1; std::string parent; for ( ik = 0; ik < parser.getNToken(); ik++ ) { lk = tline; tline = parser.getLineofToken( ik ); tk = parser.getToken( ik ); if ( lk != tline && tline > 2 ) { if ( tline > 1 ) { dList[tline - 3] = *dListItem; dListItem = new std::vector; dListNum[tline - 3] = 0; dListName[tline - 2] = parser.getToken( ik ); } } else { if ( tline == 1 ) { //This is the parent particle name parent = parser.getToken( ik ); dListItem = new std::vector; } else { //This is one of the daughters if ( tline != 2 || ( lk == tline ) ) { dListItem->push_back( parser.getToken( ik ) ); } if ( tline == 2 && ( lk != tline ) ) { dListName[tline - 2] = parser.getToken( ik ); } } } } dList[tline - 2] = *dListItem; dListNum[tline - 2] = 0; static EvtId parId = EvtPDL::getId( parent ); int count = 0; do { if ( count == 1000 * ( count / 1000 ) ) { //if (count==1*(count/1)) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Event:" << count << std::endl; //EvtGenReport(EVTGEN_INFO,"EvtGen") << HepRandom::getTheSeed()<setVectorSpinDensity(); } else { root_part->setDiagonalSpinDensity(); } myGenerator.generateDecay( root_part ); EvtParticle* p = root_part; std::vector fs = findFinalState( p ); int j; for ( j = 0; j < ( tline - 1 ); j++ ) { std::vector temp = dList[j]; if ( temp.size() == fs.size() ) { bool foundIt = true; unsigned int k, l; std::vector alreadyUsed( temp.size() ); for ( k = 0; k < temp.size(); k++ ) { bool foundThisOne = false; for ( l = 0; l < temp.size(); l++ ) { if ( k == 0 ) alreadyUsed[l] = false; if ( foundThisOne || alreadyUsed[l] ) continue; if ( temp[k] == fs[l] ) { alreadyUsed[l] = true; foundThisOne = true; // EvtGenReport(EVTGEN_INFO,"EvtGen") << "found daughter " << k << " " << l << std::endl; } } if ( !foundThisOne ) foundIt = false; } if ( foundIt ) { //EvtGenReport(EVTGEN_INFO,"EvtGen") << "found a cand \n"; (histo1[j])->Fill(0.5); //EvtGenReport(EVTGEN_INFO,"EvtGen") << "found one " << j << std::endl; dListNum[j]++; } } } root_part->deleteTree(); count++; } while ( count < nevent ); int j; for ( j = 0; j < ( tline - 1 ); j++ ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << dListName[j].c_str() << " " << j << " " << dListNum[j] << " " << count << " " << ( dListNum[j] / ( 1.0 * count ) ) << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } std::vector findFinalState( EvtParticle* tree ) { EvtParticle* p = tree; std::vector fs; static EvtId ep = EvtPDL::getId( std::string( "e+" ) ); static EvtId em = EvtPDL::getId( std::string( "e-" ) ); static EvtId kp = EvtPDL::getId( std::string( "K+" ) ); static EvtId km = EvtPDL::getId( std::string( "K-" ) ); static EvtId mup = EvtPDL::getId( std::string( "mu+" ) ); static EvtId mum = EvtPDL::getId( std::string( "mu-" ) ); static EvtId pip = EvtPDL::getId( std::string( "pi+" ) ); static EvtId pim = EvtPDL::getId( std::string( "pi-" ) ); static EvtId pi0 = EvtPDL::getId( std::string( "pi0" ) ); static EvtId pr = EvtPDL::getId( std::string( "p+" ) ); static EvtId apr = EvtPDL::getId( std::string( "anti-p-" ) ); static EvtId ne = EvtPDL::getId( std::string( "n0" ) ); static EvtId ane = EvtPDL::getId( std::string( "anti-n0" ) ); do { EvtId type = p->getId(); if ( type == ep ) fs.push_back( std::string( "e+" ) ); if ( type == em ) fs.push_back( std::string( "e-" ) ); if ( type == mup ) fs.push_back( std::string( "mu+" ) ); if ( type == mum ) fs.push_back( std::string( "mu-" ) ); if ( type == kp ) fs.push_back( std::string( "K+" ) ); if ( type == km ) fs.push_back( std::string( "K-" ) ); if ( type == pip ) fs.push_back( std::string( "pi+" ) ); if ( type == pim ) fs.push_back( std::string( "pi-" ) ); if ( type == pi0 ) fs.push_back( std::string( "pi0" ) ); if ( type == pr ) fs.push_back( std::string( "p+" ) ); if ( type == apr ) fs.push_back( std::string( "anti-p-" ) ); if ( type == ne ) fs.push_back( std::string( "n0" ) ); if ( type == ane ) fs.push_back( std::string( "anti-n0" ) ); p = p->nextIter(); - } while ( p != 0 ); + } while ( p != nullptr ); return fs; } void runTrackMult( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "trackmult.root", "RECREATE" ); TH1F* trackAll = new TH1F( "trackAll", "trackAll", 12, 1.0, 25.0 ); TH1F* trackNoSL = new TH1F( "trackNoSL", "trackNoSL", 12, 1.0, 25.0 ); TH1F* track1SL = new TH1F( "track1SL", "track1SL", 12, 1.0, 25.0 ); TH1F* track2SL = new TH1F( "track2SL", "track2SL", 12, 1.0, 25.0 ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); static EvtId BP = EvtPDL::getId( std::string( "B+" ) ); static EvtId BM = EvtPDL::getId( std::string( "B-" ) ); //look for these tracks in generic events static EvtId ep = EvtPDL::getId( std::string( "e+" ) ); static EvtId em = EvtPDL::getId( std::string( "e-" ) ); static EvtId mup = EvtPDL::getId( std::string( "mu+" ) ); static EvtId mum = EvtPDL::getId( std::string( "mu-" ) ); static EvtId pip = EvtPDL::getId( std::string( "pi+" ) ); static EvtId pim = EvtPDL::getId( std::string( "pi-" ) ); static EvtId kp = EvtPDL::getId( std::string( "K+" ) ); static EvtId km = EvtPDL::getId( std::string( "K-" ) ); static EvtId pp = EvtPDL::getId( std::string( "p+" ) ); static EvtId pm = EvtPDL::getId( std::string( "anti-p-" ) ); static EvtIdSet theTracks( ep, em, mup, mum, pip, pim, kp, km, pp, pm ); static EvtIdSet theLeptons( ep, em, mup, mum ); static EvtIdSet theBs( B0, B0B, BP, BM ); int count = 1; EvtParticle* p; myGenerator.readUDecay( "exampleFiles/GENERIC.DEC" ); int totTracks = 0; int totTracksNoSL = 0; int totTracks1SL = 0; int totTracks2SL = 0; int totNoSL = 0; int tot1SL = 0; int tot2SL = 0; do { int evTracks = 0; if ( count == 1000 * ( count / 1000 ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << count << std::endl; //EvtGenReport(EVTGEN_INFO,"EvtGen") << HepRandom::getTheSeed()<setVectorSpinDensity(); myGenerator.generateDecay( root_part ); p = root_part; int howManySL = 0; do { if ( theTracks.contains( p->getId() ) ) { totTracks += 1; evTracks += 1; } if ( theLeptons.contains( p->getId() ) ) { if ( p->getParent() ) { if ( theBs.contains( p->getParent()->getId() ) ) howManySL += 1; } } p = p->nextIter( root_part ); - } while ( p != 0 ); + } while ( p != nullptr ); //Now need to figure out which histogram to book trackAll->Fill( evTracks ); if ( howManySL == 0 ) { trackNoSL->Fill( evTracks ); totNoSL += 1; totTracksNoSL += evTracks; } if ( howManySL == 1 ) { track1SL->Fill( evTracks ); tot1SL += 1; totTracks1SL += evTracks; } if ( howManySL == 2 ) { track2SL->Fill( evTracks ); tot2SL += 1; totTracks2SL += evTracks; } root_part->deleteTree(); } while ( count++ < nevent ); double aveMulti = float( totTracks ) / float( nevent ); double aveMultiNoSL = float( totTracksNoSL ) / float( totNoSL ); double aveMulti1SL = float( totTracks1SL ) / float( tot1SL ); double aveMulti2SL = float( totTracks2SL ) / float( tot2SL ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Your average multiplicity=" << aveMulti << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Your average multiplicity for no B->semileptonic events=" << aveMultiNoSL << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Your average multiplicity for 1 B->semileptonic events=" << aveMulti1SL << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Your average multiplicity for 2 B->semileptonic events=" << aveMulti2SL << std::endl; file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runGeneric( int neventOrig, EvtGen& myGenerator, std::string listfile ) { int nevent = abs( neventOrig ); //Parse the table of particles to find.. TFile* file = new TFile( "generic.root", "RECREATE" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); static EvtId BP = EvtPDL::getId( std::string( "B+" ) ); static EvtId BM = EvtPDL::getId( std::string( "B-" ) ); static EvtIdSet theBs( B0B, B0, BP, BM ); static EvtIdSet theB0B( B0B ); static EvtIdSet theB0( B0 ); static EvtIdSet theBP( BP ); static EvtIdSet theBM( BM ); static EvtId D0 = EvtPDL::getId( std::string( "D0" ) ); static EvtId D0B = EvtPDL::getId( std::string( "anti-D0" ) ); static EvtId DP = EvtPDL::getId( std::string( "D+" ) ); static EvtId DM = EvtPDL::getId( std::string( "D-" ) ); static EvtIdSet theDs( D0B, D0, DP, DM ); static EvtIdSet theD0B( D0B ); static EvtIdSet theD0( D0 ); static EvtIdSet theDP( DP ); static EvtIdSet theDM( DM ); int count; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/GENERIC.DEC" ); myGenerator.readUDecay( udecay_name ); if ( listfile != "" ) { EvtParser parser; if ( parser.read( listfile ) != 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate." << std::endl; exit( -1 ); } std::vector histo1( parser.getNToken() ); std::vector histo2( parser.getNToken() ); std::vector massHisto( parser.getNToken() ); int ik; std::string tk, tkname; for ( ik = 0; ik < ( parser.getNToken() / 2 ); ik++ ) { tk = parser.getToken( 2 * ik ); tkname = parser.getToken( 1 + 2 * ik ); histo1[ik] = new TH1F( tkname.c_str(), tkname.c_str(), 30, 0.0, 3.0 ); char* directName; directName = new char[( strlen( tkname.c_str() ) + 8 )]; directName = strcpy( directName, tkname.c_str() ); directName = strcat( directName, "Direct" ); histo2[ik] = new TH1F( directName, directName, 30, 0.0, 3.0 ); delete directName; char* massName; massName = new char[( strlen( tkname.c_str() ) + 4 )]; massName = strcpy( massName, tkname.c_str() ); massName = strcat( massName, "Mass" ); massHisto[ik] = new TH1F( massName, massName, 3000, 0.0, 5.0 ); delete massName; } count = 1; std::vector temp( parser.getNToken() / 2, 0 ); std::vector tempB( parser.getNToken() / 2, 0 ); std::vector tempB0B( parser.getNToken() / 2, 0 ); std::vector tempB0( parser.getNToken() / 2, 0 ); std::vector tempBP( parser.getNToken() / 2, 0 ); std::vector tempBM( parser.getNToken() / 2, 0 ); std::vector tempD( parser.getNToken() / 2, 0 ); std::vector tempD0B( parser.getNToken() / 2, 0 ); std::vector tempD0( parser.getNToken() / 2, 0 ); std::vector tempDP( parser.getNToken() / 2, 0 ); std::vector tempDM( parser.getNToken() / 2, 0 ); do { //EvtGenReport(EVTGEN_INFO,"EvtGen") << "new event\n"; if ( count == 1000 * ( count / 1000 ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << count << std::endl; //EvtGenReport(EVTGEN_INFO,"EvtGen") << HepRandom::getTheSeed()< 0 ) { root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); } else { root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); } root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); //EvtStdHep stdhep; //stdhep.init(); //root_part->makeStdHep(stdhep); //EvtGenReport(EVTGEN_INFO,"EvtGen") <printTree(); root_part->deleteTree(); } while ( count++ < nevent ); int itok; std::string token; for ( itok = 0; itok < ( parser.getNToken() / 2 ); itok++ ) { token = parser.getToken( 2 * itok ); float br = 0.5 * float( temp[itok] ) / float( nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Found " << temp[itok] << " " << token.c_str() << " in " << nevent << " events. Average number of " << token.c_str() << " per B meson=" << br << std::endl; br = 0.5 * float( tempB[itok] ) / float( nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Found " << tempB[itok] << " " << token.c_str() << " produced directly in decays of B mesons avg. br.fr.=" << br << std::endl; br = 2.0 * float( tempB0[itok] ) / float( nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Found " << tempB0[itok] << " " << token.c_str() << " in decay tree of B0, br.fr.=" << br << std::endl; br = 2.0 * float( tempB0B[itok] ) / float( nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Found " << tempB0B[itok] << " " << token.c_str() << " in decay tree of anti-B0, br.fr.=" << br << std::endl; br = 2.0 * float( tempBP[itok] ) / float( nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Found " << tempBP[itok] << " " << token.c_str() << " in decay tree of B+, br.fr.=" << br << std::endl; br = 2.0 * float( tempBM[itok] ) / float( nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Found " << tempBM[itok] << " " << token.c_str() << " in decay tree of B-, br.fr.=" << br << std::endl; // br=0.5*float(tempD[itok])/float(numd0+numd0b+numdm+numdp); // EvtGenReport(EVTGEN_INFO,"EvtGen") << "Found "< 0 ) { root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); } else { root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); } root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); root_part->deleteTree(); } while ( count++ < nevent ); } file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runKstarnunu( int nevent, EvtGen& myGenerator ) { static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); //static EvtId B0B=EvtPDL::getId(std::string("anti-B0")); TFile* file = new TFile( "kstarnunu.root", "RECREATE" ); TH1F* q2 = new TH1F( "h1", "q2", 50, 0.0, 25.0 ); TH1F* enu = new TH1F( "h2", "Neutrino energy", 50, 0.0, 5.0 ); TH1F* x = new TH1F( "h3", "Total neutrino energy/B mass", 50, 0.5, 0.9 ); int count; EvtVector4R kstar, nu, nub; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/KSTARNUNU.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); kstar = root_part->getDaug( 0 )->getP4Lab(); nu = root_part->getDaug( 1 )->getP4Lab(); nub = root_part->getDaug( 2 )->getP4Lab(); q2->Fill( ( nu + nub ).mass2() ); enu->Fill( nu.get( 0 ) ); x->Fill( ( nu.get( 0 ) + nub.get( 0 ) ) / root_part->mass() ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runBsmix( int nevent, EvtGen& myGenerator ) { static EvtId BS0 = EvtPDL::getId( std::string( "B_s0" ) ); static EvtId BSB = EvtPDL::getId( std::string( "anti-B_s0" ) ); TFile* file = new TFile( "bsmix.root", "RECREATE" ); TH1F* tmix = new TH1F( "h1", "tmix (mm)", 100, 0.0, 5.0 ); TH1F* tnomix = new TH1F( "h2", "tnomix (mm)", 100, 0.0, 5.0 ); int count; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/BSMIX.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( BS0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( BS0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); double t = root_part->getLifetime(); int mix = 0; if ( root_part->getNDaug() == 1 ) { if ( root_part->getDaug( 0 )->getId() == BSB ) { mix = 1; } } if ( mix == 0 ) tnomix->Fill( t ); if ( mix == 1 ) tmix->Fill( t ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runSemic( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId EP = EvtPDL::getId( std::string( "e+" ) ); static EvtId EM = EvtPDL::getId( std::string( "e-" ) ); static EvtId DST0 = EvtPDL::getId( std::string( "D*0" ) ); static EvtId DSTB = EvtPDL::getId( std::string( "anti-D*0" ) ); static EvtId DSTP = EvtPDL::getId( std::string( "D*+" ) ); static EvtId DSTM = EvtPDL::getId( std::string( "D*-" ) ); static EvtId D0 = EvtPDL::getId( std::string( "D0" ) ); static EvtId D0B = EvtPDL::getId( std::string( "anti-D0" ) ); static EvtId DP = EvtPDL::getId( std::string( "D+" ) ); static EvtId DM = EvtPDL::getId( std::string( "D-" ) ); static EvtId D1P1P = EvtPDL::getId( std::string( "D_1+" ) ); static EvtId D1P1N = EvtPDL::getId( std::string( "D_1-" ) ); static EvtId D1P10 = EvtPDL::getId( std::string( "D_10" ) ); static EvtId D1P1B = EvtPDL::getId( std::string( "anti-D_10" ) ); static EvtId D3P2P = EvtPDL::getId( std::string( "D_2*+" ) ); static EvtId D3P2N = EvtPDL::getId( std::string( "D_2*-" ) ); static EvtId D3P20 = EvtPDL::getId( std::string( "D_2*0" ) ); static EvtId D3P2B = EvtPDL::getId( std::string( "anti-D_2*0" ) ); static EvtId D3P1P = EvtPDL::getId( std::string( "D'_1+" ) ); static EvtId D3P1N = EvtPDL::getId( std::string( "D'_1-" ) ); static EvtId D3P10 = EvtPDL::getId( std::string( "D'_10" ) ); static EvtId D3P1B = EvtPDL::getId( std::string( "anti-D'_10" ) ); static EvtId D3P0P = EvtPDL::getId( std::string( "D_0*+" ) ); static EvtId D3P0N = EvtPDL::getId( std::string( "D_0*-" ) ); static EvtId D3P00 = EvtPDL::getId( std::string( "D_0*0" ) ); static EvtId D3P0B = EvtPDL::getId( std::string( "anti-D_0*0" ) ); static EvtId D23S1P = EvtPDL::getId( std::string( "D*(2S)+" ) ); static EvtId D23S1N = EvtPDL::getId( std::string( "D*(2S)-" ) ); static EvtId D23S10 = EvtPDL::getId( std::string( "D*(2S)0" ) ); static EvtId D23S1B = EvtPDL::getId( std::string( "anti-D*(2S)0" ) ); static EvtIdSet radExitDstar( D23S1P, D23S1N, D23S10, D23S1B ); TFile* file = new TFile( "semic.root", "RECREATE" ); TH1F* Dpe_q2 = new TH1F( "h11", "q2 for B0B ->D+ e- nu", 50, 0.0, 12.0 ); TH1F* Dpe_elep = new TH1F( "h12", "Elep for B0B ->D+ e- nu", 50, 0.0, 2.5 ); TH1F* Dme_q2 = new TH1F( "h13", "q2 for B0 ->D- e+ nu", 50, 0.0, 12.0 ); TH1F* Dme_elep = new TH1F( "h14", "Elep for B0 ->D- e+ nu", 50, 0.0, 2.5 ); TH1F* D0e_q2 = new TH1F( "h15", "q2 for B- ->D0 e- nu", 50, 0.0, 12.0 ); TH1F* D0e_elep = new TH1F( "h16", "Elep for B- ->D0 e- nu", 50, 0.0, 2.5 ); TH1F* D0Be_q2 = new TH1F( "h17", "q2 for B+ ->D0B e+ nu", 50, 0.0, 12.0 ); TH1F* D0Be_elep = new TH1F( "h18", "Elep for B+ ->D0B e+ nu", 50, 0.0, 2.5 ); TH1F* Dstpe_q2 = new TH1F( "h21", "q2 for B0B ->D*+ e- nu", 50, 0.0, 12.0 ); TH1F* Dstpe_elep = new TH1F( "h22", "Elep for B0B ->D*+ e- nu", 50, 0.0, 2.5 ); TH1F* Dstme_q2 = new TH1F( "h23", "q2 for B0 ->D*- e+ nu", 50, 0.0, 12.0 ); TH1F* Dstme_elep = new TH1F( "h24", "Elep for B0 ->D*- e+ nu", 50, 0.0, 2.5 ); TH1F* Dst0e_q2 = new TH1F( "h25", "q2 for B- ->D*0 e- nu", 50, 0.0, 12.0 ); TH1F* Dst0e_elep = new TH1F( "h26", "Elep for B*- ->D*0 e- nu", 50, 0.0, 2.5 ); TH1F* Dst0Be_q2 = new TH1F( "h27", "q2 for B+ ->D*0B e+ nu", 50, 0.0, 12.0 ); TH1F* Dst0Be_elep = new TH1F( "h28", "Elep for B+ ->D*0B e+ nu", 50, 0.0, 2.5 ); TH1F* D1P1pe_q2 = new TH1F( "h31", "q2 for B0B ->1P1+ e- nu", 50, 0.0, 12.0 ); TH1F* D1P1pe_elep = new TH1F( "h32", "Elep for B0B ->1P1+ e- nu", 50, 0.0, 2.5 ); TH1F* D1P1me_q2 = new TH1F( "h33", "q2 for B0 ->1P1- e+ nu", 50, 0.0, 12.0 ); TH1F* D1P1me_elep = new TH1F( "h34", "Elep for B0 ->1P1- e+ nu", 50, 0.0, 2.5 ); TH1F* D1P10e_q2 = new TH1F( "h35", "q2 for B- ->1P10 e- nu", 50, 0.0, 12.0 ); TH1F* D1P10e_elep = new TH1F( "h36", "Elep for B*- ->1P10 e- nu", 50, 0.0, 2.5 ); TH1F* D1P10Be_q2 = new TH1F( "h37", "q2 for B+ ->1P1B e+ nu", 50, 0.0, 12.0 ); TH1F* D1P10Be_elep = new TH1F( "h38", "Elep for B+ ->1P1B e+ nu", 50, 0.0, 2.5 ); TH1F* D3P0pe_q2 = new TH1F( "h41", "q2 for B0B ->3P0+ e- nu", 50, 0.0, 12.0 ); TH1F* D3P0pe_elep = new TH1F( "h42", "Elep for B0B ->3P0+ e- nu", 50, 0.0, 2.5 ); TH1F* D3P0me_q2 = new TH1F( "h43", "q2 for B0 ->3P0- e+ nu", 50, 0.0, 12.0 ); TH1F* D3P0me_elep = new TH1F( "h44", "Elep for B0 ->3P0- e+ nu", 50, 0.0, 2.5 ); TH1F* D3P00e_q2 = new TH1F( "h45", "q2 for B- ->3P00 e- nu", 50, 0.0, 12.0 ); TH1F* D3P00e_elep = new TH1F( "h46", "Elep for B*- ->3P00 e- nu", 50, 0.0, 2.5 ); TH1F* D3P00Be_q2 = new TH1F( "h47", "q2 for B+ ->3P0B e+ nu", 50, 0.0, 12.0 ); TH1F* D3P00Be_elep = new TH1F( "h48", "Elep for B+ ->3P0B e+ nu", 50, 0.0, 2.5 ); TH1F* D3P1pe_q2 = new TH1F( "h51", "q2 for B0B ->3P1+ e- nu", 50, 0.0, 12.0 ); TH1F* D3P1pe_elep = new TH1F( "h52", "Elep for B0B ->3P1+ e- nu", 50, 0.0, 2.5 ); TH1F* D3P1me_q2 = new TH1F( "h53", "q2 for B0 ->3P1- e+ nu", 50, 0.0, 12.0 ); TH1F* D3P1me_elep = new TH1F( "h54", "Elep for B0 ->3P1- e+ nu", 50, 0.0, 2.5 ); TH1F* D3P10e_q2 = new TH1F( "h55", "q2 for B- ->3P10 e- nu", 50, 0.0, 12.0 ); TH1F* D3P10e_elep = new TH1F( "h56", "Elep for B*- ->3P10 e- nu", 50, 0.0, 2.5 ); TH1F* D3P10Be_q2 = new TH1F( "h57", "q2 for B+ ->3P1B e+ nu", 50, 0.0, 12.0 ); TH1F* D3P10Be_elep = new TH1F( "h58", "Elep for B+ ->3P1B e+ nu", 50, 0.0, 2.5 ); TH1F* D3P2pe_q2 = new TH1F( "h61", "q2 for B0B ->3P2+ e- nu", 50, 0.0, 12.0 ); TH1F* D3P2pe_elep = new TH1F( "h62", "Elep for B0B ->3P2+ e- nu", 50, 0.0, 2.5 ); TH1F* D3P2me_q2 = new TH1F( "h63", "q2 for B0 ->3P2- e+ nu", 50, 0.0, 12.0 ); TH1F* D3P2me_elep = new TH1F( "h64", "Elep for B0 ->3P2- e+ nu", 50, 0.0, 2.5 ); TH1F* D3P20e_q2 = new TH1F( "h65", "q2 for B- ->3P20 e- nu", 50, 0.0, 12.0 ); TH1F* D3P20e_elep = new TH1F( "h66", "Elep for B*- ->3P20 e- nu", 50, 0.0, 2.5 ); TH1F* D3P20Be_q2 = new TH1F( "h67", "q2 for B+ ->3P2B e+ nu", 50, 0.0, 12.0 ); TH1F* D3P20Be_elep = new TH1F( "h68", "Elep for B+ ->3P2B e+ nu", 50, 0.0, 2.5 ); TH1F* phiL = new TH1F( "h69", "phi", 50, -3.1416, 3.1416 ); int count; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/SEMIC.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); int i; for ( i = 0; i < 2; i++ ) { EvtId meson = root_part->getDaug( i )->getDaug( 0 )->getId(); EvtId lepton = root_part->getDaug( i )->getDaug( 1 )->getId(); EvtVector4R lep = root_part->getDaug( i )->getDaug( 1 )->getP4Lab(); phiL->Fill( atan2( lep.get( 1 ), lep.get( 2 ) ) ); EvtVector4R nu = root_part->getDaug( i )->getDaug( 2 )->getP4Lab(); double q2 = ( lep + nu ).mass2(); double elep = root_part->getDaug( i )->getDaug( 1 )->getP4().get( 0 ); if ( meson == DP && lepton == EM ) { Dpe_q2->Fill( q2 ); Dpe_elep->Fill( elep ); } if ( meson == DM && lepton == EP ) { Dme_q2->Fill( q2 ); Dme_elep->Fill( elep ); } if ( meson == D0 && lepton == EM ) { D0e_q2->Fill( q2 ); D0e_elep->Fill( elep ); } if ( meson == D0B && lepton == EP ) { D0Be_q2->Fill( q2 ); D0Be_elep->Fill( elep ); } if ( meson == DSTP && lepton == EM ) { Dstpe_q2->Fill( q2 ); Dstpe_elep->Fill( elep ); } if ( meson == DSTM && lepton == EP ) { Dstme_q2->Fill( q2 ); Dstme_elep->Fill( elep ); } if ( meson == DST0 && lepton == EM ) { Dst0e_q2->Fill( q2 ); Dst0e_elep->Fill( elep ); } if ( meson == DSTB && lepton == EP ) { Dst0Be_q2->Fill( q2 ); Dst0Be_elep->Fill( elep ); } if ( meson == D1P1P && lepton == EM ) { D1P1pe_q2->Fill( q2 ); D1P1pe_elep->Fill( elep ); } if ( meson == D1P1N && lepton == EP ) { D1P1me_q2->Fill( q2 ); D1P1me_elep->Fill( elep ); } if ( meson == D1P10 && lepton == EM ) { D1P10e_q2->Fill( q2 ); D1P10e_elep->Fill( elep ); } if ( meson == D1P1B && lepton == EP ) { D1P10Be_q2->Fill( q2 ); D1P10Be_elep->Fill( elep ); } if ( meson == D3P0P && lepton == EM ) { D3P0pe_q2->Fill( q2 ); D3P0pe_elep->Fill( elep ); } if ( meson == D3P0N && lepton == EP ) { D3P0me_q2->Fill( q2 ); D3P0me_elep->Fill( elep ); } if ( meson == D3P00 && lepton == EM ) { D3P00e_q2->Fill( q2 ); D3P00e_elep->Fill( elep ); } if ( meson == D3P0B && lepton == EP ) { D3P00Be_q2->Fill( q2 ); D3P00Be_elep->Fill( elep ); } if ( meson == D3P1P && lepton == EM ) { D3P1pe_q2->Fill( q2 ); D3P1pe_elep->Fill( elep ); } if ( meson == D3P1N && lepton == EP ) { D3P1me_q2->Fill( q2 ); D3P1me_elep->Fill( elep ); } if ( meson == D3P10 && lepton == EM ) { D3P10e_q2->Fill( q2 ); D3P10e_elep->Fill( elep ); } if ( meson == D3P1B && lepton == EP ) { D3P10Be_q2->Fill( q2 ); D3P10Be_elep->Fill( elep ); } if ( meson == D3P2P && lepton == EM ) { D3P2pe_q2->Fill( q2 ); D3P2pe_elep->Fill( elep ); } if ( meson == D3P2N && lepton == EP ) { D3P2me_q2->Fill( q2 ); D3P2me_elep->Fill( elep ); } if ( meson == D3P20 && lepton == EM ) { D3P20e_q2->Fill( q2 ); D3P20e_elep->Fill( elep ); } if ( meson == D3P2B && lepton == EP ) { D3P20Be_q2->Fill( q2 ); D3P20Be_elep->Fill( elep ); } } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runKstarll( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "kstkmm.root", "RECREATE" ); TH2F* _dalitz = new TH2F( "h1", "q^2! vs Elep", 70, 0.0, 3.5, 60, 0.0, 30.0 ); TH1F* _ctl = new TH1F( "h2", "ctl", 50, -1.0, 1.0 ); TH1F* _q2 = new TH1F( "h3", "q2", 50, 0.0, 25.0 ); TH1F* _q2low = new TH1F( "h4", "q2 (low)", 50, 0.0, 1.0 ); TH1F* _q2lowlow = new TH1F( "h5", "q2 (lowlow)", 50, 0.0, 0.00001 ); TH1F* _phi = new TH1F( "h6", "phi", 50, -EvtConst::pi, EvtConst::pi ); TH1F* _chi = new TH1F( "h7", "chi", 50, 0.0, EvtConst::twoPi ); TH1F* _chictl = new TH1F( "h8", "chictl", 50, 0.0, EvtConst::twoPi ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); int count = 1; EvtVector4R kstar, l1, l2; EvtVector4R k, pi, b; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/KSTARLL.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); std::vector q2low( 5 ); std::vector q2high( 5 ); std::vector counts( 5 ); //kee //int n=4; //q2low[0]=0.0; q2high[0]=4.5; //q2low[1]=4.5; q2high[1]=8.41; //q2low[2]=10.24; q2high[2]=12.96; //q2low[3]=14.06; q2high[3]=30.0; //kmm //int n=4; //q2low[0]=0.0; q2high[0]=4.5; //q2low[1]=4.5; q2high[1]=9.0; //q2low[2]=10.24; q2high[2]=12.96; //q2low[3]=14.06; q2high[3]=30.0; //K*ee int n = 5; q2low[0] = 0.0; q2high[0] = 0.1; q2low[1] = 0.1; q2high[1] = 4.5; q2low[2] = 4.5; q2high[2] = 8.41; q2low[3] = 10.24; q2high[3] = 12.96; q2low[4] = 14.06; q2high[4] = 30.0; //K*mm //int n=5; //q2low[0]=0.0; q2high[0]=0.1; //q2low[1]=0.1; q2high[1]=4.5; //q2low[2]=4.5; q2high[2]=9.0; //q2low[3]=10.24; q2high[3]=12.96; //q2low[4]=14.06; q2high[4]=30.0; do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); // root_part->printTree(); //root_part->getDaug(0)->printTree(); //root_part->getDaug(1)->printTree(); //root_part->getDaug(2)->printTree(); kstar = root_part->getDaug( 0 )->getP4Lab(); l1 = root_part->getDaug( 1 )->getP4Lab(); l2 = root_part->getDaug( 2 )->getP4Lab(); b = root_part->getP4(); k = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); pi = root_part->getDaug( 0 )->getDaug( 1 )->getP4Lab(); double qsq = ( l1 + l2 ).mass2(); for ( int j = 0; j < n; j++ ) { if ( qsq > q2low[j] && qsq < q2high[j] ) counts[j]++; } _q2->Fill( ( l1 + l2 ).mass2() ); _q2low->Fill( ( l1 + l2 ).mass2() ); _q2lowlow->Fill( ( l1 + l2 ).mass2() ); _ctl->Fill( EvtDecayAngle( ( l1 + l2 + kstar ), ( l1 + l2 ), l1 ) ); _dalitz->Fill( l1.get( 0 ), ( l1 + l2 ).mass2(), 1.0 ); root_part->deleteTree(); _phi->Fill( atan2( l1.get( 1 ), l1.get( 2 ) ) ); _chi->Fill( EvtDecayAngleChi( b, k, pi, l1, l2 ) ); if ( EvtDecayAngle( ( l1 + l2 + kstar ), ( l1 + l2 ), l1 ) > 0 ) { _chictl->Fill( EvtDecayAngleChi( b, k, pi, l1, l2 ) ); } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "count:" << count << " " << ( l1 + l2 ).mass2() << std::endl; } while ( count++ < nevent ); for ( int j = 0; j < n; j++ ) { std::cout << "[" << q2low[j] << ".." << q2high[j] << "]=" << counts[j] << std::endl; } file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runKll( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "ksem.root", "RECREATE" ); TH2F* _dalitz = new TH2F( "h1", "q^2! vs Elep", 70, 0.0, 3.5, 60, 0.0, 30.0 ); TH1F* _ctl = new TH1F( "h2", "ctl", 50, -1.0, 1.0 ); TH1F* _q2 = new TH1F( "h3", "q2", 50, 0.0, 25.0 ); TH1F* _q2low = new TH1F( "h4", "q2 (low)", 50, 0.0, 1.0 ); TH1F* _q2lowlow = new TH1F( "h5", "q2 (lowlow)", 50, 0.0, 0.00001 ); TH1F* _phi = new TH1F( "h6", "phi", 50, -EvtConst::pi, EvtConst::pi ); // TH1F* _chi = new TH1F("h7","chi",50,0.0,EvtConst::twoPi); // TH1F* _chictl = new TH1F("h8","chictl",50,0.0,EvtConst::twoPi); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); int count = 1; EvtVector4R k, l1, l2; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/KLL.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); std::vector q2low( 5 ); std::vector q2high( 5 ); std::vector counts( 5 ); //kee // int n=4; //q2low[0]=0.0; q2high[0]=4.5; //q2low[1]=4.5; q2high[1]=8.41; //q2low[2]=10.24; q2high[2]=12.96; //q2low[3]=14.06; q2high[3]=30.0; //kmm int n = 4; q2low[0] = 0.0; q2high[0] = 4.5; q2low[1] = 4.5; q2high[1] = 9.0; q2low[2] = 10.24; q2high[2] = 12.96; q2low[3] = 14.06; q2high[3] = 30.0; //K*ee //int n=5; //q2low[0]=0.0; q2high[0]=0.1; //q2low[1]=0.1; q2high[1]=4.5; //q2low[2]=4.5; q2high[2]=8.41; //q2low[3]=10.24; q2high[3]=12.96; //q2low[4]=14.06; q2high[4]=30.0; //K*mm //int n=5; //q2low[0]=0.0; q2high[0]=0.1; //q2low[1]=0.1; q2high[1]=4.5; //q2low[2]=4.5; q2high[2]=9.0; //q2low[3]=10.24; q2high[3]=12.96; //q2low[4]=14.06; q2high[4]=30.0; do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); // root_part->printTree(); //root_part->getDaug(0)->printTree(); //root_part->getDaug(1)->printTree(); //root_part->getDaug(2)->printTree(); k = root_part->getDaug( 0 )->getP4Lab(); l1 = root_part->getDaug( 1 )->getP4Lab(); l2 = root_part->getDaug( 2 )->getP4Lab(); //b=root_part->getP4(); // k=root_part->getDaug(0)->getDaug(0)->getP4Lab(); // pi=root_part->getDaug(0)->getDaug(1)->getP4Lab(); double qsq = ( l1 + l2 ).mass2(); for ( int j = 0; j < n; j++ ) { if ( qsq > q2low[j] && qsq < q2high[j] ) counts[j]++; } _q2->Fill( ( l1 + l2 ).mass2() ); _q2low->Fill( ( l1 + l2 ).mass2() ); _q2lowlow->Fill( ( l1 + l2 ).mass2() ); _ctl->Fill( EvtDecayAngle( ( l1 + l2 + k ), ( l1 + l2 ), l1 ) ); _dalitz->Fill( l1.get( 0 ), ( l1 + l2 ).mass2(), 1.0 ); root_part->deleteTree(); _phi->Fill( atan2( l1.get( 1 ), l1.get( 2 ) ) ); //_chi->Fill(EvtDecayAngleChi(b,k,pi,l1,l2)); //if (EvtDecayAngle((l1+l2+kstar),(l1+l2),l1)>0){ // _chictl->Fill(EvtDecayAngleChi(b,k,pi,l1,l2)); // } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "count:" << count << " " << ( l1 + l2 ).mass2() << std::endl; } while ( count++ < nevent ); for ( int j = 0; j < n; j++ ) { std::cout << "[" << q2low[j] << ".." << q2high[j] << "]=" << counts[j] << std::endl; } file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runHll( int nevent, EvtGen& myGenerator, char* mode ) { TString modename = mode; TString filename; filename = modename; filename = filename + "_nnlo.root"; TFile* file = new TFile( filename, "RECREATE" ); TString decname; decname += modename; decname.ToUpper(); decname = "exampleFiles/" + decname + ".DEC"; char udecay_name[100]; strcpy( udecay_name, decname ); TH2F* _dalitz = new TH2F( "h1", "q^2! vs Elep", 70, 0.0, 3.5, 60, 0.0, 30.0 ); TH1F* _ctl = new TH1F( "h2", "ctl", 50, -1.0, 1.0 ); TH1F* _q2 = new TH1F( "h3", "q2", 50, 0.0, 25.0 ); TH1F* _q2low = new TH1F( "h4", "q2 (low)", 50, 0.0, 1.0 ); TH1F* _q2lowlow = new TH1F( "h5", "q2 (lowlow)", 50, 0.0, 0.00001 ); TH1F* _phi = new TH1F( "h6", "phi", 50, -EvtConst::pi, EvtConst::pi ); TH1F* _chi = new TH1F( "h7", "chi", 50, 0.0, EvtConst::twoPi ); TH1F* _chictl = new TH1F( "h8", "chictl", 50, 0.0, EvtConst::twoPi ); EvtId B; if ( modename == "kee" || modename == "kmm" || modename == "kstksee" || modename == "kstksmm" || modename == "piee" || modename == "pimm" || modename == "rhoee" || modename == "rhomm" ) { B = EvtPDL::getId( std::string( "B+" ) ); } else { B = EvtPDL::getId( std::string( "B0" ) ); } int count = 1; EvtVector4R b, h, l1, l2; EvtVector4R hdaug1, hdaug2; myGenerator.readUDecay( udecay_name ); std::vector q2low( 7 ); std::vector q2high( 7 ); std::vector counts( 7 ); int n( 0 ); if ( modename == "kee" || modename == "ksee" || modename == "piee" || modename == "pi0ee" || modename == "etaee" || modename == "etapee" ) { //kee n = 6; q2low[0] = 0.0; q2high[0] = 4.5; q2low[1] = 4.5; q2high[1] = 8.41; q2low[2] = 8.41; q2high[2] = 10.24; q2low[3] = 10.24; q2high[3] = 12.96; q2low[4] = 12.96; q2high[4] = 14.06; q2low[5] = 14.06; q2high[5] = 30.0; } else if ( modename == "kmm" || modename == "ksmm" || modename == "pimm" || modename == "pi0mm" || modename == "etamm" || modename == "etapmm" ) { //kmm n = 6; q2low[0] = 0.0; q2high[0] = 4.5; q2low[1] = 4.5; q2high[1] = 9.0; q2low[2] = 9.0; q2high[2] = 10.24; q2low[3] = 10.24; q2high[3] = 12.96; q2low[4] = 12.96; q2high[4] = 14.06; q2low[5] = 14.06; q2high[5] = 30.0; } else if ( modename == "kstkee" || modename == "kstksee" || modename == "rhoee" || modename == "rho0ee" || modename == "omegaee" ) { //K*ee n = 7; q2low[0] = 0.0; q2high[0] = 0.1; q2low[1] = 0.1; q2high[1] = 4.5; q2low[2] = 4.5; q2high[2] = 8.41; q2low[3] = 8.41; q2high[3] = 10.24; q2low[4] = 10.24; q2high[4] = 12.96; q2low[5] = 12.96; q2high[5] = 14.06; q2low[6] = 14.06; q2high[6] = 30.0; } else if ( modename == "kstkmm" || modename == "kstksmm" || modename == "rhomm" || modename == "rho0mm" || modename == "omegamm" ) { //K*mm n = 7; q2low[0] = 0.0; q2high[0] = 0.1; q2low[1] = 0.1; q2high[1] = 4.5; q2low[2] = 4.5; q2high[2] = 9.0; q2low[3] = 9.0; q2high[3] = 10.24; q2low[4] = 10.24; q2high[4] = 12.96; q2low[5] = 12.96; q2high[5] = 14.06; q2low[6] = 14.06; q2high[6] = 30.0; } float q2binlow[n + 1]; for ( int i = 0; i < n; i++ ) { q2binlow[i] = q2low[i]; } q2binlow[n] = 30.0; TH1F* _q2var = new TH1F( "h9", "q2var", n, q2binlow ); do { EvtVector4R p_init( EvtPDL::getMass( B ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); // root_part->printTree(); //root_part->getDaug(0)->printTree(); //root_part->getDaug(1)->printTree(); //root_part->getDaug(2)->printTree(); h = root_part->getDaug( 0 )->getP4Lab(); l1 = root_part->getDaug( 1 )->getP4Lab(); l2 = root_part->getDaug( 2 )->getP4Lab(); double qsq = ( l1 + l2 ).mass2(); for ( int j = 0; j < n; j++ ) { if ( qsq > q2low[j] && qsq < q2high[j] ) counts[j]++; } _q2->Fill( ( l1 + l2 ).mass2() ); _q2var->Fill( ( l1 + l2 ).mass2() ); _q2low->Fill( ( l1 + l2 ).mass2() ); _q2lowlow->Fill( ( l1 + l2 ).mass2() ); _ctl->Fill( EvtDecayAngle( ( l1 + l2 + h ), ( l1 + l2 ), l1 ) ); _dalitz->Fill( l1.get( 0 ), ( l1 + l2 ).mass2(), 1.0 ); _phi->Fill( atan2( l1.get( 1 ), l1.get( 2 ) ) ); if ( modename == "kstkee" || modename == "kstkmm" || modename == "kstksee" || modename == "kstksmm" || modename == "rhoee" || modename == "rhomm" || modename == "rho0ee" || modename == "rho0mm" ) { b = root_part->getP4(); hdaug1 = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); hdaug2 = root_part->getDaug( 0 )->getDaug( 1 )->getP4Lab(); _chi->Fill( EvtDecayAngleChi( b, hdaug1, hdaug2, l1, l2 ) ); if ( EvtDecayAngle( ( l1 + l2 + h ), ( l1 + l2 ), l1 ) > 0 ) { _chictl->Fill( EvtDecayAngleChi( b, hdaug1, hdaug2, l1, l2 ) ); } } if ( count % 1000 == 0 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "count:" << count << " " << ( l1 + l2 ).mass2() << std::endl; } root_part->deleteTree(); } while ( count++ < nevent ); for ( int j = 0; j < n; j++ ) { std::cout << "[" << q2low[j] << ".." << q2high[j] << "] = " << counts[j] << std::endl; } file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runVectorIsr( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); TFile* file = new TFile( "vectorisr.root", "RECREATE" ); TH1F* cosv = new TH1F( "h1", "Cos vector in e+e- frame", 50, -1.0, 1.0 ); TH1F* cosd1 = new TH1F( "h2", "Cos helang 1st dau of vector", 50, -1.0, 1.0 ); TH1F* cosd1d1 = new TH1F( "h3", "Cos helang 1st dau of 1st dau", 50, -1.0, 1.0 ); TH1F* cosd2d1 = new TH1F( "h4", "Cos helang 1st dau of 2nd dau", 50, -1.0, 1.0 ); TH2F* d1vsd1d1 = new TH2F( "h5", "Cos helangs d1 vs d1d1", 20, -1.0, 1.0, 20, -1.0, 1.0 ); TH2F* d2vsd2d1 = new TH2F( "h6", "Cos helangs d2 vs d2d1", 20, -1.0, 1.0, 20, -1.0, 1.0 ); TH2F* d1d1vsd2d1 = new TH2F( "h7", "Cos helangs d1d1 vs d2d1", 20, -1.0, 1.0, 20, -1.0, 1.0 ); TH1F* chidd = new TH1F( "h8", "Chi - angle between decay planes", 60, 0., 360.0 ); TH2F* chi12vsd1d1 = new TH2F( "h9", "Chi 1-2 vs d1d1", 30, 0., 360.0, 20, -1.0, 1.0 ); TH2F* chi12vsd2d1 = new TH2F( "h10", "Chi 1-2 vs d2d1", 30, 0., 360.0, 20, -1.0, 1.0 ); TH2F* chi21vsd1d1 = new TH2F( "h11", "Chi 2-1 vs d1d1", 30, 0., 360.0, 20, -1.0, 1.0 ); TH2F* chi21vsd2d1 = new TH2F( "h12", "Chi 2-1 vs d2d1", 30, 0., 360.0, 20, -1.0, 1.0 ); int count = 1; char udecay_name[100]; EvtVector4R cm, v, d1, d2, d1d1, d1d2, d2d1, d2d2; strcpy( udecay_name, "exampleFiles/VECTORISR.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); cm = root_part->getP4Lab(); v = root_part->getDaug( 0 )->getP4Lab(); d1 = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); d2 = root_part->getDaug( 0 )->getDaug( 1 )->getP4Lab(); cosv->Fill( v.get( 3 ) / v.d3mag() ); double cosdecayd1 = EvtDecayAngle( cm, v, d1 ); double cosdecayd2 = EvtDecayAngle( cm, v, d2 ); cosd1->Fill( cosdecayd1 ); // now get daughters of the daughters // // first daughter of first daughter if ( root_part->getDaug( 0 )->getDaug( 0 )->getNDaug() >= 2 ) { d1d1 = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); double cosdecayd1d1 = EvtDecayAngle( v, d1, d1d1 ); cosd1d1->Fill( cosdecayd1d1 ); d1vsd1d1->Fill( cosdecayd1, cosdecayd1d1, 1.0 ); } // first daughter of second daughter if ( root_part->getDaug( 0 )->getDaug( 1 )->getNDaug() >= 2 ) { d2d1 = root_part->getDaug( 0 )->getDaug( 1 )->getDaug( 0 )->getP4Lab(); double cosdecayd2d1 = EvtDecayAngle( v, d2, d2d1 ); cosd2d1->Fill( cosdecayd2d1 ); d2vsd2d1->Fill( cosdecayd2, cosdecayd2d1, 1.0 ); if ( root_part->getDaug( 0 )->getDaug( 0 )->getNDaug() >= 2 ) { d1d1 = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); double cosdecayd1d1 = EvtDecayAngle( v, d1, d1d1 ); d1d1vsd2d1->Fill( cosdecayd1d1, cosdecayd2d1, 1.0 ); //second daughters of daughters 1 and 2 d1d2 = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 1 )->getP4Lab(); d2d2 = root_part->getDaug( 0 )->getDaug( 1 )->getDaug( 1 )->getP4Lab(); double chi21 = 57.29578 * EvtDecayAngleChi( v, d2d1, d2d2, d1d1, d1d2 ); double chi12 = 57.29578 * EvtDecayAngleChi( v, d1d1, d1d2, d2d1, d2d2 ); chidd->Fill( chi12 ); chi12vsd1d1->Fill( chi12, cosdecayd1d1, 1.0 ); chi12vsd2d1->Fill( chi12, cosdecayd2d1, 1.0 ); chi21vsd1d1->Fill( chi21, cosdecayd1d1, 1.0 ); chi21vsd2d1->Fill( chi21, cosdecayd2d1, 1.0 ); } } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runBsquark( int nevent, EvtGen& myGenerator ) { static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); TFile* file = new TFile( "bsquark.root", "RECREATE" ); TH1F* elep = new TH1F( "h1", "Elep", 50, 0.0, 1.5 ); TH1F* q2 = new TH1F( "h2", "q2", 50, 0.0, 3.0 ); TH2F* dalitz = new TH2F( "h3", "q2 vs. Elep", 50, 0.0, 1.5, 50, 0.0, 3.0 ); TH1F* elepbar = new TH1F( "h11", "Elep bar", 50, 0.0, 1.5 ); TH1F* q2bar = new TH1F( "h12", "q2 bar", 50, 0.0, 3.0 ); TH2F* dalitzbar = new TH2F( "h13", "q2 vs. Elep bar", 50, 0.0, 1.5, 50, 0.0, 3.0 ); int count = 1; char udecay_name[100]; EvtVector4R cm, v, d1, d2, d1d1, d1d2, d2d1, d2d2; strcpy( udecay_name, "exampleFiles/BSQUARK.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( 10.55, 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* p = root_part->nextIter(); while ( p ) { if ( p->getId() == B0 ) { //EvtParticle *dstar=p->getDaug(0); EvtParticle* lepton = p->getDaug( 1 ); EvtParticle* sneutrino = p->getDaug( 2 ); //EvtVector4R p4dstar=dstar->getP4(); EvtVector4R p4lepton = lepton->getP4(); EvtVector4R p4sneutrino = sneutrino->getP4(); elep->Fill( p4lepton.get( 0 ) ); q2->Fill( ( p4lepton + p4sneutrino ).mass2() ); dalitz->Fill( p4lepton.get( 0 ), ( p4lepton + p4sneutrino ).mass2(), 1.0 ); } if ( p->getId() == B0B ) { //EvtParticle *dstar=p->getDaug(0); EvtParticle* lepton = p->getDaug( 1 ); EvtParticle* sneutrino = p->getDaug( 2 ); //EvtVector4R p4dstar=dstar->getP4(); EvtVector4R p4lepton = lepton->getP4(); EvtVector4R p4sneutrino = sneutrino->getP4(); elepbar->Fill( p4lepton.get( 0 ) ); q2bar->Fill( ( p4lepton + p4sneutrino ).mass2() ); dalitzbar->Fill( p4lepton.get( 0 ), ( p4lepton + p4sneutrino ).mass2(), 1.0 ); } p = p->nextIter(); } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runK3gamma( int nevent, EvtGen& myGenerator ) { static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); TFile* file = new TFile( "k3gamma.root", "RECREATE" ); TH1F* costheta = new TH1F( "h1", "cosTheta", 100, -1.0, 1.0 ); int count = 1; char udecay_name[100]; EvtVector4R cm, v, d1, d2, d1d1, d1d2, d2d1, d2d2; strcpy( udecay_name, "exampleFiles/K3GAMMA.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* k3 = root_part->getDaug( 0 ); EvtParticle* k = k3->getDaug( 0 ); EvtVector4R p4b = root_part->getP4Lab(); EvtVector4R p4k3 = k3->getP4Lab(); EvtVector4R p4k = k->getP4Lab(); costheta->Fill( EvtDecayAngle( p4b, p4k3, p4k ) ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runLambda( int nevent, EvtGen& myGenerator ) { static EvtId LAMBDA = EvtPDL::getId( std::string( "Lambda0" ) ); TFile* file = new TFile( "lambda.root", "RECREATE" ); TH1F* costheta = new TH1F( "h1", "cosTheta", 100, -1.0, 1.0 ); int count = 1; char udecay_name[100]; EvtVector4R cm, v, d1, d2, d1d1, d1d2, d2d1, d2d2; strcpy( udecay_name, "exampleFiles/LAMBDA.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( LAMBDA ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( LAMBDA, p_init ); EvtSpinDensity rho; rho.setDim( 2 ); rho.set( 0, 0, 1.0 ); rho.set( 0, 1, 0.0 ); rho.set( 1, 0, 0.0 ); rho.set( 1, 1, 0.0 ); root_part->setSpinDensityForwardHelicityBasis( rho ); myGenerator.generateDecay( root_part ); EvtParticle* p = root_part->getDaug( 0 ); //EvtVector4R p4lambda=root_part->getP4Lab(); EvtVector4R p4p = p->getP4Lab(); costheta->Fill( p4p.get( 3 ) / p4p.d3mag() ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runTauTauPiPi( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); TFile* file = new TFile( "tautaupipi.root", "RECREATE" ); TH1F* cospi1 = new TH1F( "h1", "cos theta pi1", 50, -1.0, 1.0 ); TH1F* cospi2 = new TH1F( "h2", "cos theta pi2", 50, -1.0, 1.0 ); TH1F* costheta = new TH1F( "h3", "cos theta", 50, -1.0, 1.0 ); std::ofstream outmix; outmix.open( "tautaupipi.dat" ); int count = 1; EvtVector4R tau1, tau2, pi1, pi2; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/TAUTAUPIPI.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); tau1 = root_part->getDaug( 0 )->getP4Lab(); tau2 = root_part->getDaug( 1 )->getP4Lab(); pi1 = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); pi2 = root_part->getDaug( 1 )->getDaug( 0 )->getP4Lab(); cospi1->Fill( EvtDecayAngle( tau1 + tau2, tau1, pi1 ) ); cospi2->Fill( EvtDecayAngle( tau1 + tau2, tau2, pi2 ) ); costheta->Fill( tau1.get( 3 ) / tau1.d3mag() ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runTauTauEE( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); TFile* file = new TFile( "tautauee.root", "RECREATE" ); TH1F* e1 = new TH1F( "h1", "e1", 55, 0.0, 5.5 ); TH1F* e2 = new TH1F( "h2", "e2", 55, 0.0, 5.5 ); TH2F* e1vse2 = new TH2F( "h3", "e1 vs e2", 55, 0.0, 5.5, 55, 0.0, 5.5 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/TAUTAUEE.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); e1->Fill( root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab().get( 0 ) ); e2->Fill( root_part->getDaug( 1 )->getDaug( 0 )->getP4Lab().get( 0 ) ); e1vse2->Fill( root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab().get( 0 ), root_part->getDaug( 1 )->getDaug( 0 )->getP4Lab().get( 0 ), 1.0 ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runTauTau2Pi2Pi( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); TFile* file = new TFile( "tautau2pi2pi.root", "RECREATE" ); TH1F* e1 = new TH1F( "h1", "mrho", 200, 0.0, 2.0 ); TH1F* e2 = new TH1F( "h2", "coshel", 200, -1.0, 1.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/TAUTAU2PI2PI.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtVector4R p4tau = root_part->getDaug( 0 )->getP4(); EvtVector4R p4rho = root_part->getDaug( 0 )->getDaug( 0 )->getP4() + root_part->getDaug( 0 )->getDaug( 1 )->getP4(); EvtVector4R p4pi = root_part->getDaug( 0 )->getDaug( 0 )->getP4(); e1->Fill( p4rho.mass() ); double dcostheta = EvtDecayAngle( p4tau, p4rho, p4pi ); e2->Fill( dcostheta ); p4tau = root_part->getDaug( 1 )->getP4(); p4rho = root_part->getDaug( 1 )->getDaug( 0 )->getP4() + root_part->getDaug( 1 )->getDaug( 1 )->getP4(); p4pi = root_part->getDaug( 1 )->getDaug( 0 )->getP4(); e1->Fill( p4rho.mass() ); dcostheta = EvtDecayAngle( p4tau, p4rho, p4pi ); e2->Fill( dcostheta ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runTauTau3Pi3Pi( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); TFile* file = new TFile( "tautau3pi3pi.root", "RECREATE" ); TH1F* e1 = new TH1F( "h1", "a1", 200, 0.0, 2.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/TAUTAU3PI3PI.DEC" ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtVector4R p4tau = root_part->getDaug( 0 )->getP4(); EvtVector4R p4a1 = root_part->getDaug( 0 )->getDaug( 0 )->getP4() + root_part->getDaug( 0 )->getDaug( 1 )->getP4() + root_part->getDaug( 0 )->getDaug( 2 )->getP4(); e1->Fill( p4a1.mass() ); p4tau = root_part->getDaug( 1 )->getP4(); p4a1 = root_part->getDaug( 1 )->getDaug( 0 )->getP4() + root_part->getDaug( 1 )->getDaug( 1 )->getP4() + root_part->getDaug( 1 )->getDaug( 2 )->getP4(); e1->Fill( p4a1.mass() ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runJPsiKstar( int nevent, EvtGen& myGenerator, int modeInt ) { std::ofstream outmix; outmix.open( "jpsikstar.dat" ); int count = 1; char udecay_name[100]; if ( modeInt == 0 ) strcpy( udecay_name, "exampleFiles/JPSIKSTAR.DEC" ); if ( modeInt == 1 ) strcpy( udecay_name, "exampleFiles/JPSIKSTAR1.DEC" ); if ( modeInt == 2 ) strcpy( udecay_name, "exampleFiles/JPSIKSTAR2.DEC" ); if ( modeInt == 3 ) strcpy( udecay_name, "exampleFiles/JPSIKSTAR3.DEC" ); if ( modeInt == 4 ) strcpy( udecay_name, "exampleFiles/JPSIKSTAR4.DEC" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); myGenerator.readUDecay( udecay_name ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *btag, *bcp; if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } EvtId tag; if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } EvtParticle *p_b, *p_psi, *p_kstar, *p_pi0, *p_kz, *p_ep, *p_em; EvtVector4R p4_b, p4_psi, p4_kstar, p4_pi0, p4_kz, p4_ep, p4_em; p_b = bcp; p_psi = p_b->getDaug( 0 ); p_kstar = p_b->getDaug( 1 ); p_pi0 = p_kstar->getDaug( 0 ); p_kz = p_kstar->getDaug( 1 ); p_ep = p_psi->getDaug( 0 ); p_em = p_psi->getDaug( 1 ); p4_b = p_b->getP4Lab(); p4_psi = p_psi->getP4Lab(); p4_kstar = p_kstar->getP4Lab(); p4_pi0 = p_pi0->getP4Lab(); p4_kz = p_kz->getP4Lab(); p4_ep = p_ep->getP4Lab(); p4_em = p_em->getP4Lab(); outmix << tag.getId() << " "; outmix << root_part->getDaug( 0 )->getLifetime() << " "; outmix << root_part->getDaug( 1 )->getLifetime() << " "; outmix << EvtDecayAngle( p4_b, p4_ep + p4_em, p4_ep ) << " "; outmix << EvtDecayAngle( p4_b, p4_pi0 + p4_kz, p4_pi0 ) << " "; outmix << EvtDecayAngleChi( p4_b, p4_pi0, p4_kz, p4_ep, p4_em ) << "\n"; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runSVVCPLH( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "svvcplh.root", "RECREATE" ); TH1F* t = new TH1F( "h1", "t", 50, 0.0, 5.0 ); TH1F* cospsi = new TH1F( "h2", "cos theta e+", 50, -1.0, 1.0 ); TH1F* cosphi = new TH1F( "h3", "cos theta k+", 50, -1.0, 1.0 ); TH1F* chi = new TH1F( "h4", "chi", 50, 0.0, 2.0 * EvtConst::pi ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/SVVCPLH.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId BS0 = EvtPDL::getId( std::string( "B_s0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( BS0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( BS0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_b, *p_psi, *p_phi, *p_kp, *p_km, *p_ep, *p_em; EvtVector4R p4_b, p4_psi, p4_phi, p4_kp, p4_km, p4_ep, p4_em; p_b = root_part; if ( p_b->getNDaug() == 1 ) p_b = p_b->getDaug( 0 ); p_psi = p_b->getDaug( 0 ); p_phi = p_b->getDaug( 1 ); p_kp = p_phi->getDaug( 0 ); p_km = p_phi->getDaug( 1 ); p_ep = p_psi->getDaug( 0 ); p_em = p_psi->getDaug( 1 ); p4_b = p_b->getP4Lab(); p4_psi = p_psi->getP4Lab(); p4_phi = p_phi->getP4Lab(); p4_kp = p_kp->getP4Lab(); p4_km = p_km->getP4Lab(); p4_ep = p_ep->getP4Lab(); p4_em = p_em->getP4Lab(); t->Fill( root_part->getLifetime() ); cospsi->Fill( EvtDecayAngle( p4_b, p4_ep + p4_em, p4_ep ) ); cosphi->Fill( EvtDecayAngle( p4_b, p4_kp + p4_km, p4_kp ) ); chi->Fill( EvtDecayAngleChi( p4_b, p4_kp, p4_km, p4_ep, p4_em ) ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runSVSCPLH( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "svscplh.root", "RECREATE" ); TH1F* t = new TH1F( "h1", "t", 200, -5.0, 5.0 ); TH1F* tB0tag = new TH1F( "h2", "dt B0 tag (ps)", 200, -15.0, 15.0 ); TH1F* tB0Btag = new TH1F( "h3", "dt B0B tag (ps)", 200, -15.0, 15.0 ); TH1F* ctheta = new TH1F( "h4", "costheta", 50, -1.0, 1.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/SVSCPLH.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); std::ofstream outmix; outmix.open( "svscplh.dat" ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_tag, *p_cp, *p_jpsi, *p_ep; EvtVector4R p4_tag, p4_cp, p4_jpsi, p4_ep; p_tag = root_part->getDaug( 0 ); p_cp = root_part->getDaug( 1 ); p_jpsi = p_cp->getDaug( 0 ); p_ep = p_jpsi->getDaug( 0 ); p4_tag = p_tag->getP4Lab(); p4_cp = p_cp->getP4Lab(); p4_jpsi = p_jpsi->getP4Lab(); p4_ep = p_ep->getP4Lab(); double dt = p_cp->getLifetime() - p_tag->getLifetime(); dt = dt / ( 1e-12 * 3e11 ); t->Fill( dt ); if ( p_tag->getId() == B0 ) { tB0tag->Fill( dt ); outmix << dt << " 1" << std::endl; } if ( p_tag->getId() == B0B ) { tB0Btag->Fill( dt ); outmix << dt << " -1" << std::endl; } ctheta->Fill( EvtDecayAngle( p4_cp, p4_jpsi, p4_ep ) ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runSSDCP( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "ssdcp.root", "RECREATE" ); TH1F* t = new TH1F( "h1", "dt", 100, -15.0, 15.0 ); TH1F* tB0tag = new TH1F( "h2", "dt B0 tag (ps)", 100, -15.0, 15.0 ); TH1F* tB0Btag = new TH1F( "h3", "dt B0B tag (ps)", 100, -15.0, 15.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/SSDCP.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); std::ofstream outmix; do { EvtVector4R pinit( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, pinit ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_tag, *p_cp, *p_jpsi; EvtVector4R p4_tag, p4_cp, p4_jpsi, p4_ep; p_tag = root_part->getDaug( 0 ); p_cp = root_part->getDaug( 1 ); p_jpsi = p_cp->getDaug( 0 ); //p_ep=p_jpsi->getDaug(0); p4_tag = p_tag->getP4Lab(); p4_cp = p_cp->getP4Lab(); p4_jpsi = p_jpsi->getP4Lab(); //p4_ep=p_ep->getP4Lab(); double dt = p_cp->getLifetime() - p_tag->getLifetime(); dt = dt / ( 1e-12 * EvtConst::c ); t->Fill( dt ); if ( p_tag->getId() == B0 ) { tB0tag->Fill( dt ); } if ( p_tag->getId() == B0B ) { tB0Btag->Fill( dt ); } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runKstarstargamma( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "kstarstargamma.root", "RECREATE" ); TH1F* m = new TH1F( "h1", "mkpi", 100, 0.5, 2.5 ); TH1F* ctheta = new TH1F( "h2", "ctheta", 100, -1.0, 1.0 ); int count = 1; myGenerator.readUDecay( "exampleFiles/KSTARSTARGAMMA.DEC" ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); std::ofstream outmix; do { EvtVector4R pinit( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, pinit ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_kaon, *p_pion; EvtVector4R p4_kaon, p4_pion; p_kaon = root_part->getDaug( 0 ); p_pion = root_part->getDaug( 1 ); p4_kaon = p_kaon->getP4Lab(); p4_pion = p_pion->getP4Lab(); m->Fill( ( p4_kaon + p4_pion ).mass() ); ctheta->Fill( EvtDecayAngle( pinit, p4_kaon + p4_pion, p4_kaon ) ); //EvtGenReport(EVTGEN_INFO,"EvtGen") << "ctheta:"<deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runDSTARPI( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "dstarpi.root", "RECREATE" ); TH1F* t = new TH1F( "h1", "dt", 100, -15.0, 15.0 ); TH1F* tB0tagpip = new TH1F( "h2", "dt B0 tag pi+ (ps)", 100, -15.0, 15.0 ); TH1F* tB0Btagpip = new TH1F( "h3", "dt B0B tag pi+(ps)", 100, -15.0, 15.0 ); TH1F* tB0tagpim = new TH1F( "h4", "dt B0 tag pi- (ps)", 100, -15.0, 15.0 ); TH1F* tB0Btagpim = new TH1F( "h5", "dt B0B tag pi- (ps)", 100, -15.0, 15.0 ); int count = 1; myGenerator.readUDecay( "exampleFiles/DSTARPI.DEC" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); static EvtId PIP = EvtPDL::getId( std::string( "pi+" ) ); static EvtId PIM = EvtPDL::getId( std::string( "pi-" ) ); std::ofstream outmix; do { EvtVector4R pinit( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, pinit ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_tag, *p_cp, *p_pi; p_tag = root_part->getDaug( 0 ); p_cp = root_part->getDaug( 1 ); //p_dstar=p_cp->getDaug(1); p_pi = p_cp->getDaug( 0 ); double dt = p_cp->getLifetime() - p_tag->getLifetime(); dt = dt / ( 1e-12 * EvtConst::c ); t->Fill( dt ); if ( p_tag->getId() == B0 ) { if ( p_pi->getId() == PIP ) tB0tagpip->Fill( dt ); if ( p_pi->getId() == PIM ) tB0tagpim->Fill( dt ); } if ( p_tag->getId() == B0B ) { if ( p_pi->getId() == PIP ) tB0Btagpip->Fill( dt ); if ( p_pi->getId() == PIM ) tB0Btagpim->Fill( dt ); } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runETACPHIPHI( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "etacphiphi.root", "RECREATE" ); TH2F* cosphi12 = new TH2F( "h1", "cos phi1 vs phi2", 50, -1.0, 1.0, 50, -1.0, 1.0 ); TH1F* cosphi1 = new TH1F( "h2", "cos phi1", 50, -1.0, 1.0 ); TH1F* cosphi2 = new TH1F( "h3", "cos phi2", 50, -1.0, 1.0 ); TH1F* chi = new TH1F( "h4", "chi", 50, 0.0, 2.0 * EvtConst::pi ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/ETACPHIPHI.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId ETAC = EvtPDL::getId( std::string( "eta_c" ) ); do { EvtVector4R p_init( EvtPDL::getMass( ETAC ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( ETAC, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_etac, *p_phi1, *p_phi2, *p_kp1, *p_km1, *p_kp2, *p_km2; EvtVector4R p4_etac, p4_phi1, p4_phi2, p4_kp1, p4_km1, p4_kp2, p4_km2; p_etac = root_part; p_phi1 = p_etac->getDaug( 0 ); p_phi2 = p_etac->getDaug( 1 ); p_kp1 = p_phi1->getDaug( 0 ); p_km1 = p_phi1->getDaug( 1 ); p_kp2 = p_phi2->getDaug( 0 ); p_km2 = p_phi2->getDaug( 1 ); p4_etac = p_etac->getP4Lab(); p4_phi1 = p_phi1->getP4Lab(); p4_phi2 = p_phi2->getP4Lab(); p4_kp1 = p_kp1->getP4Lab(); p4_km1 = p_km1->getP4Lab(); p4_kp2 = p_kp2->getP4Lab(); p4_km2 = p_km2->getP4Lab(); cosphi12->Fill( EvtDecayAngle( p4_etac, p4_phi1, p4_kp1 ), EvtDecayAngle( p4_etac, p4_phi2, p4_kp2 ), 1.0 ); cosphi1->Fill( EvtDecayAngle( p4_etac, p4_phi1, p4_kp1 ) ); cosphi2->Fill( EvtDecayAngle( p4_etac, p4_phi2, p4_kp2 ) ); chi->Fill( EvtDecayAngleChi( p4_etac, p4_kp1, p4_km1, p4_kp2, p4_km2 ) ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runVVPiPi( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "vvpipi.root", "RECREATE" ); TH1F* cospsi = new TH1F( "h1", "cos theta J/psi ", 50, -1.0, 1.0 ); TH1F* cose = new TH1F( "h2", "cos theta e+ ", 50, -1.0, 1.0 ); TH1F* mpipi = new TH1F( "h3", "m pipi ", 50, 0.0, 1.0 ); TH2F* cosevspsi = new TH2F( "h4", "cos theta e+vs cos thete J/psi ", 25, -1.0, 1.0, 25, -1.0, 1.0 ); TH1F* cose1 = new TH1F( "h5", "cos theta e+ 1 ", 50, -1.0, 1.0 ); TH1F* cose2 = new TH1F( "h6", "cos theta e+ 2 ", 50, -1.0, 1.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/VVPIPI.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_b, *p_psip, *p_psi, *p_ep, *p_pi1, *p_pi2; EvtVector4R p4_b, p4_psip, p4_psi, p4_ep, p4_pi1, p4_pi2; p_b = root_part; p_psip = p_b->getDaug( 0 ); p_psi = p_psip->getDaug( 0 ); p_pi1 = p_psip->getDaug( 1 ); p_pi2 = p_psip->getDaug( 2 ); p_ep = p_psi->getDaug( 0 ); p4_b = p_b->getP4Lab(); p4_psip = p_psip->getP4Lab(); p4_psi = p_psi->getP4Lab(); p4_pi1 = p_pi1->getP4Lab(); p4_pi2 = p_pi2->getP4Lab(); p4_ep = p_ep->getP4Lab(); cospsi->Fill( EvtDecayAngle( p4_b, p4_psip, p4_psi ) ); cose->Fill( EvtDecayAngle( p4_psip, p4_psi, p4_ep ) ); mpipi->Fill( ( p4_pi1 + p4_pi2 ).mass() ); cosevspsi->Fill( EvtDecayAngle( p4_b, p4_psip, p4_psi ), EvtDecayAngle( p4_psip, p4_psi, p4_ep ), 1.0 ); if ( std::fabs( EvtDecayAngle( p4_b, p4_psip, p4_psi ) ) > 0.95 ) { cose1->Fill( EvtDecayAngle( p4_psip, p4_psi, p4_ep ) ); } if ( std::fabs( EvtDecayAngle( p4_b, p4_psip, p4_psi ) ) < 0.05 ) { cose2->Fill( EvtDecayAngle( p4_psip, p4_psi, p4_ep ) ); } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runSVVHelAmp( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "svvhelamp.root", "RECREATE" ); TH1F* cospip = new TH1F( "h1", "cos theta pi+", 50, -1.0, 1.0 ); TH1F* cospim = new TH1F( "h2", "cos theta pi-", 50, -1.0, 1.0 ); TH1F* chi = new TH1F( "h3", "chi pi+ to pi- in D+ direction", 50, 0.0, EvtConst::twoPi ); TH1F* chicospipp = new TH1F( "h4", "chi pi+ to pi- in D+ direction (cospip>0)", 50, 0.0, EvtConst::twoPi ); TH1F* chicospipn = new TH1F( "h5", "chi pi+ to pi- in D+ direction (cospip<0", 50, 0.0, EvtConst::twoPi ); TH1F* chipp = new TH1F( "h6", "chi pi+ to pi- in D+ direction (cospip>0,cospim>0)", 50, 0.0, EvtConst::twoPi ); TH1F* chipn = new TH1F( "h7", "chi pi+ to pi- in D+ direction (cospip>0,cospim<0)", 50, 0.0, EvtConst::twoPi ); TH1F* chinp = new TH1F( "h8", "chi pi+ to pi- in D+ direction (cospip<0,cospim>0)", 50, 0.0, EvtConst::twoPi ); TH1F* chinn = new TH1F( "h9", "chi pi+ to pi- in D+ direction (cospip<0,cospim<0)", 50, 0.0, EvtConst::twoPi ); TH1F* chinnnn = new TH1F( "h10", "chi pi+ to pi- in D+ direction (cospip<-0.5,cospim<-0.5)", 50, 0.0, EvtConst::twoPi ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/SVVHELAMP.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_b, *p_dstp, *p_dstm, *p_pip, *p_pim, *p_d0, *p_d0b; EvtVector4R p4_b, p4_dstp, p4_dstm, p4_pip, p4_pim, p4_d0, p4_d0b; p_b = root_part; p_dstp = p_b->getDaug( 0 ); p_dstm = p_b->getDaug( 1 ); p_pip = p_dstp->getDaug( 1 ); p_pim = p_dstm->getDaug( 1 ); p_d0 = p_dstp->getDaug( 0 ); p_d0b = p_dstm->getDaug( 0 ); p4_b = p_b->getP4Lab(); p4_dstp = p_dstp->getP4Lab(); p4_dstm = p_dstm->getP4Lab(); p4_pip = p_pip->getP4Lab(); p4_pim = p_pim->getP4Lab(); p4_d0 = p_d0->getP4Lab(); p4_d0b = p_d0b->getP4Lab(); double costhpip = EvtDecayAngle( p4_b, p4_pip + p4_d0, p4_pip ); double costhpim = EvtDecayAngle( p4_b, p4_pim + p4_d0b, p4_pim ); double chiang = EvtDecayAngleChi( p4_b, p4_pip, p4_d0, p4_pim, p4_d0b ); cospip->Fill( costhpip ); cospim->Fill( costhpim ); chi->Fill( chiang ); if ( costhpip > 0 ) chicospipp->Fill( chiang ); if ( costhpip < 0 ) chicospipn->Fill( chiang ); if ( costhpip > 0 && costhpim > 0 ) chipp->Fill( chiang ); if ( costhpip > 0 && costhpim < 0 ) chipn->Fill( chiang ); if ( costhpip < 0 && costhpim > 0 ) chinp->Fill( chiang ); if ( costhpip < 0 && costhpim < 0 ) chinn->Fill( chiang ); if ( costhpip < -0.5 && costhpim < -0.5 ) chinnnn->Fill( chiang ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPartWave( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "partwave.root", "RECREATE" ); TH1F* cospip = new TH1F( "h1", "cos theta pi+", 50, -1.0, 1.0 ); TH1F* cospim = new TH1F( "h2", "cos theta pi-", 50, -1.0, 1.0 ); TH1F* chi = new TH1F( "h3", "chi pi+ to pi- in D+ direction", 50, 0.0, EvtConst::twoPi ); TH1F* chicospipp = new TH1F( "h4", "chi pi+ to pi- in D+ direction (cospip>0)", 50, 0.0, EvtConst::twoPi ); TH1F* chicospipn = new TH1F( "h5", "chi pi+ to pi- in D+ direction (cospip<0", 50, 0.0, EvtConst::twoPi ); TH1F* chipp = new TH1F( "h6", "chi pi+ to pi- in D+ direction (cospip>0,cospim>0)", 50, 0.0, EvtConst::twoPi ); TH1F* chipn = new TH1F( "h7", "chi pi+ to pi- in D+ direction (cospip>0,cospim<0)", 50, 0.0, EvtConst::twoPi ); TH1F* chinp = new TH1F( "h8", "chi pi+ to pi- in D+ direction (cospip<0,cospim>0)", 50, 0.0, EvtConst::twoPi ); TH1F* chinn = new TH1F( "h9", "chi pi+ to pi- in D+ direction (cospip<0,cospim<0)", 50, 0.0, EvtConst::twoPi ); TH1F* chinnnn = new TH1F( "h10", "chi pi+ to pi- in D+ direction (cospip<-0.5,cospim<-0.5)", 50, 0.0, EvtConst::twoPi ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/PARTWAVE.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_b, *p_dstp, *p_dstm, *p_pip, *p_pim, *p_d0, *p_d0b; EvtVector4R p4_b, p4_dstp, p4_dstm, p4_pip, p4_pim, p4_d0, p4_d0b; p_b = root_part; p_dstp = p_b->getDaug( 0 ); p_dstm = p_b->getDaug( 1 ); p_pip = p_dstp->getDaug( 1 ); p_pim = p_dstm->getDaug( 1 ); p_d0 = p_dstp->getDaug( 0 ); p_d0b = p_dstm->getDaug( 0 ); p4_b = p_b->getP4Lab(); p4_dstp = p_dstp->getP4Lab(); p4_dstm = p_dstm->getP4Lab(); p4_pip = p_pip->getP4Lab(); p4_pim = p_pim->getP4Lab(); p4_d0 = p_d0->getP4Lab(); p4_d0b = p_d0b->getP4Lab(); double costhpip = EvtDecayAngle( p4_b, p4_pip + p4_d0, p4_pip ); double costhpim = EvtDecayAngle( p4_b, p4_pim + p4_d0b, p4_pim ); double chiang = EvtDecayAngleChi( p4_b, p4_pip, p4_d0, p4_pim, p4_d0b ); cospip->Fill( costhpip ); cospim->Fill( costhpim ); chi->Fill( chiang ); if ( costhpip > 0 ) chicospipp->Fill( chiang ); if ( costhpip < 0 ) chicospipn->Fill( chiang ); if ( costhpip > 0 && costhpim > 0 ) chipp->Fill( chiang ); if ( costhpip > 0 && costhpim < 0 ) chipn->Fill( chiang ); if ( costhpip < 0 && costhpim > 0 ) chinp->Fill( chiang ); if ( costhpip < 0 && costhpim < 0 ) chinn->Fill( chiang ); if ( costhpip < -0.5 && costhpim < -0.5 ) chinnnn->Fill( chiang ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPartWave2( int nevent, EvtGen& myGenerator ) { TFile file( "partwave2.root", "RECREATE" ); TH1F* cthetapi = new TH1F( "h1", "cos theta pi", 50, -1.0, 1.0 ); TH1F* cthetapi2 = new TH1F( "h2", "cos theta pi (|cosrho|<0.1)", 50, -1.0, 1.0 ); TH1F* cthetan = new TH1F( "h3", "cos thetan", 50, -1.0, 1.0 ); //TH1F* cthetan2 = new TH1F("h4","cos thetan costhetapi>0 ", // 50,-1.0,1.0); TH1F* cthetarho = new TH1F( "h4", "cos thetarho ", 50, -1.0, 1.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/PARTWAVE2.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_b, *p_jpsi, *p_rho, *p_pi1, *p_pi2; EvtVector4R p4_b, p4_jpsi, p4_rho, p4_pi1, p4_pi2; p_b = root_part; p_jpsi = root_part->getDaug( 0 ); - p_rho = 0; + p_rho = nullptr; if ( p_jpsi->getDaug( 0 )->getNDaug() == 2 ) { p_rho = p_jpsi->getDaug( 0 ); } if ( p_jpsi->getDaug( 1 )->getNDaug() == 2 ) { p_rho = p_jpsi->getDaug( 1 ); } assert( p_rho != 0 ); p_pi1 = p_rho->getDaug( 0 ); p_pi2 = p_rho->getDaug( 1 ); p4_b = p_b->getP4Lab(); p4_jpsi = p_jpsi->getP4Lab(); p4_rho = p_rho->getP4Lab(); p4_pi1 = p_pi1->getP4Lab(); p4_pi2 = p_pi2->getP4Lab(); double costhetan = EvtDecayPlaneNormalAngle( p4_b, p4_jpsi, p4_pi1, p4_pi2 ); //EvtGenReport(EVTGEN_INFO,"EvtGen") << "costhetan:"<Fill( costhetan ); double costhpi = EvtDecayAngle( p4_jpsi, p4_rho, p4_pi1 ); double costhrho = EvtDecayAngle( p4_b, p4_jpsi, p4_rho ); //EvtGenReport(EVTGEN_INFO,"EvtGen") << "costhetarho:"<Fill( costhrho ); //if (((p4_rho.get(3)/p4_rho.d3mag()))<-0.95) cthetan2->Fill( costhetan ); cthetapi->Fill( costhpi ); if ( ( p4_rho.get( 3 ) / p4_rho.d3mag() ) > 0.9 ) { cthetapi2->Fill( costhpi ); } root_part->deleteTree(); } while ( count++ < nevent ); file.Write(); file.Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runTwoBody( int nevent, EvtGen& myGenerator, std::string decFile, std::string rootFile ) { TFile* file = new TFile( rootFile.c_str(), "RECREATE" ); int count = 0; myGenerator.readUDecay( decFile.c_str() ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); vector histograms; do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); //root_part->printTree(); myGenerator.generateDecay( root_part ); int nhist = 0; EvtParticle* p = root_part; do { int nDaug = p->getNDaug(); if ( !( nDaug == 0 || nDaug == 2 ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "nDaug=" << nDaug << " but can only handle 0 or 2!" << std::endl; abort(); } if ( nDaug == 2 ) { - if ( p->getParent() == 0 ) { + if ( p->getParent() == nullptr ) { EvtVector4R p4 = p->getDaug( 0 )->getP4(); double ctheta = p4.get( 3 ) / p4.d3mag(); double phi = atan2( p4.get( 2 ), p4.get( 1 ) ); if ( count == 0 ) { histograms.push_back( new TH1F( "h1", "cos theta", 50, -1.0, 1.0 ) ); histograms.push_back( new TH1F( "h2", "phi", 50, -EvtConst::pi, EvtConst::pi ) ); } histograms[nhist++]->Fill( ctheta ); histograms[nhist++]->Fill( phi ); } else { double ctheta = EvtDecayAngle( p->getParent()->getP4Lab(), p->getP4Lab(), p->getDaug( 0 )->getP4Lab() ); if ( count == 0 ) { // char* tmp=new char[10]; // std::ostrstream strm(tmp,9); // strm << (nhist+1) << '\0'<< std::endl; // histograms.push_back(new TH1F(TString("h")+tmp,TString("cos theta")+tmp,50,-1.0,1.0)); std::ostringstream strm; strm << ( nhist + 1 ); histograms.push_back( new TH1F( TString( "h" ) + strm.str().c_str(), TString( "cos theta" ) + strm.str().c_str(), 50, -1.0, 1.0 ) ); } histograms[nhist++]->Fill( ctheta ); if ( p->getDaug( 0 )->getNDaug() == 2 ) { double costhetan = EvtDecayPlaneNormalAngle( p->getParent()->getP4Lab(), p->getP4Lab(), p->getDaug( 0 )->getDaug( 0 )->getP4Lab(), p->getDaug( 0 )->getDaug( 1 )->getP4Lab() ); if ( count == 0 ) { // char* tmp=new char[10]; // std::ostrstream strm(tmp,9); // strm << (nhist+1) << '\0'<< std::endl; // histograms.push_back(new TH1F(TString("h")+tmp,TString("cos thetan")+tmp,50,-1.0,1.0)); std::ostringstream strm; strm << ( nhist + 1 ); histograms.push_back( new TH1F( TString( "h" ) + strm.str().c_str(), TString( "cos theta" ) + strm.str().c_str(), 50, -1.0, 1.0 ) ); } histograms[nhist++]->Fill( costhetan ); } if ( p->getDaug( 1 )->getNDaug() == 2 ) { double costhetan = EvtDecayPlaneNormalAngle( p->getParent()->getP4Lab(), p->getP4Lab(), p->getDaug( 1 )->getDaug( 0 )->getP4Lab(), p->getDaug( 1 )->getDaug( 1 )->getP4Lab() ); if ( count == 0 ) { // char* tmp=new char[10]; // std::ostrstream strm(tmp,9); // strm << (nhist+1) << '\0'<< std::endl; // histograms.push_back(new TH1F(TString("h")+tmp,TString("cos thetan")+tmp,50,-1.0,1.0)); std::ostringstream strm; strm << ( nhist + 1 ); histograms.push_back( new TH1F( TString( "h" ) + strm.str().c_str(), TString( "cos theta" ) + strm.str().c_str(), 50, -1.0, 1.0 ) ); } histograms[nhist++]->Fill( costhetan ); } } } p = p->nextIter( root_part ); - } while ( p != 0 ); + } while ( p != nullptr ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPiPi( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "pipi.dat" ); TFile* file = new TFile( "pipi.root", "RECREATE" ); TH1F* tB0Hist = new TH1F( "h1", "dt in B->pipi with B0 tag", 50, -5.0, 5.0 ); TH1F* tB0BHist = new TH1F( "h2", "dt in B->pipi with B0B tag", 50, -5.0, 5.0 ); TH1F* tB0 = new TH1F( "h3", "t in B->pipi for B0 tag", 25, 0.0, 5.0 ); TH1F* tB0B = new TH1F( "h4", "t in B->pipi for B0B tag", 25, 0.0, 5.0 ); char udecay_name[100]; strcpy( udecay_name, "exampleFiles/PIPI.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); EvtParticle *bcp, *btag; int count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } // int a1=bcp->getDaug(0)->getId(); if ( tag == B0 ) tB0Hist->Fill( bcp->getLifetime() - btag->getLifetime() ); if ( tag == B0 ) tB0->Fill( btag->getLifetime() ); if ( tag == B0B ) tB0BHist->Fill( bcp->getLifetime() - btag->getLifetime() ); if ( tag == B0B ) tB0B->Fill( btag->getLifetime() ); outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << tag.getId() << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runA1Pi( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "a1pi.dat" ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/A1PI.DEC" ); myGenerator.readUDecay( udecay_name ); EvtParticle *bcp, *btag; EvtParticle *a1, *rho0, *pi1, *pi2, *pi3, *pi4; EvtVector4R p4bcp, p4a1, p4rho0, p4pi1, p4pi2, p4pi3, p4pi4; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } a1 = bcp->getDaug( 0 ); pi1 = bcp->getDaug( 1 ); rho0 = a1->getDaug( 0 ); pi2 = a1->getDaug( 1 ); pi3 = rho0->getDaug( 0 ); pi4 = rho0->getDaug( 1 ); p4bcp = bcp->getP4Lab(); p4a1 = a1->getP4Lab(); p4pi1 = pi1->getP4Lab(); p4rho0 = rho0->getP4Lab(); p4pi2 = pi2->getP4Lab(); p4pi3 = pi3->getP4Lab(); p4pi4 = pi4->getP4Lab(); EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << EvtDecayAngle( p4bcp, p4rho0 + p4pi2, p4rho0 ) << " " << EvtDecayAngle( p4a1, p4pi3 + p4pi4, p4pi3 ) << " " << EvtPDL::getStdHep( tag ) << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runCPTest( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "cptest.dat" ); int count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); char udecay_name[100]; strcpy( udecay_name, "exampleFiles/CPTEST.DEC" ); //EvtGen myGenerator(decay_name,pdttable_name,myRandomEngine); myGenerator.readUDecay( udecay_name ); EvtParticle *bcp, *btag; do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << tag.getId() << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runBtoXsgamma( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); TFile* file = new TFile( "BtoXsgamma.root", "RECREATE" ); int count = 1; EvtParticle* root_part; EvtVectorParticle* vector_part; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/BTOXSGAMMA.DEC" ); myGenerator.readUDecay( udecay_name ); // Plot kinematics for b->s,gamma int strangeid, antistrangeid; int Bmulti, bId1a, bId1b, bId2a, bId2b, b1Id, b2Id; do { vector_part = new EvtVectorParticle; EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); vector_part->init( UPS4, p_init ); root_part = (EvtParticle*)vector_part; root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* B1 = root_part->getDaug( 0 ); Bmulti = B1->getNDaug(); if ( Bmulti == 1 ) B1 = B1->getDaug( 0 ); EvtId BId1a = B1->getDaug( 0 )->getId(); bId1a = EvtPDL::getStdHep( BId1a ); EvtId BId1b = B1->getDaug( 1 )->getId(); bId1b = EvtPDL::getStdHep( BId1b ); if ( Bmulti == 1 ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "B1" << " bId1a=" << bId1a << " bId1b=" << bId1b << " ndaug=" << B1->getNDaug() << " Bid=" << EvtPDL::getStdHep( B1->getId() ) << std::endl; EvtParticle* B2 = root_part->getDaug( 1 ); Bmulti = B2->getNDaug(); if ( Bmulti == 1 ) B2 = B2->getDaug( 0 ); // B has a daughter which is a string EvtId BId2a = B2->getDaug( 0 )->getId(); bId2a = EvtPDL::getStdHep( BId2a ); EvtId BId2b = B2->getDaug( 1 )->getId(); bId2b = EvtPDL::getStdHep( BId2b ); if ( Bmulti == 1 ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "B2" << " bId2a=" << bId2a << " bId2b=" << bId2b << " ndaug=" << B2->getNDaug() << " Bid=" << EvtPDL::getStdHep( B2->getId() ) << std::endl; EvtId B1Id = B1->getId(); b1Id = EvtPDL::getStdHep( B1Id ); EvtId B2Id = B2->getId(); b2Id = EvtPDL::getStdHep( B2Id ); strangeid = 0; antistrangeid = 0; if ( ( b1Id == 511 ) || ( b1Id == -511 ) || ( b2Id == 511 ) || ( b2Id == -511 ) ) { strangeid = 30343; antistrangeid = -30343; } else if ( ( b1Id == 521 ) || ( b1Id == -521 ) || ( b2Id == 521 ) || ( b2Id == -521 ) ) { strangeid = 30353; antistrangeid = -30353; } else if ( ( b1Id == 531 ) || ( b1Id == -531 ) || ( b2Id == 531 ) || ( b2Id == -531 ) ) { strangeid = 30363; antistrangeid = -30363; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "bId1a " << bId1a << " bId1b " << bId1b << " bId2a " << bId2a << " bId2b " << bId2b << " for event " << count << std::endl; - EvtParticle* Bpeng = 0; + EvtParticle* Bpeng = nullptr; //int bnum=0; int pengcount = 0; if ( ( ( bId1a == strangeid ) && ( bId1b == 22 ) ) || ( ( bId1a == antistrangeid ) && ( bId1b == 22 ) ) || ( ( bId1b == strangeid ) && ( bId1a == 22 ) ) || ( ( bId1b == antistrangeid ) && ( bId1a == 22 ) ) ) { Bpeng = B1; //bnum=1; pengcount++; } if ( ( ( bId2a == strangeid ) && ( bId2b == 22 ) ) || ( ( bId2a == antistrangeid ) && ( bId2b == 22 ) ) || ( ( bId2b == strangeid ) && ( bId2a == 22 ) ) || ( ( bId2b == antistrangeid ) && ( bId2a == 22 ) ) ) { Bpeng = B2; //bnum=2; pengcount++; } if ( pengcount == 0 ) { Bpeng = B1; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "No penguin decay for event " << count << std::endl; //bnum=0; } else if ( pengcount == 2 ) { Bpeng = B1; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Two penguin decays in event " << count << std::endl; //bnum=0; } Bmulti = Bpeng->getNDaug(); EvtParticle* Xs = Bpeng->getDaug( 0 ); //EvtParticle *gam = Bpeng->getDaug(1); //EvtVector4R p4Xs = Xs->getP4Lab(); //EvtId BId = Bpeng->getId(); //EvtId XsId = Xs->getId(); int Xsmulti = Xs->getNDaug(); //EvtId gamId = gam->getId(); //int bId = EvtPDL::getStdHep(BId); //int XId = EvtPDL::getStdHep(XsId); //int gId = EvtPDL::getStdHep(gamId); //float XsMass = p4Xs.mass(); //double gmass = p4gam.mass(); //double genergy = p4gam.get(0); // debug stuff: EvtGenReport(EVTGEN_INFO,"EvtGen") << "bnum=" << bnum << " pengcount=" << pengcount << " bId=" << bId << " Bmulti=" << Bmulti << " XsId=" << XId << " gId=" << gId << std::endl; //need to change this to root...I don't have the energy now //tuple->column("bnum", bnum); //tuple->column("pengcount", pengcount); //tuple->column("bId", bId); //tuple->column("Bmulti", Bmulti); //tuple->column("XsId", XId); //tuple->column("gId", gId); //tuple->column("XsMass", XsMass); //tuple->column("Xsmulti", Xsmulti, 0,"Xs", HTRange(0,200)); //tuple->column("gmass", gmass); //tuple->column("genergy", genergy); //HTValOrderedVector XDaugId, XDaugNephewId; //HTValOrderedVector XsDaugMass, XsDaugNephewMass; int nTot( 0 ); for ( int i = 0; i < Xsmulti; i++ ) { EvtParticle* XsDaug = Xs->getDaug( i ); //EvtVector4R p4XsDaug = XsDaug->getP4Lab(); EvtId XsDaugId = XsDaug->getId(); //XDaugId.push_back(EvtPDL::getStdHep(XsDaugId)); //XsDaugMass.push_back( p4XsDaug.mass()); int Daumulti = XsDaug->getNDaug(); if ( abs( EvtPDL::getStdHep( XsDaugId ) ) == 321 || EvtPDL::getStdHep( XsDaugId ) == 310 || EvtPDL::getStdHep( XsDaugId ) == 111 || abs( EvtPDL::getStdHep( XsDaugId ) ) == 211 || Daumulti == 0 ) { nTot++; //EvtVector4R p4XsDaugNephew = XsDaug->getP4Lab(); //EvtId XsDaugNephewId =XsDaug->getId() ; //XDaugNephewId.push_back(EvtPDL::getStdHep(XsDaugId)); //XsDaugNephewMass.push_back( p4XsDaug.mass()); } else if ( Daumulti != 0 ) { for ( int k = 0; k < Daumulti; k++ ) { EvtParticle* XsDaugNephew = XsDaug->getDaug( k ); EvtId XsDaugNephewId = XsDaugNephew->getId(); int Nephmulti = XsDaugNephew->getNDaug(); if ( Nephmulti == 0 || abs( EvtPDL::getStdHep( XsDaugNephewId ) ) == 321 || EvtPDL::getStdHep( XsDaugNephewId ) == 310 || EvtPDL::getStdHep( XsDaugNephewId ) == 111 || abs( EvtPDL::getStdHep( XsDaugNephewId ) ) == 211 ) { nTot++; //EvtVector4R p4XsDaugNephew = XsDaugNephew->getP4Lab(); //XDaugNephewId.push_back(EvtPDL::getStdHep(XsDaugNephewId)); //XsDaugNephewMass.push_back( p4XsDaugNephew.mass()); } else { for ( int g = 0; g < Nephmulti; g++ ) { nTot++; //EvtParticle *XsDaugNephewNephew = XsDaugNephew->getDaug(g); //EvtVector4R p4XsDaugNephewNephew = XsDaugNephewNephew->getP4Lab(); //EvtId XsDaugNephewNephewId = XsDaugNephewNephew->getId(); //XDaugNephewId.push_back(EvtPDL::getStdHep(XsDaugNephewNephewId)); //XsDaugNephewMass.push_back( p4XsDaugNephewNephew.mass()); } } } } } //tuple->column("XsDaugId", XDaugId,"Xsmulti", 0, "Xs"); //tuple->column("XsDaugMass", XsDaugMass,"Xsmulti", 0, "Xs"); //tuple->column("nTot", nTot, 0,"nTot", HTRange(0,200)); //tuple->column("XsDaugNephewId", XDaugNephewId,"nTot", 0, "nTot"); //tuple->column("XsDaugNephewMass", XsDaugNephewMass,"nTot", 0, "nTot"); //tuple->dumpData(); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "End EvtGen. Ran on " << nevent << " events." << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runBtoK1273gamma( int nevent, EvtGen& myGenerator ) { static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); TFile* file = new TFile( "BtoK1273gamma.root", "RECREATE" ); //HepTuple *tuple = hfile.ntuple("BtoK1273gamma", 1); int count = 1; EvtParticle* root_part; EvtVectorParticle* vector_part; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/BTOK1273GAMMA.DEC" ); myGenerator.readUDecay( udecay_name ); // Plot kinematics for b->s,gamma int strangeid, antistrangeid; int Bmulti, bId1a, bId1b, bId2a, bId2b, b1Id, b2Id; do { vector_part = new EvtVectorParticle; EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); vector_part->init( UPS4, p_init ); root_part = (EvtParticle*)vector_part; root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* B1 = root_part->getDaug( 0 ); Bmulti = B1->getNDaug(); if ( Bmulti == 1 ) B1 = B1->getDaug( 0 ); EvtId BId1a = B1->getDaug( 0 )->getId(); bId1a = EvtPDL::getStdHep( BId1a ); EvtId BId1b = B1->getDaug( 1 )->getId(); bId1b = EvtPDL::getStdHep( BId1b ); if ( Bmulti == 1 ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "B1" << " bId1a=" << bId1a << " bId1b=" << bId1b << " ndaug=" << B1->getNDaug() << " Bid=" << EvtPDL::getStdHep( B1->getId() ) << std::endl; EvtParticle* B2 = root_part->getDaug( 1 ); Bmulti = B2->getNDaug(); if ( Bmulti == 1 ) B2 = B2->getDaug( 0 ); // B has a daughter which is a string EvtId BId2a = B2->getDaug( 0 )->getId(); bId2a = EvtPDL::getStdHep( BId2a ); EvtId BId2b = B2->getDaug( 1 )->getId(); bId2b = EvtPDL::getStdHep( BId2b ); if ( Bmulti == 1 ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "B2" << " bId2a=" << bId2a << " bId2b=" << bId2b << " ndaug=" << B2->getNDaug() << " Bid=" << EvtPDL::getStdHep( B2->getId() ) << std::endl; EvtId B1Id = B1->getId(); b1Id = EvtPDL::getStdHep( B1Id ); EvtId B2Id = B2->getId(); b2Id = EvtPDL::getStdHep( B2Id ); strangeid = 0; antistrangeid = 0; if ( ( b1Id == 511 ) || ( b1Id == -511 ) || ( b2Id == 511 ) || ( b2Id == -511 ) ) { strangeid = 10313; antistrangeid = -10313; } else if ( ( b1Id == 521 ) || ( b1Id == -521 ) || ( b2Id == 521 ) || ( b2Id == -521 ) ) { strangeid = 10323; antistrangeid = -10323; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "bId1a " << bId1a << " bId1b " << bId1b << " bId2a " << bId2a << " bId2b " << bId2b << " for event " << count << std::endl; - EvtParticle* Bpeng = 0; + EvtParticle* Bpeng = nullptr; //int bnum=0; int pengcount = 0; if ( ( ( bId1a == strangeid ) && ( bId1b == 22 ) ) || ( ( bId1a == antistrangeid ) && ( bId1b == 22 ) ) || ( ( bId1b == strangeid ) && ( bId1a == 22 ) ) || ( ( bId1b == antistrangeid ) && ( bId1a == 22 ) ) ) { Bpeng = B1; //bnum=1; pengcount++; } if ( ( ( bId2a == strangeid ) && ( bId2b == 22 ) ) || ( ( bId2a == antistrangeid ) && ( bId2b == 22 ) ) || ( ( bId2b == strangeid ) && ( bId2a == 22 ) ) || ( ( bId2b == antistrangeid ) && ( bId2a == 22 ) ) ) { Bpeng = B2; //bnum=2; pengcount++; } if ( pengcount == 0 ) { Bpeng = B1; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "No penguin decay for event " << count << std::endl; //bnum=0; } else if ( pengcount == 2 ) { Bpeng = B1; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Two penguin decays in event " << count << std::endl; //bnum=0; } Bmulti = Bpeng->getNDaug(); //EvtParticle *Ks = Bpeng->getDaug(0); //EvtParticle *gam = Bpeng->getDaug(1); //EvtVector4R p4Ks = Ks->getP4Lab(); //const EvtVector4R& p4gam = gam->getP4(); // gamma 4-mom in parent's rest frame //EvtId BId = Bpeng->getId(); //EvtId KsId = Ks->getId(); //int Ksmulti = Ks->getNDaug(); //EvtId gamId = gam->getId(); //int bId = EvtPDL::getStdHep(BId); //int XId = EvtPDL::getStdHep(KsId); //int gId = EvtPDL::getStdHep(gamId); //double KsMass = p4Ks.mass(); //double gmass = p4gam.mass(); //double genergy = p4gam.get(0); // debug stuff: EvtGenReport(EVTGEN_INFO,"EvtGen") << "bnum=" << bnum << " pengcount=" << pengcount << " bId=" << bId << " Bmulti=" << Bmulti << " KsId=" << XId << " gId=" << gId << std::endl; //tuple->column("bnum", bnum); //tuple->column("pengcount", pengcount); //tuple->column("bId", bId); //tuple->column("Bmulti", Bmulti); //tuple->column("KsId", XId); //tuple->column("gId", gId); //tuple->column("KsMass", KsMass); //tuple->column("Ksmulti", Ksmulti); //tuple->column("gmass", gmass); //tuple->column("genergy", genergy); //for(int i=0;igetDaug(i); //EvtVector4R p4KsDaug = KsDaug->getP4Lab(); //EvtId KsDaugId = KsDaug->getId(); //int XDaugId = EvtPDL::getStdHep(KsDaugId); //double KsDaugMass = p4KsDaug.mass(); //tuple->column("KsDaugId", XDaugId); //tuple->column("KsDaugMass", KsDaugMass); //} //tuple->dumpData(); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "End EvtGen. Ran on " << nevent << " events." << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runCheckRotBoost() { EvtDiracSpinor sp1, sp2; //Generate ryd/lange random spinors. sp1.set( EvtComplex( 1.0, -2.0 ), EvtComplex( 3.0, 1.0 ), EvtComplex( -4.5, 0.5 ), EvtComplex( 0.2, -0.5 ) ); sp2.set( EvtComplex( 0.1, -1.0 ), EvtComplex( 1.2, -0.5 ), EvtComplex( 3.6, 1.8 ), EvtComplex( -0.2, -0.6 ) ); EvtComplex s = EvtLeptonSCurrent( sp1, sp2 ); EvtComplex p = EvtLeptonPCurrent( sp1, sp2 ); EvtVector4C a = EvtLeptonACurrent( sp1, sp2 ); EvtVector4C v = EvtLeptonVCurrent( sp1, sp2 ); EvtVector4C va = EvtLeptonVACurrent( sp1, sp2 ); EvtTensor4C t = EvtLeptonTCurrent( sp1, sp2 ); //start with boosts... EvtVector4R ranBoost( 2.0, 0.4, -0.8, 0.3 ); EvtDiracSpinor sp1Boost = boostTo( sp1, ranBoost ); EvtDiracSpinor sp2Boost = boostTo( sp2, ranBoost ); EvtComplex sBoost = EvtLeptonSCurrent( sp1Boost, sp2Boost ); EvtComplex pBoost = EvtLeptonPCurrent( sp1Boost, sp2Boost ); EvtVector4C aBoost = EvtLeptonACurrent( sp1Boost, sp2Boost ); EvtVector4C vBoost = EvtLeptonVCurrent( sp1Boost, sp2Boost ); EvtVector4C vaBoost = EvtLeptonVACurrent( sp1Boost, sp2Boost ); EvtTensor4C tBoost = EvtLeptonTCurrent( sp1Boost, sp2Boost ); EvtVector4C aDirBoost = boostTo( a, ranBoost ); EvtVector4C vDirBoost = boostTo( v, ranBoost ); EvtVector4C vaDirBoost = boostTo( va, ranBoost ); EvtTensor4C tDirBoost( t ); tDirBoost.applyBoostTo( ranBoost ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Comparing after doing a random boost" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Scalar " << s << " " << sBoost << s - sBoost << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "PseudoScalar " << p << " " << pBoost << p - pBoost << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "AxialVector " << aDirBoost << " " << aBoost << aDirBoost - aBoost << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Vector " << vDirBoost << " " << vBoost << vDirBoost - vBoost << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "V-A " << vaDirBoost << " " << vaBoost << vaDirBoost - vaBoost << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Tensor " << tDirBoost << " " << tBoost << tDirBoost - tBoost << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Done comparing after doing a random boost" << std::endl; //Now do rotations... //start with boosts... double alpha = 0.4; double beta = -0.61; double gamma = 3.0; EvtDiracSpinor sp1Rot = rotateEuler( sp1, alpha, beta, gamma ); EvtDiracSpinor sp2Rot = rotateEuler( sp2, alpha, beta, gamma ); EvtComplex sRot = EvtLeptonSCurrent( sp1Rot, sp2Rot ); EvtComplex pRot = EvtLeptonPCurrent( sp1Rot, sp2Rot ); EvtVector4C aRot = EvtLeptonACurrent( sp1Rot, sp2Rot ); EvtVector4C vRot = EvtLeptonVCurrent( sp1Rot, sp2Rot ); EvtVector4C vaRot = EvtLeptonVACurrent( sp1Rot, sp2Rot ); EvtTensor4C tRot = EvtLeptonTCurrent( sp1Rot, sp2Rot ); EvtVector4C aDirRot( a ); EvtVector4C vDirRot( v ); EvtVector4C vaDirRot( va ); EvtTensor4C tDirRot( t ); aDirRot.applyRotateEuler( alpha, beta, gamma ); vDirRot.applyRotateEuler( alpha, beta, gamma ); vaDirRot.applyRotateEuler( alpha, beta, gamma ); tDirRot.applyRotateEuler( alpha, beta, gamma ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Comparing after doing a random rotation" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Scalar " << s << " " << sRot << s - sRot << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "PseudoScalar " << p << " " << pRot << p - pRot << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "AxialVector " << aDirRot << " " << aRot << aDirRot - aRot << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Vector " << vDirRot << " " << vRot << vDirRot - vRot << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "V-A " << vaDirRot << " " << vaRot << vaDirRot - vaRot << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Tensor " << tDirRot << " " << tRot << tDirRot - tRot << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Done comparing after doing a random rotation" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } int countInclusive( std::string name, EvtParticle* root_part, TH1F* mom, TH1F* mass ) { EvtParticle* p = root_part; int temp = 0; EvtId searchFor = EvtPDL::getId( name ); do { EvtId type = p->getId(); if ( type == searchFor ) { temp += 1; if ( mom ) mom->Fill( p->getP4Lab().d3mag() ); if ( mass ) mass->Fill( p->mass() ); //if ( theBs.contains(p->getParent()->getId()) ) { //dirPsimom->Fill(p->getP4Lab().d3mag()); //} //EvtGenReport(EVTGEN_INFO,"EvtGen") << "LANGE " << p->getP4Lab().d3mag() << " " << p->getP4Lab().get(3)/p->getP4Lab().d3mag() << std::endl; } p = p->nextIter( root_part ); - } while ( p != 0 ); + } while ( p != nullptr ); return temp; } int countInclusiveSubTree( std::string name, EvtParticle* root_part, EvtIdSet setIds, TH1F* /*mom*/ ) { int temp = 0; EvtParticle* p = root_part; do { if ( setIds.contains( p->getId() ) ) { temp += countInclusive( name, p ); } //p->printTree(); p = p->nextIter( root_part ); - } while ( p != 0 ); + } while ( p != nullptr ); //EvtGenReport(EVTGEN_INFO,"EvtGen") << "done"<getId(); if ( type == searchFor ) { if ( p->getParent() ) { if ( setIds.contains( p->getParent()->getId() ) ) { temp += 1; if ( mom ) mom->Fill( p->getP4Lab().d3mag() ); } } } p = p->nextIter( root_part ); - } while ( p != 0 ); + } while ( p != nullptr ); return temp; } void runBMix( int nevent, EvtGen& myGenerator, std::string userFile, std::string rootFile ) { TFile* file = new TFile( rootFile.c_str(), "RECREATE" ); TH1F* b0_b0 = new TH1F( "h1", "dt B0-B0", 100, -15.0, 15.0 ); TH1F* b0b_b0b = new TH1F( "h2", "dt B0B-B0B", 100, -15.0, 15.0 ); TH1F* b0b_b0 = new TH1F( "h3", "dt B0B-B0", 100, -15.0, 15.0 ); TH1F* b0_b0b = new TH1F( "h4", "dt B0-B0B", 100, -15.0, 15.0 ); int count = 1; myGenerator.readUDecay( userFile.c_str() ); EvtId b0 = EvtPDL::getId( "B0" ); EvtId b0b = EvtPDL::getId( "anti-B0" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); std::ofstream outmix; TString outFileName( rootFile.c_str() ); outFileName.ReplaceAll( ".root", ".dat" ); outmix.open( outFileName.Data() ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtId id1 = root_part->getDaug( 0 )->getId(); EvtId id2 = root_part->getDaug( 1 )->getId(); double t1 = root_part->getDaug( 0 )->getLifetime(); double t2 = root_part->getDaug( 1 )->getLifetime(); double dt = ( t1 - t2 ) / ( 1e-12 * 3e11 ); if ( id1 == b0 && id2 == b0 ) { b0_b0->Fill( dt ); outmix << dt << " 1" << std::endl; } if ( id1 == b0b && id2 == b0b ) { b0b_b0b->Fill( dt ); outmix << dt << " 2" << std::endl; } if ( id1 == b0b && id2 == b0 ) { b0b_b0->Fill( dt ); outmix << dt << " 0" << std::endl; } if ( id1 == b0 && id2 == b0b ) { b0_b0b->Fill( dt ); outmix << dt << " 0" << std::endl; } root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runDDalitz( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "ddalitz.root", "RECREATE" ); TH2F* dalitz = new TH2F( "h1", "m^2!?[K-[p]+! vs m^2!?[K-[p]0!", 70, 0.0, 3.5, 70, 0.0, 3.5 ); TH2F* dalitz2 = new TH2F( "h5", "m^2!([p]^-![p]^0!) vs m^2!([K-[p]+!", 100, 0.0, 3.5, 100, 0.0, 2.0 ); TH1F* m12 = new TH1F( "h2", "m?[K-[p]+!", 100, 0.0, 3.0 ); TH1F* m13 = new TH1F( "h3", "m?[K-[p]0!", 100, 0.0, 3.0 ); TH1F* m23 = new TH1F( "h4", "m?[[p]+[p]0!", 100, 0.0, 2.0 ); int count; myGenerator.readUDecay( "exampleFiles/DDALITZ.DEC" ); count = 1; static EvtId D0 = EvtPDL::getId( std::string( "D0" ) ); std::ofstream outmix; outmix.open( "ddalitz.dat" ); do { EvtVector4R p_init( EvtPDL::getMass( D0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( D0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtVector4R p1 = root_part->getDaug( 0 )->getP4Lab(); EvtVector4R p2 = root_part->getDaug( 1 )->getP4Lab(); EvtVector4R p3 = root_part->getDaug( 2 )->getP4Lab(); dalitz->Fill( ( p1 + p2 ).mass2(), ( p1 + p3 ).mass2(), 1.0 ); dalitz2->Fill( ( p1 + p2 ).mass2(), ( p2 + p3 ).mass2(), 1.0 ); m12->Fill( ( p1 + p2 ).mass2() ); m13->Fill( ( p1 + p3 ).mass2() ); m23->Fill( ( p2 + p3 ).mass2() ); outmix << ( p1 + p2 ).mass2() << " " << ( p2 + p3 ).mass2() << " " << ( p1 + p3 ).mass2() << std::endl; root_part->deleteTree(); if ( count == nevent - 1 ) { std::ofstream testi( "testi.dat" ); double val = m12->GetMean(); double errval = m12->GetMeanError(); testi << "evtgenlhc_test1 1 " << val << " " << errval << std::endl; val = m23->GetMean(); errval = m23->GetMeanError(); testi << "evtgenlhc_test1 2 " << val << " " << errval << std::endl; } } while ( count++ < nevent ); file->Write(); file->Close(); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPiPiPi( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "pipipi.dat" ); int count; EvtVector4R p4pip, p4pim, p4pi0; myGenerator.readUDecay( "exampleFiles/PIPIPI.DEC" ); count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); p4pip = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); p4pim = root_part->getDaug( 0 )->getDaug( 1 )->getP4Lab(); p4pi0 = root_part->getDaug( 0 )->getDaug( 2 )->getP4Lab(); outmix << root_part->getDaug( 0 )->getLifetime() << " " << root_part->getDaug( 1 )->getLifetime() << " "; outmix << ( p4pip + p4pim ).mass2() << " " << ( p4pip + p4pi0 ).mass2() << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runBHadronic( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "bhadronic.dat" ); int count; myGenerator.readUDecay( "exampleFiles/BHADRONIC.DEC" ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle* p; // root_part->printTree(); p = root_part; do { outmix << p->getId().getId() << " " << p->getP4Lab().d3mag() << std::endl; p = p->nextIter(); - } while ( p != 0 ); + } while ( p != nullptr ); root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runSingleB( int nevent, EvtGen& myGenerator ) { int count; static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); count = 1; do { EvtVector4R p_init( EvtPDL::getMass( B0 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B0, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); root_part->deleteTree(); } while ( count++ < nevent ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPiPiPiPi( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "pipipipi.dat" ); int count; EvtVector4R p4pi1, p4pi2, p4pi3, p4pi4; myGenerator.readUDecay( "exampleFiles/PIPIPIPI.DEC" ); count = 1; EvtParticle *bcp, *btag; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } p4pi1 = bcp->getDaug( 0 )->getP4Lab(); p4pi2 = bcp->getDaug( 1 )->getP4Lab(); p4pi3 = bcp->getDaug( 2 )->getP4Lab(); p4pi4 = bcp->getDaug( 3 )->getP4Lab(); EvtVector4R p4bcp, p4rho0, p4a2; p4rho0 = p4pi1 + p4pi2; p4a2 = p4rho0 + p4pi3; p4bcp = p4a2 + p4pi4; outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << tag.getId() << " " << ( p4pi1 + p4pi2 + p4pi3 ).mass() << " " << ( p4pi1 + p4pi2 ).mass() << " " << EvtDecayAngle( p4bcp, p4rho0 + p4pi3, p4rho0 ) << " " << EvtDecayAngle( p4a2, p4pi1 + p4pi2, p4pi1 ) << std::endl; root_part->deleteTree(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "count:" << count << std::endl; } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runA2Pi( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "a2pi.dat" ); int count; myGenerator.readUDecay( "exampleFiles/A2PI.DEC" ); EvtParticle *bcp, *btag; EvtParticle *a2, *rho0, *pi1, *pi2, *pi3, *pi4; EvtVector4R p4bcp, p4a2, p4rho0, p4pi1, p4pi2, p4pi3, p4pi4; count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } a2 = bcp->getDaug( 0 ); pi1 = bcp->getDaug( 1 ); rho0 = a2->getDaug( 0 ); pi2 = a2->getDaug( 1 ); pi3 = rho0->getDaug( 0 ); pi4 = rho0->getDaug( 1 ); p4bcp = bcp->getP4Lab(); p4a2 = a2->getP4Lab(); p4pi1 = pi1->getP4Lab(); p4rho0 = rho0->getP4Lab(); p4pi2 = pi2->getP4Lab(); p4pi3 = pi3->getP4Lab(); p4pi4 = pi4->getP4Lab(); EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << EvtDecayAngle( p4bcp, p4rho0 + p4pi2, p4rho0 ) << " " << EvtDecayAngle( p4a2, p4pi3 + p4pi4, p4pi3 ) << " " << EvtPDL::getStdHep( tag ) << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runHelAmp( int nevent, EvtGen& myGenerator, std::string userFile, std::string rootFile ) { TFile* file = new TFile( rootFile.c_str(), "RECREATE" ); TH1F* costheta = new TH1F( "h1", "costheta", 100, -1.0, 1.0 ); TH1F* costheta2 = new TH1F( "h2", "costheta2", 100, -1.0, 1.0 ); int count; myGenerator.readUDecay( userFile.c_str() ); count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtVector4R d14 = root_part->getDaug( 0 )->getP4Lab(); double c = d14.get( 3 ) / d14.d3mag(); costheta->Fill( c ); EvtVector4R p = root_part->getP4Lab(); EvtVector4R q = root_part->getDaug( 0 )->getP4Lab(); EvtVector4R d = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); costheta2->Fill( EvtDecayAngle( p, q, d ) ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runHelAmp2( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "helamp2.root", "RECREATE" ); TH1F* costheta = new TH1F( "h1", "costheta", 100, -1.0, 1.0 ); int count; myGenerator.readUDecay( "exampleFiles/HELAMP2.DEC" ); count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtVector4R p = root_part->getDaug( 0 )->getDaug( 0 )->getP4Lab(); EvtVector4R q = root_part->getDaug( 0 )->getDaug( 0 )->getDaug( 0 )->getP4Lab(); EvtVector4R d = root_part->getDaug( 0 ) ->getDaug( 0 ) ->getDaug( 0 ) ->getDaug( 0 ) ->getP4Lab(); costheta->Fill( EvtDecayAngle( p, q, d ) ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runD2Pi( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "d2pi.root", "RECREATE" ); TH1F* cospi = new TH1F( "h1", "cos[Q]?[p]!", 50, -1.0, 1.0 ); TH1F* ptpi = new TH1F( "h2", "Pt of pion", 50, 0.0, 1.5 ); TH1F* ppi = new TH1F( "h3", "P?[p]! in [Y](4S) rest frame", 50, 0.0, 1.5 ); int count; myGenerator.readUDecay( "exampleFiles/D2PI.DEC" ); EvtParticle* b; EvtParticle *d2, *pi; EvtVector4R p4b, p4d2, p4pi; count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); b = root_part->getDaug( 0 ); d2 = b->getDaug( 0 ); pi = d2->getDaug( 1 ); p4b = b->getP4Lab(); p4d2 = d2->getP4Lab(); p4pi = pi->getP4Lab(); cospi->Fill( EvtDecayAngle( p4b, p4d2, p4pi ) ); ptpi->Fill( sqrt( p4pi.get( 2 ) * p4pi.get( 2 ) + p4pi.get( 3 ) * p4pi.get( 3 ) ) ); ppi->Fill( p4pi.d3mag() ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPiPiCPT( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "pipicpt.dat" ); int count; myGenerator.readUDecay( "exampleFiles/PIPICPT.DEC" ); EvtParticle *bcp, *btag; count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << tag.getId() << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runJpsiKs( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "jpsiks.dat" ); int count; myGenerator.readUDecay( "exampleFiles/JPSIKS.DEC" ); EvtParticle *bcp, *btag; count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId B0 = EvtPDL::getId( std::string( "B0" ) ); static EvtId B0B = EvtPDL::getId( std::string( "anti-B0" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); if ( root_part->getDaug( 0 )->getNDaug() == 3 ) { btag = root_part->getDaug( 0 ); bcp = root_part->getDaug( 1 ); } else { bcp = root_part->getDaug( 0 ); btag = root_part->getDaug( 1 ); } EvtId tag; //cp tag if ( btag->getId() == B0B ) { tag = B0; } else { tag = B0B; } outmix << bcp->getLifetime() << " " << btag->getLifetime() << " " << tag.getId() << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runDump( int nevent, EvtGen& myGenerator ) { int count; std::ofstream outmix; outmix.open( "dump.dat" ); EvtParticle* p; myGenerator.readUDecay( "exampleFiles/DUMP.DEC" ); count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId PIP = EvtPDL::getId( std::string( "pi+" ) ); static EvtId PIM = EvtPDL::getId( std::string( "pi-" ) ); static EvtId EP = EvtPDL::getId( std::string( "e+" ) ); static EvtId KP = EvtPDL::getId( std::string( "K+" ) ); static EvtId MUP = EvtPDL::getId( std::string( "mu+" ) ); static EvtId EM = EvtPDL::getId( std::string( "e-" ) ); static EvtId KM = EvtPDL::getId( std::string( "K-" ) ); static EvtId MUM = EvtPDL::getId( std::string( "mu-" ) ); static EvtId GAMM = EvtPDL::getId( std::string( "gamma" ) ); static EvtId K0L = EvtPDL::getId( std::string( "K_L0" ) ); do { if ( count == 100 * ( count / 100 ) ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << count << std::endl; } EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); p = root_part; EvtParticle* otherb = root_part->getDaug( 1 ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Event:" << count << std::endl; root_part->printTree(); outmix << "B" << " " << otherb->getP4Lab().get( 0 ) << " " << otherb->getP4Lab().get( 1 ) << " " << otherb->getP4Lab().get( 2 ) << " " << otherb->getP4Lab().get( 3 ) << std::endl; do { if ( p->getId() == PIP || p->getId() == EP || p->getId() == KP || p->getId() == MUP ) { outmix << "chg +1" << " " << p->getP4Lab().get( 1 ) << " " << p->getP4Lab().get( 2 ) << " " << p->getP4Lab().get( 3 ) << std::endl; } if ( p->getId() == PIM || p->getId() == EM || p->getId() == KM || p->getId() == MUM ) { outmix << "chg -1" << " " << p->getP4Lab().get( 1 ) << " " << p->getP4Lab().get( 2 ) << " " << p->getP4Lab().get( 3 ) << std::endl; } if ( p->getId() == GAMM || p->getId() == K0L ) { outmix << "neu" << " " << p->getP4Lab().get( 1 ) << " " << p->getP4Lab().get( 2 ) << " " << p->getP4Lab().get( 3 ) << std::endl; } p = p->nextIter(); - } while ( p != 0 ); + } while ( p != nullptr ); outmix << "event" << std::endl; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runGenericCont( int nevent, EvtGen& myGenerator ) { int count; std::ofstream outmix; outmix.open( "genericcont.dat" ); EvtParticle* p; myGenerator.readUDecay( "exampleFiles/GENERIC.DEC" ); count = 1; static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); static EvtId VPHO = EvtPDL::getId( std::string( "vpho" ) ); do { if ( count == 1000 * ( count / 1000 ) ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << count << std::endl; } EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( VPHO, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); p = root_part; do { outmix << p->getId().getId() << " " << p->getP4Lab().d3mag() << std::endl; p = p->nextIter(); - } while ( p != 0 ); + } while ( p != nullptr ); //root_part->printTree(); root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runD1( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "d1.dat" ); int count = 1; myGenerator.readUDecay( "exampleFiles/D1.DEC" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); EvtParticle *p_b, *p_d1, *p_e, *p_nu, *p_pi1, *p_dstar, *p_pi2, *p_d; EvtVector4R p4_b, p4_d1, p4_e, p4_nu, p4_pi1, p4_dstar, p4_pi2, p4_d; // code for analyzing B->D1 e nu ; D1 -> D* pi ; D* -> D pi p_b = root_part->getDaug( 1 ); p_d1 = p_b->getDaug( 0 ); p_e = p_b->getDaug( 1 ); p_nu = p_b->getDaug( 2 ); p_dstar = p_d1->getDaug( 0 ); p_pi1 = p_d1->getDaug( 1 ); p_d = p_dstar->getDaug( 0 ); p_pi2 = p_dstar->getDaug( 1 ); p4_b = p_b->getP4Lab(); p4_d1 = p_d1->getP4Lab(); p4_e = p_e->getP4Lab(); p4_nu = p_nu->getP4Lab(); p4_dstar = p_dstar->getP4Lab(); p4_pi1 = p_pi1->getP4Lab(); p4_pi2 = p_pi2->getP4Lab(); p4_d = p_d->getP4Lab(); outmix << p4_e.get( 0 ) << " "; outmix << ( p4_e + p4_nu ) * ( p4_e + p4_nu ) << " "; outmix << EvtDecayAngle( p4_b, p4_e + p4_nu, p4_e ) << " "; outmix << EvtDecayAngle( p4_b, p4_dstar + p4_pi1, p4_dstar ) << " "; outmix << EvtDecayAngle( p4_d1, p4_d + p4_pi2, p4_d ) << " "; outmix << EvtDecayAngleChi( p4_b, p4_e, p4_nu, p4_dstar, p4_pi1 ) << "\n"; root_part->deleteTree(); EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << "count:" << count << std::endl; } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runMix( int nevent, EvtGen& myGenerator ) { std::ofstream outmix; outmix.open( "mix.dat" ); int count = 1; myGenerator.readUDecay( "exampleFiles/MIX.DEC" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); do { EvtVector4R p_init( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( UPS4, p_init ); root_part->setVectorSpinDensity(); myGenerator.generateDecay( root_part ); outmix << root_part->getDaug( 0 )->getId().getId() << " "; outmix << root_part->getDaug( 0 )->getLifetime() << " "; outmix << root_part->getDaug( 1 )->getId().getId() << " "; outmix << root_part->getDaug( 1 )->getLifetime() << "\n"; root_part->deleteTree(); } while ( count++ < nevent ); outmix.close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runBaryonic( int nEvent, EvtGen& myGenerator ) { TFile* f = new TFile( "baryonic.root", "RECREATE" ); TH1D* q2Hist = new TH1D( "q2Hist", "q square", 50, 0.0, 25.00 ); EvtId BMINUS = EvtPDL::getId( "B-" ); EvtVector4R p_init( EvtPDL::getMass( BMINUS ), 0.0, 0.0, 0.0 ); EvtParticle* root_part; myGenerator.readUDecay( "exampleFiles/BARYONIC.DEC" ); EvtVector4R l; EvtVector4R p; EvtVector4R g; EvtVector4R sum; for ( int i = 0; i < nEvent; ++i ) { root_part = EvtParticleFactory::particleFactory( BMINUS, p_init ); root_part->setDiagonalSpinDensity(); myGenerator.generateDecay( root_part ); l = root_part->getDaug( 0 )->getP4Lab(); // lambda momentum p = root_part->getDaug( 1 )->getP4Lab(); // pBar momentum g = root_part->getDaug( 2 )->getP4Lab(); // gamma momentum sum = p + g; q2Hist->Fill( sum.mass2() ); root_part->deleteTree(); } f->Write(); f->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runPhspDecaytimeCut( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "phspdecaytimecut.root", "RECREATE" ); TH1F* thist = new TH1F( "h1", "t [ps]", 100, 0.0, 10.0 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/PhspDecaytimeCut.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B = EvtPDL::getId( std::string( "B+" ) ); std::ofstream outmix; do { EvtVector4R pinit( EvtPDL::getMass( B ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B, pinit ); myGenerator.generateDecay( root_part ); double t = root_part->getLifetime() / ( 1e-12 * EvtConst::c ); thist->Fill( t ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void run3BPhspRegion( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "3BodyPhspRegion.root", "RECREATE" ); TH1F* pxhist = new TH1F( "h1", "p_x ", 100, -3.0, 3.0 ); TH1F* pyhist = new TH1F( "h2", "p_y ", 100, -3.0, 3.0 ); TH1F* pzhist = new TH1F( "h3", "p_z ", 100, -3.0, 3.0 ); TH2F* dalitz = new TH2F( "h4", "Dalitz", 50, 12.5, 27., 50, 0.35, 4.8 ); TH2F* pxpyhist = new TH2F( "h5", "px-py", 50, -1.8, 1.8, 50, -1.8, 1.8 ); TH2F* pxpzhist = new TH2F( "h6", "px-pz", 50, -1.8, 1.8, 50, -1.8, 1.8 ); TH2F* pypzhist = new TH2F( "h7", "py-pz", 50, -1.8, 1.8, 50, -1.8, 1.8 ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/3BodyPhspRegion.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B = EvtPDL::getId( std::string( "B+" ) ); std::ofstream outmix; do { EvtVector4R pinit( EvtPDL::getMass( B ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B, pinit ); myGenerator.generateDecay( root_part ); EvtParticle* daug1 = root_part->getDaug( 0 ); EvtParticle* daug2 = root_part->getDaug( 1 ); EvtParticle* daug3 = root_part->getDaug( 2 ); pxhist->Fill( daug1->getP4().get( 1 ) ); pyhist->Fill( daug1->getP4().get( 2 ) ); pzhist->Fill( daug1->getP4().get( 3 ) ); pxpyhist->Fill( daug1->getP4().get( 1 ), daug1->getP4().get( 2 ) ); pxpzhist->Fill( daug1->getP4().get( 1 ), daug1->getP4().get( 3 ) ); pypzhist->Fill( daug1->getP4().get( 2 ), daug1->getP4().get( 3 ) ); double m12 = ( daug1->getP4() + daug2->getP4() ).mass(); double m23 = ( daug2->getP4() + daug3->getP4() ).mass(); dalitz->Fill( m12 * m12, m23 * m23 ); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } void runFourBody( int nevent, EvtGen& myGenerator ) { TFile* file = new TFile( "fourBody.root", "RECREATE" ); double m12, m13, m14, m23, m24, m34, m123, m124, m234; double mB, m1, m2, m3, m4; double pBe, pBx, pBy, pBz; double p1e, p1x, p1y, p1z; double p2e, p2x, p2y, p2z; double p3e, p3x, p3y, p3z; double p4e, p4x, p4y, p4z; double theta1, theta3, chi; TTree* tree = new TTree( "tree", "" ); tree->Branch( "m12", &m12, "m12/D" ); tree->Branch( "m13", &m13, "m13/D" ); tree->Branch( "m14", &m14, "m14/D" ); tree->Branch( "m23", &m23, "m23/D" ); tree->Branch( "m24", &m24, "m24/D" ); tree->Branch( "m34", &m34, "m34/D" ); tree->Branch( "m123", &m123, "m123/D" ); tree->Branch( "m124", &m124, "m124/D" ); tree->Branch( "m234", &m234, "m234/D" ); tree->Branch( "mB", &mB, "mB/D" ); tree->Branch( "m1", &m1, "m1/D" ); tree->Branch( "m2", &m2, "m2/D" ); tree->Branch( "m3", &m3, "m3/D" ); tree->Branch( "m4", &m4, "m4/D" ); tree->Branch( "pBe", &pBe, "pBe/D" ); tree->Branch( "pBx", &pBx, "pBx/D" ); tree->Branch( "pBy", &pBy, "pBy/D" ); tree->Branch( "pBz", &pBz, "pBz/D" ); tree->Branch( "p1e", &p1e, "p1e/D" ); tree->Branch( "p1x", &p1x, "p1x/D" ); tree->Branch( "p1y", &p1y, "p1y/D" ); tree->Branch( "p1z", &p1z, "p1z/D" ); tree->Branch( "p2e", &p2e, "p2e/D" ); tree->Branch( "p2x", &p2x, "p2x/D" ); tree->Branch( "p2y", &p2y, "p2y/D" ); tree->Branch( "p2z", &p2z, "p2z/D" ); tree->Branch( "p3e", &p3e, "p3e/D" ); tree->Branch( "p3x", &p3x, "p3x/D" ); tree->Branch( "p3y", &p3y, "p3y/D" ); tree->Branch( "p3z", &p3z, "p3z/D" ); tree->Branch( "p4e", &p4e, "p4e/D" ); tree->Branch( "p4x", &p4x, "p4x/D" ); tree->Branch( "p4y", &p4y, "p4y/D" ); tree->Branch( "p4z", &p4z, "p4z/D" ); tree->Branch( "theta1", &theta1, "theta1/D" ); tree->Branch( "theta3", &theta3, "theta3/D" ); tree->Branch( "chi", &chi, "chi/D" ); int count = 1; char udecay_name[100]; strcpy( udecay_name, "exampleFiles/4BodyPhsp.DEC" ); myGenerator.readUDecay( udecay_name ); static EvtId B = EvtPDL::getId( std::string( "B+" ) ); do { EvtVector4R pinit( EvtPDL::getMass( B ), 0.0, 0.0, 0.0 ); EvtParticle* root_part = EvtParticleFactory::particleFactory( B, pinit ); myGenerator.generateDecay( root_part ); mB = root_part->mass(); m1 = root_part->getDaug( 0 )->mass(); m2 = root_part->getDaug( 1 )->mass(); m3 = root_part->getDaug( 2 )->mass(); m4 = root_part->getDaug( 3 )->mass(); EvtParticle* daug1 = root_part->getDaug( 0 ); EvtParticle* daug2 = root_part->getDaug( 1 ); EvtParticle* daug3 = root_part->getDaug( 2 ); EvtParticle* daug4 = root_part->getDaug( 3 ); m12 = ( daug1->getP4() + daug2->getP4() ).mass(); m13 = ( daug1->getP4() + daug3->getP4() ).mass(); m14 = ( daug1->getP4() + daug4->getP4() ).mass(); m23 = ( daug2->getP4() + daug3->getP4() ).mass(); m24 = ( daug2->getP4() + daug4->getP4() ).mass(); m34 = ( daug3->getP4() + daug4->getP4() ).mass(); m123 = ( daug1->getP4() + daug2->getP4() + daug3->getP4() ).mass(); m124 = ( daug1->getP4() + daug2->getP4() + daug4->getP4() ).mass(); m234 = ( daug2->getP4() + daug3->getP4() + daug4->getP4() ).mass(); pBe = root_part->getP4().get( 0 ); pBx = root_part->getP4().get( 1 ); pBy = root_part->getP4().get( 2 ); pBz = root_part->getP4().get( 3 ); p1e = daug1->getP4().get( 0 ); p1x = daug1->getP4().get( 1 ); p1y = daug1->getP4().get( 2 ); p1z = daug1->getP4().get( 3 ); p2e = daug2->getP4().get( 0 ); p2x = daug2->getP4().get( 1 ); p2y = daug2->getP4().get( 2 ); p2z = daug2->getP4().get( 3 ); p3e = daug3->getP4().get( 0 ); p3x = daug3->getP4().get( 1 ); p3y = daug3->getP4().get( 2 ); p3z = daug3->getP4().get( 3 ); p4e = daug4->getP4().get( 0 ); p4x = daug4->getP4().get( 1 ); p4y = daug4->getP4().get( 2 ); p4z = daug4->getP4().get( 3 ); theta1 = EvtDecayAngle( root_part->getP4(), daug1->getP4() + daug2->getP4(), daug1->getP4() ); theta3 = EvtDecayAngle( root_part->getP4(), daug3->getP4() + daug4->getP4(), daug3->getP4() ); chi = EvtDecayAngleChi( root_part->getP4(), daug1->getP4(), daug2->getP4(), daug3->getP4(), daug4->getP4() ); tree->Fill(); root_part->deleteTree(); } while ( count++ < nevent ); file->Write(); file->Close(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "SUCCESS\n"; } diff --git a/test/example1.cc b/test/example1.cc index cbb71e1..e45e634 100644 --- a/test/example1.cc +++ b/test/example1.cc @@ -1,113 +1,113 @@ /*********************************************************************** * 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 . * ***********************************************************************/ // // Sample test program for running EvtGen // #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include #include #include int main( int /*argc*/, char** /*argv*/ ) { - EvtParticle* parent( 0 ); + EvtParticle* parent( nullptr ); // Define the random number generator - EvtRandomEngine* eng = 0; + EvtRandomEngine* eng = nullptr; #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) eng = new EvtMTRandomEngine(); #else eng = new EvtSimpleRandomEngine(); #endif EvtRandom::setRandomEngine( eng ); - EvtAbsRadCorr* radCorrEngine = 0; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); bool useEvtGenRandom( true ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif //Initialize the generator - read in the decay table and particle properties EvtGen myGenerator( "../DECAY.DEC", "../evt.pdl", eng, radCorrEngine, &extraModels ); //If I wanted a user decay file, I would read it in now. //myGenerator.readUDecay("../user.dec"); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); int nEvents( 100 ); // Loop to create nEvents, starting from an Upsilon(4S) int i; for ( i = 0; i < nEvents; i++ ) { std::cout << "Event number " << i << std::endl; // Set up the parent particle EvtVector4R pInit( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); parent = EvtParticleFactory::particleFactory( UPS4, pInit ); parent->setVectorSpinDensity(); // Generate the event myGenerator.generateDecay( parent ); // Write out the results EvtHepMCEvent theEvent; theEvent.constructEvent( parent ); GenEvent* genEvent = theEvent.getEvent(); #ifdef EVTGEN_HEPMC3 HepMC3::Print::line( *genEvent ); #else genEvent->print( std::cout ); #endif parent->deleteTree(); } delete eng; return 0; } diff --git a/test/exampleWriteHepMC.cc b/test/exampleWriteHepMC.cc index 1d16d28..d98aa78 100644 --- a/test/exampleWriteHepMC.cc +++ b/test/exampleWriteHepMC.cc @@ -1,154 +1,154 @@ /*********************************************************************** * 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 . * ***********************************************************************/ // // Sample test program for running EvtGen // #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include #include #include #include #ifdef EVTGEN_HEPMC3 #include typedef HepMC3::WriterAsciiHepMC2 output_writer; #else class output_writer : public std::ofstream { public: output_writer( const char* a ) : std::ofstream( a ) {} bool write_event( HepMC::GenEvent& e ) { ( *this ) << e; return true; } }; #endif bool filter( GenEvent* event ) { bool hasLepton = false; bool hasCharm = false; #ifdef EVTGEN_HEPMC3 for ( auto p : event->particles() ) { #else for ( HepMC::GenEvent::particle_iterator it = event->particles_begin(); it != event->particles_end(); ++it ) { GenParticlePtr p = *it; #endif if ( abs( p->pdg_id() ) == 11 || abs( p->pdg_id() ) == 13 ) { hasLepton = true; } int id = abs( p->pdg_id() ); if ( id > 400 && id < 500 ) { hasCharm = true; } } return ( hasLepton && ( !hasCharm ) ); } int main( int /*argc*/, char** /*argv*/ ) { - EvtParticle* parent( 0 ); + EvtParticle* parent( nullptr ); // Define the random number generator - EvtRandomEngine* eng = 0; + EvtRandomEngine* eng = nullptr; #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) eng = new EvtMTRandomEngine(); #else eng = new EvtSimpleRandomEngine(); #endif EvtRandom::setRandomEngine( eng ); - EvtAbsRadCorr* radCorrEngine = 0; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); bool useEvtGenRandom( true ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif //Initialize the generator - read in the decay table and particle properties EvtGen myGenerator( "../DECAY.DEC", "../evt.pdl", eng, radCorrEngine, &extraModels ); //If I wanted a user decay file, I would read it in now. myGenerator.readUDecay( "exampleFiles/Btousemileptonic.dec" ); static EvtId UPS4 = EvtPDL::getId( std::string( "Upsilon(4S)" ) ); int nEvents( 40000 ); output_writer hepmcFile( "hepMCtest" ); // Loop to create nEvents, starting from an Upsilon(4S) int i; for ( i = 0; i < nEvents; i++ ) { std::cout << "Event number " << i << std::endl; // Set up the parent particle EvtVector4R pInit( EvtPDL::getMass( UPS4 ), 0.0, 0.0, 0.0 ); parent = EvtParticleFactory::particleFactory( UPS4, pInit ); parent->setVectorSpinDensity(); // Generate the event myGenerator.generateDecay( parent ); // Write out the results EvtHepMCEvent theEvent; theEvent.constructEvent( parent ); GenEvent* genEvent = theEvent.getEvent(); if ( filter( genEvent ) ) hepmcFile.write_event( *genEvent ); parent->deleteTree(); } hepmcFile.close(); delete eng; return 0; } diff --git a/validation/compareRootFiles.cc b/validation/compareRootFiles.cc index 7039e51..81d1219 100644 --- a/validation/compareRootFiles.cc +++ b/validation/compareRootFiles.cc @@ -1,668 +1,668 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ #include "compareRootFiles.hh" #include "TAxis.h" #include "TLatex.h" #include "TLegend.h" #include "TROOT.h" #include "TStyle.h" #include "TText.h" #include #include using std::cout; using std::endl; compareRootFiles::compareRootFiles( string decayName, string newFileName, string oldFileName, string description ) { _decayName = decayName; _newFileName = newFileName; _oldFileName = oldFileName; _description = description; _newFile = new TFile( newFileName.c_str(), "read" ); _oldFile = new TFile( oldFileName.c_str(), "read" ); gROOT->SetStyle( "Plain" ); gStyle->SetOptStat( 0 ); _theCanvas = new TCanvas( "theCanvas", "", 900, 700 ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _emptyHist = new TH1D( "", "", 10, 0.0, 0.0 ); _nGroupMax = 12; } compareRootFiles::~compareRootFiles() { _newFile->Close(); _oldFile->Close(); } void compareRootFiles::getMtmPlots() { // Plot mtm plots for different particle groups // Leptons+gamma, pions, kaons, charm, light/strange baryons, other vector newHistVect, oldHistVect; vector leptonInts; leptonInts.push_back( 0 ); leptonInts.push_back( 1 ); TH1D* newLeptMtmHist = getMtmHist( _newFile, "newLeptMtmHist", leptonInts ); TH1D* oldLeptMtmHist = getMtmHist( _oldFile, "oldLeptMtmHist", leptonInts ); newHistVect.push_back( newLeptMtmHist ); oldHistVect.push_back( oldLeptMtmHist ); vector pionInts; pionInts.push_back( 2 ); pionInts.push_back( 3 ); TH1D* newPionMtmHist = getMtmHist( _newFile, "newPionMtmHist", pionInts ); TH1D* oldPionMtmHist = getMtmHist( _oldFile, "oldPionMtmHist", pionInts ); newHistVect.push_back( newPionMtmHist ); oldHistVect.push_back( oldPionMtmHist ); vector kaonInts; kaonInts.push_back( 4 ); kaonInts.push_back( 5 ); TH1D* newKaonMtmHist = getMtmHist( _newFile, "newKaonMtmHist", kaonInts ); TH1D* oldKaonMtmHist = getMtmHist( _oldFile, "oldKaonMtmHist", kaonInts ); newHistVect.push_back( newKaonMtmHist ); oldHistVect.push_back( oldKaonMtmHist ); vector charmInts; charmInts.push_back( 6 ); charmInts.push_back( 7 ); TH1D* newCharmMtmHist = getMtmHist( _newFile, "newCharmMtmHist", charmInts ); TH1D* oldCharmMtmHist = getMtmHist( _oldFile, "oldCharmMtmHist", charmInts ); newHistVect.push_back( newCharmMtmHist ); oldHistVect.push_back( oldCharmMtmHist ); vector baryonInts; baryonInts.push_back( 8 ); baryonInts.push_back( 9 ); TH1D* newBaryonMtmHist = getMtmHist( _newFile, "newBaryonMtmHist", baryonInts ); TH1D* oldBaryonMtmHist = getMtmHist( _oldFile, "oldBaryonMtmHist", baryonInts ); newHistVect.push_back( newBaryonMtmHist ); oldHistVect.push_back( oldBaryonMtmHist ); vector otherInts; otherInts.push_back( 10 ); TH1D* newOtherMtmHist = getMtmHist( _newFile, "newOtherMtmHist", otherInts ); TH1D* oldOtherMtmHist = getMtmHist( _oldFile, "oldOtherMtmHist", otherInts ); newHistVect.push_back( newOtherMtmHist ); oldHistVect.push_back( oldOtherMtmHist ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); gPad->SetLogy(); // Different colours for the particle groups int colours[6] = {1, 2, 4, 6, 8, 28}; string histLabels[6] = { "Leptons,#gamma", "Pions", "Kaons", "D+,D-,D0", "Light/strange baryons", "Other"}; TLegend* theLegend = new TLegend( 0.7, 0.7, 0.9, 0.9 ); theLegend->SetFillColor( kWhite ); double newHistMax( 0.0 ), oldHistMax( 0.0 ); int newHistMaxInt( 0 ), oldHistMaxInt( 0 ); double totalNewFreq( 0.0 ), totalOldFreq( 0.0 ); int iHist( 0 ); int nHistVect = newHistVect.size(); for ( iHist = 0; iHist < nHistVect; iHist++ ) { TH1D* newHist = newHistVect[iHist]; string labelName = histLabels[iHist]; theLegend->AddEntry( newHist, labelName.c_str(), "lpf" ); int colour = colours[iHist]; newHist->SetLineColor( colour ); double theNewHistMax = newHist->GetMaximum(); if ( theNewHistMax > newHistMax ) { newHistMax = theNewHistMax; newHistMaxInt = iHist; } newHist->SetMarkerSize( 0.8 ); newHist->SetMarkerStyle( kFullCircle ); newHist->SetMarkerColor( colour ); totalNewFreq += newHist->Integral(); TH1D* oldHist = oldHistVect[iHist]; oldHist->SetLineStyle( kDashed ); oldHist->SetLineColor( colour ); oldHist->SetMarkerSize( 0.8 ); oldHist->SetMarkerStyle( kOpenCircle ); oldHist->SetMarkerColor( colour ); double theOldHistMax = oldHist->GetMaximum(); if ( theOldHistMax > oldHistMax ) { oldHistMax = theOldHistMax; oldHistMaxInt = iHist; } totalOldFreq += oldHist->Integral(); } double newScale = 1.0 / totalNewFreq; double oldScale = 1.0 / totalOldFreq; if ( newHistMax > oldHistMax ) { TH1D* newFirstHist = newHistVect[newHistMaxInt]; TAxis* xAxis = newFirstHist->GetXaxis(); double dx = xAxis->GetBinWidth( 1 ) * 1000.0; char dxChar[100]; sprintf( dxChar, "Normalised frequency/%.0f (MeV/c)", dx ); newFirstHist->SetXTitle( "p (GeV/c)" ); newFirstHist->SetYTitle( dxChar ); newFirstHist->SetTitleOffset( 1.25, "Y" ); newFirstHist->Scale( newScale ); newFirstHist->Draw( "p" ); for ( iHist = 0; iHist < nHistVect; iHist++ ) { if ( iHist != newHistMaxInt ) { TH1D* otherNewHist = newHistVect[iHist]; otherNewHist->Scale( newScale ); otherNewHist->Draw( "samep" ); } TH1D* otherOldHist = oldHistVect[iHist]; otherOldHist->Scale( oldScale ); otherOldHist->Draw( "samep" ); } } else { TH1D* oldFirstHist = oldHistVect[oldHistMaxInt]; TAxis* xAxis = oldFirstHist->GetXaxis(); double dx = xAxis->GetBinWidth( 1 ) * 1000.0; char dxChar[100]; sprintf( dxChar, "Normalised frequency/%.0f (MeV/c)", dx ); oldFirstHist->SetXTitle( "p (GeV/c)" ); oldFirstHist->SetYTitle( dxChar ); oldFirstHist->SetTitleOffset( 1.25, "Y" ); oldFirstHist->Scale( oldScale ); oldFirstHist->Draw( "p" ); for ( iHist = 0; iHist < nHistVect; iHist++ ) { if ( iHist != oldHistMaxInt ) { TH1D* otherOldHist = oldHistVect[iHist]; otherOldHist->Scale( oldScale ); otherOldHist->Draw( "samep" ); } TH1D* otherNewHist = newHistVect[iHist]; otherNewHist->Scale( newScale ); otherNewHist->Draw( "samep" ); } } theLegend->Draw(); TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_mtmHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); gPad->SetLogy( 0 ); } void compareRootFiles::getPartIdPlots() { TH1D* newPartIdHist = getPartIdHist( _newFile, "newPartIdHist" ); TH1D* oldPartIdHist = getPartIdHist( _oldFile, "oldPartIdHist" ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); gPad->SetLogy(); double newPartIdMax = newPartIdHist->GetMaximum(); double oldPartIdMax = oldPartIdHist->GetMaximum(); newPartIdHist->SetMarkerSize( 1.0 ); newPartIdHist->SetMarkerStyle( kFullCircle ); oldPartIdHist->SetLineStyle( kDashed ); oldPartIdHist->SetMarkerSize( 1.0 ); oldPartIdHist->SetMarkerStyle( kOpenCircle ); if ( newPartIdMax > oldPartIdMax ) { newPartIdHist->SetXTitle( "" ); newPartIdHist->SetYTitle( "Normalised frequency" ); newPartIdHist->SetTitleOffset( 1.25, "Y" ); newPartIdHist->Draw( "p" ); oldPartIdHist->Draw( "samep" ); } else { oldPartIdHist->SetXTitle( "" ); oldPartIdHist->SetYTitle( "Normalised frequency" ); oldPartIdHist->SetTitleOffset( 1.25, "Y" ); oldPartIdHist->Draw( "p" ); newPartIdHist->Draw( "samep" ); } TLatex* latex = new TLatex(); latex->SetTextAngle( 90.0 ); latex->SetTextSize( 0.035 ); latex->DrawLatex( 0.5, 0, "Leptons" ); latex->SetTextSize( 0.045 ); latex->DrawLatex( 1.5, 0, "#gamma" ); latex->DrawLatex( 2.5, 0, "#pi^{#pm}" ); latex->DrawLatex( 3.5, 0, "#pi^{0}" ); latex->DrawLatex( 4.5, 0, "K^{#pm}" ); latex->DrawLatex( 5.5, 0, "K^{0}" ); latex->DrawLatex( 6.5, 0, "D^{#pm}" ); latex->DrawLatex( 7.5, 0, "D^{0}" ); latex->SetTextSize( 0.035 ); latex->DrawLatex( 8.4, 0, "Light" ); latex->DrawLatex( 8.75, 0, "baryons" ); latex->DrawLatex( 9.4, 0, "Strange" ); latex->DrawLatex( 9.75, 0, "baryons" ); latex->DrawLatex( 10.5, 0, "Other" ); TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_partIdHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); gPad->SetLogy( 0 ); } void compareRootFiles::getAllIdPlots() { TH1D* newAllIdHist = getAllIdHist( _newFile, "newAllIdHist" ); TH1D* oldAllIdHist = getAllIdHist( _oldFile, "oldAllIdHist" ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); gPad->SetLogy(); double newAllIdMax = newAllIdHist->GetMaximum(); double oldAllIdMax = oldAllIdHist->GetMaximum(); newAllIdHist->SetMarkerSize( 1.0 ); newAllIdHist->SetMarkerStyle( kFullCircle ); oldAllIdHist->SetLineStyle( kDashed ); oldAllIdHist->SetMarkerSize( 1.0 ); oldAllIdHist->SetMarkerStyle( kOpenCircle ); if ( newAllIdMax > oldAllIdMax ) { newAllIdHist->SetXTitle( "PDG Id" ); newAllIdHist->SetYTitle( "Normalised frequency" ); newAllIdHist->SetTitleOffset( 1.25, "Y" ); newAllIdHist->Draw( "p" ); oldAllIdHist->Draw( "samep" ); } else { oldAllIdHist->SetXTitle( "PDG Id" ); oldAllIdHist->SetYTitle( "Normalised frequency" ); oldAllIdHist->SetTitleOffset( 1.25, "Y" ); oldAllIdHist->Draw( "p" ); newAllIdHist->Draw( "samep" ); } TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_allIdHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); gPad->SetLogy( 0 ); } void compareRootFiles::getNDaugPlots() { TH1D* newDaugHist = getDaugHist( _newFile, "newDaugHist" ); TH1D* oldDaugHist = getDaugHist( _oldFile, "oldDaugHist" ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); double newDaugMax = newDaugHist->GetMaximum(); double oldDaugMax = oldDaugHist->GetMaximum(); newDaugHist->SetMarkerSize( 1.0 ); newDaugHist->SetMarkerStyle( kFullCircle ); oldDaugHist->SetLineStyle( kDashed ); oldDaugHist->SetMarkerSize( 1.0 ); oldDaugHist->SetMarkerStyle( kOpenCircle ); if ( newDaugMax > oldDaugMax ) { newDaugHist->SetXTitle( "nDaughters" ); newDaugHist->SetYTitle( "Normalised frequency" ); newDaugHist->SetTitleOffset( 1.25, "Y" ); newDaugHist->Draw( "p" ); oldDaugHist->Draw( "samep" ); } else { oldDaugHist->SetXTitle( "nDaughters" ); oldDaugHist->SetYTitle( "Normalised frequency" ); oldDaugHist->SetTitleOffset( 1.25, "Y" ); oldDaugHist->Draw( "p" ); newDaugHist->Draw( "samep" ); } TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_daugHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); } TH1D* compareRootFiles::getMtmHist( TFile* theFile, string histName, vector groupInts ) { - if ( theFile == 0 ) { + if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* theTree = dynamic_cast( theFile->Get( "Data" ) ); - if ( theTree == 0 ) { + if ( theTree == nullptr ) { // Return empty histogram return _emptyHist; } int id; double p; theTree->SetBranchAddress( "id", &id ); theTree->SetBranchAddress( "p", &p ); double pMax = theTree->GetMaximum( "p" ); TH1D* mtmHist = new TH1D( histName.c_str(), "", 100, 0.0, pMax * 1.1 ); int i; int nEntries = theTree->GetEntries(); for ( i = 0; i < nEntries; i++ ) { theTree->GetEntry( i ); int testInt = this->getPartGroup( id ); // See if the particle id matches any in the group integer vector vector::iterator iter; for ( iter = groupInts.begin(); iter != groupInts.end(); ++iter ) { int groupInt = *iter; if ( groupInt == testInt ) { // We have the right particle group id code mtmHist->Fill( p ); } } } return mtmHist; } TH1D* compareRootFiles::getPartIdHist( TFile* theFile, string histName ) { // Group pi,K,D etc.. into groups and plot multiplicities // with bins along the x axis representing each group // leptons gamma pi+- pi0 K+- K0 D+- D0 light_baryons strange_baryons other - if ( theFile == 0 ) { + if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* theTree = dynamic_cast( theFile->Get( "Data" ) ); - if ( theTree == 0 ) { + if ( theTree == nullptr ) { // Return empty histogram return _emptyHist; } int id; theTree->SetBranchAddress( "id", &id ); int nGroupMax = _nGroupMax; vector partNumbers( nGroupMax ); int iP; for ( iP = 0; iP < nGroupMax; iP++ ) { partNumbers[iP] = 0.0; } int i; int nEntries = theTree->GetEntries(); for ( i = 0; i < nEntries; i++ ) { theTree->GetEntry( i ); int groupInt = this->getPartGroup( id ); if ( groupInt >= 0 && groupInt < nGroupMax ) { partNumbers[groupInt] += 1.0; } } TH1D* idHist = new TH1D( histName.c_str(), "", nGroupMax, 0, nGroupMax ); idHist->SetMinimum( 1 ); for ( iP = 0; iP < nGroupMax; iP++ ) { double total = partNumbers[iP]; idHist->Fill( iP, total ); } idHist->Scale( 1.0 / ( nEntries * 1.0 ) ); idHist->SetMaximum( 1.0 ); return idHist; } int compareRootFiles::getPartGroup( int PDGId ) { int group( -1 ); int absPDGId = std::abs( PDGId ); if ( absPDGId >= 11 && absPDGId <= 16 ) { group = 0; // leptons } else if ( absPDGId == 22 ) { group = 1; // photon } else if ( absPDGId == 211 ) { group = 2; // pi+- } else if ( absPDGId == 111 ) { group = 3; // pi0 } else if ( absPDGId == 321 ) { group = 4; // K+- } else if ( absPDGId == 311 || absPDGId == 130 || absPDGId == 310 ) { group = 5; // K0 } else if ( absPDGId == 411 ) { group = 6; // D+- } else if ( absPDGId == 421 ) { group = 7; // D0 } else if ( absPDGId == 2212 || absPDGId == 2112 || absPDGId == 2224 || absPDGId == 2214 || absPDGId == 2114 || absPDGId == 1114 ) { group = 8; // light baryons } else if ( absPDGId >= 3112 && absPDGId <= 3334 ) { group = 9; // strange baryons } else if ( absPDGId != 0 ) { group = 10; // other particles } return group; } TH1D* compareRootFiles::getAllIdHist( TFile* theFile, string histName ) { - if ( theFile == 0 ) { + if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* theTree = dynamic_cast( theFile->Get( "Data" ) ); - if ( theTree == 0 ) { + if ( theTree == nullptr ) { // Return empty histogram return _emptyHist; } int id; theTree->SetBranchAddress( "id", &id ); // Just limit the PDG id integer codes up to 4000 int idMax( 4000 ); TH1D* idHist = new TH1D( histName.c_str(), "", 100, -idMax, idMax ); int nEntries = theTree->GetEntries(); cout << "Number of entries = " << nEntries << endl; int i; for ( i = 0; i < nEntries; i++ ) { theTree->GetEntry( i ); idHist->Fill( id ); } double nIdScale = idHist->Integral(); idHist->Scale( 1.0 / nIdScale ); idHist->SetMaximum( 1.0 ); return idHist; } TH1D* compareRootFiles::getDaugHist( TFile* theFile, string histName ) { - if ( theFile == 0 ) { + if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* nDaugTree = dynamic_cast( theFile->Get( "nDaugTree" ) ); - if ( nDaugTree == 0 ) { + if ( nDaugTree == nullptr ) { // Return empty histogram return _emptyHist; } int nDaug; nDaugTree->SetBranchAddress( "nDaug", &nDaug ); int nDaugMax = (int)nDaugTree->GetMaximum( "nDaug" ); int nDaugLimit = nDaugMax + 2; TH1D* nDaugHist = new TH1D( histName.c_str(), "", nDaugLimit, 0, nDaugLimit ); int nEntries = nDaugTree->GetEntries(); cout << "Number of entries = " << nEntries << endl; int i; for ( i = 0; i < nEntries; i++ ) { nDaugTree->GetEntry( i ); if ( nDaug > 0 ) { nDaugHist->Fill( nDaug ); } } double nDaugScale = nDaugHist->Integral(); nDaugHist->Scale( 1.0 / nDaugScale ); cout << "nDaugScale = " << nDaugScale << endl; return nDaugHist; } int main( int argc, char** argv ) { string decayName( "UpsilonDecay1" ); if ( argc > 1 ) { decayName = argv[1]; } string newRootFile( "rootFiles/newUpsilonDecay1.root" ); if ( argc > 2 ) { newRootFile = argv[2]; } string oldRootFile( "rootFiles/oldUpsilonDecay1.root" ); if ( argc > 3 ) { oldRootFile = argv[3]; } string description( "Example description" ); if ( argc > 4 ) { description = argv[4]; } compareRootFiles myCompareRootFiles( decayName, newRootFile, oldRootFile, description ); myCompareRootFiles.getNDaugPlots(); myCompareRootFiles.getAllIdPlots(); myCompareRootFiles.getPartIdPlots(); myCompareRootFiles.getMtmPlots(); } diff --git a/validation/genExampleRootFiles.cc b/validation/genExampleRootFiles.cc index a6d2204..5b0c8a7 100644 --- a/validation/genExampleRootFiles.cc +++ b/validation/genExampleRootFiles.cc @@ -1,291 +1,291 @@ /*********************************************************************** * 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 . * ***********************************************************************/ // Program to create ROOT files for EvtGen validation plots. // This looks at the 1st generation daughters and stores 4-momenta // info into a ROOT file for further analysis. // Useful for Pythia, Photos and Tauola decay tests. #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include "EvtGenBase/EvtHepMCEvent.hh" #include "TFile.h" #include "TTree.h" #include #include #include using std::cout; using std::endl; int main( int argc, char** argv ) { std::string decayFileName( "../DECAY.DEC" ); if ( argc > 1 ) { decayFileName = argv[1]; } cout << "Decay file name is " << decayFileName << endl; std::string rootFileName( "evtgenTest.root" ); if ( argc > 2 ) { rootFileName = argv[2]; } cout << "Root file name is " << rootFileName << endl; std::string parentName( "Upsilon(4S)" ); if ( argc > 3 ) { parentName = argv[3]; } cout << "Parent name is " << parentName << endl; int nEvents( 10 ); if ( argc > 4 ) { nEvents = atoi( argv[4] ); } bool useXml = false; if ( argc > 5 ) { useXml = ( atoi( argv[5] ) == 1 ); } bool useEvtGenRandom = true; if ( argc > 6 ) { useEvtGenRandom = ( atoi( argv[6] ) == 1 ); } cout << "Number of events is " << nEvents << endl; TFile* theFile = new TFile( rootFileName.c_str(), "recreate" ); TTree* theTree = new TTree( "Data", "Data" ); TTree* nDaugTree = new TTree( "nDaugTree", "nDaugTree" ); TTree* dalitzTree = new TTree( "dalitzTree", "dalitzTree" ); theTree->SetDirectory( theFile ); nDaugTree->SetDirectory( theFile ); dalitzTree->SetDirectory( theFile ); int event( 0 ), nDaug( 0 ), daugId( 0 ); double E( 0.0 ), p( 0.0 ), px( 0.0 ), py( 0.0 ), pz( 0.0 ); double t( 0.0 ), x( 0.0 ), y( 0.0 ), z( 0.0 ); double mass( 0.0 ), lifetime( 0.0 ); double inv12( 0.0 ), inv13( 0.0 ), inv23( 0.0 ); double inv12Sq( 0.0 ), inv13Sq( 0.0 ), inv23Sq( 0.0 ); theTree->Branch( "event", &event, "event/I" ); theTree->Branch( "nDaug", &nDaug, "nDaug/I" ); theTree->Branch( "id", &daugId, "id/I" ); theTree->Branch( "E", &E, "E/D" ); theTree->Branch( "p", &p, "p/D" ); theTree->Branch( "px", &px, "px/D" ); theTree->Branch( "py", &py, "py/D" ); theTree->Branch( "pz", &pz, "pz/D" ); theTree->Branch( "t", &t, "t/D" ); theTree->Branch( "x", &x, "x/D" ); theTree->Branch( "y", &y, "x/D" ); theTree->Branch( "z", &z, "x/D" ); theTree->Branch( "mass", &mass, "mass/D" ); theTree->Branch( "lifetime", &lifetime, "lifetime/D" ); nDaugTree->Branch( "event", &event, "event/I" ); nDaugTree->Branch( "nDaug", &nDaug, "nDaug/I" ); dalitzTree->Branch( "invMass12", &inv12, "invMass12/D" ); dalitzTree->Branch( "invMass13", &inv13, "invMass13/D" ); dalitzTree->Branch( "invMass23", &inv23, "invMass23/D" ); dalitzTree->Branch( "invMass12Sq", &inv12Sq, "invMass12Sq/D" ); dalitzTree->Branch( "invMass13Sq", &inv13Sq, "invMass13Sq/D" ); dalitzTree->Branch( "invMass23Sq", &inv23Sq, "invMass23Sq/D" ); - EvtParticle* baseParticle( 0 ); - EvtParticle* theParent( 0 ); + EvtParticle* baseParticle( nullptr ); + EvtParticle* theParent( nullptr ); // Define the random number generator - EvtRandomEngine* myRandomEngine = 0; + EvtRandomEngine* myRandomEngine = nullptr; #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) myRandomEngine = new EvtMTRandomEngine(); #else myRandomEngine = new EvtSimpleRandomEngine(); #endif // Initialize the generator - read in the decay table and particle properties. // For our validation purposes, we just want to read in one decay file and create // plots from that. - EvtAbsRadCorr* radCorrEngine = 0; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif int mixingType( 1 ); EvtGen myGenerator( decayFileName.c_str(), "../evt.pdl", myRandomEngine, radCorrEngine, &extraModels, mixingType, useXml ); // If I wanted a user decay file, I would read it in now, e.g: // myGenerator.readUDecay(otherFileName); EvtId theId = EvtPDL::getId( parentName ); if ( theId.getId() == -1 && theId.getAlias() == -1 ) { cout << "Error. Could not find valid EvtId for " << parentName << endl; return -1; } static EvtId stringId = EvtPDL::getId( std::string( "string" ) ); // Loop to create nEvents int i; for ( i = 0; i < nEvents; i++ ) { if ( i % 1000 == 0 ) { cout << "Event number = " << i + 1 << " out of " << nEvents << std::endl; } // Set up the parent particle EvtVector4R pInit( EvtPDL::getMass( theId ), 0.0, 0.0, 0.0 ); baseParticle = EvtParticleFactory::particleFactory( theId, pInit ); if ( baseParticle->getSpinStates() == 3 ) { baseParticle->setVectorSpinDensity(); } // Generate the event myGenerator.generateDecay( baseParticle ); // Alternative way to generate decays and print out information: // int PDGId = EvtPDL::getStdHep(theId); // EvtVector4R origin(0.0, 0.0, 0.0, 0.0); // EvtHepMCEvent* theEvent = myGenerator.generateDecay(PDGId, pInit, origin); // HepMC::GenEvent* hepMCEvent = theEvent->getEvent(); // hepMCEvent->print(); // Extract other info from the HepMC event. Then delete it: // delete theEvent; // Now get the particle decay information, looping through daughter tracks (1st generation only) // Find out if the first daughter is a string. // If so, set this as the new parent particle. EvtId daugEvtId( -1, -1 ); EvtParticle* baseDaughter = baseParticle->getDaug( 0 ); - if ( baseDaughter != 0 ) { + if ( baseDaughter != nullptr ) { daugEvtId = baseDaughter->getId(); } if ( daugEvtId == stringId ) { theParent = baseDaughter; } else { theParent = baseParticle; } nDaug = theParent->getNDaug(); int iDaug( 0 ); nDaugTree->Fill(); //theParent->printTree(); // Loop over the daughter tracks for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* daug = theParent->getDaug( iDaug ); - if ( daug != 0 ) { + if ( daug != nullptr ) { EvtVector4R p4Lab = daug->getP4Lab(); EvtVector4R pos4 = daug->get4Pos(); // PDG id daugId = EvtPDL::getStdHep( daug->getId() ); // 4-momenta E = p4Lab.get( 0 ); px = p4Lab.get( 1 ); py = p4Lab.get( 2 ); pz = p4Lab.get( 3 ); p = sqrt( px * px + py * py + pz * pz ); // 4-position t = pos4.get( 0 ); x = pos4.get( 1 ); y = pos4.get( 2 ); z = pos4.get( 3 ); mass = daug->mass(); lifetime = daug->getLifetime(); theTree->Fill(); } // Daughter exists } // Number of daughters if ( nDaug == 3 ) { EvtVector4R p4_d1 = theParent->getDaug( 0 )->getP4Lab(); EvtVector4R p4_d2 = theParent->getDaug( 1 )->getP4Lab(); EvtVector4R p4_d3 = theParent->getDaug( 2 )->getP4Lab(); inv12Sq = ( p4_d1 + p4_d2 ) * ( p4_d1 + p4_d2 ); inv13Sq = ( p4_d1 + p4_d3 ) * ( p4_d1 + p4_d3 ); inv23Sq = ( p4_d2 + p4_d3 ) * ( p4_d2 + p4_d3 ); inv12 = sqrt( inv12Sq ); inv13 = sqrt( inv13Sq ); inv23 = sqrt( inv23Sq ); dalitzTree->Fill(); } // Cleanup baseParticle->deleteTree(); } // Write out the TTree information to the ROOT file theFile->cd(); theTree->Write(); nDaugTree->Write(); dalitzTree->Write(); theFile->Close(); cout << "Done." << endl; delete myRandomEngine; return 0; } diff --git a/validation/genRootDecayChain.cc b/validation/genRootDecayChain.cc index 88d5066..3afbbaa 100644 --- a/validation/genRootDecayChain.cc +++ b/validation/genRootDecayChain.cc @@ -1,406 +1,406 @@ /*********************************************************************** * Copyright 1998-2020 CERN for the benefit of the EvtGen authors * * * * This file is part of EvtGen. * * * * EvtGen is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * EvtGen is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with EvtGen. If not, see . * ***********************************************************************/ // Program to create ROOT files for EvtGen validation plots, // generalising storage of daughter information for each decay chain step. // There are three integers to keep track of the decay tree history: // dVtx = present decay vertex integer number // pVtx = parent decay vertex integer number // daug = daughter order number for the given particle // // Consider the following decay chain history, where Vj is vertex number j: // V1 // A -> B + C <---- First chain level // | | // +--> B1 + B2 +--> C1 C2 C3 <---- Second chain level // V2 | V5 | // +--> B1a B1b +--> C1a C1b C1c <---- Third chain level // V3 | V6 // +--> d1 d2 <---- Fourth chain level // V4 // // Since the decay tree is stored recursively, the information order follows // the immediate, sequential, sub-decay vertex order V1, V2, V3, V4, V5, V6: // A, B, B1, B1a, B1b, d1, d2, B2, C, C1, C1a, C1b, C1c, C2, C3 // // The unique set of integer "attributes" for each particle is as follows: // // Particle dVtx pVtx daug // A 0 0 0 The mother particle // B 1 0 1 // B1 2 1 1 // B1a 3 2 1 // B1b 3 2 2 // d1 4 3 1 // d2 4 3 2 // B2 2 1 2 // C 1 0 2 // C1 5 1 1 // C1a 6 5 1 // C1b 6 5 2 // C1c 6 5 3 // C2 5 1 2 // C3 5 1 3 // // The decay tree will be defined by the decay file. Additional photons from PHOTOS will // only appear as appended, extra daughters on the RHS of a given vertex, e.g. if a FSR // photon is added to the RHS of V4, there will be a "d3" particle with attributes (4,3,3) #include "genRootDecayChain.hh" #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandomEngine.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include "TROOT.h" #include "TStyle.h" #include #include #include using std::cout; using std::endl; using std::string; genRootDecayChain::genRootDecayChain( const string& decayFileName, const string& rootFileName, const string& parentName, int nEvents, bool storeMtmXYZ ) : _decayFileName( decayFileName ), _rootFileName( rootFileName ), _parentName( parentName ), _nEvents( nEvents ), _storeMtmXYZ( storeMtmXYZ ), - _theFile( 0 ), - _theTree( 0 ), - _probHist( 0 ), - _theCanvas( 0 ) + _theFile( nullptr ), + _theTree( nullptr ), + _probHist( nullptr ), + _theCanvas( nullptr ) { _theFile = new TFile( rootFileName.c_str(), "recreate" ); _theTree = new TTree( "Data", "Data" ); _theTree->SetDirectory( _theFile ); _probHist = new TH1D( "probHist", "probHist", 100, 0.0, 0.0 ); _probHist->SetXTitle( "Prob/MaxProb" ); _probHist->SetDirectory( _theFile ); gROOT->SetStyle( "Plain" ); gStyle->SetOptStat( 0 ); _theCanvas = new TCanvas( "theCanvas", "", 900, 700 ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); } genRootDecayChain::~genRootDecayChain() { _theFile->Close(); delete _theCanvas; } void genRootDecayChain::run() { this->initTree(); this->generateEvents(); this->writeTree(); } void genRootDecayChain::initTree() { // Initialise internal variables _eventId = 0; _PDGId = 0; _dVtx = 0, _pVtx = 0, _daug = 0; _px = 0.0, _py = 0.0, _pz = 0.0; _p = 0.0, _E = 0.0, _m = 0.0, _t = 0.0; // Set-up the TTree _theTree->Branch( "eventId", &_eventId, "eventId/I" ); _theTree->Branch( "PDGId", &_PDGId, "PDGId/I" ); _theTree->Branch( "dVtx", &_dVtx, "dVtx/I" ); _theTree->Branch( "pVtx", &_pVtx, "pVtx/I" ); _theTree->Branch( "daug", &_daug, "daug/I" ); _theTree->Branch( "p", &_p, "p/D" ); _theTree->Branch( "E", &_E, "E/D" ); _theTree->Branch( "pL", &_pL, "pL/D" ); _theTree->Branch( "EL", &_EL, "EL/D" ); _theTree->Branch( "m", &_m, "m/D" ); if ( _storeMtmXYZ ) { // Store momentum components as well _theTree->Branch( "px", &_px, "px/D" ); _theTree->Branch( "py", &_py, "py/D" ); _theTree->Branch( "pz", &_pz, "pz/D" ); _theTree->Branch( "pxL", &_pxL, "pxL/D" ); _theTree->Branch( "pyL", &_pyL, "pyL/D" ); _theTree->Branch( "pzL", &_pzL, "pzL/D" ); } // Lifetime _theTree->Branch( "t", &_t, "t/D" ); } void genRootDecayChain::writeTree() { _theFile->cd(); _theTree->Write(); _probHist->Write(); } void genRootDecayChain::generateEvents() { - EvtRandomEngine* randomEngine = 0; - EvtAbsRadCorr* radCorrEngine = 0; + EvtRandomEngine* randomEngine = nullptr; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; // Define the random number generator #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) randomEngine = new EvtMTRandomEngine(); #else randomEngine = new EvtSimpleRandomEngine(); #endif // Initialize the generator - read in the decay table and particle properties. // For our validation purposes, we just want to read in one decay file #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); bool useEvtGenRandom( true ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif int mixingType( 1 ); bool useXml( false ); EvtGen evtGen( _decayFileName.c_str(), "../evt.pdl", randomEngine, radCorrEngine, &extraModels, mixingType, useXml ); - EvtParticle* theParent( 0 ); + EvtParticle* theParent( nullptr ); EvtId theId = EvtPDL::getId( _parentName ); if ( theId.getId() == -1 && theId.getAlias() == -1 ) { cout << "Error. Could not find valid EvtId for " << _parentName << endl; return; } // Loop to create nEvents int i; for ( i = 0; i < _nEvents; i++ ) { // Parent particle 4-momentum EvtVector4R pInit( EvtPDL::getMass( theId ), 0.0, 0.0, 0.0 ); _eventId = i; if ( i % 1000 == 0 ) { cout << "Event number = " << i + 1 << " out of " << _nEvents << std::endl; } theParent = EvtParticleFactory::particleFactory( theId, pInit ); if ( theParent->getSpinStates() == 3 ) { theParent->setVectorSpinDensity(); } // Generate the event evtGen.generateDecay( theParent ); // Decay vertex index theParent->setAttribute( "dVtx", 0 ); // Parent vertex index theParent->setAttribute( "pVtx", 0 ); // Daughter index theParent->setAttribute( "daug", 0 ); int nDaug = theParent->getNDaug(); int iDaug( 0 ); storeTreeInfo( theParent ); //cout<<"Event number = "<printTree(); // Initialise the vertex number _vertexNo = 1; // Loop over the daughter tracks for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* daug = theParent->getDaug( iDaug ); // Decay vertex index daug->setAttribute( "dVtx", 1 ); // Parent decay vertex daug->setAttribute( "pVtx", 0 ); // Daughter index: 1,2,..,nDaug daug->setAttribute( "daug", iDaug + 1 ); // Recursively store the daughter information this->storeDaughterInfo( daug ); } // daughter loop // Store probability/max probability const double* dProb = theParent->decayProb(); if ( dProb ) { _probHist->Fill( *dProb ); } theParent->deleteTree(); } // event loop delete randomEngine; } void genRootDecayChain::storeDaughterInfo( EvtParticle* theParticle ) { if ( !theParticle ) { return; } // Store the particle information in the TTree storeTreeInfo( theParticle ); // Loop over the particle's own daughter tracks and call this function // recursively, keeping track of the decay chain order number int nDaug = theParticle->getNDaug(); int iDaug( 0 ); // Increment the decay vertex integer if this particle has daughters if ( nDaug > 0 ) { _vertexNo++; } // The parent vertex index for the daughters is equal to the // current particle decay vertex index int parentVtx = theParticle->getAttribute( "dVtx" ); // First, we need to loop over the given particle's daughters and set the // attributes so we keep track of the decay tree history at this chain level for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* daug = theParticle->getDaug( iDaug ); // Set the attributes for the daughters daug->setAttribute( "dVtx", _vertexNo ); daug->setAttribute( "pVtx", parentVtx ); daug->setAttribute( "daug", iDaug + 1 ); } // Now loop over the daughters again and recursively call this function to // follow the rest of the decay tree history for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* daug = theParticle->getDaug( iDaug ); storeDaughterInfo( daug ); } } void genRootDecayChain::storeTreeInfo( EvtParticle* theParticle ) { if ( !theParticle ) { return; } // Store the particle information in the TTree by first setting the internal // variables and then calling Fill() _dVtx = theParticle->getAttribute( "dVtx" ); _pVtx = theParticle->getAttribute( "pVtx" ); _daug = theParticle->getAttribute( "daug" ); //cout<<"Particle "<getName()<<", dVtx = "<<_dVtx //<<", pVtx = "<<_pVtx<<", daug = "<<_daug<getP4Lab(); // lab frame = mother frame EvtVector4R p4 = theParticle->getP4(); // frame = parents frame // PDG id _PDGId = EvtPDL::getStdHep( theParticle->getId() ); // 4-momenta in parent frame _E = p4.get( 0 ); _px = p4.get( 1 ); _py = p4.get( 2 ); _pz = p4.get( 3 ); _p = sqrt( _px * _px + _py * _py + _pz * _pz ); // 4-momenta in lab frame _EL = p4Lab.get( 0 ); _pxL = p4Lab.get( 1 ); _pyL = p4Lab.get( 2 ); _pzL = p4Lab.get( 3 ); _pL = sqrt( _pxL * _pxL + _pyL * _pyL + _pzL * _pzL ); // Rest mass and lifetime _m = theParticle->mass(); _t = theParticle->getLifetime(); // Store the information in the TTree _theTree->Fill(); } int main( int argc, char** argv ) { // Use the B0 -> K'*0 gamma, K'*0 -> K+ pi- decays as an example string decayFileName( "BKstarGamma.dec" ); //string decayFileName("BuDst0rhop.dec"); if ( argc > 1 ) { decayFileName = argv[1]; } cout << "Decay file name is " << decayFileName << endl; string rootFileName( "BKstarGamma.root" ); //string rootFileName("BuDst0rhop.root"); if ( argc > 2 ) { rootFileName = argv[2]; } cout << "Root file name is " << rootFileName << endl; string parentName( "B0" ); //string parentName("B-"); if ( argc > 3 ) { parentName = argv[3]; } cout << "Parent name is " << parentName << endl; int nEvents( 100000 ); if ( argc > 4 ) { nEvents = atoi( argv[4] ); } bool storeMtmXYZ = true; genRootDecayChain myGen( decayFileName, rootFileName, parentName, nEvents, storeMtmXYZ ); myGen.run(); return 0; } diff --git a/validation/testCPVDecays.cc b/validation/testCPVDecays.cc index 5d88c4a..9e64770 100644 --- a/validation/testCPVDecays.cc +++ b/validation/testCPVDecays.cc @@ -1,477 +1,477 @@ /*********************************************************************** * 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 . * ***********************************************************************/ // Program to create ROOT files for EvtGen validation plots. // This looks at the 1st generation daughters and stores 4-momenta // info into a ROOT file for further analysis. // Useful for Pythia, Photos and Tauola decay tests. #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtSpinDensity.hh" #include "EvtGenBase/EvtSpinType.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include "TCanvas.h" #include "TF1.h" #include "TFile.h" #include "TH1.h" #include "TLine.h" #include "TROOT.h" #include "TStyle.h" #include "TTree.h" #include #include #include #include using std::cout; using std::endl; using std::string; // Flight-time histograms for B0, B0bar TH1F* H_total = new TH1F( "Total", "", 300, 0.0, 12.0 ); TH1F* H_B0 = new TH1F( "B0", "", 300, 0.0, 12.0 ); TH1F* H_B0bar = new TH1F( "B0bar", "", 300, 0.0, 12.0 ); int B0Id( 511 ), B0barId( -511 ); void storeBFlightTimes( GenEvent* theEvent ); bool checkSignal( std::vector& daugIdVect ); double calcFlightTime( FourVector& BDecayVtx, FourVector& B4mtm ); double sineFitFun( double* x, double* p ); double timeFitFun( double* x, double* p ); int main( int argc, char** argv ) { string decayFileName( "CPVDecayFiles/Bd_JpsiKSeeCPV.dec" ); if ( argc > 1 ) { decayFileName = argv[1]; } cout << "Decay file name is " << decayFileName << endl; string rootFileName( "rootFiles/CPVDecayTest.root" ); if ( argc > 2 ) { rootFileName = argv[2]; } cout << "Root file name is " << rootFileName << endl; string parentName( "Upsilon(4S)" ); if ( argc > 3 ) { parentName = argv[3]; } cout << "Parent name is " << parentName << endl; int nEvents( 10000 ); if ( argc > 4 ) { nEvents = atoi( argv[4] ); } double sin2Beta = sin( 0.775 ); if ( argc > 5 ) { sin2Beta = atof( argv[5] ); } cout << "Number of events is " << nEvents << endl; cout << "sin2Beta = " << sin2Beta << " (used to draw oscillation maxima lines)" << endl; // Define the random number generator - EvtRandomEngine* myRandomEngine = 0; + EvtRandomEngine* myRandomEngine = nullptr; #ifdef EVTGEN_CPP11 // Use the Mersenne-Twister generator (C++11 only) myRandomEngine = new EvtMTRandomEngine(); #else myRandomEngine = new EvtSimpleRandomEngine(); #endif - EvtAbsRadCorr* radCorrEngine = 0; + EvtAbsRadCorr* radCorrEngine = nullptr; std::list extraModels; #ifdef EVTGEN_EXTERNAL bool convertPythiaCodes( false ); bool useEvtGenRandom( true ); EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom ); radCorrEngine = genList.getPhotosModel(); extraModels = genList.getListOfModels(); #endif int mixingType = EvtCPUtil::Incoherent; // Initialize the generator - read in the decay table and particle properties. EvtGen myGenerator( "../DECAY.DEC", "../evt.pdl", myRandomEngine, radCorrEngine, &extraModels, mixingType ); myGenerator.readUDecay( decayFileName.c_str() ); EvtId theId = EvtPDL::getId( parentName ); if ( theId.getId() == -1 && theId.getAlias() == -1 ) { cout << "Error. Could not find valid EvtId for " << parentName << endl; return -1; } // Start all initial (parent) decays at the origin EvtVector4R origin( 0.0, 0.0, 0.0, 0.0 ); - EvtSpinDensity* spinDensity = 0; + EvtSpinDensity* spinDensity = nullptr; EvtSpinType::spintype baseSpin = EvtPDL::getSpinType( theId ); if ( baseSpin == EvtSpinType::VECTOR ) { cout << "Setting spin density for vector particle " << parentName << endl; spinDensity = new EvtSpinDensity(); spinDensity->setDiag( EvtSpinType::getSpinStates( EvtSpinType::VECTOR ) ); spinDensity->set( 1, 1, EvtComplex( 0.0, 0.0 ) ); } // Loop to create nEvents int i; for ( i = 0; i < nEvents; i++ ) { if ( i % 1000 == 0 ) { cout << "Event number = " << i + 1 << " out of " << nEvents << std::endl; } // Set up the parent particle int PDGId = EvtPDL::getStdHep( theId ); EvtVector4R pInit( EvtPDL::getMass( theId ), 0.0, 0.0, 0.0 ); // Generate a new HepMC event with the decays. We own this pointer, so we must // delete it after using the HepMC event information. EvtHepMCEvent* theEvent = myGenerator.generateDecay( PDGId, pInit, origin, spinDensity ); // Retrieve the HepMC event information GenEvent* hepMCEvent = theEvent->getEvent(); //hepMCEvent->print(); // Fill the B0/B0bar flight time histograms storeBFlightTimes( hepMCEvent ); // Cleanup the event to avoid memory leaks delete theEvent; } H_total->Sumw2(); H_B0->Sumw2(); H_B0bar->Sumw2(); TH1F* H_Diff = dynamic_cast( H_B0->Clone( "H_Diff" ) ); H_Diff->Add( H_B0bar, -1.0 ); TH1F* H_DiffSum = dynamic_cast( H_Diff->Clone( "H_DiffSum" ) ); H_DiffSum->Divide( H_total ); TF1* sineFit = new TF1( "sineFit", sineFitFun, 0.0, 12.0, 3 ); sineFit->SetParName( 0, "N" ); sineFit->SetParName( 1, "a" ); sineFit->SetParName( 2, "#phi" ); sineFit->SetParameter( 0, 0.5 ); sineFit->SetParameter( 1, 0.7 ); sineFit->SetParameter( 2, -0.7 ); H_DiffSum->Fit( sineFit ); TF1* timeFit = new TF1( "timeFit", timeFitFun, 0.0, 12.0, 2 ); timeFit->SetParName( 0, "N" ); timeFit->SetParName( 1, "#Gamma" ); timeFit->SetParameter( 0, 500 ); timeFit->SetParameter( 1, 0.6 ); timeFit->SetParLimits( 1, 0.0, 1.0 ); H_total->Fit( timeFit ); gROOT->SetStyle( "Plain" ); gStyle->SetOptFit( 1111 ); TCanvas* theCanvas = new TCanvas( "theCanvas", "", 900, 700 ); theCanvas->UseCurrentStyle(); H_DiffSum->SetXTitle( "t (ps)" ); H_DiffSum->Draw(); // Plot +- sin(2beta) lines TLine line1( 0.0, sin2Beta, 12.0, sin2Beta ); line1.Draw(); TLine line2( 0.0, -sin2Beta, 12.0, -sin2Beta ); line2.Draw(); theCanvas->Print( "BCPVSinFit.gif" ); H_total->SetXTitle( "t (ps)" ); H_total->Draw(); theCanvas->Print( "BTimeFit.gif" ); TFile* theFile = new TFile( rootFileName.c_str(), "recreate" ); theFile->cd(); H_B0->Write(); H_B0bar->Write(); H_total->Write(); H_Diff->Write(); H_DiffSum->Write(); theFile->Close(); // Cleanup delete theCanvas; delete spinDensity; delete myRandomEngine; cout << "Done." << endl; return 0; } #ifdef EVTGEN_HEPMC3 void storeBFlightTimes( GenEvent* theEvent ) { std::list allVertices; // Loop over vertices in the event for ( auto theVertex : theEvent->vertices() ) { - if ( theVertex == 0 ) { + if ( theVertex == nullptr ) { continue; } // Check to see if the incoming particle is a B candidate. // If so, also look at the outgoing particles to see if we have a signal decay. // For these, get the B decay vertex position and the B 4-momentum to calculate // the B lifetime. bool gotB0( false ), gotB0bar( false ); FourVector B4mtm; for ( auto inParticle : theVertex->particles_in() ) { - if ( inParticle == 0 ) { + if ( inParticle == nullptr ) { continue; } int inPDGId = inParticle->pdg_id(); if ( inPDGId == B0Id ) { gotB0 = true; } else if ( inPDGId == B0barId ) { gotB0bar = true; } if ( gotB0 == true || gotB0bar == true ) { B4mtm = inParticle->momentum(); } } // Loop over ingoing vertex particles if ( gotB0 == true || gotB0bar == true ) { // Check outgoing particles std::vector daugIdVect; for ( auto outParticle : theVertex->particles_out() ) { - if ( outParticle != 0 ) { + if ( outParticle != nullptr ) { int outPDGId = outParticle->pdg_id(); daugIdVect.push_back( outPDGId ); } } // Loop over outgoing vertex particles // Check if we have the signal decay bool gotSignal = checkSignal( daugIdVect ); // Fill the flight time histograms for signal B decays if ( gotSignal == true ) { FourVector BDecayVtx = theVertex->position(); double flightTime = calcFlightTime( BDecayVtx, B4mtm ); if ( gotB0 == true ) { H_B0->Fill( flightTime ); H_total->Fill( flightTime ); } else { H_B0bar->Fill( flightTime ); H_total->Fill( flightTime ); } } // Got signal B decay (for flight-time histograms) } // Got a B candidate } // Loop over event vertices } #else void storeBFlightTimes( GenEvent* theEvent ) { std::list allVertices; HepMC::GenEvent::vertex_iterator vertexIter; // Loop over vertices in the event for ( vertexIter = theEvent->vertices_begin(); vertexIter != theEvent->vertices_end(); ++vertexIter ) { // Get the vertex HepMC::GenVertex* theVertex = *vertexIter; - if ( theVertex == 0 ) { + if ( theVertex == nullptr ) { continue; } // Check to see if the incoming particle is a B candidate. // If so, also look at the outgoing particles to see if we have a signal decay. // For these, get the B decay vertex position and the B 4-momentum to calculate // the B lifetime. bool gotB0( false ), gotB0bar( false ); FourVector B4mtm; HepMC::GenVertex::particles_in_const_iterator inIter; for ( inIter = theVertex->particles_in_const_begin(); inIter != theVertex->particles_in_const_end(); ++inIter ) { HepMC::GenParticle* inParticle = *inIter; - if ( inParticle == 0 ) { + if ( inParticle == nullptr ) { continue; } int inPDGId = inParticle->pdg_id(); if ( inPDGId == B0Id ) { gotB0 = true; } else if ( inPDGId == B0barId ) { gotB0bar = true; } if ( gotB0 == true || gotB0bar == true ) { B4mtm = inParticle->momentum(); } } // Loop over ingoing vertex particles if ( gotB0 == true || gotB0bar == true ) { // Check outgoing particles std::vector daugIdVect; HepMC::GenVertex::particles_out_const_iterator outIter; for ( outIter = theVertex->particles_out_const_begin(); outIter != theVertex->particles_out_const_end(); ++outIter ) { HepMC::GenParticle* outParticle = *outIter; - if ( outParticle != 0 ) { + if ( outParticle != nullptr ) { int outPDGId = outParticle->pdg_id(); daugIdVect.push_back( outPDGId ); } } // Loop over outgoing vertex particles // Check if we have the signal decay bool gotSignal = checkSignal( daugIdVect ); // Fill the flight time histograms for signal B decays if ( gotSignal == true ) { HepMC::FourVector BDecayVtx = theVertex->position(); double flightTime = calcFlightTime( BDecayVtx, B4mtm ); if ( gotB0 == true ) { H_B0->Fill( flightTime ); H_total->Fill( flightTime ); } else { H_B0bar->Fill( flightTime ); H_total->Fill( flightTime ); } } // Got signal B decay (for flight-time histograms) } // Got a B candidate } // Loop over event vertices } #endif double calcFlightTime( FourVector& BDecayVtx, FourVector& B4mtm ) { double flightTime( 0.0 ); #ifdef EVTGEN_HEPMC3 double distance = BDecayVtx.length() * 1e-3; // metres double momentum = B4mtm.length(); // GeV/c #else double distance = BDecayVtx.rho() * 1e-3; // metres double momentum = B4mtm.rho(); // GeV/c #endif double BMass = 5.2795; // GeV/c^2 double c0 = 299792458.0; // m/s if ( momentum > 0.0 ) { flightTime = 1.0e12 * distance * BMass / ( momentum * c0 ); // picoseconds } return flightTime; } bool checkSignal( std::vector& daugIdVect ) { bool gotSignal( false ); int nDaug = daugIdVect.size(); // Check for J/psi Ks decays if ( nDaug == 2 ) { int daug1Id = daugIdVect[0]; int daug2Id = daugIdVect[1]; if ( ( daug1Id == 443 && daug2Id == 310 ) || ( daug1Id == 310 && daug2Id == 443 ) ) { gotSignal = true; } } return gotSignal; } double sineFitFun( double* x, double* p ) { double t = x[0]; double N = p[0]; double a = p[1]; double phi = p[2]; double funcVal = N * sin( a * t + phi ); return funcVal; } double timeFitFun( double* x, double* p ) { double t = x[0]; double N0 = p[0]; double gamma = p[1]; double funcVal = N0 * ( exp( -gamma * t ) ); return funcVal; }