diff --git a/CepGen/CMakeLists.txt b/CepGen/CMakeLists.txt index a946120..072118f 100644 --- a/CepGen/CMakeLists.txt +++ b/CepGen/CMakeLists.txt @@ -1,110 +1,120 @@ file(GLOB core_sources Core/*.cpp *.cpp) file(GLOB phys_sources Physics/*.cpp) file(GLOB sf_sources StructureFunctions/*.cpp) file(GLOB io_sources IO/GenericExportHandler.cpp IO/TextHandler.cpp) file(GLOB hadr_sources Hadronisers/GenericHadroniser.cpp) include_directories(${PROJECT_SOURCE_DIR}) #----- check the external dependencies for SFs set(GRV_PATH ${PROJECT_SOURCE_DIR}/External) file(GLOB grv_sources ${GRV_PATH}/grv_*.f) if(grv_sources) message(STATUS "GRV PDFset found in ${grv_sources}!") add_definitions(-DGRVPDF) list(APPEND sf_sources ${grv_sources}) else() message(STATUS "GRV PDFset not found. Will proceed without it") endif() #----- check the external dependencies for physics utilities if(alphas_sources) list(APPEND phys_sources ${alphas_sources}) endif() set(addons_libraries "") set(strf_libraries ${GSL_LIB} ${GSL_CBLAS_LIB}) #--- linking with LHAPDF if(LHAPDF) message(STATUS "LHAPDF found in ${LHAPDF}") list(APPEND strf_libraries ${LHAPDF}) include_directories(${LHAPDF_INCLUDE}) else() file(GLOB partonic_sf StructureFunctions/Partonic.cpp) list(REMOVE_ITEM sf_sources ${partonic_sf}) endif() #--- linking with Pythia 6 if(PYTHIA6) message(STATUS "Pythia 6 found in ${PYTHIA6}") list(APPEND hadr_sources "Hadronisers/Pythia6Hadroniser.cpp") list(APPEND addons_libraries ${PYTHIA6}) if(PYTHIA6DUMMY) message(STATUS "Pythia 6 addons found in ${PYTHIA6DUMMY}") list(APPEND addons_libraries ${PYTHIA6DUMMY}) endif() elseif(EXISTS $ENV{PYTHIA6_SRC}) file(GLOB pythia6_src $ENV{PYTHIA6_SRC}) message(STATUS "Pythia 6 source found in ${pythia6_src}") set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wno-tabs -Wno-maybe-uninitialized -Wno-integer-division -Wno-unused-variable -Wno-unused-dummy-argument") add_library(pythia6 SHARED ${pythia6_src}) list(APPEND hadr_sources "Hadronisers/Pythia6Hadroniser.cpp") list(APPEND addons_libraries pythia6) endif() #--- linking with Pythia 8 if(PYTHIA8) message(STATUS "Pythia 8 found in ${PYTHIA8}") message(STATUS "Pythia 8 will be used for LHEF output") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-misleading-indentation") include_directories(${PYTHIA8_INCLUDE}) add_definitions(-DPYTHIA8) list(APPEND hadr_sources "Hadronisers/Pythia8Hadroniser.cpp") list(APPEND io_sources "IO/PythiaEventInterface.cpp") list(APPEND io_sources "IO/LHEFPythiaHandler.cpp") list(APPEND addons_libraries ${PYTHIA8} dl) endif() #--- linking with HepMC if(HEPMC_LIB) message(STATUS "HepMC found in ${HEPMC_LIB}") if(HEPMC_LIB MATCHES ".*HepMC3.?.so") message(STATUS "HepMC version 3 found") if(HEPMC_ROOT_LIB) message(STATUS "HepMC ROOT I/O library found") add_definitions(-DHEPMC3_ROOTIO) list(APPEND addons_libraries ${HEPMC_ROOT_LIB}) endif() add_definitions(-DHEPMC3) endif() list(APPEND io_sources "IO/HepMCHandler.cpp") if(NOT PYTHIA8) message(STATUS "HepMC will be used for LHEF output") list(APPEND io_sources "IO/LHEFHepMCHandler.cpp") endif() list(APPEND addons_libraries ${HEPMC_LIB}) include_directories(${HEPMC_INCLUDE}) endif() +#--- linking with ROOT + +if(ROOT_FOUND) + message(STATUS "ROOT found in ${ROOT_LIBRARY_DIR}") + list(APPEND addons_libraries ${ROOT_LIBRARIES}) + list(APPEND io_sources "IO/ROOTTreeHandler.cpp") + include_directories(${ROOT_INCLUDE_DIRS}) + link_directories(${ROOT_LIBRARY_DIR}) +endif() + #----- build the objects add_library(CepGenCore SHARED ${core_sources} ${phys_sources} ${sf_sources}) target_link_libraries(CepGenCore ${CEPGEN_EXTERNAL_CORE_REQS}) target_link_libraries(CepGenCore ${strf_libraries}) add_library(CepGenAddOns SHARED ${io_sources} ${hadr_sources}) target_link_libraries(CepGenAddOns ${addons_libraries}) target_link_libraries(CepGenAddOns CepGenEvent) #----- installation rules install(TARGETS CepGenCore DESTINATION lib) install(TARGETS CepGenAddOns DESTINATION lib) diff --git a/CepGen/IO/ROOTTreeHandler.cpp b/CepGen/IO/ROOTTreeHandler.cpp new file mode 100644 index 0000000..2b4d51f --- /dev/null +++ b/CepGen/IO/ROOTTreeHandler.cpp @@ -0,0 +1,103 @@ +#include "CepGen/IO/ExportHandler.h" +#include "CepGen/IO/ROOTTreeInfo.h" + +#include "CepGen/Core/Exception.h" +#include "CepGen/Core/ParametersList.h" + +#include "CepGen/Event/Event.h" +#include "CepGen/Parameters.h" + +// ROOT includes +#include "TFile.h" + +#include + +namespace cepgen +{ + namespace io + { + /** + * Handler for the storage of events in a ROOT format + * \author Laurent Forthomme + * \date 27 Jan 2014 + */ + class ROOTTreeHandler : public GenericExportHandler + { + public: + /// Class constructor + explicit ROOTTreeHandler( const ParametersList& ); + ~ROOTTreeHandler(); + + void initialise( const Parameters& ) override; + /// Writer operator + void operator<<( const Event& ) override; + void setCrossSection( double, double ) override; + + private: + std::unique_ptr file_; + std::unique_ptr run_tree_; + std::unique_ptr evt_tree_; + }; + + ROOTTreeHandler::ROOTTreeHandler( const ParametersList& params ) : + GenericExportHandler( "root" ), + file_( TFile::Open( params.get( "filename", "output.root" ).c_str(), "recreate" ) ), + run_tree_( new ROOT::CepGenRun ), evt_tree_( new ROOT::CepGenEvent ) + { + if ( !file_->IsOpen() ) + throw CG_FATAL( "ROOTTreeHandler" ) << "Failed to create the output file!"; + run_tree_->create(); + evt_tree_->create(); + } + + ROOTTreeHandler::~ROOTTreeHandler() + { + run_tree_->fill(); + file_->Write(); + } + + void + ROOTTreeHandler::initialise( const Parameters& params ) + { + run_tree_->litigious_events = 0; + run_tree_->sqrt_s = params.kinematics.sqrtS(); + } + + void + ROOTTreeHandler::operator<<( const Event& ev ) + { + evt_tree_->gen_time = ev.time_generation; + evt_tree_->tot_time = ev.time_total; + evt_tree_->np = 0; + for ( const auto& p : ev.particles() ) { + const cepgen::Particle::Momentum m = p.momentum(); + evt_tree_->rapidity[evt_tree_->np] = m.rapidity(); + evt_tree_->pt[evt_tree_->np] = m.pt(); + evt_tree_->eta[evt_tree_->np] = m.eta(); + evt_tree_->phi[evt_tree_->np] = m.phi(); + evt_tree_->E[evt_tree_->np] = p.energy(); + evt_tree_->m[evt_tree_->np] = p.mass(); + evt_tree_->pdg_id[evt_tree_->np] = p.integerPdgId(); + evt_tree_->parent1[evt_tree_->np] = ( p.mothers().size() > 0 ) ? *p.mothers().begin() : -1; + evt_tree_->parent2[evt_tree_->np] = ( p.mothers().size() > 1 ) ? *p.mothers().rbegin() : -1; + evt_tree_->status[evt_tree_->np] = (int)p.status(); + evt_tree_->stable[evt_tree_->np] = ( (short)p.status() > 0 ); + evt_tree_->charge[evt_tree_->np] = p.charge(); + evt_tree_->role[evt_tree_->np] = p.role(); + + evt_tree_->np++; + } + run_tree_->num_events += 1; + evt_tree_->fill(); + } + + void + ROOTTreeHandler::setCrossSection( double xsect, double xsect_err ) + { + run_tree_->xsect = xsect; + run_tree_->errxsect = xsect_err; + } + } +} + +REGISTER_IO_MODULE( root, ROOTTreeHandler ) diff --git a/test/TreeInfo.h b/CepGen/IO/ROOTTreeInfo.h similarity index 98% rename from test/TreeInfo.h rename to CepGen/IO/ROOTTreeInfo.h index 7d95027..b7082c7 100644 --- a/test/TreeInfo.h +++ b/CepGen/IO/ROOTTreeInfo.h @@ -1,201 +1,200 @@ -#ifndef Test_TreeInfo_h -#define Test_TreeInfo_h +#ifndef CepGen_IO_ROOTTreeInfo_h +#define CepGen_IO_ROOTTreeInfo_h #include "TFile.h" #include "TTree.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" #include #include +#include namespace ROOT { /// All useful information about a generation run class CepGenRun { public: static constexpr const char* TREE_NAME = "run"; ///< Output tree name double sqrt_s; ///< Centre of mass energy for beam particles double xsect; ///< Process cross section, in pb double errxsect; ///< Uncertainty on process cross section, in pb unsigned int num_events; ///< Number of events generated in run unsigned int litigious_events; ///< Number of litigious events in run CepGenRun() { clear(); } /// Reinitialise the run tree void clear() { sqrt_s = -1.; xsect = errxsect = -1.; num_events = litigious_events = 0; } /// Populate the run tree void create() { tree_ = std::make_shared( TREE_NAME, "a tree containing information on the previous run" ); if ( !tree_ ) throw std::runtime_error( "Failed to create the run TTree!" ); tree_->Branch( "xsect", &xsect, "xsect/D" ); tree_->Branch( "errxsect", &errxsect, "errxsect/D" ); tree_->Branch( "num_events", &num_events, "num_events/i" ); tree_->Branch( "litigious_events", &litigious_events, "litigious_events/i" ); tree_->Branch( "sqrt_s", &sqrt_s, "sqrt_s/D" ); } /// Retrieve the ROOT tree TTree* tree() { return tree_.get(); } /// Fill the run tree void fill() { tree_->Fill(); } /// Attach the run tree reader to a given file void attach( const char* filename, const char* run_tree = TREE_NAME ) { attach( TFile::Open( filename ), run_tree ); } /// Attach the run tree reader to a given tree void attach( TFile* file, const char* run_tree = TREE_NAME ) { //--- special constructor to avoid the memory to be cleared at destruction time tree_ = std::shared_ptr( dynamic_cast( file->Get( run_tree ) ), [=]( TTree* ){} ); if ( !tree_ ) throw std::runtime_error( "Failed to attach to the run TTree!" ); tree_->SetBranchAddress( "xsect", &xsect ); tree_->SetBranchAddress( "errxsect", &errxsect ); tree_->SetBranchAddress( "num_events", &num_events ); tree_->SetBranchAddress( "litigious_events", &litigious_events ); tree_->SetBranchAddress( "sqrt_s", &sqrt_s ); if ( tree_->GetEntriesFast() > 1 ) std::cerr << "The run tree has more than one entry." << std::endl; tree_->GetEntry( 0 ); } private: /// ROOT tree used for storage/retrieval of this run information std::shared_ptr tree_; }; /// All useful information about a generated event class CepGenEvent { public: // book a sufficienly large number to allow the large multiplicity // of excited proton fragmentation products static constexpr unsigned short maxpart = 5000; ///< Maximal number of particles in event static constexpr const char* TREE_NAME = "events"; ///< Output tree name float gen_time; ///< Event generation time float tot_time; ///< Total event generation time int nremn_ch[2], nremn_nt[2]; int np; ///< Number of particles in the event double pt[maxpart]; ///< Particles transverse momentum double eta[maxpart]; ///< Particles pseudo-rapidity double phi[maxpart]; ///< Particles azimutal angle double rapidity[maxpart]; ///< Particles rapidity double E[maxpart]; ///< Particles energy, in GeV double m[maxpart]; ///< Particles mass, in GeV/c\f${}^2\f$ double charge[maxpart]; ///< Particles charges, in e int pdg_id[maxpart]; ///< Integer particles PDG id int parent1[maxpart]; ///< First particles mother int parent2[maxpart]; ///< Last particles mother int stable[maxpart]; ///< Whether the particle must decay or not int role[maxpart]; ///< Particles role in the event int status[maxpart]; ///< Integer status code CepGenEvent() { clear(); } /// Reinitialise the event content void clear() { gen_time = tot_time = 0.; for ( unsigned short i = 0; i < 2; ++i ) nremn_ch[i] = nremn_nt[i] = 0; np = 0; for ( unsigned short i = 0; i < maxpart; ++i ) { pt[i] = eta[i] = phi[i] = rapidity[i] = E[i] = m[i] = charge[i] = 0.; pdg_id[i] = parent1[i] = parent2[i] = stable[i] = role[i] = status[i] = 0; } } /// Retrieve the ROOT tree TTree* tree() { return tree_.get(); } /// Fill the tree with a new event void fill() { if ( !tree_ ) throw std::runtime_error( "CepGenEvent: Trying to fill a non-existent tree!" ); tree_->Fill(); clear(); } /// Populate the tree and all associated branches void create() { tree_ = std::make_shared( TREE_NAME, "a tree containing information on events generated in previous run" ); if ( !tree_ ) throw std::runtime_error( "Failed to create the events TTree!" ); tree_->Branch( "npart", &np, "npart/I" ); tree_->Branch( "nremn_charged", nremn_ch, "nremn_charged[2]/I" ); tree_->Branch( "nremn_neutral", nremn_nt, "nremn_neutral[2]/I" ); tree_->Branch( "role", role, "role[npart]/I" ); tree_->Branch( "pt", pt, "pt[npart]/D" ); tree_->Branch( "eta", eta, "eta[npart]/D" ); tree_->Branch( "phi", phi, "phi[npart]/D" ); tree_->Branch( "rapidity", rapidity, "rapidity[npart]/D" ); tree_->Branch( "E", E, "E[npart]/D" ); tree_->Branch( "m", m, "m[npart]/D" ); tree_->Branch( "charge", charge, "charge[npart]/D" ); tree_->Branch( "pdg_id", pdg_id, "pdg_id[npart]/I" ); tree_->Branch( "parent1", parent1, "parent1[npart]/I" ); tree_->Branch( "parent2", parent2, "parent2[npart]/I" ); tree_->Branch( "stable", stable, "stable[npart]/I" ); tree_->Branch( "status", status, "status[npart]/I" ); tree_->Branch( "generation_time", &gen_time, "generation_time/F" ); tree_->Branch( "total_time", &tot_time, "total_time/F" ); } /// Attach the event tree reader to a given file void attach( const char* filename, const char* events_tree = TREE_NAME ) { file_.reset( TFile::Open( filename ) ); attach( file_.get(), events_tree ); } /// Attach the event tree reader to a given ROOT file void attach( TFile* f, const char* events_tree = TREE_NAME ) { //--- special constructor to avoid the memory to be cleared at destruction time tree_ = std::shared_ptr( dynamic_cast( f->Get( events_tree ) ), [=]( TTree* ){} ); attach(); } /// Attach the event tree reader to a given tree void attach() { if ( !tree_ ) throw std::runtime_error( "Failed to attach to the events TTree!" ); tree_->SetBranchAddress( "npart", &np ); tree_->SetBranchAddress( "nremn_charged", nremn_ch ); tree_->SetBranchAddress( "nremn_neutral", nremn_ch ); tree_->SetBranchAddress( "role", role ); tree_->SetBranchAddress( "pt", pt ); tree_->SetBranchAddress( "eta", eta ); tree_->SetBranchAddress( "phi", phi ); tree_->SetBranchAddress( "rapidity", rapidity ); tree_->SetBranchAddress( "E", E ); tree_->SetBranchAddress( "m", m ); tree_->SetBranchAddress( "charge", charge ); tree_->SetBranchAddress( "pdg_id", pdg_id ); tree_->SetBranchAddress( "parent1", parent1 ); tree_->SetBranchAddress( "parent2", parent2 ); tree_->SetBranchAddress( "stable", stable ); tree_->SetBranchAddress( "status", status ); tree_->SetBranchAddress( "generation_time", &gen_time ); tree_->SetBranchAddress( "total_time", &tot_time ); } private: /// Tree for which the event is booked std::shared_ptr tree_; std::unique_ptr file_; }; } constexpr const char* ROOT::CepGenRun::TREE_NAME; constexpr const char* ROOT::CepGenEvent::TREE_NAME; #endif diff --git a/cmake/UseEnvironment.cmake b/cmake/UseEnvironment.cmake index 6114b63..8705392 100644 --- a/cmake/UseEnvironment.cmake +++ b/cmake/UseEnvironment.cmake @@ -1,84 +1,86 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.1) set(CMAKE_CXX_STANDARD 14) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") endif() set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wall -cpp") #--- check if we are at CERN if($ENV{HOSTNAME} MATCHES "^lxplus[0-9]+.cern.ch") set(IS_LXPLUS "yes") endif() #--- ensure a proper version of the compiler is found if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.1) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic-errors -g") else() message(STATUS "clang or gcc above 6.1 is required") if(IS_LXPLUS) set(LXPLUS_SRC_ENV "source ${CMAKE_SOURCE_DIR}/source-lxplus.sh") message(STATUS "Compiling on LXPLUS. Did you properly source the environment variables? E.g.\n\n\t${LXPLUS_SRC_ENV}\n") endif() message(FATAL_ERROR "Please clean up this build environment, i.e.\n\trm -rf CMake*\nand try again...") endif() #--- set the default paths for external dependencies if(IS_LXPLUS) set(BASE_DIR "/cvmfs/sft.cern.ch/lcg") list(APPEND CMAKE_PREFIX_PATH "${BASE_DIR}/external/CMake/2.8.9/Linux-i386/share/cmake-2.8/Modules") set(GSL_DIR "${BASE_DIR}/releases/GSL/2.5-32fc5/x86_64-centos7-gcc62-opt") set(HEPMC_DIR "${BASE_DIR}/releases/HepMC/2.06.09-0a23a/x86_64-centos7-gcc62-opt") set(LHAPDF_DIR "${BASE_DIR}/releases/MCGenerators/lhapdf/6.2.2-8a3e6/x86_64-centos7-gcc62-opt") set(PYTHIA6_DIR "${BASE_DIR}/releases/MCGenerators/pythia6/429.2-c4089/x86_64-centos7-gcc62-opt") set(PYTHIA8_DIR "${BASE_DIR}/releases/MCGenerators/pythia8/240p1-ecd34/x86_64-centos7-gcc62-opt") set(PYTHON_DIR "${BASE_DIR}/releases/Python/2.7.15-075d4/x86_64-centos7-gcc62-opt") set(PYTHON_LIBRARY "${PYTHON_DIR}/lib/libpython2.7.so") set(PYTHON_EXECUTABLE "${PYTHON_DIR}/bin/python") set(PYTHON_INCLUDE_DIR "${PYTHON_DIR}/include/python2.7") message(STATUS "Compiling on LXPLUS. Do not forget to source the environment variables!") message(STATUS "e.g. `${LXPLUS_SRC_ENV}`") endif() #--- searching for GSL find_library(GSL_LIB gsl HINTS ${GSL_DIR} PATH_SUFFIXES lib REQUIRED) find_library(GSL_CBLAS_LIB gslcblas HINTS ${GSL_DIR} PATH_SUFFIXES lib) find_path(GSL_INCLUDE gsl HINTS ${GSL_DIR} PATH_SUFFIXES include) include_directories(${GSL_INCLUDE}) #--- searching for LHAPDF find_library(LHAPDF LHAPDF HINTS ${LHAPDF_DIR} PATH_SUFFIXES lib) find_path(LHAPDF_INCLUDE LHAPDF HINTS ${LHAPDF_DIR} PATH_SUFFIXES include) #--- searching for HepMC find_library(HEPMC_LIB NAMES HepMC3 HepMC HINTS ${HEPMC_DIR} PATH_SUFFIXES lib) find_library(HEPMC_ROOT_LIB NAMES HepMC3rootIO PATH_SUFFIXES root) find_path(HEPMC_INCLUDE NAMES HepMC3 HepMC HINTS ${HEPMC_DIR} PATH_SUFFIXES include) #--- searching for Pythia 6 set(PYTHIA6_DIRS $ENV{PYTHIA6_DIR} ${PYTHIA6_DIR} /usr /usr/local /opt/pythia6) find_library(PYTHIA6 pythia6 HINTS ${PYTHIA6_DIRS} PATH_SUFFIXES lib) find_library(PYTHIA6DUMMY pythia6_dummy HINTS ${PYTHIA6_DIRS} PATH_SUFFIXES lib) #--- searching for Pythia 8 set(PYTHIA8_DIRS $ENV{PYTHIA8_DIR} ${PYTHIA8_DIR} /usr /usr/local /opt/pythia8) find_library(PYTHIA8 pythia8 HINTS ${PYTHIA8_DIRS} PATH_SUFFIXES lib) find_path(PYTHIA8_INCLUDE Pythia8 HINTS ${PYTHIA8_DIRS} PATH_SUFFIXES include include/Pythia8 include/pythia8) +#--- searching for ROOT +find_package(ROOT QUIET) message(STATUS "GSL found in ${GSL_LIB}") list(APPEND CEPGEN_EXTERNAL_CORE_REQS ${GSL_LIB} ${GSL_CBLAS_LIB}) find_package(PythonLibs 2.7) find_library(MUPARSER muparser) if(MUPARSER) message(STATUS "muParser found in ${MUPARSER}") list(APPEND CEPGEN_EXTERNAL_CORE_REQS ${MUPARSER}) add_definitions(-DMUPARSER) else() find_path(EXPRTK exprtk.hpp PATH_SUFFIXES include) if(EXPRTK) message(STATUS "exprtk found in ${EXPRTK}") add_definitions(-DEXPRTK) include_directories(${EXPRTK}) endif() endif() #--- semi-external dependencies set(ALPHAS_PATH ${PROJECT_SOURCE_DIR}/External) file(GLOB alphas_sources ${ALPHAS_PATH}/alphaS.f) if(alphas_sources) message(STATUS "alphaS evolution found in ${alphas_sources}") add_definitions(-DALPHA_S) endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 867ae34..16b6510 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,53 +1,52 @@ #----- list all test executables file(GLOB executables_noroot RELATIVE ${PROJECT_SOURCE_DIR}/test *.cpp) file(GLOB executables_root RELATIVE ${PROJECT_SOURCE_DIR}/test *.cxx) file(GLOB executables_fortran RELATIVE ${PROJECT_SOURCE_DIR}/test *.f) #----- include the utilitaries set(tests "") #----- build all tests and link them to the core library foreach(exec_src ${executables_noroot}) string(REPLACE ".cpp" "" exec_bin ${exec_src}) add_executable(${exec_bin} ${exec_src}) set_target_properties(${exec_bin} PROPERTIES EXCLUDE_FROM_ALL true) target_link_libraries(${exec_bin} ${CEPGEN_LIBRARIES}) list(APPEND tests ${exec_bin}) endforeach() foreach(exec_src ${executables_fortran}) string(REPLACE ".f" "" exec_bin ${exec_src}) add_executable(${exec_bin} ${exec_src}) set_target_properties(${exec_bin} PROPERTIES EXCLUDE_FROM_ALL true) target_link_libraries(${exec_bin} ${CEPGEN_LIBRARIES}) list(APPEND tests ${exec_bin}) endforeach() #----- specify the tests requiring ROOT -find_package(ROOT QUIET) if(ROOT_FOUND) include_directories(${ROOT_INCLUDE_DIRS}) link_directories(${ROOT_LIBRARY_DIR}) foreach(exec_src ${executables_root}) string(REPLACE ".cxx" "" exec_bin ${exec_src}) add_executable(${exec_bin} ${exec_src}) set_target_properties(${exec_bin} PROPERTIES EXCLUDE_FROM_ALL true) target_link_libraries(${exec_bin} ${CEPGEN_LIBRARIES} ${ROOT_LIBRARIES}) list(APPEND tests ${exec_bin}) endforeach() else() message(STATUS "ROOT not found! skipping these tests!") endif() message(STATUS "The following tests/executables are available:\n${tests}") file(GLOB_RECURSE test_input_cards RELATIVE ${PROJECT_SOURCE_DIR}/test test_processes/* __init__.py) foreach(_files ${test_input_cards}) configure_file(${_files} ${_files} COPYONLY) endforeach() configure_file(${PROJECT_SOURCE_DIR}/test/test_processes.cfg test_processes.cfg COPYONLY) diff --git a/test/cepgen-root.cxx b/test/cepgen-root.cxx deleted file mode 100644 index d40ced3..0000000 --- a/test/cepgen-root.cxx +++ /dev/null @@ -1,116 +0,0 @@ -#include "CepGen/Cards/Handler.h" -#include "CepGen/Generator.h" -#include "CepGen/Event/Event.h" - -#include -#include - -#include "TreeInfo.h" -#include "AbortHandler.h" - -// ROOT includes -#include "TFile.h" -#include "TTree.h" -#include "TLorentzVector.h" - -using namespace std; - -std::unique_ptr run; -std::unique_ptr ev; - -void fill_event_tree( const cepgen::Event& event, unsigned long ev_id ) -{ - //if ( ev_id % 10 == 0 ) - // cout << ">> event " << ev_id << " generated" << endl; - - if ( !ev || !run ) - return; - - ev->gen_time = event.time_generation; - ev->tot_time = event.time_total; - ev->np = 0; - //cout << event.particles().size() << endl; - for ( const auto& p : event.particles() ) { - const cepgen::Particle::Momentum m = p.momentum(); - ev->rapidity[ev->np] = m.rapidity(); - ev->pt[ev->np] = m.pt(); - ev->eta[ev->np] = m.eta(); - ev->phi[ev->np] = m.phi(); - ev->E[ev->np] = p.energy(); - ev->m[ev->np] = p.mass(); - ev->pdg_id[ev->np] = p.integerPdgId(); - ev->parent1[ev->np] = ( p.mothers().size() > 0 ) ? *p.mothers().begin() : -1; - ev->parent2[ev->np] = ( p.mothers().size() > 1 ) ? *p.mothers().rbegin() : -1; - ev->status[ev->np] = (int)p.status(); - ev->stable[ev->np] = ( (short)p.status() > 0 ); - ev->charge[ev->np] = p.charge(); - ev->role[ev->np] = p.role(); - - ev->np++; - } - run->num_events += 1; - ev->fill(); -} - -/** - * Generation of events and storage in a ROOT format - * \author Laurent Forthomme - * \date 27 jan 2014 - * \defgroup Executables List of executables - * \addtogroup Executables - */ -int main( int argc, char* argv[] ) -{ - cepgen::utils::AbortHandler ctrl_c; - - cepgen::Generator mg; - - if ( argc < 2 ) - throw CG_FATAL( "main" ) << "Usage: " << argv[0] << " input-card [filename=events.root]"; - - mg.setParameters( cepgen::card::Handler::parse( argv[1] ) ); - CG_INFO( "main" ) << mg.parametersPtr(); - - //----- open the output root file - - const char* filename = ( argc > 2 ) ? argv[2] : "events.root"; - TFile file( filename, "recreate" ); - if ( !file.IsOpen() ) - throw CG_FATAL( "main" ) << "Failed to create the output file!"; - - //----- then generate the events and the container tree structure - - run.reset( new ROOT::CepGenRun ); - run->create(); - ev.reset( new ROOT::CepGenEvent ); - ev->create(); - - try { - //----- start by computing the cross section for the list of parameters applied - double xsec, err; - mg.computeXsection( xsec, err ); - - //----- populate the run tree - - run->xsect = xsec; - run->errxsect = err; - run->litigious_events = 0; - run->sqrt_s = mg.parameters().kinematics.sqrtS(); - - //----- launch the events generation - mg.generate( fill_event_tree ); - run->fill(); - } catch ( const cepgen::utils::RunAbortedException& e ) { - e.dump(); - } catch ( const cepgen::Exception& e ) { - e.dump(); - } - - file.Write(); - CG_INFO( "main" ) - << run->num_events << " event" << cepgen::utils::s( run->num_events ) - << " written in \"" << filename << "\"."; - - return 0; -} -