Warning, /tutorial-reconstruction-algorithms/_episodes/05-adding-an-algorithm.md is written in an unsupported language. File is not indexed.
0001 ---
0002 title: "Adding an algorithm"
0003 teaching: 5
0004 exercises: 1
0005 objectives:
0006 - "Understand the difference between a factory and an algorithm"
0007 - "Understand where to put the algorithm code"
0008 - "Understand the basic algorithm interface"
0009 - "Understand how to call an algorithm from a factory"
0010 ---
0011
0012 ## The difference between a factory and an algorithm
0013
0014 *Algorithms* are classes that perform one kind of calculation we need and they do so in a generic, framework-independent way. The core of an Algorithm is a method called `execute` which inputs some PODIO collections and outputs some other PODIO collections. Algorithms don't know or care where the inputs come from and where they go. Algorithms also don't know much about where their parameters come from; rather, they are passed a `Config` structure which contains the parameters' values. The nice thing about algorithms is that they are simple to design and test, and easy to reuse for different detectors, frameworks, or even entire experiments.
0015
0016
0017 Most of what makes an Algorithm an Algorithm is convention. (These are largely inspired by the KISS principle in software engineering!) There is an ongoing effort to create a "framework-less framework" for formally expressing Algorithms using templates, which lives at https://github.com/eic/algorithms. Eventually, we may encourage users to have all Algorithms inherit from the `Algorithm<Input<...>, Output<...>>` templated interface. For now, however, just follow the Algorithm conventions that we will go over next.
0018
0019 ## Where to put the algorithm code
0020
0021 All algorithms that are not specific to a single detector should go under `src/algorithms`. Because this falls in the category of reconstruction, we'll put it in `src/algorithms/reco`.
0022
0023
0024 ## The basic algorithm interface
0025
0026 Here is a template for an algorithm header file:
0027
0028 ~~~ c++
0029
0030 #pragma once
0031
0032 // #include relevant header files here
0033
0034 namespace eicrecon {
0035
0036 class MyAlgorithmName {
0037
0038 public:
0039
0040 // init function contains any required initialization
0041 void init();
0042
0043 // execute function contains main algorithm processes
0044 // (e.g. manipulate existing objects to create new objects)
0045 std::unique_ptr<MyReturnDataType> execute();
0046
0047 // Any additional public members go here
0048
0049 private:
0050 std::shared_ptr<spdlog::logger> m_log;
0051 // any additional private members (e.g. services and calibrations) go here
0052
0053 };
0054 } // namespace eicrecon
0055
0056 ~~~
0057
0058 ## How to call an algorithm from a factory
0059
0060 The code to call an algorithm from a factory generally follows a specific pattern:
0061
0062 ```c++
0063 void Configure() {
0064 // This is called when the factory is instantiated.
0065 // Use this callback to make sure the algorithm is configured.
0066 // The logger, parameters, and services have all been fetched before this is called
0067 m_algo = std::make_unique<eicrecon::ElectronReconstruction>();
0068
0069 // Pass config object to algorithm
0070 m_algo->applyConfig(config());
0071
0072 // If we needed geometry, we'd obtain it like so
0073 // m_algo->init(m_geoSvc().detector(), m_geoSvc().converter(), logger());
0074
0075 m_algo->init(logger());
0076 }
0077
0078 void Process(int64_t run_number, uint64_t event_number) {
0079 // This is called on every event.
0080 // Use this callback to call your Algorithm using all inputs and outputs
0081 // The inputs will have already been fetched for you at this point.
0082 auto output = m_algo->execute(
0083 m_in_mc_particles(),
0084 m_in_rc_particles(),
0085 m_in_rc_particles_assoc(),
0086 m_in_clu_assoc()
0087 );
0088
0089 m_out_reco_particles() = std::move(output);
0090 // JANA will take care of publishing the outputs for you.
0091 }
0092 ```
0093
0094
0095 > Exercise:
0096 > - Create your own ElectronReconstruction algorithm using the code skeleton above.
0097 > - Print some log messages from your algorithm's `execute()` method.
0098 > - Have your ElectronReconstruction factory call the algorithm.
0099 > - Run this end-to-end.
0100 {: .challenge}