Hello World in the Gaudi Framework
Gaudi in LHCb
- "Learn how to write a simple test Gaudi program."
Hello World in Gaudi
The following is a minimum example to build an algorithm in Gaudi as a new package. This code is part of this repository, in /code/GaudiMinimal
. If you don't have this repository cloned already, the following line will just get the project you need for this lesson:1
local:~ $ svn export https://github.com/lhcb/starterkit-lessons/trunk/first-development-steps/code/GaudiMinimal GaudiMinimal
Project
First, you will need a Gaudi project. The example was setup to match the way that most Gaudi projects work, with packages inside. This is the recommended directory structure for this example:
└── GaudiMinimal
├── CMakeLists.txt
└── GaudiHelloWorld
├── CMakeLists.txt
├── src
│ ├── HelloWorld.cpp
│ └── HelloWorld.h
└── options
└── gaudi_opts.py
Here is an example top-level CMakeLists.txt
for a new LHCb package:
cmake_minimum_required(VERSION 2.8.5)
find_package(GaudiProject)
gaudi_project(GaudiMinimal v1r0
USE Gaudi v27r1)
This first line sets the CMake version, and the second loads the GaudiProject CMake module. Then a new project (GaudiMinimal
) is declared, and Gaudi is set as a dependency. Gaudi automatically looks for directories in the current one for packages. This is done because it makes it simple to grab a few packages, and they are automatically picked up by the project, and if the rest of the project is built and ready elsewhere in the path, the local and remote portions are combined. This makes
it easy to build a small piece of a project with rebuilding the entire project, or add a piece to a project.
Note about organization
A further organizational tool are project groups; which are simply one more layer of folders. We don't need it for this project, but to add it is as simple as adding one more directory to the path. No extra CMakeLists are needed. It is commonly used to factor out common code between multiple projects, with the subprojects living in separate git repositories. For an often out of date but useful description, see this TWiki page.
An example of this would be writing an Algorithm for DaVinci; DaVinci is the project, Phys is the subproject, and SomeDaVinciPackage could be the package you are working on, and is the only piece you need to clone in git. The code lives in the Phys git repository, which means it could be used by other projects too.
The package needs to be created in the GaudiHelloWorld
subdirectory, and has a CMakeLists.txt that looks like this:
cmake_minimum_required(VERSION 2.8.5)
gaudi_subdir(GaudiHelloWorld)
gaudi_add_module(GaudiHelloWorld src/*.cpp
LINK_LIBRARIES GaudiAlg)
This is tagged as a Gaudi subdirectory. The module we are making is added as GaudiHelloWorld
, and linked to the Gaudi Kernel. More advanced algorithms may need to be linked to more libraries, including some that are discovered by find_package
.
The header file
To create an algorithm, the following header file is used:
#pragma once
#include "GaudiAlg/GaudiAlgorithm.h"
class HelloWorldEx : public GaudiAlgorithm {
public:
HelloWorldEx(const std::string& name, ISvcLocator* pSvcLocator);
StatusCode initialize() override;
StatusCode execute() override;
StatusCode finalize() override;
};
This creates a new algorithm, and overrides all five of the user-accessible functions. Many algorithms will not need to override all of these. The constructor is needed primarily to delegate to the Algorithm constructor, and is also needed if you want to use it to initialize member variables.
Note on inheriting constructorsClick to expand
The implementation
The implementation is simple:
#include "HelloWorldEx.h"
#include "GaudiKernel/MsgStream.h"
DECLARE_COMPONENT(HelloWorldEx)
Here, we include our header file and use the DECLARE_COMPONENT
macro to register this as a Gaudi factory in Gaudi's Registry singleton.
HelloWorldEx::HelloWorldEx(const std::string& name, ISvcLocator* ploc) :
Algorithm(name, ploc) {
}
The only requirement for the constructor is to pass on the two arguments to the Algorithm constructor, written here with C++ forwarding syntax. Any code here will be run when the C++ object is created, so can be used for local initialization. If you don't need a constructor, be sure you delegate to the base class constructor, either explicitly as is done here or with the using
statement noted above.
StatusCode HelloWorldEx::initialize() {
StatusCode sc = Algorithm::initialize();
if(sc.isFailure() ) return sc;
info() << "Hello World: Inilializing..." << endmsg;
return StatusCode::SUCCESS;
}
This is an optional initialization method. If run, it should first call the base class's initialize method, and return the status code if it was not successful. After that, any initialization code you may need can be added. In this example, we are simply printing a message.
StatusCode HelloWorldEx::execute() {
info() << "Hello World: Executing..." << endmsg;
return StatusCode::SUCCESS;
}
This is the execute method. It will run once per event. This usually is the most important method, and ideally is the only one present. Most of the other methods break the concept of stateless algorithms, making this hard to move into a multithreaded framework.
StatusCode HelloWorldEx::finalize() {
info() << "Hello World: Finalizing..." << endmsg;
return Algorithm::finalize(); // must be executed last
}
This is the final method. If you do implement it, you should end by passing on to the base class finalize method.
Performing the run
An example gaudi_opts.py
options file that uses our algorithm:
from Gaudi.Configuration import *
from Configurables import HelloWorldEx
alg = HelloWorldEx()
ApplicationMgr(
EvtMax = 10,
EvtSel = 'NONE',
HistogramPersistency = 'NONE',
TopAlg = [alg],
)
We first import from the magic Configurables
module, which contains our algorithm(s).
The EvtSel = 'NONE'
statement sets the input events to none, since we are not running over a real data file or detector.
We then set up the Gaudi application manager, with the settings that we need and with a list of algorithms, which in this case is just one. We could also append algorithms to .TopAlg
on the application manager instance.
To run, the following commands can be used on LXPlus:
local:~ $ cd GaudiMinimal
local:GaudiMinimal $ lb-project-init
local:GaudiMinimal $ make
local:GaudiMinimal $ ./build.x86_64-slc6-gcc49-opt/run gaudirun.py GaudiHelloWorld/options/gaudi_opts.py
# setting LC_ALL to "C"
# --> Including file '/afs/cern.ch/user/w/whoami/tmp/GaudiMinimal/GaudiHelloWorld/options/gaudi_opts.py'
# <-- end="" of="" file="" '="" afs="" cern.ch="" user="" w="" whoami="" tmp="" gaudiminimal="" gaudihelloworld="" options="" gaudi_opts.py'<="" span="">
-->ApplicationMgr SUCCESS
====================================================================================
Welcome to GaudiMinimal version v1r0
running on lxplus001 on Fri Nov 11 15:43:06 2016
====================================================================================
ApplicationMgr INFO Application Manager Configured successfully
HelloWorldEx INFO Hello World: Inilializing...
EventLoopMgr WARNING Unable to locate service "EventSelector"
EventLoopMgr WARNING No events will be processed from external input.
HistogramPersis...WARNING Histograms saving not required.
ApplicationMgr INFO Application Manager Initialized successfully
ApplicationMgr INFO Application Manager Started successfully
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
HelloWorldEx INFO Hello World: Executing...
ApplicationMgr INFO Application Manager Stopped successfully
HelloWorldEx INFO Hello World: Finalizing...
EventLoopMgr INFO Histograms converted successfully according to request.
ApplicationMgr INFO Application Manager Finalized successfully
ApplicationMgr INFO Application Manager Terminated successfully
You should be able to see your algorithm running, and the output at the various points.
Further reading
There are further examples in the Gaudi repository: Gaudi/GaudiExamples/src.
1. Yes, this is checking out GitHub repository. With SVN. ↩