Belle II Software development
cellularAutomaton.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <array>
10#include <iostream>
11#include <gtest/gtest.h>
12
13#include <framework/logging/Logger.h>
14
15#include <tracking/trackFindingVXD/segmentNetwork/DirectedNode.h>
16#include <tracking/trackFindingVXD/segmentNetwork/DirectedNodeNetworkContainer.h>
17#include <tracking/trackFindingVXD/segmentNetwork/CACell.h>
18#include <tracking/trackFindingVXD/algorithms/CellularAutomaton.h>
19#include <tracking/trackFindingVXD/algorithms/CAValidator.h>
20#include <tracking/trackFindingVXD/algorithms/PathCollectorRecursive.h>
21#include <tracking/trackFindingVXD/algorithms/NodeCompatibilityCheckerPathCollector.h>
22
23
24using namespace std;
25using namespace Belle2;
26
32
33
35 class CellularAutomatonTest : public ::testing::Test {
36 protected:
37
38 };
39
40
44 TEST(CellularAutomatonTest, TestCAAndPathCollectorRecursiveUsingDirectedNodeNetworkInt)
45 {
46 // just some input for testing (same as in DirectedNodeNetwork-tests):
47 std::array<int, 5> intArray = { { 2, 5, 3, 4, 99} };
48 std::array<int, 5> intArray2 = { { 144, 121, 33, 35, 31415} }; // these entries are independent of the first intArray-entries
49 std::array<int, 5> intArray3 = { { 1440, 1210, 3, 33, 3141529} }; // entry 2 crosses intArray, entry 3 crosses intArray2
50 std::vector<int> onTheFlyCreatedInts; // the user has to take care about the lifetime of the objects to be linked in the network!
51 onTheFlyCreatedInts.reserve(4);
52
53
55 EXPECT_EQ(0, intNetwork.size());
56
57 // filling network:
58 for (unsigned int index = 1 ; index < 5; index++) {
59 // correct order: outerEntry, innerEntry:
60 intNetwork.addNode(intArray.at(index - 1), intArray.at(index - 1));
61 intNetwork.addNode(intArray.at(index), intArray.at(index));
62
63 intNetwork.linkNodes(intArray.at(index - 1), intArray.at(index));
64 }
65
66 for (unsigned int index = 1 ; index < 5; index++) {
67 intNetwork.addNode(intArray2.at(index - 1), intArray2.at(index - 1));
68 intNetwork.addNode(intArray2.at(index), intArray2.at(index));
69
70 intNetwork.linkNodes(intArray2.at(index - 1), intArray2.at(index));
71 }
72
73 for (unsigned int index = 1 ; index < 5; index++) {
74 intNetwork.addNode(intArray3.at(index - 1), intArray3.at(index - 1));
75 intNetwork.addNode(intArray3.at(index), intArray3.at(index));
76
77 intNetwork.linkNodes(intArray3.at(index - 1), intArray3.at(index));
78 }
79
80 {
81 int oldOuterInt = 2;
82 onTheFlyCreatedInts.push_back(42);
83 int& newInnerInt = onTheFlyCreatedInts.back();
84 intNetwork.addNode(newInnerInt, newInnerInt);
85 intNetwork.linkNodes(newInnerInt, oldOuterInt);
86 }
87
88 {
89 onTheFlyCreatedInts.push_back(23);
90 int& newOuterInt = onTheFlyCreatedInts.back();
91 int& existingInt = intArray.at(1); // neither an outer nor an inner end before.
92 intNetwork.addNode(newOuterInt, newOuterInt);
93 intNetwork.linkNodes(newOuterInt, existingInt);
94 }
95
96 intNetwork.linkNodes(intArray.at(0), intArray.at(2));
97 intNetwork.addInnerToLastOuterNode(intArray.at(3));
98
99 {
100 onTheFlyCreatedInts.push_back(31);
101 int& newInnerInt = onTheFlyCreatedInts.back();
102 intNetwork.addNode(newInnerInt, newInnerInt);
103 intNetwork.addInnerToLastOuterNode(newInnerInt);
104 }
105
106 intNetwork.addOuterToLastInnerNode(intArray2.at(1));
107
108 {
109 onTheFlyCreatedInts.push_back(66);
110 int& newOuterInt = onTheFlyCreatedInts.back();
111 intNetwork.addNode(newOuterInt, newOuterInt);
112 intNetwork.addOuterToLastInnerNode(newOuterInt);
113 }
114 // filling network - end.
115 EXPECT_EQ(17, intNetwork.size());
116 // uncomment following line if you want to stream a directed-graph-print of the network into "outputFile".gv
117 // DNN::printNetwork(intNetwork, "outputFile");
118
119
122
123 int nRounds = cellularAutomaton.apply(intNetwork);
124 unsigned int nSeeds = cellularAutomaton.findSeeds(intNetwork);
125 EXPECT_EQ(8,
126 nRounds); // CA starts counting with 1, not with 0, the length of the paths is the number of Cells stored in it. the last round is an empty round.
127 EXPECT_EQ(13, nSeeds);
128
129 typedef PathCollectorRecursive <
132 std::vector<DirectedNode<int, CACell>*>,
134
135
137 PathCollectorType pathCollector;
138
139 std::vector< PathCollectorType::Path> paths;
140 pathCollector.findPaths(intNetwork, paths, 100000000);
141
142 std::string out = PathCollectorType::printPaths(paths);
143 B2INFO(out);
144
145 // there could be more paths than seeds: why?
146 // -> the pathCollectorRecursive based on the CA also adds alternative paths with the same length.
147 EXPECT_EQ(13, paths.size());
148 unsigned int longestPath = 0;
149 for (auto& aPath : paths) {
150 if (longestPath < aPath.size()) {
151 longestPath = aPath.size();
152 }
153 }
154
155 EXPECT_EQ(7, longestPath); // TODO: fix
156 EXPECT_EQ(nRounds, longestPath +
157 1); // CA starts counting with 1, not with 0, the length of the paths is the number of Cells stored in it.
158
159 // also collect subpaths
160 paths.clear();
161 bool test = pathCollector.findPaths(intNetwork, paths, 50, true);
162 EXPECT_EQ(44, paths.size()); // Out of the 13 paths one gets 31 subpaths -> 44 in total
163 EXPECT_EQ(true, test); // Should return true, as 44 paths do not exceed the given limit of 50
164
165 // Checking if limit works
166 paths.clear();
167 test = pathCollector.findPaths(intNetwork, paths, 10);
168 EXPECT_EQ(false, test); // Should return false, as 13 paths exceed the given limit of 10
169 }
170}
The CellularAutomaton class This class serves as a functor for the algorithm itself.
int apply(ContainerType &aNetworkContainer) override final
actual algorithm of Cellular Automaton, returns number of rounds needed to finish or -1 if CA was abo...
unsigned int findSeeds(ContainerType &aNetworkContainer, bool strictSeeding=false) override final
checks network given for seeds, returns number of seeds found (if strictSeeding is set to true,...
Network of directed nodes of the type EntryType.
bool addInnerToLastOuterNode(NodeID innerNodeID)
to the last outerNode added, another innerNode will be attached
unsigned int size() const
Returns number of nodes to be found in the network.
bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
takes two entry IDs and weaves them into the network
bool addNode(NodeID nodeID, EntryType &newEntry)
************************* PUBLIC MEMBER FUNCTIONS *************************
bool addOuterToLastInnerNode(NodeID outerNodeID)
to the last innerNode added, another outerNode will be attached
The Node-Class.
Definition: DirectedNode.h:31
Path finder for generic ContainerType.
Test class demonstrating the behavior of The Cellular Automaton and the PathCollectorRecursive.
Abstract base class for different kinds of events.
These tests cover the functionality of the classes: DirectedNode, DirectedNodeNetwork.
STL namespace.
validation tool for CA algorithm
Definition: CAValidator.h:19
simple NodeCompatibilityChecker, which checks for compatible Neighboring states of passed nodes (does...