Tasks in R3BRoot - R3BRootGroup/R3BRoot GitHub Wiki
Tasks in R3BRoot take event-based data, and transform it into new data or fill Histogramms.
They can also read and save and parameters from parameter (par
) files. Tasks can be chained, i.e., the output of one task is available in the next.
All tasks are all derived from FairTask, which in turn is derived from TTask.
Start with thinking more closely about what the task is supposed to do, and derive the Class and File names from this.
Remember not to pack a task too full - just because you can transform data and fill histograms at the same time doesn't always make it a good idea. A task should have a clearly defined and delimited purpose. This is well supported by the naming convention, e.g. Cal2Hit
.
Here, we take some A
s from the Detector
detector as input and create B
s, thus the name, including the R3B prefix, is R3BDetectorA2B
. The detector named detector
does not exist, obviously. To follow this example, use any existing detector you like.
To start: In the /detector/
directory, create R3BDetectorA2B.h
:
#ifndef R3BDETECTORA2B_H
#define R3BDETECTORA2B_H
#include "FairTask.h"
class R3BDetectorA2B : public FairTask
{
public:
R3BDetectorA2B() = default;
~R3BDetectorA2B() override = default;
ClassDefOverride(R3BDetectorA2B, 1);
};
#endif
Also create R3BDetectorA2B.cxx
:
#include "R3BDetectorA2B.h"
ClassImp(R3BDetectorA2B);
Add these to the respective CMakeLists.txt
and DetectorLinkDef.h
files, and it should compile. (Use the compile script or your IDE!)
Make sure you have run . build/config.sh
at least once in your shell, and run root -l
. In ROOT, you should be able to create the task:
root [0] task = R3BDetectorA2B();
root [1] task
(R3BDetectorA2B &) Name: Title:
root [2]
Congratulations, you have just created a task that does absolutely nothing!
Now, you implement the functions you need in your Task - and only these.
There are tons of very similar functions declared in FairTask.h
. I can't tell you what most of them are good for - and have never needed them. Some also effectively do the same thing and are just named differently.
You only need:
- The Constructor (In the minimal case without any attributes
= default
. In particular, you do not need the uselessname
andverbose
!) - The Destructor (In the minimal case
= default
) -
Init()
, which is called once at the beginning, mostly to establish the connection to the data source and to make histograms ready. -
Exec()
, which is executed for each event.
and optionally, if needed
-
Finish()
, mostly to output aggregated data and save histograms. -
SetParContainers()
, if parameters are needed.
Note: In the past, poorly thought out and poorly implemented templates have been copied too often - by people who don't know C++ or just code it to the "barely works" state, when that should be only the first step. Remember:
- If you don't need a function, e.g.,
SetParContainers()
, leave it out! - Remove unnecessary comments! We know that
Init()
does the initialization. Code is self-documenting to a degree! - Do comment on: What is this whole task supposed to do and what is needed for the task to work? Also, comment code that uses special tricks, works only in this configuration, uses workarounds, or is otherwise hard to understand.
One of the smallest working examples is R3BNeulandClusterFinder: Here, only Init and Exec are used. Both the annoying input-output connection and the logic itself is outsourced, so the implementation gets by with few lines. A more detailed example with TClonesArrays
is R3BNeulandMapped2Cal - it's not good, but not terrible either.
Running git status
should look like this:
On branch dev
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: detector/CMakeLists.txt
modified: detector/DetectorLinkDef.h
Untracked files:
(use "git add <file>..." to include in what will be committed)
detector/R3BDetectorA2B.cxx
detector/R3BDetectorA2B.h
no changes added to commit (use "git add" and/or "git commit -a")
Run the code formatting tool on the C++ files and then add them to the commit in a new branch:
clang-format -i detector/R3BDetectorA2B.cxx detector/R3BDetectorA2B.h
git checkout -b detectora2b
git add detector/*
git status
should now show:
On branch detectora2b
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: detector/CMakeLists.txt
modified: detector/DetectorLinkDef.h
new file: detector/R3BDetectorA2B.cxx
new file: detector/R3BDetectorA2B.h
Now, you can commit them.
git commit -m "Add A2B for Detector"
Once you finished development, rebase to the main repo and push to your GitHub fork. Note that it is encouraged that you squash individual commits into one while rebasing.
git fetch origin
git rebase -i origin
git push mine detectora2b