-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: generate a template algorithm (#67)
- Loading branch information
Showing
6 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
//############################################################################ | ||
//# include the algorithm header | ||
//############################################################################ | ||
#include "ExampleAlgorithm.h" | ||
|
||
//############################################################################ | ||
//# namespace must match that in the header | ||
//############################################################################ | ||
namespace iguana::example { | ||
|
||
//############################################################################ | ||
//# boilerplate to register an algorithm, so `AlgorithmFactory` knows about it | ||
//# - this is a preprocessor macro call (see `../AlgorithmBoilerplate.h`) | ||
//# - this must be done here in the source file, not in the header | ||
//# - the argument is the class name; do not surround it with quotes | ||
//# - usage of a semicolon at the end is optional, but recommended | ||
//############################################################################ | ||
REGISTER_IGUANA_ALGORITHM(ExampleAlgorithm); | ||
|
||
//############################################################################ | ||
//# define `ExampleAlgorithm::Start()` | ||
//# - again, a preprocessor macro is used here | ||
//# - this overrides the virtual function `Algorithm::Start`; see `Algorithm.h` | ||
//# for its parameters and return type | ||
//############################################################################ | ||
START_IGUANA_ALGORITHM(ExampleAlgorithm) { | ||
//############################################################################ | ||
//# define configuration options, their default values, and cache them | ||
//# - see `Algorithm.h` for more details | ||
//# - this function "caches" the option values into the `o_*` members, to | ||
//# avoid looking them up in the `Algorithm::Run` method | ||
//############################################################################ | ||
CacheOption("testInt", 8, o_testInt); | ||
CacheOption("testFloat", 7.0, o_testFloat); | ||
//############################################################################ | ||
//# cache expected bank indices | ||
//# - here we make sure that parameter `banks` includes the banks that are | ||
//# required to run this algorithm | ||
//# - this function "caches" the bank index values into the `b_*` members, to | ||
//# avoid looking them up in the `Algorithm::Run` method | ||
//############################################################################ | ||
CacheBankIndex(banks, "REC::Particle", b_particle); | ||
} | ||
|
||
|
||
//############################################################################ | ||
//# define `ExampleAlgorithm::Run()` | ||
//# - this overrides the virtual function `Algorithm::Run`; see `Algorithm.h` | ||
//# for its parameters and return type | ||
//# - note that this method must be _thread safe_, for example, you cannot modify | ||
//# class instance objects | ||
//# - try to avoid expensive operations here; instead, put them in the `Start` method | ||
//# if it is reasonable to do so | ||
//############################################################################ | ||
RUN_IGUANA_ALGORITHM(ExampleAlgorithm) { | ||
//############################################################################ | ||
//# get the banks; here we just need `REC::Particle` | ||
//############################################################################ | ||
auto& particleBank = GetBank(banks, b_particle, "REC::Particle"); | ||
//############################################################################ | ||
//# dump the bank | ||
//# - this will only happen if the log level for this algorithm is set low enough | ||
//# - this provides a look at the bank _before_ the algorithm runs | ||
//# - this is optional | ||
//############################################################################ | ||
ShowBank(particleBank, Logger::Header("INPUT PARTICLES")); | ||
|
||
//############################################################################ | ||
//# loop over the bank rows | ||
//############################################################################ | ||
for(int row = 0; row < particleBank.getRows(); row++) { | ||
//############################################################################ | ||
//# get the `pid` and feed it to the `Filter` action function; if the row | ||
//# is not acceptable, mask it out | ||
//############################################################################ | ||
auto pid = particleBank.getInt("pid", row); | ||
auto accept = Filter(pid); | ||
if(!accept) | ||
MaskRow(particleBank, row); | ||
//############################################################################ | ||
//# print a useful debugging method (see `Logger.h` for details, or other | ||
//# algorithms for examples of how to use the logger) | ||
//############################################################################ | ||
m_log->Debug("input PID {} -- accept = {}", pid, accept); | ||
} | ||
|
||
//############################################################################ | ||
//# dump the modified bank (only if the log level is low enough); this is also optional | ||
//############################################################################ | ||
ShowBank(particleBank, Logger::Header("OUTPUT PARTICLES")); | ||
} | ||
|
||
|
||
//############################################################################ | ||
//# define the action function | ||
//############################################################################ | ||
bool ExampleAlgorithm::Filter(const int pid) const { | ||
return pid > 0; | ||
} | ||
|
||
|
||
//############################################################################ | ||
//# define `ExampleAlgorithm::Stop()` | ||
//# - this overrides the virtual function `Algorithm::Stop`; see `Algorithm.h` | ||
//# for its parameters and return type | ||
//# - in this example, there is nothing to do | ||
//############################################################################ | ||
STOP_IGUANA_ALGORITHM(ExampleAlgorithm) { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//############################################################################ | ||
//# allow this header to be included only once | ||
//############################################################################ | ||
#pragma once | ||
|
||
//############################################################################ | ||
//# include `AlgorithmFactory`, so that we may register this algorithm for factory creation | ||
//############################################################################ | ||
#include "iguana/algorithms/AlgorithmFactory.h" | ||
|
||
//############################################################################ | ||
//# define the namespace | ||
//# - all `iguana` code should be within the `iguana` namespace | ||
//# - algorithms specific to an experiment or analysis may be put in a namespace within the `iguana` namespace | ||
//# - here we use the `iguana::example` namespace | ||
//# - for CLAS12-specific algorithms, use `iguana::clas12` | ||
//############################################################################ | ||
namespace iguana::example { | ||
|
||
//############################################################################ | ||
//# define the algorithm class | ||
//# - it must inherit from `Algorithm`, which includes common methods and objects used by each algorithm | ||
//# - it must also include a Doxygen docstring, typically defined by 3 forward slashes `///`; | ||
//# see Doxygen documentation for more details, or see other algorithms | ||
//############################################################################ | ||
/// @brief This is a template algorithm; provide a brief, one-line description of your algorithm here. | ||
/// | ||
/// Provide a more detailed description of your algorithm here, if you want. | ||
class ExampleAlgorithm : public Algorithm { | ||
|
||
//############################################################################ | ||
//# this is a preprocessor macro call which generates boilerplate for the algorithm definition | ||
//# - the arguments are: | ||
//# - the class name, `ExampleAlgorithm` | ||
//# - a unique, "full" name of the algorithm, used by `AlgorithmFactory`; typically is the | ||
//# namespace with the class name, excluding the `iguana::` part, but you are free to choose any name | ||
//# - NOTE: quotes are not used, and there is no need for a semicolon at the end of this call | ||
//# - see `../AlgorithmBoilerplate.h` for details | ||
//# - the macros are relatively modular, so if you want to use your own constructor or destructor, you may | ||
//# do so, and use other preprocessor macros called within `DEFINE_IGUANA_ALGORITHM` to complete | ||
//# the boilerplate public and private functions and members | ||
//############################################################################ | ||
DEFINE_IGUANA_ALGORITHM(ExampleAlgorithm, example::ExampleAlgorithm) | ||
|
||
public: | ||
|
||
//############################################################################ | ||
//# public functions go here | ||
//# - typically these are "action functions", which expose the primary operation of an algorithm | ||
//# - these functions are _unique_ to each algorithm, and therefore are not defined in the | ||
//# `Algorithm` base class | ||
//# - their purpose is to allow the usage of the algorithm for users who _don't_ process full banks, | ||
//# but rather process bank rows, or from some other data source | ||
//# - try to keep the parameters and return types _friendly_ to language bindings; for example, | ||
//# avoid "complicated" types and lvalue references | ||
//# - don't forget the Doxygen docstrings | ||
//# - the action function here is trivial, just to show an example | ||
//# - you do not have to name it as `Filter`, but take a look at other algorithms and try to | ||
//# keep some consistency, for example: | ||
//# - `bool Filter` for a filtering type algorithm, such as fiducial cuts | ||
//# - `Transform` for a transformation type algorithm, such as momentum corrections | ||
//# - `Create` for a creation type algorithm, such as inclusive kinematic (x, Q2, etc.) reconstruction | ||
//############################################################################ | ||
/// **Action function**: checks if the PDG `pid` is positive; | ||
/// this is an example action function, please replace it with your own | ||
/// @param pid the particle PDG to check | ||
/// @returns `true` if `pid` is positive | ||
bool Filter(const int pid) const; | ||
|
||
private: | ||
|
||
//############################################################################ | ||
//# indices for the banks needed for this algorithm | ||
//# - see `Algorithm::CacheBankIndex` for details | ||
//# - here, we just define one for the `REC::Particle` bank | ||
//# - convention: they should start with `b_` | ||
//############################################################################ | ||
/// `hipo::banklist` index for the particle bank (as an example) | ||
hipo::banklist::size_type b_particle; | ||
|
||
//############################################################################ | ||
//# configuration options | ||
//# - their type may be: | ||
//# - one of the allowed types in `option_t`, which is a `std::variant` | ||
//# - `std::set`, used by `Algorithm::CacheOptionToSet`, which converts | ||
//# a user's `std::vector` option to a `std::set` | ||
//# - your own type, but you will have to set it in the `Start()` method | ||
//# - here we show example `int` and `float` options | ||
//# - convention: they should start with `o_` | ||
//############################################################################ | ||
/// Example integer configuration option | ||
int o_testInt; | ||
/// Example float configuration option | ||
double o_testFloat; | ||
|
||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Example Algorithm Template | ||
|
||
This directory includes a fully documented, simple example algorithm: | ||
- [`ExampleAlgorithm.h`](ExampleAlgorithm.h) | ||
- [`ExampleAlgorithm.cc`](ExampleAlgorithm.cc) | ||
|
||
In this code, the following comment styles are used: | ||
- `//#`: this is a comment which describes in detail what each line of the code does; you probably | ||
don't want this much detail in your own algorithm | ||
- `///`: this is a docstring for [Doxygen](https://www.doxygen.nl/), for automated documentation generation; | ||
you'll need to use these when documenting your algorithm | ||
|
||
To generate a template algorithm (without the `//#` comments) so you may get | ||
started coding, run the `make_template.sh` script here: | ||
```bash | ||
# run with no arguments to see usage | ||
src/iguana/algorithms/example/make_template.sh | ||
|
||
# example: make a CLAS12 algorithm called AwesomeAlgorithm | ||
src/iguana/algorithms/example/make_template.sh AwesomeAlgorithm clas12 src/iguana/algorithms/clas12 | ||
``` | ||
|
||
Once you have generated your new algorithm, add it to the appropriate | ||
`meson.build` file (likely [`src/iguana/algorithms/meson.build`](../meson.build)), | ||
and get started coding! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#!/bin/bash | ||
# generate a template algorithm from the example algorithm | ||
|
||
set -e | ||
|
||
namespace=clas12 | ||
installDir=src/iguana/algorithms/clas12 | ||
|
||
if [ $# -lt 1 ]; then | ||
echo """USAGE: $0 [algorithm class name] [namespace] [directory] | ||
[algorithm class name]: the name of your new algorithm | ||
(required) | ||
[namespace]: the namespace (within the \`iguana\` namespace) of your new algorithm | ||
(default: '$namespace') | ||
- if you want the namespace to be \`iguana\` alone, set this to 'iguana' | ||
[directory]: the directory where your algorithm will be created | ||
(default: $installDir) | ||
""" >&2 | ||
exit 2 | ||
fi | ||
|
||
algo=$1 | ||
[ $# -ge 2 ] && namespace=$2 | ||
[ $# -ge 3 ] && installDir=$3 | ||
|
||
thisFile=${BASH_SOURCE[0]:-$0} | ||
thisDir=$(cd $(dirname $thisFile) && pwd -P) | ||
exName=ExampleAlgorithm | ||
|
||
mkdir -p $installDir | ||
|
||
for ext in h cc; do | ||
outFile=$installDir/$algo.$ext | ||
cat $thisDir/$exName.$ext |\ | ||
sed "s;$exName;$algo;g" |\ | ||
sed "s;example::;$namespace::;g" |\ | ||
sed "s;::example;::$namespace;g" |\ | ||
sed "s;iguana::iguana;iguana;g" |\ | ||
grep -v '//#' \ | ||
> $outFile | ||
echo Created $outFile | ||
done | ||
|
||
echo """ | ||
Done. Now add '$algo.h' and '$algo.cc' to the appropriate meson.build file | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters