KaliVeda
Toolkit for HIC analysis
|
KaliVeda provides a class which can write source code for other classes: KVClassFactory. At its simplest, only a class name and short description are required in order to generate a fully ROOT-compatible class from the KaliVeda command line. Giving a base class to derive your new class from will copy and implement all constructors from the base class:
will generate the following MyClass.h
and MyClass.cpp
files which includes a template doxygen comment block for documenting your class (not shown):
You can also add methods to your class before generating the code, or use template files to define complicated methods which can be reused in many classes. See the KVClassFactory documentation and associated examples.
The header file KVConfig.h which is configured and generated at build time contains several symbols which may be of help when writing your own code using KaliVeda. KVConfig.h is #include
d by most class headers in the toolkit; in case of doubt, just add #include "KVConfig.h"
in your code.
The following symbols are mainly to ensure portability of code:
Symbol | Meaning/Function |
---|---|
External software | |
WITH_GEMINI | GEMINI++ interface KVGemini exists (see Optional software) |
WITH_ZMQ | compiled with ZeroMQ support (KVZMQMessage) |
WITH_MFM | can read GANIL MFM format data (KVMFMDataFileReader) |
WITH_BOOST | compiled with boost library support |
WITH_MESYTEC | can read Mesytec acquisition data |
WITH_PROTOBUF | can read Google Proto Buffer data (KVProtobufDataReader) |
WITH_RSQLITE | has SQLite interfaces (KVSQLite::database, KVSQLROOTFile) |
WITH_BUILTIN_GRU | can read legacy GANIL EBYEDAT format data (KVGANILDataReader) |
Hardware | |
WITH_MULTICORE_CPU | integer value equal to number of processors/cores |
C++ standard | |
WITH_CPP11 | C++11 language can be used |
WITH_CPP14 | C++14 & C++11 language can be used |
WITH_CPP17 | C++17,C++14 & C++11 can be used |
WITH_CPP20 | C++20, C++17,C++14 & C++11 can be used |
If you want/need to compile code using the toolkit in stand-alone mode, you can use the kaliveda-config tool in order to obtain the necessary installation-dependent paths to header files and libraries. Given the following code:
this can be compiled and linked into an executable using the following command:
(we assume the g++ compiler; in reality you should use whatever compiler was used to compile ROOT, i.e. the result of root-config --cxx
). Running the executable produces:
Note that the above commands include also the required paths and libraries from ROOT, and are equivalent to
The compilation method given just above is unwieldy for anything more than a simple executable. It cannot be used to make shared libraries containing your own classes, for which you would also need to generate the associated ROOT dictionaries, etc.. Therefore we provide modules which enable KaliVeda to be used with the CMake build system.
Given the MyCode.cpp
file above, the same executable can be built using cmake
with the following configuration file CMakeLists.txt
:
Configuration of the build then proceeds like this (note that we strongly discourage in-source builds, the following is just a simplified example):
After which your code can be compiled like so (note we are assuming a Unix Makefile build generator):
Assuming you have a directory with class source files and a LinkDef.h
file like this:
myProj/ class1.h class1.cpp class2.h class2.cpp LinkDef.h
the minimum cmake-based project to build and install the shared library and other necessary files will look like this:
[myProj/CMakeLists.txt:] cmake_minimum_required (VERSION 3.5) project(myProj) #------- locate KaliVeda installation find_package(KaliVeda REQUIRED) include(${KALIVEDA_USE_FILE}) #------- locate ROOT installation find_package(ROOT REQUIRED) include(SetUpROOTBuild) #------- set up standard GNU installation directories include(GNUInstallDirs) #------- use KaliVeda-provided CMake module for ROOT dictionary & library generation include(GenerateRootLibrary) GENERATE_ROOT_LIBRARY(myProj DEPENDENCIES ${KALIVEDA_LIBRARIES} ${ROOT_LIBRARIES})
Note that find_package(KaliVeda)
is called before find_package(ROOT)
: this is so that the KaliVeda modules are used to find ROOT on the system, instead of whatever default modules were installed by ROOT. This ensures transparent operation with either ROOT 5 or ROOT 6. If you inverse the order, it might work with certain versions of ROOT but not all.
To build and install this project, make a fresh build directory somewhere outside the source tree and do:
cmake [path to myProj]/myProj -DCMAKE_INSTALL_PREFIX=[where you want to install] make [-jN] install
with -jN
for parallel building on an N-core machine.
The resulting installation will look like this:
[installation prefix]/ lib/ libmyProj.so libmyProj.rootmap libmyProj_rdict.pcm include/ class1.h class2.h
You may need to explicitly require that certain ROOT libraries are available in order for CMake to link them with your library, e.g.: if you get errors like undefined reference to typeinfo for TChain
and similar ones for TH1
and TFile
, then you need to specify the corresponding libraries in the call to find_package(ROOT)
like so:
find_package(ROOT REQUIRED Tree Hist RIO)
using the name of each lib[Name].so
which contains the undefined classes: Tree
for libTree.so
(TChain
), Hist
for libHist.so
(TH1
) and RIO
for libRIO.so
(TFile
).
You could even have several directories corresponding to different libraries. No problem, do it like this:
myProj/ CMakeLists.txt myLib1/ class1.h class1.cpp class2.h class2.cpp CMakeLists.txt LinkDef.h
In the top-level CMakeLists.txt
:
[myProj/CMakeLists.txt:] cmake_minimum_required (VERSION 3.5) project(myProj) #------- locate KaliVeda installation find_package(KaliVeda REQUIRED) include(${KALIVEDA_USE_FILE}) #------- locate ROOT installation find_package(ROOT REQUIRED) include(SetUpROOTBuild) #------- set up standard GNU installation directories include(GNUInstallDirs) #------- build library myLib1 add_subdirectory(myLib1)
And in the library directory:
[myProj/myLib1/CMakeLists.txt:] include(GenerateRootLibrary) GENERATE_ROOT_LIBRARY(myLib1 DEPENDENCIES ${KALIVEDA_LIBRARIES} ${ROOT_LIBRARIES})
Usage:
find_package(KaliVeda [version] [EXACT] # Minimum or EXACT version e.g. 1.13.01 [REQUIRED] # Fail with error if KaliVeda not found [[COMPONENTS] <modules/libs>...] # Required specific components, either modules or libraries (see below) [OPTIONAL_COMPONENTS <modules/libs>] # Optional component libraries or modules (see below) )
Search for an installation of KaliVeda on the system, optionally specifying the version and/or specific components. The components can be either one of the main subprojects which are enabled or disabled using the -DUSE_<comp> switches (see [[CMake options|Build-system#cmake-options]]: e.g. INDRA, FAZIA, BACKTRACK, etc.), or the name of a specific library target (see [[library targets|Build-system#library-targets]]: e.g. KVMultiDetbase, MicroStatmontecarlo, etc.)
Results of the search are reported in the following variables:
KaliVeda_FOUND - True if a compatible version with all required components was found KaliVeda_<comp>_FOUND - True if specific component was found KALIVEDA_USE_FILE - Path to file to be included by top-level project KALIVEDA_INCLUDE_DIR - Path to installed header files KALIVEDA_LIB_DIR - Path to installed libraries KALIVEDA_BIN_DIR - Path to installed executables KALIVEDA_CMAKEPKG_DIR - Path to CMake modules installed by KaliVeda KALIVEDA_LIBRARIES - List of all installed library targets for linking
In most cases it is sufficient to include the file given by KALIVEDA_USE_FILE
in order to compile and link your code with the KaliVeda libraries, and use the other CMake modules we provide (see below):
find_package(KaliVeda REQUIRED) include(${KALIVEDA_USE_FILE}) add_executable(toto [your sources]) target_link_libraries(toto ${KALIVEDA_LIBRARIES} ${ROOT_LIBRARIES})
Note that ${ROOT_LIBRARIES}
contains only the core ROOT libraries if no ROOT components are explicitly requested in the call to find_package(ROOT)
. Any other required libraries should be explicitly requested (e.g. find_package(ROOT REQUIRED Hist)
in order to link with libHisto.so
). Another solution to the problem may be to just link with ${KALIVEDA_LIBRARIES}
, as the KaliVeda libraries are themselves linked with many more than just the core ROOT libraries.
Usage:
GENERATE_ROOT_LIBRARY(<libname> [DICT_EXCLUDE Class1.h Class2.h ...] # header files of classes to exclude from the dictionary [LIB_EXCLUDE Class1 Class2 ...] # classes which should not be compiled [DEPENDENCIES lib1 lib2 ...] # other libraries this library depends on )
This macro can generate a ROOT dictionary (using rootcint or rootcling depending on ROOT version 5 or 6), shared library and rootmap file (plus the pcm file for ROOT6). The CMakeLists.txt
file invoking this macro should be in the same directory as the source files, plus the LinkDef.h
, i.e. a layout such as:
some_dir/ CMakeLists.txt Class1.h Class1.cpp Class2.h Class2.cpp LinkDef.h
The CMakeLists.txt
file should contain at least the following:
include(GenerateRootLibrary) GENERATE_ROOT_LIBRARY(MyLib)
where we have assumed that some top-level CMakeLists.txt
contains the necessary calls to find_package(...
etc. in order to set up the necessary CMake module search paths (see above).
The resulting library libMyLib.so
and its rootmap file libMyLib.rootmap
(plus the libMyLib_rdict.pcm
file if ROOT6 is used) will be installed in paths defined by ${CMAKE_INSTALL_LIBDIR}
, while the class headers will be installed in paths defined by ${CMAKE_INSTALL_INCLUDEDIR}
. These variables are not defined by default, you must make sure they are defined before calling GenerateRootLibrary
, for example
set(CMAKE_INSTALL_LIBDIR lib) set(CMAKE_INSTALL_INCLUDEDIR include/MyLib) ... GENERATE_ROOT_LIBRARY(MyLib)
then the final installation locations will be ${CMAKE_INSTALL_PREFIX}/lib
and ${CMAKE_INSTALL_PREFIX}/include/MyLib
.
Another way to set up the installation paths is to use the standard CMake module GNUInstallDirs
([[see here|https://cmake.org/cmake/help/v2.8.11/cmake.html::module:GNUInstallDirs]]). This will define standard GNU-type values for all the CMAKE_INSTALL_*
variables.
Don't forget that with ROOT6 you will need to add the path to the header files to environment variable ROOT_INCLUDE_PATH
at runtime (i.e. before trying to use the shared library in a ROOT session).