The C++ Code

Suppose we have created a package named FirstAlg, and we want to define an algorithm with the same name. The necessary work includes,

  • define a C++ class named FirstAlg, which is inherited from the AlgBase class;
  • define a constructor, which takes a string parameter;
  • implement the 3 abstract methods in base class, initialize(), execute() and finalize(); The bool return value indicates the execution status. If there is any error, the return value should be false, and the application will be stopped.

Class defination

In the example, we will also involve the properties, which are defined as the data members of the algorithm class.

The contents of the header file (FirstAlg.h),

// file FirstAlg.h
#ifndef FIRST_ALG_H
#define FIRST_ALG_H

#include "SniperKernel/AlgBase.h"  //the AlgBase defination

class FirstAlg : public AlgBase
{
    public:
        FirstAlg(const std::string& name);  //constructor

        bool initialize();
        bool execute();
        bool finalize();

    private:
        unsigned int  m_count;  //the count of event loop
        int           m_value;  //an int property
        std::string   m_msg;    //a string property
};
#endif

Algorithm declaration

An algorithm must be declared in SNiPER, so that it can be registered into the framework when the module is loaded. This is done by a macro DECLARE_ALGORITHM, which takes the algorithm class name as its parameter. It's recommended to put the declaration at the beginning of the source file.

DECLARE_ALGORITHM(FirstAlg);

Properties

Properties are the C++ variables that configurable in Python at run time. In an algorithm, a property can be declared by the declProp() method. This method takes 2 parameters, the first is the name of the property, and the second is its correlated variable.

The following variable types can be declared as properties,

  • scalar: C++ build in types and std::string;
  • std::vector with scalar element type
  • std::map with scalar key type and scalar value type

The properties have to be declared in the constructor. We can set a default value while the declaration. For example,

declProp("TheValue", m_value = 1);

Logs

We can print any message via SniperLog just like the std::cout.

LogDebug << "in the FirstAlg::execute()" << std::endl;

The corresponding message on the screen is,

task:FirstAlg.execute         DEBUG: in the FirstAlg::execute()

At the beginning, it shows this is a log printed in the execute() method of FirstAlg. Then, it is an indicator of the log level. And finally it is the log content.

There are 6 log levels in SNiPER. From lowest to highest they are,

  • 0: LogTest, the indicator is "TEST";
  • 2: LogDebug, the indicator is "DEBUG";
  • 3: LogInfo, the indicator is "INFO";
  • 4: LogWarn, the indicator is "WARN", means this is a warning message;
  • 5: LogError, the indicator is "ERROR";
  • 6: LogFatal, the indicator is "FATAL";

We can set the log level globally via Task, or set a different log level to each DLE component. Then the logs with lower levels will not shown on the screen.

The implementation

We put the contents together. Here is the implementation of the source file (FirstAlg.cc),

// file FirstAlg.cc
#include "FirstAlg.h"
#include "SniperKernel/AlgFactory.h"  //the macro DECLARE_ALGORITHM

DECLARE_ALGORITHM(FirstAlg);

FirstAlg::FirstAlg(const std::string& name)
    : AlgBase(name),
      m_count(0)
{
    declProp("TheValue", m_value = 1);
    declProp("Message",  m_msg);
}

bool FirstAlg::initialize()
{
    LogDebug << "in the FirstAlg::initialize()" << std::endl;
    return true;
}

bool FirstAlg::execute()
{
    LogDebug << "in the FirstAlg::execute()" << std::endl;

    ++m_count;
    m_value *= m_count;
    LogInfo << "Loop " << m_count << m_msg << m_value << std::endl;

    return true;
}

bool FirstAlg::finalize()
{
    LogDebug << "in the FirstAlg::finalize()" << std::endl;
    return true;
}

results matching ""

    No results matching ""