R3BROOT
R3B analysis software
|
These tasks are derived from FairTask and used in the steering macros. Task ending on a process usually apply a transformation to data, and take the input and output branch names as attributes, e.g.:
Task ending on mon create control histograms, and might be quite messy. They take the input branch and output folder names as arguments. Examples:
Note that the classes indented for storing data (derived from TObject for usage with TClonesArray) are located in r3bdata/neulandData.
The Digitizing task R3BNeulandDigitizer handles the Input and Output of data while invoking the Neuland::DigitizingEngine for the actual processing.
See digitizing/ for more details.
Clustering is the process of grouping Objects together by a specified condition.
The task R3BNeulandClusterFinder uses the implementation in Neuland::ClusteringEngine of what can be called handshake-chain clustering, where a cluster is finished if all of the Digis in it have no neighbor that is not in the cluster.
The task takes the TClonesArray NeulandHits(R3BNeulandHit) and fills TClonesArray NeulandClusters(R3BNeulandCluster).
Control histograms are located to R3BNeulandClusterMon.
The implementation is a template, thus any type of object can be clustered together. For this example, integers are used. Starting point is an unsorted vector of integers and the clustering condition is a difference of 1 or less. For the clustering process, several iterators referencing certain points in the vector are needed:
In the beginning, the vector is completely unclustered and a new cluster is started with the first element:
{ 28, 13, 23, 22, 15, 16, 3, 6, 4, 26, 10, 11, 19, 8, 29, 12, 25, 30, 17, 18, 24 } │ │ │ │ └ moving_divider └ end └ begin, a
Now, each object from the moving_divider to the end is compared with a, which currently is the first element, and if the clustering condition is fulfilled, moved next to it. This is done by std::partition. Now the moving_divider is set to the end of this partitioned part, and the next element between the current a and the moving_divider becomes the new a, which the unclustered part is compared to:
{ 28, 29, 30, 22, 15, 16, 3, 6, 4, 26, 10, 11, 19, 8, 23, 12, 25, 13, 17, 18, 24 } │ │ │ │ │ a └ moving_divider └ end └ begin
This continues until the moving_divider is reached, at this point the cluster is finished and extracted, and a new cluster is started:
{ xx, xx, xx, 22, 15, 16, 3, 6, 4, 26, 10, 11, 19, 8, 23, 12, 25, 13, 17, 18, 24 } │ │ │ │ └ moving_divider └ end └ begin, a
Note that the moving_divider does move every time std::partition adds new objects to the cluster, thus also these times are iterated over:
{ xx, xx, xx, 22, 23, 16, 3, 6, 4, 26, 10, 11, 19, 8, 15, 12, 25, 13, 17, 18, 24 } │ │ │ │ │ a └ moving_divider └ end └ begin { xx, xx, xx, 22, 23, 24, 3, 6, 4, 26, 10, 11, 19, 8, 15, 12, 25, 13, 17, 18, 16 } │ │ │ │ │ a └ moving_divider └ end └ begin { xx, xx, xx, 22, 23, 24, 25, 6, 4, 26, 10, 11, 19, 8, 15, 12, 3, 13, 17, 18, 16 } │ │ │ │ │ a └ moving_divider └ end └ begin
Note that for this process, the order of the objects is irrelevant. The algorithm will always find all elements that belong together.
In this example, the result is:
{ 28, 29, 30 }, { 22, 23, 24, 25, 26 }, { 4, 3 }, { 10, 11, 12, 13 }, { 8 }, { 19, 18, 17, 16, 15 }, { 6 }