diff --git a/CMakeLists.txt b/CMakeLists.txt index 06cfbdb..3efcbd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,104 +1,111 @@ # Top level CMakeLists.txt for EvtGen # Enforce an out-of-source build. # Should be the first action in the top level CMakeLists.txt if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(STATUS "EvtGen requires an out-of-source build.") message(STATUS "Please remove the following files from ${CMAKE_BINARY_DIR}:") message(STATUS " CMakeCache.txt") message(STATUS " CMakeFiles") message(STATUS "Once these files are removed, create a separate directory") message(STATUS "and run CMake from there, pointing it to:") message(STATUS " ${CMAKE_SOURCE_DIR}") message(FATAL_ERROR "in-source build detected") endif() # Also require a minimum version of CMake cmake_minimum_required(VERSION 3.11.0) # Project setup if(${CMAKE_VERSION} VERSION_LESS 3.12.0) project(EvtGen VERSION 2.0.0 DESCRIPTION "Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons." ) else() project(EvtGen VERSION 2.0.0 DESCRIPTION "Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons." HOMEPAGE_URL "https://evtgen.hepforge.org" ) endif() # Prepend this project's custom module path(s) to CMAKE_MODULE_PATH set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules ${CMAKE_MODULE_PATH}) # Include needed modules to perform any custom setup # Install paths include(GNUInstallDirs) # Compilation/linking flags and related settings include(CompilerFlags) # EvtGen external dependencies option(EVTGEN_PYTHIA "Enable/disable linking with Pythia8" OFF) option(EVTGEN_PHOTOS "Enable/disable linking with Photos++" OFF) option(EVTGEN_TAUOLA "Enable/disable linking with Tauola++" OFF) +option(EVTGEN_HEPMC3 "Enable/disable linking with HepMC3" ON) +if (EVTGEN_HEPMC3) +message(STATUS "EvtGen: Linking with HepMC3") +else() message(STATUS "EvtGen: Linking with HepMC2") -message(STATUS "EvtGen: Optional linking with Pythia8 ${EVTGEN_PYTHIA}") -message(STATUS "EvtGen: Optional linking with Photos++ ${EVTGEN_PHOTOS}") -message(STATUS "EvtGen: Optional linking with Tauola++ ${EVTGEN_TAUOLA}") +endif() + +message(STATUS "EvtGen: Optional linking with Pythia8 EVTGEN_PYTHIA ${EVTGEN_PYTHIA}") +message(STATUS "EvtGen: Optional linking with Photos++ EVTGEN_PHOTOS ${EVTGEN_PHOTOS}") +message(STATUS "EvtGen: Optional linking with Tauola++ EVTGEN_TAUOLA ${EVTGEN_TAUOLA}") +message(STATUS "EvtGen: Optional linking with HepMC3 EVTGEN_HEPMC3 ${EVTGEN_HEPMC3}") include(ExternalDependencies) # Now build the library add_subdirectory(src) # Copy the particle property and decay tables configure_file(DECAY.DEC ${CMAKE_CURRENT_BINARY_DIR}/DECAY.DEC COPYONLY) configure_file(DECAY.XML ${CMAKE_CURRENT_BINARY_DIR}/DECAY.XML COPYONLY) configure_file(evt.pdl ${CMAKE_CURRENT_BINARY_DIR}/evt.pdl COPYONLY) # Build the executables in the test and validation directories option(EVTGEN_BUILD_TESTS "Enable/disable building of executables in 'test' directory" OFF) option(EVTGEN_BUILD_VALIDATIONS "Enable/disable building of executables in 'validation' directory" OFF) -message(STATUS "EvtGen: Building of executables in 'test' directory ${EVTGEN_BUILD_TESTS}") -message(STATUS "EvtGen: Building of executables in 'validation' directory ${EVTGEN_BUILD_VALIDATIONS}") +message(STATUS "EvtGen: Building of executables in 'test' directory EVTGEN_BUILD_TESTS ${EVTGEN_BUILD_TESTS}") +message(STATUS "EvtGen: Building of executables in 'validation' directory EVTGEN_BUILD_VALIDATIONS ${EVTGEN_BUILD_VALIDATIONS}") if(${EVTGEN_BUILD_TESTS}) add_subdirectory(test) endif() if(${EVTGEN_BUILD_VALIDATIONS}) add_subdirectory(validation) endif() # Install the include directories install(DIRECTORY EvtGen DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY EvtGenBase DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY EvtGenExternal DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY EvtGenModels DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # Install the particle properties and decay tables -install(FILES DECAY.DEC DECAY.XML evt.pdl DESTINATION ${CMAKE_INSTALL_PREFIX}) +install(FILES DECAY.DEC DECAY.XML evt.pdl DESTINATION ${CMAKE_INSTALL_DATADIR}/EvtGen) # Generate CMake config files, which can be used by other projects include(CMakePackageConfigHelpers) set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) configure_package_config_file(cmake/Templates/EvtGenConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/EvtGenConfig.cmake INSTALL_DESTINATION cmake PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR ) write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/EvtGenConfigVersion.cmake COMPATIBILITY AnyNewerVersion ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/EvtGenConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/EvtGenConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake + DESTINATION ${CMAKE_INSTALL_DATADIR}/EvtGen/cmake ) install( EXPORT "EvtGenTargets" NAMESPACE "EvtGen::" - DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake + DESTINATION ${CMAKE_INSTALL_DATADIR}/EvtGen/cmake ) diff --git a/EvtGenBase/EvtHepMCEvent.hh b/EvtGenBase/EvtHepMCEvent.hh index cb503eb..af0dae3 100644 --- a/EvtGenBase/EvtHepMCEvent.hh +++ b/EvtGenBase/EvtHepMCEvent.hh @@ -1,77 +1,101 @@ //-------------------------------------------------------------------------- // // Environment: // This software is part of the EvtGen package. If you use all or part // of it, please give an appropriate acknowledgement. // // Copyright Information: See EvtGen/COPYRIGHT // Copyright (C) 2011 University of Warwick, UK // // Module: EvtHepMCEvent // // Description: Create an HepMC::GenEvent for the complete EvtParticle // decay tree. // // Modification history: // // John Back June 2011 Module created // //------------------------------------------------------------------------ #ifndef EVTHEPMCEVENT_HH #define EVTHEPMCEVENT_HH #include "EvtGenBase/EvtVector4R.hh" +#ifdef EVTGEN_HEPMC3 +#include "HepMC3/GenEvent.h" +#include "HepMC3/GenParticle.h" +#include "HepMC3/GenVertex.h" +#include "HepMC3/Print.h" +#include "HepMC3/Units.h" +typedef HepMC3::GenParticlePtr GenParticlePtr; +typedef HepMC3::GenVertexPtr GenVertexPtr; +typedef HepMC3::GenEvent GenEvent; +typedef HepMC3::FourVector FourVector; +typedef HepMC3::Units Units; +inline GenParticlePtr newGenParticlePtr( const FourVector &mom=FourVector::ZERO_VECTOR(), int pid=0, int status=0){return std::make_shared(mom,pid,status);} +inline GenVertexPtr newGenVertexPtr( const FourVector &pos=FourVector::ZERO_VECTOR()){return std::make_shared(pos);} +#else #include "HepMC/GenEvent.h" #include "HepMC/GenParticle.h" +#include "HepMC/GenVertex.h" #include "HepMC/SimpleVector.h" +#include "HepMC/Units.h" +typedef HepMC::GenParticle* GenParticlePtr; +typedef HepMC::GenVertex* GenVertexPtr; +typedef HepMC::GenEvent GenEvent; +typedef HepMC::FourVector FourVector; +#define Units HepMC::Units +inline GenParticlePtr newGenParticlePtr( const FourVector &mom=FourVector(0.0,0.0,0.0,0.0), int pid=0, int status=0){return new HepMC::GenParticle(mom,pid,status);} +inline GenVertexPtr newGenVertexPtr( const FourVector &pos=FourVector(0.0,0.0,0.0,0.0)){return new HepMC::GenVertex(pos);} +#endif class EvtParticle; class EvtHepMCEvent { public: EvtHepMCEvent(); virtual ~EvtHepMCEvent(); // Select what frame a given GenParticle is in: // its own restframe, the lab frame (first mother), or its mother's frame enum HepMCFrame {RESTFRAME = 1, LAB = 2, MOTHER = 3}; // Select the GenParticle status enum HepMCStatus {STABLE = 1, DECAYED = 2, HISTORY = 3}; void constructEvent(EvtParticle* baseParticle); void constructEvent(EvtParticle* baseParticle, EvtVector4R& translation); - HepMC::GenEvent* getEvent() {return _theEvent;} + GenEvent* getEvent() {return _theEvent;} // Methods used to create GenParticles and FourVectors of vertices. // Make these public so that other classes may call them if they use EvtHepMCEvent. // Create a GenParticle using info from the EvtParticle, specifying what frame // the 4-momentum is from. - HepMC::GenParticle* createGenParticle(EvtParticle* theParticle, int frameType); + GenParticlePtr createGenParticle(EvtParticle* theParticle, int frameType); // Find out the decay vertex position for the given EvtParticle. - HepMC::FourVector getVertexCoord(EvtParticle* theParticle); + FourVector getVertexCoord(EvtParticle* theParticle); protected: private: // Delete the event structure (called by destructor) void deleteEvent(); // Add a vertex to the event. This is called by the constructEvent function // and is recursive, i.e. it loops through all possible daughter particles and // their descendents. - void addVertex(EvtParticle* inEvtParticle, HepMC::GenParticle* inGenParticle); + void addVertex(EvtParticle* inEvtParticle, GenParticlePtr inGenParticle); - HepMC::GenEvent* _theEvent; + GenEvent* _theEvent; EvtVector4R _translation; }; #endif diff --git a/EvtGenExternal/EvtPhotosEngine.hh b/EvtGenExternal/EvtPhotosEngine.hh index 2d41711..fb1bd6f 100644 --- a/EvtGenExternal/EvtPhotosEngine.hh +++ b/EvtGenExternal/EvtPhotosEngine.hh @@ -1,63 +1,71 @@ #ifdef EVTGEN_PHOTOS //-------------------------------------------------------------------------- // // Environment: // This software is part of the EvtGen package. If you use all or part // of it, please give an appropriate acknowledgement. // // Copyright Information: See EvtGen/COPYRIGHT // Copyright (C) 2011 University of Warwick, UK // // Module: EvtPhotosEngine // // Description: Interface to the PHOTOS external generator // // Modification history: // // John Back May 2011 Module created // //------------------------------------------------------------------------ #ifndef EVTPHOTOSENGINE_HH #define EVTPHOTOSENGINE_HH #include "EvtGenModels/EvtAbsExternalGen.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtVector4R.hh" -#include "HepMC/GenEvent.h" -#include "HepMC/GenParticle.h" -#include "HepMC/GenVertex.h" + +#ifdef EVTGEN_HEPMC3 +#include "Photos/PhotosHepMC3Event.h" +#include "Photos/PhotosHepMC3Particle.h" +#include "HepMC3/Units.h" +#else +#include "Photos/PhotosHepMCEvent.h" +#include "Photos/PhotosHepMCParticle.h" +#include "Photos/PhotosParticle.h" +#endif +#include "EvtGenBase/EvtHepMCEvent.hh" #include class EvtPhotosEngine : public EvtAbsExternalGen { public: EvtPhotosEngine(std::string photonType = "gamma", bool useEvtGenRandom = true); virtual ~EvtPhotosEngine(); virtual bool doDecay(EvtParticle* theMother); virtual void initialise(); protected: private: std::string _photonType; EvtId _gammaId; int _gammaPDG; double _mPhoton; bool _initialised; - HepMC::GenParticle* createGenParticle(EvtParticle* theParticle, bool incoming); - int getNumberOfPhotons(const HepMC::GenVertex* theVertex) const; + GenParticlePtr createGenParticle(EvtParticle* theParticle, bool incoming); + int getNumberOfPhotons(const GenVertexPtr theVertex) const; }; #endif #endif diff --git a/EvtGenExternal/EvtTauolaEngine.hh b/EvtGenExternal/EvtTauolaEngine.hh index 690a548..a7d6049 100644 --- a/EvtGenExternal/EvtTauolaEngine.hh +++ b/EvtGenExternal/EvtTauolaEngine.hh @@ -1,68 +1,78 @@ #ifdef EVTGEN_TAUOLA //-------------------------------------------------------------------------- // // Environment: // This software is part of the EvtGen package. If you use all or part // of it, please give an appropriate acknowledgement. // // Copyright Information: See EvtGen/COPYRIGHT // Copyright (C) 2011 University of Warwick, UK // // Module: EvtTauolaEngine // // Description: Interface to the TAUOLA external generator // // Modification history: // // John Back May 2011 Module created // //------------------------------------------------------------------------ #ifndef EVTTAUOLAENGINE_HH #define EVTTAUOLAENGINE_HH #include "EvtGenModels/EvtAbsExternalGen.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtDecayBase.hh" #include "EvtGenBase/EvtVector4R.hh" -#include "HepMC/GenEvent.h" -#include "HepMC/GenParticle.h" +#ifdef EVTGEN_HEPMC3 +#include "Tauola/TauolaHepMC3Particle.h" +#include "Tauola/TauolaHepMC3Event.h" +#include "HepMC3/Units.h" +#include "HepMC3/Relatives.h" +#else +#include "Tauola/TauolaHepMCEvent.h" +#include "Tauola/TauolaHepMCParticle.h" +#include "Tauola/TauolaParticle.h" +#endif +#include "EvtGenBase/EvtHepMCEvent.hh" + #include #include class EvtTauolaEngine : public EvtAbsExternalGen { public: EvtTauolaEngine(bool useEvtGenRandom = true); virtual ~EvtTauolaEngine(); virtual bool doDecay(EvtParticle* theMother); virtual void initialise(); protected: private: bool _initialised; int _tauPDG, _nTauolaModes; int _neutPropType, _posPropType, _negPropType; - HepMC::GenParticle* createGenParticle(EvtParticle* theParticle); + GenParticlePtr createGenParticle(EvtParticle* theParticle); void setUpPossibleTauModes(); void setOtherParameters(); int getModeInt(EvtDecayBase* decayModel); void decayTauEvent(EvtParticle* tauParticle); }; #endif #endif diff --git a/History.txt b/History.txt index b5309e4..e14b424 100644 --- a/History.txt +++ b/History.txt @@ -1,588 +1,591 @@ //========================================================================== // // History file for EvtGen // //=========================================================================== +Dec 12 2019 + Trying to implemment HepMC3 support/Andrii Verbytskyi + 15th Nov 2019 John Back Added EvtPsi2JpsiPiPi model for psi2S -> J/psi pi+ pi- decays based on hep-ph/1507.07985, courtesy of Aleksei Luchinsky (LHCb). 21st August 2019 Michal Kreps Added the EvtDToKpienu decay model for D -> K pi e nu decays from BESIII, courtesy of Liaoyuan Dong. 3rd July 2019 John Back Added the EvtLambdacPHH decay model for Lc -> p K pi decays with K*(890), Delta++(1232) and Lambda(1520) resonances, based on the Fermilab E791 analysis hep-ex/9912003v1, courtesy of Elisabeth Niel and Patrick Robbe (LHCb). Modified EvtResonance2 to accept other barrier factor radii. 3rd July 2019 Michal Kreps Make sure minimum mass for resonances with non-zero widths is larger than 1e-4 GeV in EvtRelBreitWignerBarrierFact. 3rd May 2019 John Back Corrected EvtSLDiBaryonAmp bugs/issues in the BToDiBaryonlnupQCD model: parity, amplitude terms and B momentum reference frame variables. Corrected treament of spinor indices in EvtRareLb2Lll, courtesy of Tom Blake and Michal Kreps (LHCb). Updated the EvtBcVHad model to also handle Bc -> psi Ks K decays, courtesy of Aleksei Luchinsky (LHCb). Add new decay model EvtBsMuMuKK (BS_MUMUKK) for Bs to J/psi (mu+mu-) K+K-, courtesy of Veronika Chobanova, Jeremy Dalseno, Diego Martinez Santos and Marcos Romero Lamas (LHCb). Fix infinite loop during initialisation of the EvtBTo3hCP model via EvtCBTo3piP00 and EvtCBTo3piMPP, courtesy of Peter Richardson (Durham). 15th March 2019 Tom Latham Implement cmake build system, replacing the old config method. 29th Jan 2019 Michal Kreps Allow reading decay files which are missing end-of-line before end-of-file. 7th December 2018 John Back Added the EvtBLLNuL (BLLNUL) model that generates rare B -> ell ell nu ell decays, where ell = e or mu, courtesy of Anna Danilina and Nikolai Nikitin (LHCb). Removed the EvtB2MuMuMuNu (BUTOMMMN) model, since its now replaced by the more general BLLNuL one. 5th November 2018 John Back Added the BToDiBaryonlnupQCD model for generating B to p N* l nu decays, where N can be any (exited) charged baryon (spin 1/2 or 3/2), courtesy of Mark Smith and Ryan Newcombe (LHCb), with added code optimisations. 17th October 2018 John Back Added various decay models from LHCb EvtGenExtras package: EvtBcVHad ("BC_VHAD"), Evtbs2llGammaMNT ("BSTOGLLMNT"), Evtbs2llGammaISRFSR ("BSTOGLLISRFSR"), EvtbTosllMS ("BTOSLLMS"), EvtbTosllMSExt ("BTOSLLMSEXT"), EvtLb2Baryonlnu ("Lb2Baryonlnu"), EvtLb2plnuLCSR ("Lb2plnuLCSR"), EvtLb2plnuLQCD ("Lb2plnuLQCD"), EvtFlatSqDalitz ("FLATSQDALITZ") and EvtPhspFlatLifetime ("PHSPFLATLIFETIME"). 5th October 2018 John Back Updated setupEvtGen.sh to work with the new HepForge Phabricator site. 13th March 2018 John Back Updated EvtPythiaEngine to correctly handle updates of various particle properties so that Pythia uses the same information as EvtGen (evt.pdl) for the generic and alias PYTHIA decay model. 12th March 2018 John Back Updated EvtBcXMuNu models (X = Scalar, Vector, Tensor) to generate Bc to D0(star) mu nu decays, with associated form factors in EvtBCXFF, courtesy of Aleksei Luchinsky (LHCb). Also generalised the calculation of their maximum probabilities by reusing the CalcMaxProb method in EvtSemiLeptonicAmp, which now allows for different Q^2 binning (default remains at 25 bins). R01-07-00------------------------------------------------------------------- 13th December 2017 John Back New tag incorporating all changes below. Recommended external packages are HepMC 2.06.09, pythia 8.230, Photos++ 3.61 and Tauola++ 1.1.6c, as used in the setupEvtGen.sh script. 12th December 2017 John Back Changed Pythia validation example decay files to use Pythia8 codes. 6th December 2017 John Back Modified the examples to use DECAY.DEC (see 25th April 2016) instead of DECAY_2010.DEC. Changed EvtExternalGenList to assume Pythia8 codes are used in decay files by default, which is the case for DECAY.DEC. Also updated the setupEvtGen.sh script to work with Pythia 8.2x versions. 29th November 2017 John Back Modified EvtSVP, EvtVVP and EvtTVP models to handle both radiative and two-lepton decays, courtesy of Aleksei Luchinsky (LHCb). 14th July 2017 John Back Only create external generator objects if they don't already exist in EvtExternalGenFactory. Modified configure script to work with Pythia 8.2x 5th July 2017 Michal Kreps Register the VTOSLL model. 14th June 2017 John Back Add isNeutralKaon() boolean function and corrected comments in EvtDDalitz. 8th May 2017 Michal Kreps Fix bug in EvtbTosllVectorAmp to recognise Bs --> K*bar mu mu decay as b --> d ll transition. 8th May 2017 Michal Kreps Significantly simplify way how we decide on decay mode and daughters ordering in DDalitz model. With new code by definition all orderings of daughters in the decay file will yield same output. 4th May 2017 John Back Further fixes to DDalitz particle ordering (including charge-conjugates): Mode 5: D0 -> K- K0bar K+ and K+ K- K0bar Mode 12: D0 -> pi0 pi- pi+ and pi+ pi0 pi- Removed unneeded index ordering checks for mode 10 (D+ -> pi- pi+ pi+) and mode 11 (Ds+ -> pi- pi+ pi+) 27th April 2017 John Back Fixed DDalitz particle ordering for mode 7: D+ -> pi+ K- K+ and K+ pi+ K- and their charge-conjugates 7th April 2017 John Back Modified EvtGenExternal/EvtPythiaEngine to ensure that the EvtGen-based instances of Pythia8 (for generic and alias decays) use the same particle properties as defined by EvtGen, courtesy Patrick Robbe (LHCb). 5th April 2017 Michal Kreps Fixed indexing in copy constructor of Evt3Rank3C, which would otherwise produce an infinite loop; bug report from David Grellscheid. 3rd November 2016 John Back Modified EvtFlatQ2 model to work for all B -> X lepton lepton modes, as well as adding an extra phase space factor to correct for the dip at low q^2, courtesy of Marcin Chrzaszcz & Thomas Blake (LHCb), which is enabled by using "FLATQ2 1" instead of just "FLATQ2" in the decay file. 13th October 2016 John Back Added the TauolaCurrentOption decfile keyword to select the hadronic current in Tauola; default is the BaBar-tuned current option (int = 1). EvtParticles can store double attributes using the functions setAttributeDouble(name, double) and getAttributeDouble(name), which can be useful for storing and retrieving amplitude weights, for example. The analogous EvtParticle integer attribute interface remains unchanged: setAttribute(name, int) and getAttribute(name). 13th September 2016 John Back Modified EvtTauolaEngine to use internal Tauola spin matrices for tau pair events by temporarily setting the PDG id of the mother as a boson, keeping the same 4-momentum. The BaBar hadronic currents are now used by default. Also added the ability to change some Tauola parameters using the "Define" keyword in decay files. Added an example decay file illustrating the new features: validation/TauolaFiles/Btautau.dec 9th September 2016 Michal Kreps Reimplement code in EvtBTo3pi.F, EvtBTo3piMPP.F, EvtBTo3piP00.F and EvtBToKpipi.F in C++ in order to remove dependence on Fortran compiler. With this, there is no internal Fortran code in EvtGen. R01-06-00------------------------------------------------------------------- 1st June 2016 John Back New tag incorporating all changes below. Recommended external packages are HepMC 2.06.09, pythia 8.186, Photos++ 3.61 and Tauola++ 1.1.5. 28th April 2016 Michal Kreps For Ds+ --> 2pi+ pi- there was double counting of branching fraction resulting in total branching fraction being 1.5 times larger than measured one. Fix by revisiting submodes, which now fill total Ds --> 3pi. 25th April 2016 Michal Kreps Added DECAY.DEC/XML, which contain updated semileptonic charm and beauty branching fractions using the 2014 PDG, tuned to minimize disagreements between measurements and EvtGen for both inclusive and exclusive decays. Updated the evt.pdl particle properties file to the PDG 2014 edition. Implemented new LQCD form factors for Lb --> L mu mu from arXiv paper 1602.01399 (EvtRareLbToLllFFlQCD); old LQCD form factors are removed. 18th March 2016 John Back Fixed incorrect spinor algebra used in S1 -> 1/2 S2, 1/2 -> S3 S4 decays in EvtDiracParticle::rotateToHelicityBasis() functions, courtesy of Luis Miguel Garcia Martin and the IFIC Valencia LHCb group. 19th Feburary 2016 John Back Fixed bug in the definition of the initial spinor term Sinit in EvtRareLbToLll::HadronicAmpRS(), from Tom Blake (LHCb). 12th February 2016 John Back From LHCb, added extensions to the EvtHQET2(FF) model for semitauonic decays from Brian Hamilton, which needs a patch to EvtSemiLeptonicAmp from Jack Wimberley to ensure that the q^2 range is physical when finding the maximum amplitude probability. 2nd December 2015 John Back From LHCb, added EvtKStopizmumu model for KS -> pi0 mu mu decays based on JHEP08(1998)004, courtesy of Veronika Chobanova, Diego Martinez Santos and Jeremy Dalseno. Added EvtConst::Fermi for Fermi coupling constant. R01-05-00------------------------------------------------------------------- 21st October 2015 John Back New tag incorporating all changes below. Recommended external packages are HepMC 2.06.09, pythia 8.186, Photos++ 3.61 and Tauola++ 1.1.5. Added the EvtB2MuMuMuNu model for simulating the very rare four-leptonic decays B- -> mu+ mu- anti-nu_mu mu-, courtesy Nikolai Nikitin. 16th October 2015 John Back Updated the configure script to automatically select the library names for PHOTOS++; version 3.56 and below uses Fortran, version 3.61 and above uses C++ only (default). Avoid using v3.60, since it does not work. This needs the PHOTOS libraries built before EvtGen is configured. Modified setupEvtGen.sh to use Photos++ v3.61. 7th October 2015 John Back Updated EvtGenExternal/EvtPhotosEngine to check that additional particles from the outgoing vertex are indeed (FSR) photons, since later versions of PHOTOS introduce pair emission, where particles may not always be photons. Added the genRootDecayChain.cc validation program to create ROOT files containing information about the complete decay tree. Two example test decay files BKstarGamma.dec and BuDst0rhop.dec can be used with this; the first tests PHOTOS, the second looks at sequential decay chain storage. The plotBKstarGamma.C ROOT macro can be used for B -> K* gamma plots. 2nd October 2015 John Back Modified EvtSVPHelAmp and added a new EvtSVPHelCPMix model, implementing the complete mixing phenomenology of Bs to vector gamma decays, courtesy of Clara Remon (LHCb). EvtD0mixDalitz code: cleanup, inverted q/p for decays of D0bar (simplifies user decay files) and fixed y parameter bug, courtesy of Jordi Tico (LHCb). Changed the initialisation order of the infrared cut-off in EvtPhotosEngine. This actually has no effect, since the exponentiation function sets it to the same 1e-7 value, but it's now in the correct order if we need to update it. Removed all remaining obsolete pragma (Win32) warnings from some classes. 23rd September 2015 Michal Kreps Reimplement the real Spence function in C++ and removed its fortran implementation. 15th September 2015 Michal Kreps Fixed accessed uninitialised memory in EvtPDL.cpp, line 213. Modified the configure and setupEvtGen.sh scripts to work on Mac; needed Mac compilation patch files added to the new "platform" subdirectory. 10th September 2015 John Back Updated setupEvtGen.sh to use the recommended external packages: HepMC 2.06.09, pythia 8.186, Photos++ 3.56 and Tauola++ 1.1.5. Fixed form-factor calculations for the BTOSLLBALL model 6 used to generate b -> sll decays, courtesy of Christoph Langenbruch and David Loh (LHCb). Affects B->K*ll, B->rholl and B->omegall, particularly the electron modes. In the validation directory, added runPhotosTest.sh for testing FSR in Upsilon(4S) -> e+ e- decays, and changed the plot comparison scripts to use the 2nd directory "oldRootFiles" (which could be a soft-link) for including ROOT histograms made from a previous version of EvtGen. 27th August 2015 John Back Added Mersenne-Twister random number generator (RNG) EvtMTRandomEngine. It requires c++11 compiler features (>= gcc 4.7), which should automatically be enabled by the configure script. Introduced the preprocessor environment variable EVTGEN_CPP11 for c++11 features. EvtMTRandomEngine is the default RNG for the validation and test examples if c++11 features are enabled. Added a phase-space test validation/genPHSP.sh and PhaseSpacePlots.C to visually check the flatness of Dalitz plots in order to ensure that the RNG is not producing biased results that depend on particle ordering. Added the models EvtbsToLLLLAmp and EvtbsToLLLLHyperCP for B0_q -> l+ l- l+ l- decays (SM and one supersymmetric scenario), courtesy of Nikolai Nikitin and Konstantin Toms. Documentation provided in doc/evt_BQTOLLLL_model.pdf and doc/evt_BQTOLLLLHYPERCP_model.pdf. Changed the installation and set-up script name to be just setupEvtGen.sh; it uses the VERSION variable to specify the required tag. List of tags are available using either "svn ls -v http://svn.cern.ch/guest/evtgen/tags" or by going to http://svn.cern.ch/guest/evtgen/tags in a web browser. 12th June 2015 John Back Changed the width of chi_b1 in evt.pdl from 9.8928 GeV (!) to zero. 1st May 2015 John Back Added Bc -> scalar ell nu (EvtBcSMuNu) and Bc -> tensor ell nu (EvtBcTMuNu) decays, courtesy of Jack Wimberley, LHCb. Also included the chi_c1 mode for EvtBcVMuNu. R01-04-00------------------------------------------------------------------- 2nd April 2015 John Back Removed the EvtStdlibRandomEngine class since this can produce biases to kinematic distributions when one or more of the daughters is a resonance, such as B0 -> K pi psi (thanks to Antonio Augusto Alves Jr who discovered this issue). EvtSimpleRandomEngine is now the default random number generator in the validation and test examples. Incorporated several additions and modifications from LHCb: a) From Michal Kreps, Tom Blake & Christoph Langenbruch, added rare Lb --> Lambda^(*) ell ell models described in arXiv:1108.6129, with various form factors from Gutsche et al. (arXiv:1301.3737) and lattice QCD (arXiv:1212.4827) b) From Andrew Crocombe, implemented Bs --> K* form factors from Ball-Zwicky and z-parametrization form factors from arXiv:1006.4945 for EvtbTosllBallFF c) Christoph Langenbruch fixed the Bs -> phi ll form factors in EvtbTosllBallFF; T3 showed a non-physical pole at very low q2 which significantly affected the electron mode d) From Michal Kreps, removed semicolons from wrong places to clear warnings when compiled with the "-pedantic" option. 9th October 2014 John Back Change svnweb.cern.ch to svn.cern.ch in the setup script. 1st April 2014 John Back In EvtReport, modified the logging output severity status flags to have the "EVTGEN_" prefix, e.g. INFO becomes EVTGEN_INFO. The global report() function has been renamed to EvtGenReport(). 31st March 2014 John Back Added the ability to store named attributes for EvtParticles in the form of a map. The setAttribute(name, value) stores the required value, while getAttribute(name) retrieves the integer value. This is used in EvtPhotosEngine to specify the final-state radiation "FSR" attribute to 1 for any additional photons (EvtPhotonParticles) created by Photos++. It also stores the "ISR" attribute, but this is always set to zero, since only FSR photons are created. If the named attribute doesn't exist, then getAttribute() returns zero. 29th January 2014 Daniel Craik Removed mass assertion on GS shape in EvtDalitzReso to allow it to also be used for charged rho resonances. 27th January 2014 John Back Minor corrections to Vub models to remove further gcc 4.8 warnings. Updated configure script to work for MacOS clang (from Genser team). R01-03-00------------------------------------------------------------------- 9th January 2014 John Back New tag version "1.3.0", incorporating all changes below. Replaced auto-install script to work with this version as well as the latest versions of all external generator packages. Updated README to mention the new CERN-based web pages for Photos++ and Tauola++. 8th January 2014 John Back Fix gcc 4.6 and 4.8 compilation warnings, courtesy of Patrick Robbe (LHCb); main changes are removal of unused variables. Changed the EvtPythiaEngine class and configure script to use new Pythia 8 header locations; Pythia 8.180 or above is now required. 7th January 2014 John Back Modified EvtBCVFF to correct the Kiselev form factors from Jack Wimberley (LHCb). 9th October 2013 Daniel Craik Added Gounaris-Sakurai and Gaussian shapes to EvtGenericDalitz and set sensible defaults for LASS parameters. 19th September 2013 John Back Modified EvtGenExternal/EvtPythiaEngine to keep track of any new particles that are added to the default Pythia database to avoid duplicating particle/anti-particle entries that could override previously defined Pythia decay chains. 18th September 2013 John Back Added Mac OS flags for the configure script and src/Makefile. 15th July 2013 Daniel Craik Added flag to turn on scaling of LASS amplitude by M/q in EvtDalitzReso 15th July 2013 Daniel Craik EvtParserXML now accepts file names containing environment variables, exponential non-resonant shape in EvtDalitzReso now defined as exp(-alpha*m^2), LASS shape in EvtDalitzReso now takes a cutoff parameter 4th July 2013 Daniel Craik Added LASS, exponential non-resonant and linear non-resonant shapes to EvtGenericDalitz. 3rd July 2013 Daniel Craik Fixed auto-install script for R01-02-00. 1st July 2013 Daniel Craik Added auto-install script for R01-02-00. R01-02-00------------------------------------------------------------------- 15th May 2013 John Back New tag, version "1.2.0", incorporating all changes below. 14th May 2013 Michal Kreps Added Blatt-Weisskopf barrier factors up to L=5 in EvtGenBase/EvtBlattWeisskopf::compute(). 14th May 2013 John Back Added additional entries (appended at the end) to the evt.pdl particle data file courtesy of Romulus Godang and Belle II colleagues. 14th March 2013 John Back Added the method EvtParticle::getPDGId() to get the PDG integer for a particle directly (which just calls EvtPDL::getStdHep()). Added a check in EvtPhotosEngine::doDecay to skip Photos if a given particle has too many daughters (>= 10) to avoid a problem with a hard coded upper limit in the Photos PHOENE subroutine. 2nd February 2013 Daniel Craik Updated EvtDalitzTable to estimate probMax when it is missing from a Dalitz model. 1st February 2013 John Back Added the ability to read in Pythia 6 commands in ascii decay files in EvtDecayTable::readDecayFile (this was already possible in xml files). Modified the Photos++ engine default settings to be more suited to B decays (from LHCb defaults). 31st January 2013 John Back Added the ability to read in Pythia 8 commands in ascii decay files in EvtDecayTable::readDecayFile. They can be set using the syntax: "PythiaTypeParam module:variable=value", where Type = Generic, Alias or Both for specifying whether the parameter is for the generic or alias Pythia decay engines (or both). The 2nd argument must not contain any spaces. Fixed the list of commands strings being used in the EvtPythiaEngine class (i.e. Pythia parameters that can be set via decay files). 31st January 2013 Daniel Craik Added named parameters to various decay models. 30th January 2013 John Back Fixed some of the parameter arguments used in the EvtSVSCPiso model. 24th January 2013 John Back Set the Photos++ and Tauola++ models to use the EvtGen random number engine when useEvtGenRandom is set to true in the EvtExternalGenList constructor. 23rd January 2013 John Back Added EvtGenExternal/EvtPythiaRandom to allow the use of the EvtGen random number engine to also be used for the random engine for Pythia 8. Added a boolean (useEvtGenRandom, default = true) within the EvtExternalGenList constructor to use this feature. 18th December 2012 John Back Corrected some wrong daughter ordering assignments for decay modes 5 and 12 in EvtDDalitz. Updated validation/DalitzDecays.xml to also contain D decay mode 12, as well as various modes that may use K_S0 and K_L0. Added validation/genDDalitzModes.sh and updated validation/compareDalitz.C to do a complete comparison of the D Dalitz modes with the xml versions. 11th December 2012 Daniel Craik Updated the Xml parser to support named model parameters. Updated the generic Dalitz model to use named model parameters as an example. 15th October 2012 John Back Make EvtSimpleRandomEngine inherit from EvtRandomEngine to avoid crash in EvtGen.cpp when no random engine is defined (from Bjoern Spruck). R01-01-00------------------------------------------------------------------- 4th October 2012 John Back New tag, version "1.1.0", incorporating all changes below. Provide proper default constructors for EvtVector4R and EvtPhotonParticle. Modified the validation and test code to also compile/link in the case of no external generators being included. 3rd October 2012 John Back Corrected the t3 vector form factor values for the Ball-Zwicky '05 model (modelId = 6) in EvtbTosllBallFF::getVectorFF(), which were set to t3tilde instead. 18th September 2012 John Back Moved the external generator engines to a new sub-directory EvtGenExternal. Building the code now creates 2 libraries: libEvtGen.so (Base+Models) and libEvtGenExternal.so. This allows anyone to ignore using the new external generators if required (by not creating/loading the 2nd library). Added prefix option to the configure script/Makefile to allow the user to specify an installation directory for the include files, libraries, DECAY.DEC and evt.pdl files (for Genser). 14th September 2012 Michal Kreps Fixed the calculation of the angle between decay planes in the function EvtKine::EvtDecayAngleChi. Fixed typo in EvtLb2Lll decay model. Only some NP scenarious could be affected, SM one is definitely unaffected. 13th September 2012 John Back Added the use of the environment variables EVTGEN_PHOTOS, EVTGEN_PYTHIA and EVTGEN_TAUOLA to specify if the Photos, Pythia and/or Tauola engine classes are used or not. These variables are set by the configure script, depending if the library paths are specified for these generators. R01-00-01-------------------------------------------------------------------- 12th September 2012 John Back New tag incorporating all changes below, since R01-00-00. 11th September 2012 John Back Modified the Photos and Tauola engine classes to use the new Photospp and Tauolapp namespaces that are present in the latest versions of Photos++(3.5) and Tauola++(1.0.7). Updated the configure file to get the correct location of the Tauola++ include files. Added the D0->pi+pi-pi0 decay mode in EvtDDalitz from Marco Gersabeck and Frederic Dreyer (LHCb). Added new decay models/classes from Alexey Luchinsky (LHCb): EvtBcVMuNu, EvtTVP, EvtWnPi, EvtSVP, EvtXPsiGamma, EvtBcVNpi 29th June 2012 John Back Corrected mass(squared) variables filled in the Dalitz TTree in validation/genExampleRootFiles. 15th May 2012 Daniel Craik Updated EvtD0gammaDalitz to deal with D mesons from neutral B->DK Added save function to validation/compareDalitz.C. 11th May 2012 Daniel Craik Replaced BaBar specific configuration for BlattWeisskopf birth factors. Updated XML conversion script to handle new configuration. Fixed some bugs in the XML conversion script related to particle modifications. 9th May 2012 Daniel Craik Added latex documentation for xml decay files. 2nd May 2012 Daniel Craik Added resDaughters attribute to the Dalitz resonance xml tag to simplify defining symmetric resonances. Updated validation xml files to use the new functionality. 27th April 2012 Daniel Craik Upgraded EvtGenericDalitz to use EvtDalitzReso for resonances. Added validation to compare EvtGenericDalitz to all 11 EvtDDalitz modes. Added a root macro to quickly compare two Dalitz decays for validation. 24th April 2012 John Back Solved two bugs in the EvtD0gammaDalitz model (from Jordi Tico, LHCb): configuration of the conjugated model, and using only the B charge to determine the model used, not the D flavour. 17th April 2012 Daniel Craik Updated the GenericDalitz validation code to use the same probMax values as DDalitz. Added XML decay file parsing to EvtGen::readUDecay. Dec files are still the default. 30th March 2012 John Back Update maximum probability values in EvtDDalitz::initProbMax() for all DDalitz modes. 23rd March 2012 John Back Added the EvtEta2MuMuGamma decay model from LHCb. 21st March 2012 John Back Added EvtD0gammaDalitz decay model from LHCb. 20th March 2012 Daniel Craik Added backwards compatibility for Pythia 6 commands in the XML configuration. Updated decay file conversion tool to convert JetSetPar lines to pythia6Param tags. 19th March 2012 Daniel Craik Added infrastructure to pass commands to external generators. XML config now takes Pythia8 configuration commands. 16th March 2012 Daniel Craik Added the ability to define particles from the PDL for Dalitz decay resonances instead of defining mass, width and spin seperately. Renamed the lifetime attribute of Dalitz decay resonaces to width to avoid confusion. Added further validation code for the generic Dalitz model. 15th March 2012 Daniel Craik Added validation code for xml decay files and the generic Dalitz model. R01-00-00 ------------------------------------------------------------------ 6th March 2012 John Back First official version for Genser (evtgen 1.0.0) that includes support for external generators: Pythia8, Photos++ and Tauola++. This also includes a preliminary version of creating Dalitz plot decay models using EvtGenericDalitz. diff --git a/cmake/Modules/ExternalDependencies.cmake b/cmake/Modules/ExternalDependencies.cmake index d34e95d..64c7ab2 100644 --- a/cmake/Modules/ExternalDependencies.cmake +++ b/cmake/Modules/ExternalDependencies.cmake @@ -1,20 +1,38 @@ set(HEPMC2_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/HepMC" CACHE PATH "Location of HepMC 2 installation") +set(HEPMC3_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/HepMC3" CACHE PATH "Location of HepMC 3 installation") + if(DEFINED ENV{PYTHIAVER}) set(PYTHIA8_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/pythia$ENV{PYTHIAVER}" CACHE PATH "Location of Pythia8 installation") else() set(PYTHIA8_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/pythia8230" CACHE PATH "Location of Pythia8 installation") endif() -set(PHOTOSPP_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/PHOTOS" CACHE PATH "Location of Photos++ installation") -set(TAUOLAPP_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/TAUOLA" CACHE PATH "Location of Tauola++ installation") +set(Photos++_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/PHOTOS" CACHE PATH "Location of Photos++ installation") +set(Tauola++_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/TAUOLA" CACHE PATH "Location of Tauola++ installation") +set(PHOTOSPP_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/PHOTOS" CACHE PATH "Location of Photos++ installation/alternative spelling") +set(TAUOLAPP_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/TAUOLA" CACHE PATH "Location of Tauola++ installation/alternative spelling") +#Here we are looking for HepMC interfaces. Note that the OPTIONAL_COMPONENTS includes the libraries that appear only in the new TAUOLA/PHOTOS +if (EVTGEN_HEPMC3) +find_package(HepMC3 REQUIRED) +if(${EVTGEN_PYTHIA}) + find_package(Pythia8 REQUIRED) +endif() +if(${EVTGEN_PHOTOS}) + find_package(Photos++ REQUIRED COMPONENTS pp ppHepMC3) +endif() +if(${EVTGEN_TAUOLA}) + find_package(Tauola++ REQUIRED COMPONENTS Fortran CxxInterface HepMC3) +endif() +else() find_package(HepMC2 REQUIRED) if(${EVTGEN_PYTHIA}) find_package(Pythia8 REQUIRED) endif() if(${EVTGEN_PHOTOS}) - find_package(Photos++ REQUIRED) + find_package(Photos++ REQUIRED OPTIONAL_COMPONENTS pp ppHepMC CxxInterface Fortran) endif() if(${EVTGEN_TAUOLA}) - find_package(Tauola++ REQUIRED) + find_package(Tauola++ REQUIRED COMPONENTS Fortran CxxInterface OPTIONAL_COMPONENTS HepMC) +endif() endif() diff --git a/cmake/Modules/FindPhotos++.cmake b/cmake/Modules/FindPhotos++.cmake index 3cb454a..33ce1c8 100644 --- a/cmake/Modules/FindPhotos++.cmake +++ b/cmake/Modules/FindPhotos++.cmake @@ -1,50 +1,54 @@ # - Try to find Photos++ # Defines: # -# PHOTOS++_FOUND -# PHOTOS++_INCLUDE_DIR -# PHOTOS++_INCLUDE_DIRS (not cached) -# PHOTOS++__LIBRARY -# PHOTOS++__FOUND -# PHOTOS++_LIBRARIES (not cached) -# PHOTOS++_LIBRARY_DIRS (not cached) +# Photos++_FOUND +# Photos++_INCLUDE_DIR +# Photos++_INCLUDE_DIRS (not cached) +# Photos++__LIBRARY +# Photos++__FOUND +# Photos++_LIBRARIES (not cached) +# Photos++_LIBRARY_DIRS (not cached) -# Enforce a minimal list if none is explicitly requested -if(NOT PHOTOS++_FIND_COMPONENTS) - set(PHOTOS++_FIND_COMPONENTS pp ppHepMC) +# Check all list if none is explicitly requested +if(NOT Photos++_FIND_COMPONENTS) + set(Photos++_FIND_COMPONENTS pp ppHepMC ppHEPEVT ppHepMC3 CxxInterface Fortran) endif() - -foreach(component ${PHOTOS++_FIND_COMPONENTS}) - find_library(PHOTOS++_${component}_LIBRARY NAMES Photos${component} - HINTS ${PHOTOS++_ROOT_DIR}/lib - $ENV{PHOTOSPP_ROOT_DIR}/lib - ${PHOTOSPP_ROOT_DIR}/lib) - if (PHOTOS++_${component}_LIBRARY) - set(PHOTOS++_${component}_FOUND 1) - list(APPEND PHOTOS++_LIBRARIES ${PHOTOS++_${component}_LIBRARY}) - - get_filename_component(libdir ${PHOTOS++_${component}_LIBRARY} PATH) - list(APPEND PHOTOS++_LIBRARY_DIRS ${libdir}) +set(Photos++_FOUND TRUE) +foreach(component ${Photos++_FIND_COMPONENTS}) + find_library(Photos++_${component}_LIBRARY NAMES Photos${component} + HINTS ${Photos++_ROOT_DIR}/lib $ENV{PHOTOSPP_ROOT_DIR}/lib ${PHOTOSPP_ROOT_DIR}/lib + ${Photos++_ROOT_DIR}/lib64 $ENV{PHOTOSPP_ROOT_DIR}/lib64 ${PHOTOSPP_ROOT_DIR}/lib64 + ) + if (Photos++_${component}_LIBRARY) + set(Photos++_${component}_FOUND TRUE) + list(APPEND Photos++_LIBRARIES ${Photos++_${component}_LIBRARY}) + get_filename_component(libdir ${Photos++_${component}_LIBRARY} PATH) + list(APPEND Photos++_LIBRARY_DIRS ${libdir}) else() - set(PHOTOS++_${component}_FOUND 0) + set(Photos++_${component}_FOUND FALSE) + if (Photos++_FIND_REQUIRED_${component}) + set(Photos++_FOUND FALSE) + endif() endif() - mark_as_advanced(PHOTOS++_${component}_LIBRARY) + message(STATUS "EvtGen: Photos++_${component}_FOUND=${Photos++_${component}_FOUND}, Photos++_FIND_REQUIRED_${component}=${Photos++_FIND_REQUIRED_${component}} in ${Photos++_${component}_LIBRARY}") + mark_as_advanced(Photos++_${component}_LIBRARY) endforeach() -if(PHOTOS++_LIBRARY_DIRS) - list(REMOVE_DUPLICATES PHOTOS++_LIBRARY_DIRS) +if(Photos++_LIBRARY_DIRS) + list(REMOVE_DUPLICATES Photos++_LIBRARY_DIRS) endif() -find_path(PHOTOS++_INCLUDE_DIR Photos/Photos.h - HINTS ${PHOTOS++_ROOT_DIR}/include +find_path(Photos++_INCLUDE_DIR Photos/Photos.h + HINTS ${Photos++_ROOT_DIR}/include $ENV{PHOTOSPP_ROOT_DIR}/include ${PHOTOSPP_ROOT_DIR}/include) -set(PHOTOS++_INCLUDE_DIRS ${PHOTOS++_INCLUDE_DIR}) -mark_as_advanced(PHOTOS++_INCLUDE_DIR) +set(Photos++_INCLUDE_DIRS ${Photos++_INCLUDE_DIR} ${Photos++_INCLUDE_DIR}/Photos) +mark_as_advanced(Photos++_INCLUDE_DIR) -# handle the QUIETLY and REQUIRED arguments and set PHOTOS++_FOUND to TRUE if +# handle the QUIETLY and REQUIRED arguments and set Photos++_FOUND to TRUE if # all listed variables are TRUE +if (Photos++_FOUND) include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Photos++ DEFAULT_MSG PHOTOS++_INCLUDE_DIR PHOTOS++_LIBRARIES) - -mark_as_advanced(PHOTOS++_FOUND) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Photos++ DEFAULT_MSG Photos++_INCLUDE_DIR Photos++_LIBRARIES) +endif() +mark_as_advanced(Photos++_FOUND) diff --git a/cmake/Modules/FindTauola++.cmake b/cmake/Modules/FindTauola++.cmake index c2a7644..6c01c02 100644 --- a/cmake/Modules/FindTauola++.cmake +++ b/cmake/Modules/FindTauola++.cmake @@ -1,53 +1,53 @@ # - Try to find Tauola++ # Defines: # -# TAUOLA++_FOUND -# TAUOLA++_INCLUDE_DIR -# TAUOLA++_INCLUDE_DIRS (not cached) -# TAUOLA++__LIBRARY -# TAUOLA++__FOUND -# TAUOLA++_LIBRARIES (not cached) -# TAUOLA++_LIBRARY_DIRS (not cached) - -# Enforce a minimal list if none is explicitly requested +# Tauola++_FOUND +# Tauola++_INCLUDE_DIR +# Tauola++_INCLUDE_DIRS (not cached) +# Tauola++__LIBRARY +# Tauola++__FOUND +# Tauola++_LIBRARIES (not cached) +# Tauola++_LIBRARY_DIRS (not cached) + +# Check all if none is explicitly requested if(NOT Tauola++_FIND_COMPONENTS) - set(Tauola++_FIND_COMPONENTS Fortran CxxInterface) + set(Tauola++_FIND_COMPONENTS Fortran CxxInterface HepMC HepMC3) endif() - -#message(STATUS "Tauola++ CMAKE_PREFIX_PATH") -#foreach(_x ${CMAKE_PREFIX_PATH}) -# message(STATUS "Tauola++ -- ${_x}") -#endforeach() - +set(Tauola++_FOUND TRUE) foreach(component ${Tauola++_FIND_COMPONENTS}) - find_library(TAUOLA++_${component}_LIBRARY NAMES Tauola${component} - HINTS ${TAUOLA++_ROOT_DIR}/lib - $ENV{TAUOLAPP_ROOT_DIR}/lib ${TAUOLAPP_ROOT_DIR}/lib) - if (TAUOLA++_${component}_LIBRARY) - set(TAUOLA++_${component}_FOUND 1) - list(APPEND TAUOLA++_LIBRARIES ${TAUOLA++_${component}_LIBRARY}) - - get_filename_component(libdir ${TAUOLA++_${component}_LIBRARY} PATH) - list(APPEND TAUOLA++_LIBRARY_DIRS ${libdir}) + find_library(Tauola++_${component}_LIBRARY NAMES Tauola${component} + HINTS ${Tauola++_ROOT_DIR}/lib $ENV{TAUOLAPP_ROOT_DIR}/lib ${TAUOLAPP_ROOT_DIR}/lib + ${Tauola++_ROOT_DIR}/lib64 $ENV{TAUOLAPP_ROOT_DIR}/lib64 ${TAUOLAPP_ROOT_DIR}/lib64 + ) + if (Tauola++_${component}_LIBRARY) + set(Tauola++_${component}_FOUND TRUE) + list(APPEND Tauola++_LIBRARIES ${Tauola++_${component}_LIBRARY}) + get_filename_component(libdir ${Tauola++_${component}_LIBRARY} PATH) + list(APPEND Tauola++_LIBRARY_DIRS ${libdir}) else() - set(TAUOLA++_${component}_FOUND 0) + set(Tauola++_${component}_FOUND FALSE) + if (Tauola++_FIND_REQUIRED_${component}) + set(Tauola++_FOUND FALSE) + endif() endif() - mark_as_advanced(TAUOLA++_${component}_LIBRARY) + message(STATUS "EvtGen: Tauola++_${component}_FOUND=${Tauola++_${component}_FOUND}, Tauola++_FIND_REQUIRED_${component}=${Tauola++_FIND_REQUIRED_${component}} in ${Tauola++_${component}_LIBRARY}") + mark_as_advanced(Tauola++_${component}_LIBRARY) endforeach() -if(TAUOLA++_LIBRARY_DIRS) - list(REMOVE_DUPLICATES TAUOLA++_LIBRARY_DIRS) +if(Tauola++_LIBRARY_DIRS) + list(REMOVE_DUPLICATES Tauola++_LIBRARY_DIRS) endif() -find_path(TAUOLA++_INCLUDE_DIR Tauola/Tauola.h - HINTS ${TAUOLA++_ROOT_DIR}/include +find_path(Tauola++_INCLUDE_DIR Tauola/Tauola.h + HINTS ${Tauola++_ROOT_DIR}/include $ENV{TAUOLAPP_ROOT_DIR}/include ${TAUOLAPP_ROOT_DIR}/include) -set(TAUOLA++_INCLUDE_DIRS ${TAUOLA++_INCLUDE_DIR}) -mark_as_advanced(TAUOLA++_INCLUDE_DIR) +set(Tauola++_INCLUDE_DIRS ${Tauola++_INCLUDE_DIR}) +mark_as_advanced(Tauola++_INCLUDE_DIR) -# handle the QUIETLY and REQUIRED arguments and set TAUOLA++_FOUND to TRUE if +# handle the QUIETLY and REQUIRED arguments and set Tauola++_FOUND to TRUE if # all listed variables are TRUE +if (Tauola++_FOUND) include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Tauola++ DEFAULT_MSG TAUOLA++_INCLUDE_DIR TAUOLA++_LIBRARIES) - -mark_as_advanced(TAUOLA++_FOUND) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Tauola++ DEFAULT_MSG Tauola++_INCLUDE_DIR Tauola++_LIBRARIES) +endif() +mark_as_advanced(Tauola++_FOUND) diff --git a/setupEvtGen.sh b/setupEvtGen.sh index bd0d76f..5057a00 100644 --- a/setupEvtGen.sh +++ b/setupEvtGen.sh @@ -1,110 +1,158 @@ #!/bin/bash # This script installs EvtGen with all external dependencies. The variable VERSION specifies the # tag of EvtGen you want to use. The list of available tags can be found by either going to the url # https://phab.hepforge.org/source/evtgen/tags/master # or issuing the command (without the need to clone the git repository) # git ls-remote --tags http://phab.hepforge.org/source/evtgen.git | cut -d '/' -f3 # Note that some earlier EvtGen versions will not be compatible with all external dependency # versions given below, owing to C++ interface differences; see the specific tagged version of # the EvtGen/README file for guidance. # To obtain this script use the "Download File" option on the right of the webpage: # https://phab.hepforge.org/source/evtgen/browse/master/setupEvtGen.sh?view=raw # Version or tag number. No extra spaces on this line! VERSION=cmake # Pythia version number with no decimal points, e.g. 8230 corresponds to version 8.230. This # follows the naming convention of Pythia install tar files. Again, no extra spaces allowed PYTHIAVER=8230 PYTHIAPKG="pythia"$PYTHIAVER PYTHIATAR=$PYTHIAPKG".tgz" echo Pythia version set to $PYTHIAVER, package tar name $PYTHIATAR +HEPMCMAJORVERSION="3" + mkdir -p EvtGen cd EvtGen INSTALL_BASE=`pwd` echo Will setup EvtGen $VERSION in $INSTALL_BASE echo Downloading EvtGen from GIT git clone https://phab.hepforge.org/source/evtgen.git evtgen.git cd evtgen.git #git checkout -b $VERSION $VERSION git checkout $VERSION cd $INSTALL_BASE # Replace the above lines with the following one for the "head" version #git clone http://phab.hepforge.org/source/evtgen.git evtgen.git osArch=`uname` echo Downloading external dependencies mkdir -p external cd external # Recommended versions of the external packages. HepMC is mandatory. # Later versions should be OK as well, assuming their C++ interfaces do not change -curl -O http://hepmc.web.cern.ch/hepmc/releases/hepmc2.06.09.tgz +curl -O http://hepmc.web.cern.ch/hepmc/releases/hepmc2.06.10.tgz +curl -O http://hepmc.web.cern.ch/hepmc/releases/HepMC3-3.2.0.tar.gz curl -O http://home.thep.lu.se/~torbjorn/pythia8/$PYTHIATAR -curl -O http://photospp.web.cern.ch/photospp/resources/PHOTOS.3.61/PHOTOS.3.61.tar.gz -curl -O http://tauolapp.web.cern.ch/tauolapp/resources/TAUOLA.1.1.6c/TAUOLA.1.1.6c.tar.gz +curl -O http://photospp.web.cern.ch/photospp/resources/PHOTOS.3.64/PHOTOS.3.64.tar.gz +curl -O http://tauolapp.web.cern.ch/tauolapp/resources/TAUOLA.1.1.8/TAUOLA.1.1.8.tar.gz echo Extracting external dependencies -tar -xzf hepmc2.06.09.tgz +tar -xzf hepmc2.06.10.tgz +tar -xzf HepMC3-3.2.0.tar.gz tar -xzf $PYTHIATAR tar -xzf PHOTOS.3.61.tar.gz tar -xzf TAUOLA.1.1.6c.tar.gz # Patch TAUOLA and PHOTOS on Darwin (Mac) if [ "$osArch" == "Darwin" ] then patch -p0 < $INSTALL_BASE/evtgen.git/platform/tauola_Darwin.patch patch -p0 < $INSTALL_BASE/evtgen.git/platform/photos_Darwin.patch fi + + + + + + + +if [ "$HEPMCMAJORVERSION" -lt "3" ] +then echo Installing HepMC in $INSTALL_BASE/external/HepMC mkdir -p HepMC mkdir -p HepMC.build cd HepMC.build -cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_BASE/external/HepMC $INSTALL_BASE/external/hepmc2.06.09 -Dmomentum:STRING=GEV -Dlength:STRING=MM +cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_BASE/external/HepMC $INSTALL_BASE/external/hepmc2.06.10 -Dmomentum:STRING=GEV -Dlength:STRING=MM make make install echo Installing pythia8 in $INSTALL_BASE/external/$PYTHIAPKG cd ../$PYTHIAPKG if [ "$PYTHIAVER" -lt "8200" ] then - ./configure --with-hepmc=$INSTALL_BASE/external/HepMC --with-hepmcversion=2.06.09 --enable-shared + ./configure --with-hepmc=$INSTALL_BASE/external/HepMC --with-hepmcversion=2.06.10 --enable-shared else ./configure --with-hepmc2=$INSTALL_BASE/external/HepMC --enable-shared fi make echo Installing PHOTOS in $INSTALL_BASE/external/PHOTOS cd ../PHOTOS ./configure --with-hepmc=$INSTALL_BASE/external/HepMC make echo Installing TAUOLA in $INSTALL_BASE/external/TAUOLA cd ../TAUOLA ./configure --with-hepmc=$INSTALL_BASE/external/HepMC make +else + +echo Installing HepMC3 in $INSTALL_BASE/external/HepMC3 +mkdir -p HepMC3 +mkdir -p HepMC3.build +cd HepMC3.build +cmake -DHEPMC3_ENABLE_ROOTIO=OFF -DHEPMC3_ENABLE_PYTHON=OFF -DCMAKE_INSTALL_PREFIX=$INSTALL_BASE/external/HepMC3 $INSTALL_BASE/external/HepMC3-3.2.0 +make +make install + +echo Installing pythia8 in $INSTALL_BASE/external/$PYTHIAPKG +cd ../$PYTHIAPKG +if [ "$PYTHIAVER" -lt "8200" ] +then + ./configure --enable-shared +else + ./configure --with-hepmc3=$INSTALL_BASE/external/HepMC3 --enable-shared +fi +make + +echo Installing PHOTOS in $INSTALL_BASE/external/PHOTOS +cd ../PHOTOS +./configure --with-hepmc3=$INSTALL_BASE/external/HepMC3 +make + +echo Installing TAUOLA in $INSTALL_BASE/external/TAUOLA +cd ../TAUOLA +./configure --with-hepmc3=$INSTALL_BASE/external/HepMC3 +make +fi echo Building EvtGen cd $INSTALL_BASE mkdir -p evtgen.build mkdir -p evtgen cd evtgen.build +if [ "$HEPMCMAJORVERSION" -lt "3" ] +then +cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_BASE/evtgen $INSTALL_BASE/evtgen.git -DEVTGEN_PYTHIA=ON -DEVTGEN_PHOTOS=ON -DEVTGEN_TAUOLA=ON -DEVTGEN_HEPMC3=OFF +else cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_BASE/evtgen $INSTALL_BASE/evtgen.git -DEVTGEN_PYTHIA=ON -DEVTGEN_PHOTOS=ON -DEVTGEN_TAUOLA=ON +fi make make install cd $INSTALL_BASE/evtgen echo Setup done. echo To complete, set the Pythia8 data path: if [ "$PYTHIAVER" -lt "8200" ] then echo PYTHIA8DATA=$INSTALL_BASE/external/$PYTHIAPKG/xmldoc else echo PYTHIA8DATA=$INSTALL_BASE/external/$PYTHIAPKG/share/Pythia8/xmldoc fi diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d61cb75..e78aaec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,104 +1,181 @@ # Use glob to find the sources for the main and external libraries file(GLOB EVTGEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/EvtGenBase/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/EvtGenModels/*.cpp ) file(GLOB EVTGEN_EXTERNAL_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/EvtGenExternal/*.cpp ) - # Add the main EvtGen library... add_library(objlib OBJECT ${EVTGEN_SOURCES}) set_target_properties(objlib PROPERTIES POSITION_INDEPENDENT_CODE 1) target_include_directories(objlib PRIVATE ${CMAKE_SOURCE_DIR}) -target_include_directories(objlib PRIVATE ${HEPMC2_INCLUDE_DIR}) + target_compile_definitions(objlib PRIVATE EVTGEN_CPP11) +if (EVTGEN_HEPMC3) +target_compile_definitions(objlib PRIVATE EVTGEN_HEPMC3) +target_include_directories(objlib PRIVATE ${HEPMC3_INCLUDE_DIR}) +else() +target_include_directories(objlib PRIVATE ${HEPMC2_INCLUDE_DIR}) +endif() add_library(EvtGen SHARED $) set_target_properties(EvtGen PROPERTIES OUTPUT_NAME EvtGen) set_target_properties(EvtGen PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) set_target_properties(EvtGen PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) target_include_directories(EvtGen PUBLIC $ $) + +if (EVTGEN_HEPMC3) +target_include_directories(EvtGen PUBLIC ${HEPMC3_INCLUDE_DIR}) +target_link_libraries(EvtGen ${HEPMC3_LIB} ${HEPMC3_SEARCH_LIB} ) +else() target_include_directories(EvtGen PUBLIC ${HEPMC2_INCLUDE_DIR}) -target_compile_definitions(EvtGen PUBLIC EVTGEN_CPP11) target_link_libraries(EvtGen ${HEPMC2_LIBRARIES}) +endif() + +target_compile_definitions(EvtGen PUBLIC EVTGEN_CPP11) + add_library(EvtGenStatic STATIC $) set_target_properties(EvtGenStatic PROPERTIES OUTPUT_NAME EvtGen) set_target_properties(EvtGenStatic PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/archive) target_include_directories(EvtGenStatic PUBLIC $ $) +if (EVTGEN_HEPMC3) +target_include_directories(EvtGenStatic PUBLIC ${HEPMC3_INCLUDE_DIR}) +target_link_libraries(EvtGenStatic ${HEPMC3_LIB} ${HEPMC3_SEARCH_LIB} ) +else() target_include_directories(EvtGenStatic PUBLIC ${HEPMC2_INCLUDE_DIR}) -target_compile_definitions(EvtGenStatic PUBLIC EVTGEN_CPP11) target_link_libraries(EvtGenStatic ${HEPMC2_LIBRARIES}) +endif() +target_compile_definitions(EvtGenStatic PUBLIC EVTGEN_CPP11) + # Add the EvtGenExternal library... if( ${EVTGEN_PYTHIA} OR ${EVTGEN_PHOTOS} OR ${EVTGEN_TAUOLA} ) add_library(objlib_ext OBJECT ${EVTGEN_EXTERNAL_SOURCES}) set_target_properties(objlib_ext PROPERTIES POSITION_INDEPENDENT_CODE 1) target_include_directories(objlib_ext PRIVATE ${CMAKE_SOURCE_DIR}) - target_include_directories(objlib_ext PRIVATE ${HEPMC2_INCLUDE_DIR}) + if (EVTGEN_HEPMC3) + target_include_directories(objlib_ext PUBLIC ${HEPMC3_INCLUDE_DIR}) + target_compile_definitions(objlib_ext PRIVATE EVTGEN_HEPMC3) + else() + target_include_directories(objlib_ext PUBLIC ${HEPMC2_INCLUDE_DIR}) + endif() target_compile_definitions(objlib_ext PRIVATE EVTGEN_CPP11) if(${EVTGEN_PYTHIA}) - target_include_directories(objlib_ext PRIVATE ${PYTHIA8_INCLUDE_DIR}) + target_include_directories(objlib_ext PRIVATE ${PYTHIA8_INCLUDE_DIRS}) target_compile_definitions(objlib_ext PRIVATE EVTGEN_PYTHIA) endif() if(${EVTGEN_PHOTOS}) - target_include_directories(objlib_ext PRIVATE ${PHOTOS++_INCLUDE_DIR}) + target_include_directories(objlib_ext PRIVATE ${Photos++_INCLUDE_DIRS}) target_compile_definitions(objlib_ext PRIVATE EVTGEN_PHOTOS) endif() if(${EVTGEN_TAUOLA}) - target_include_directories(objlib_ext PRIVATE ${TAUOLA++_INCLUDE_DIR}) + target_include_directories(objlib_ext PRIVATE ${Tauola++_INCLUDE_DIRS}) target_compile_definitions(objlib_ext PRIVATE EVTGEN_TAUOLA) endif() add_library(EvtGenExternal SHARED $) set_target_properties(EvtGenExternal PROPERTIES OUTPUT_NAME EvtGenExternal) set_target_properties(EvtGenExternal PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) set_target_properties(EvtGenExternal PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) - target_link_libraries(EvtGenExternal ${HEPMC2_LIBRARIES}) + if(${EVTGEN_PYTHIA}) target_link_libraries(EvtGenExternal ${PYTHIA8_LIBRARIES}) endif() + + + if (EVTGEN_HEPMC3) + target_link_libraries(EvtGenExternal ${HEPMC3_LIB} ${HEPMC3_SEARCH_LIB} ) if(${EVTGEN_PHOTOS}) - target_link_libraries(EvtGenExternal ${PHOTOS++_LIBRARIES}) + target_link_libraries(EvtGenExternal ${Photos++_pp_LIBRARY} ${Photos++_ppHepMC3_LIBRARY} ) endif() if(${EVTGEN_TAUOLA}) - target_link_libraries(EvtGenExternal ${TAUOLA++_LIBRARIES}) + target_link_libraries(EvtGenExternal ${Tauola++_CxxInterface_LIBRARY} ${Tauola++_Fortran_LIBRARY} ${Tauola++_HepMC3_LIBRARY}) + endif() + else() + target_link_libraries(EvtGenExternal ${HEPMC2_LIBRARIES}) + if(${EVTGEN_PHOTOS}) +#Photos should always have ppHepMC for compilation with HepMC2 + if (Photos++_pp_FOUND AND Photos++_ppHepMC_FOUND ) + message(STATUS "EvtGen: PHOTOS has pp and ppHepMC components") + target_link_libraries(EvtGenExternal ${Photos++_pp_LIBRARY} ${Photos++_ppHepMC_LIBRARY}) + else() + if(Photos++_CxxInterface_FOUND AND Photos++_Fortran_FOUND ) + message(STATUS "EvtGen: PHOTOS has CxxInterface and Fortran components") + target_link_libraries(EvtGenExternal ${Photos++_CxxInterface_LIBRARY} ${Photos++_Fortran_LIBRARY}) + else() + message(ERROR "EvtGen: PHOTOS lacks pp+ppHepMC or CxxInterface+Fortran components") + endif() + endif() endif() + if(${EVTGEN_TAUOLA}) + target_link_libraries(EvtGenExternal ${Tauola++_CxxInterface_LIBRARY} ${Tauola++_Fortran_LIBRARY}) +#The old versions of Tauola don't have HepMC, the HepMC2 interface is in CxxInterface + if (Tauola++_HepMC_FOUND) + target_link_libraries(EvtGenExternal ${Tauola++_HepMC_LIBRARY}) + endif() + endif() + endif() + + add_library(EvtGenExternalStatic STATIC $) set_target_properties(EvtGenExternalStatic PROPERTIES OUTPUT_NAME EvtGenExternal) set_target_properties(EvtGenExternalStatic PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/archive) - target_link_libraries(EvtGenExternalStatic ${HEPMC2_LIBRARIES}) if(${EVTGEN_PYTHIA}) target_link_libraries(EvtGenExternalStatic ${PYTHIA8_LIBRARIES}) endif() + if (EVTGEN_HEPMC3) + target_link_libraries(EvtGenExternalStatic ${HEPMC3_LIB} ${HEPMC3_SEARCH_LIB} ) if(${EVTGEN_PHOTOS}) - target_link_libraries(EvtGenExternalStatic ${PHOTOS++_LIBRARIES}) + target_link_libraries(EvtGenExternalStatic ${Photos++_pp_LIBRARY} ${Photos++_ppHepMC3_LIBRARY}) endif() if(${EVTGEN_TAUOLA}) - target_link_libraries(EvtGenExternalStatic ${TAUOLA++_LIBRARIES}) + target_link_libraries(EvtGenExternalStatic ${Tauola++_CxxInterface_LIBRARY} ${Tauola++_Fortran_LIBRARY} ${Tauola++_HepMC3_LIBRARY}) + endif() + else() + if(${EVTGEN_PHOTOS}) + if (Photos++_pp_FOUND AND Photos++_ppHepMC_FOUND ) + message(STATUS "EvtGen: PHOTOS has pp and ppHepMC components") + target_link_libraries(EvtGenExternal ${Photos++_pp_LIBRARY} ${Photos++_ppHepMC_LIBRARY}) + else() + if(Photos++_CxxInterface_FOUND AND Photos++_Fortran_FOUND ) + message(STATUS "EvtGen: PHOTOS has CxxInterface and Fortran components") + target_link_libraries(EvtGenExternal ${Photos++_CxxInterface_LIBRARY} ${Photos++_Fortran_LIBRARY}) + else() + message(ERROR "EvtGen: PHOTOS lacks pp+ppHepMC or CxxInterface+Fortran components") + endif() + endif() + endif() + if(${EVTGEN_TAUOLA}) + target_link_libraries(EvtGenExternalStatic ${Tauola++_CxxInterface_LIBRARY} ${Tauola++_Fortran_LIBRARY}) + if (Tauola++_HepMC_FOUND) + target_link_libraries(EvtGenExternalStatic ${Tauola++_HepMC_LIBRARY} ) + endif() + endif() + target_link_libraries(EvtGenExternalStatic ${HEPMC2_LIBRARIES}) endif() endif() # Install the libraries install( TARGETS EvtGen EvtGenStatic EXPORT "EvtGenTargets" LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/archive ) if( ${EVTGEN_PYTHIA} OR ${EVTGEN_PHOTOS} OR ${EVTGEN_TAUOLA} ) install( TARGETS EvtGenExternal EvtGenExternalStatic EXPORT "EvtGenTargets" LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/archive ) endif() diff --git a/src/EvtGenBase/EvtHepMCEvent.cpp b/src/EvtGenBase/EvtHepMCEvent.cpp index 308e006..3c54b6b 100644 --- a/src/EvtGenBase/EvtHepMCEvent.cpp +++ b/src/EvtGenBase/EvtHepMCEvent.cpp @@ -1,198 +1,197 @@ //-------------------------------------------------------------------------- // // Environment: // This software is part of the EvtGen package. If you use all or part // of it, please give an appropriate acknowledgement. // // Copyright Information: See EvtGen/COPYRIGHT // Copyright (C) 2011 University of Warwick, UK // // Module: EvtHepMCEvent // // Description: Create an HepMC::GenEvent for the complete EvtParticle // decay tree. // // Modification history: // // John Back June 2011 Module created // //------------------------------------------------------------------------ #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPDL.hh" -#include "HepMC/Units.h" EvtHepMCEvent::EvtHepMCEvent() : _theEvent(0), _translation(0.0, 0.0, 0.0, 0.0) { } EvtHepMCEvent::~EvtHepMCEvent() { this->deleteEvent(); } void EvtHepMCEvent::deleteEvent() { if (_theEvent != 0) { _theEvent->clear(); delete _theEvent; _theEvent = 0; } } 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) {return;} - _theEvent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM); + _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"). - HepMC::GenParticle* hepMCGenParticle = this->createGenParticle(baseParticle, EvtHepMCEvent::LAB); + GenParticlePtr hepMCGenParticle = this->createGenParticle(baseParticle, EvtHepMCEvent::LAB); this->addVertex(baseParticle, hepMCGenParticle); } -HepMC::GenParticle* EvtHepMCEvent::createGenParticle(EvtParticle* theParticle, int frameType) { +GenParticlePtr EvtHepMCEvent::createGenParticle(EvtParticle* theParticle, int frameType) { // Create an HepMC GenParticle, with the 4-momenta in the frame given by the frameType integer - HepMC::GenParticle* genParticle = 0; + GenParticlePtr genParticle{nullptr}; if (theParticle != 0) { // 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); - HepMC::FourVector hepMC_p4(px, py, pz, E); + FourVector hepMC_p4(px, py, pz, E); // Get the particle PDG integer id int PDGInt = EvtPDL::getStdHep(theParticle->getId()); - genParticle = new HepMC::GenParticle(hepMC_p4, PDGInt, status); + genParticle = newGenParticlePtr(hepMC_p4, PDGInt, status); } return genParticle; } -void EvtHepMCEvent::addVertex(EvtParticle* inEvtParticle, HepMC::GenParticle* inGenParticle) { +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) {return;} // Create the decay vertex - HepMC::FourVector vtxCoord = this->getVertexCoord(inEvtParticle); - HepMC::GenVertex* theVertex = new HepMC::GenVertex(vtxCoord); + 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); - HepMC::GenParticle* genDaughter = this->createGenParticle(evtDaughter, EvtHepMCEvent::LAB); + GenParticlePtr genDaughter = this->createGenParticle(evtDaughter, EvtHepMCEvent::LAB); if (genDaughter != 0) { // 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 } -HepMC::FourVector EvtHepMCEvent::getVertexCoord(EvtParticle* theParticle) { +FourVector EvtHepMCEvent::getVertexCoord(EvtParticle* theParticle) { - HepMC::FourVector vertexCoord(0.0, 0.0, 0.0, 0.0); + FourVector vertexCoord(0.0, 0.0, 0.0, 0.0); if (theParticle != 0 && 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) { 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; -} +} \ No newline at end of file diff --git a/src/EvtGenExternal/EvtPhotosEngine.cpp b/src/EvtGenExternal/EvtPhotosEngine.cpp index 65660c4..50a183d 100644 --- a/src/EvtGenExternal/EvtPhotosEngine.cpp +++ b/src/EvtGenExternal/EvtPhotosEngine.cpp @@ -1,303 +1,307 @@ #ifdef EVTGEN_PHOTOS //-------------------------------------------------------------------------- // // Environment: // This software is part of the EvtGen package. If you use all or part // of it, please give an appropriate acknowledgement. // // Copyright Information: See EvtGen/COPYRIGHT // Copyright (C) 2011 University of Warwick, UK // // Module: EvtPhotosEngine // // Description: Interface to the PHOTOS external generator // // Modification history: // // John Back May 2011 Module created // //------------------------------------------------------------------------ #include "EvtGenExternal/EvtPhotosEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenBase/EvtPhotonParticle.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtRandom.hh" -#include "Photos/Photos.h" -#include "Photos/PhotosHepMCEvent.h" -#include "Photos/PhotosHepMCParticle.h" -#include "Photos/PhotosParticle.h" - -#include "HepMC/SimpleVector.h" -#include "HepMC/Units.h" - #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."<initialise();} if (theMother == 0) {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. - HepMC::GenEvent* theEvent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM); + GenEvent* theEvent = new GenEvent(Units::GEV, Units::MM); // Create the decay "vertex". - HepMC::GenVertex* theVertex = new HepMC::GenVertex(); + GenVertexPtr theVertex = newGenVertexPtr(); theEvent->add_vertex(theVertex); // Add the mother particle as the incoming particle to the vertex. - HepMC::GenParticle* hepMCMother = this->createGenParticle(theMother, true); + 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); - HepMC::GenParticle* hepMCDaughter = this->createGenParticle(theDaughter, false); + 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); +#else Photospp::PhotosHepMCEvent photosEvent(theEvent); +#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) { - HepMC::FourVector HepMCP4 = outParticle->momentum(); + 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) { // 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(); delete theEvent; return true; } -HepMC::GenParticle* EvtPhotosEngine::createGenParticle(EvtParticle* theParticle, bool incoming) { +GenParticlePtr EvtPhotosEngine::createGenParticle(EvtParticle* theParticle, bool incoming) { // Method to create an HepMC::GenParticle version of the given EvtParticle. if (theParticle == 0) {return 0;} // 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); - HepMC::FourVector hepMC_p4(px, py, pz, E); + 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;} - HepMC::GenParticle* genParticle = new HepMC::GenParticle(hepMC_p4, PDGInt, status); + GenParticlePtr genParticle = newGenParticlePtr(hepMC_p4, PDGInt, status); return genParticle; } -int EvtPhotosEngine::getNumberOfPhotons(const HepMC::GenVertex* theVertex) const { +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) {pdgId = outParticle->pdg_id();} // Keep track of how many photons there are if (pdgId == _gammaPDG) {nPhotons++;} } return nPhotons; } #endif diff --git a/src/EvtGenExternal/EvtTauolaEngine.cpp b/src/EvtGenExternal/EvtTauolaEngine.cpp index a33a94b..6b61090 100644 --- a/src/EvtGenExternal/EvtTauolaEngine.cpp +++ b/src/EvtGenExternal/EvtTauolaEngine.cpp @@ -1,608 +1,614 @@ #ifdef EVTGEN_TAUOLA //-------------------------------------------------------------------------- // // Environment: // This software is part of the EvtGen package. If you use all or part // of it, please give an appropriate acknowledgement. // // Copyright Information: See EvtGen/COPYRIGHT // Copyright (C) 2011 University of Warwick, UK // // Module: EvtTauolaEngine // // Description: Interface to the TAUOLA external generator, which // decays tau particles // // Modification history: // // John Back May 2011 Module created // //------------------------------------------------------------------------ #include "EvtGenExternal/EvtTauolaEngine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSymTable.hh" #include "Tauola/Log.h" #include "Tauola/Tauola.h" -#include "Tauola/TauolaHepMCEvent.h" -#include "Tauola/TauolaHepMCParticle.h" -#include "Tauola/TauolaParticle.h" - -#include "HepMC/GenVertex.h" -#include "HepMC/SimpleVector.h" -#include "HepMC/Units.h" #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."<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 != 0) { // 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 " < 0.0) { EvtGenReport(EVTGEN_INFO,"EvtGen")<<"Setting TAUOLA BF modes using the definitions for the particle " <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< 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 "<add_vertex(theVertex); // Get the parent of this tau particle EvtParticle* theParent = tauParticle->getParent(); - HepMC::GenParticle* hepMCParent(0); + GenParticlePtr hepMCParent(0); // Assign the parent particle as the incoming particle to the vertex. if (theParent != 0) { 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. - HepMC::GenParticle* tauGenInit = this->createGenParticle(tauParticle); + 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; + 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 != 0) { // 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 != 0) { - HepMC::GenParticle* hepMCDaughter = this->createGenParticle(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 != 0) { 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. - HepMC::GenParticle* singleTau = this->createGenParticle(tauParticle); + 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); +#else Tauolapp::TauolaHepMCEvent tauolaEvent(theEvent); +#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 != 0 && 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 != 0) { // 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 - HepMC::GenVertex* endVertex = aParticle->end_vertex(); - HepMC::GenVertex::particle_iterator tauIter; + 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). - HepMC::GenVertex* daugDecayVtx = tauDaug->end_vertex(); + GenVertexPtr daugDecayVtx = tauDaug->end_vertex(); if (daugDecayVtx != 0) {continue;} // Store the particle id and 4-momentum int tauDaugPDG = tauDaug->pdg_id(); EvtId daugId = EvtPDL::evtIdFromStdHep(tauDaugPDG); daugIdVect.push_back(daugId); - HepMC::FourVector tauDaugP4 = tauDaug->momentum(); + 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 != 0) { 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(); delete theEvent; } -HepMC::GenParticle* EvtTauolaEngine::createGenParticle(EvtParticle* theParticle) { +GenParticlePtr EvtTauolaEngine::createGenParticle(EvtParticle* theParticle) { // Method to create an HepMC::GenParticle version of the given EvtParticle. if (theParticle == 0) {return 0;} // 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); - HepMC::FourVector hepMC_p4(px, py, pz, E); + 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; - HepMC::GenParticle* genParticle = new HepMC::GenParticle(hepMC_p4, PDGInt, status); + GenParticlePtr genParticle = newGenParticlePtr(hepMC_p4, PDGInt, status); return genParticle; } #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6f1d3e7..2f18f47 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,29 +1,33 @@ # the test executables require ROOT for histogramming etc. -find_package(ROOT REQUIRED) - +find_package(ROOT QUIET COMPONENTS Hist) +if (ROOT_FOUND) add_library(root_interface INTERFACE IMPORTED) target_include_directories(root_interface INTERFACE ${ROOT_INCLUDE_DIRS}) target_link_libraries(root_interface INTERFACE ${ROOT_LIBRARIES}) # build each of the executables foreach( test_exe evt_dalitz evtgenlhc_test1 example1 exampleWriteHepMC ) add_executable(${test_exe} ${test_exe}.cc) target_link_libraries(${test_exe} PRIVATE EvtGen) if( ${EVTGEN_PYTHIA} OR ${EVTGEN_PHOTOS} OR ${EVTGEN_TAUOLA} ) target_compile_definitions(${test_exe} PRIVATE EVTGEN_EXTERNAL) target_link_libraries(${test_exe} PRIVATE EvtGenExternal) + if (EVTGEN_HEPMC3) + target_compile_definitions(${test_exe} PRIVATE EVTGEN_HEPMC3) + endif() endif() target_link_libraries(${test_exe} PRIVATE root_interface) endforeach() # install the executables install(TARGETS evt_dalitz evtgenlhc_test1 example1 exampleWriteHepMC RUNTIME DESTINATION test ) # install the decay files, macros, scripts, etc. install(DIRECTORY exampleFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/test) install(FILES do_tests DESTINATION ${CMAKE_INSTALL_PREFIX}/test PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +endif() \ No newline at end of file diff --git a/test/example1.cc b/test/example1.cc index 66a56f9..f1a265b 100644 --- a/test/example1.cc +++ b/test/example1.cc @@ -1,92 +1,96 @@ // // Sample test program for running EvtGen // #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtDecayBase.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include #include #include int main(int /*argc*/, char** /*argv*/) { EvtParticle* parent(0); // Define the random number generator EvtRandomEngine* eng = 0; #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; 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 "<setVectorSpinDensity(); // Generate the event myGenerator.generateDecay(parent); // Write out the results EvtHepMCEvent theEvent; theEvent.constructEvent(parent); - HepMC::GenEvent* genEvent = theEvent.getEvent(); + 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 d086d65..7279381 100644 --- a/test/exampleWriteHepMC.cc +++ b/test/exampleWriteHepMC.cc @@ -1,123 +1,137 @@ // // Sample test program for running EvtGen // #include "EvtGen/EvtGen.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtAbsRadCorr.hh" #include "EvtGenBase/EvtDecayBase.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif #include #include #include #include -bool filter(HepMC::GenEvent* event) +#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)<particles()) { +#else for (HepMC::GenEvent::particle_iterator it = event->particles_begin(); it != event->particles_end(); ++it) { - if ( abs((*it)->pdg_id()) == 11 || abs((*it)->pdg_id()) == 13 ) + GenParticlePtr p=*it; +#endif + if ( abs(p->pdg_id()) == 11 || abs(p->pdg_id()) == 13 ) { hasLepton = true; } - int id = abs((*it)->pdg_id()); + 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); // Define the random number generator EvtRandomEngine* eng = 0; #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; 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); - std::ofstream hepmcFile("hepMCtest"); + 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 "<setVectorSpinDensity(); // Generate the event myGenerator.generateDecay(parent); // Write out the results EvtHepMCEvent theEvent; theEvent.constructEvent(parent); - HepMC::GenEvent* genEvent = theEvent.getEvent(); + GenEvent* genEvent = theEvent.getEvent(); - if ( filter(genEvent) ) - { -// genEvent->print(hepmcFile); - hepmcFile<<(*genEvent); - } + if ( filter(genEvent) ) hepmcFile.write_event(*genEvent); parent->deleteTree(); } hepmcFile.close(); delete eng; return 0; } diff --git a/validation/CMakeLists.txt b/validation/CMakeLists.txt index d5855d0..91d09ea 100644 --- a/validation/CMakeLists.txt +++ b/validation/CMakeLists.txt @@ -1,59 +1,60 @@ # the validation executables require ROOT for histogramming etc. -find_package(ROOT REQUIRED) - +find_package(ROOT QUIET COMPONENTS Hist) +if (ROOT_FOUND) add_library(root_interface INTERFACE IMPORTED) target_include_directories(root_interface INTERFACE ${ROOT_INCLUDE_DIRS}) target_link_libraries(root_interface INTERFACE ${ROOT_LIBRARIES}) # build each of the executables foreach( validation_exe compareRootFiles genExampleRootFiles genRootDecayChain testCPVDecays ) add_executable(${validation_exe} ${validation_exe}.cc) target_link_libraries(${validation_exe} PRIVATE EvtGen) if( ${EVTGEN_PYTHIA} OR ${EVTGEN_PHOTOS} OR ${EVTGEN_TAUOLA} ) target_compile_definitions(${validation_exe} PRIVATE EVTGEN_EXTERNAL) target_link_libraries(${validation_exe} PRIVATE EvtGenExternal) endif() target_link_libraries(${validation_exe} PRIVATE root_interface) endforeach() # install the executables install(TARGETS compareRootFiles genExampleRootFiles genRootDecayChain testCPVDecays RUNTIME DESTINATION validation ) # install the decay files, macros, scripts, etc. install(DIRECTORY B0Files DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY CPVDecayFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY UpsilonFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY TauolaFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY Bs0Files DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY tauFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY rootFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY PHSPFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY BpFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY gifFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(DIRECTORY DalitzFiles DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(FILES BKstarGamma.dec BuDst0rhop.dec Kspimumu.dec photosTest.dec DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(FILES compareDalitz.C PhaseSpacePlots.C photosPlots.C plotBKstarGamma.C PlotKspimumu.C DESTINATION ${CMAKE_INSTALL_PREFIX}/validation) install(FILES compareAllDecays.sh compareB0PythiaDecays.sh compareBpPythiaDecays.sh compareBs0PythiaDecays.sh compareTauolaDecays.sh compareTauPythiaDecays.sh compareUpsilonPythiaDecays.sh genAllDecayExamples.sh genB0PythiaDecays.sh genBpPythiaDecays.sh genBs0PythiaDecays.sh genDalitzDecays.sh genDDalitzModes.sh genPHSP.sh genTauolaDecays.sh genTauPythiaDecays.sh genUpsilonPythiaDecays.sh runKspimumu.sh runPhotosTest.sh DESTINATION ${CMAKE_INSTALL_PREFIX}/validation PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +endif() diff --git a/validation/genExampleRootFiles.cc b/validation/genExampleRootFiles.cc index 1279d6f..af16a89 100644 --- a/validation/genExampleRootFiles.cc +++ b/validation/genExampleRootFiles.cc @@ -1,261 +1,260 @@ // 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/EvtParticle.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtSimpleRandomEngine.hh" #include "EvtGenBase/EvtMTRandomEngine.hh" #include "EvtGenBase/EvtDecayBase.hh" #ifdef EVTGEN_EXTERNAL #include "EvtGenExternal/EvtExternalGenList.hh" #endif -//#include "EvtGenBase/EvtHepMCEvent.hh" -#include "HepMC/GenEvent.h" +#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 "< 2) {rootFileName = argv[2];} cout<<"Root file name is "< 3) {parentName = argv[3];} cout<<"Parent name is "< 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 "<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); // Define the random number generator EvtRandomEngine* myRandomEngine = 0; #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; 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 "<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) {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) { 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."< #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(HepMC::GenEvent* theEvent); +void storeBFlightTimes(GenEvent* theEvent); bool checkSignal(std::vector& daugIdVect); -double calcFlightTime(HepMC::FourVector& BDecayVtx, HepMC::FourVector& B4mtm); +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 "< 2) {rootFileName = argv[2];} cout<<"Root file name is "< 3) {parentName = argv[3];} cout<<"Parent name is "< 4) {nEvents = atoi(argv[4]);} double sin2Beta = sin(0.775); if (argc > 5) {sin2Beta = atof(argv[5]);} cout<<"Number of events is "< 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 "<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 = "<getEvent(); + 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."< allVertices; + + + // Loop over vertices in the event + for (auto theVertex: theEvent->vertices()) { -void storeBFlightTimes(HepMC::GenEvent* theEvent) { + if (theVertex == 0) {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) {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) { + 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) {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); - HepMC::FourVector B4mtm; + 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) {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) { 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 } -double calcFlightTime(HepMC::FourVector& BDecayVtx, HepMC::FourVector& B4mtm) { + +#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; }