Belle II Software development
DirectedNodeNetwork.h
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#pragma once
9
10#include <framework/logging/Logger.h>
11
12#include <tracking/trackFindingVXD/segmentNetwork/DirectedNode.h>
13
14#include <algorithm>
15#include <cstdint>
16#include <unordered_map>
17#include <vector>
18
19namespace Belle2 {
28 template<typename EntryType, typename MetaInfoType>
30 protected:
34 using NodeID = std::int64_t;
35
36 public:
42 m_isFinalized(false)
43 {
44 m_nodeMap.reserve(40000);
45 m_nodes.reserve(40000);
46 }
47
48
52 {
53 for (auto nodePointer : m_nodeMap) {
54 delete nodePointer.second;
55 }
56 m_nodeMap.clear();
57 }
58
59
63 bool addNode(NodeID nodeID, EntryType& newEntry)
64 {
65 if (m_nodeMap.count(nodeID) == 0) {
66 // cppcheck-suppress stlFindInsert
67 m_nodeMap.emplace(nodeID, new Node(newEntry));
68 m_isFinalized = false;
69 return true;
70 }
71 return false;
72 }
73
74
77 {
78 // check if entry does not exist, constructed with ID=-1
79 if (m_lastOuterNodeID < 0) {
80 B2WARNING("Last OuterNode is not yet in this network! CurrentNetworkSize is: " << size());
81 return false;
82 }
83 // check if entries are identical (catch loops):
84 if (m_lastOuterNodeID == innerNodeID) {
85 B2WARNING("LastOuterNode and innerEntry are identical! Skipping linking-process");
86 return false;
87 }
88
89 if (linkNodes(m_lastOuterNodeID, innerNodeID)) {
90 return true;
91 }
92 B2WARNING("Last OuterNode and innerEntry were already in the network and were already connected."
93 "This is a sign for unintended behavior!");
94 return false;
95 }
96
97
100 {
101 // check if entry does not exist, constructed with ID=-1
102 if (m_lastInnerNodeID < 0) {
103 B2WARNING("Last InnerNode is not yet in this network! CurrentNetworkSize is: " << size());
104 return false;
105 }
106 // check if entries are identical (catch loops):
107 if (outerNodeID == m_lastInnerNodeID) {
108 B2WARNING("OuterEntry and lastInnerNode are identical! Skipping linking-process");
109 return false;
110 }
111
112 if (linkNodes(outerNodeID, m_lastInnerNodeID)) {
113 return true;
114 }
115
116 B2WARNING("Last InnerNode and outerEntry were already in the network and were already connected."
117 "This is a sign for unintended behavior!");
118 return false;
119 }
120
121
123 bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
124 {
125 m_isFinalized = false;
126 // check if entries are identical (catch loops):
127 if (outerNodeID == innerNodeID) {
128 B2WARNING("OuterNodeID and innerNodeID are identical! Skipping linking-process");
129 return false;
130 }
131 if (m_nodeMap.count(innerNodeID) == 0 or m_nodeMap.count(outerNodeID) == 0) {
132 B2WARNING("Trying to link Nodes that are not present yet");
133 return false;
134 }
135
136 m_lastOuterNodeID = outerNodeID;
137 m_lastInnerNodeID = innerNodeID;
138
139 return createLink(*(m_nodeMap[outerNodeID]), *(m_nodeMap[innerNodeID]));
140 }
141
142
144 inline bool isNodeInNetwork(const NodeID nodeID) const
145 {
146 return m_nodeMap.count(nodeID);
147 }
148
149
154 void clear()
155 {
156 m_nodes.clear();
157 // Clearing the unordered_map is important as the following modules will process the event
158 // if it still contains entries.
159 for (auto nodePointer : m_nodeMap) {
160 delete nodePointer.second;
161 }
162 m_nodeMap.clear();
163 }
164
165
167
168 std::vector<Node*> getOuterEnds()
169 {
170 if (!m_isFinalized) finalize();
171 return m_outerEnds;
172 }
173
174
176 std::vector<Node*> getInnerEnds()
177 {
178 if (!m_isFinalized) finalize();
179 return m_innerEnds;
180 }
181
182
185 Node* getNode(NodeID toBeFound)
186 {
187 if (m_nodeMap.count(toBeFound)) return m_nodeMap.at(toBeFound);
188 else return nullptr;
189 }
190
192 std::vector<Node* >& getNodes()
193 {
194 if (!m_isFinalized) finalize();
195 return m_nodes;
196 }
197
198
200 typename std::vector<Node* >::iterator begin()
201 {
202 if (!m_isFinalized) finalize();
203 return m_nodes.begin();
204 }
205
206
208 typename std::vector<Node* >::iterator end()
209 {
210 if (!m_isFinalized) finalize();
211 return m_nodes.end();
212 }
213
214
216 inline unsigned int size() const { return m_nodeMap.size(); }
217
218
219 protected:
222 static bool createLink(Node& outerNode, Node& innerNode)
223 {
224 // not successful if one of them was already added to the other one:
225 if (std::find(outerNode.getInnerNodes().begin(), outerNode.getInnerNodes().end(), &innerNode) != outerNode.getInnerNodes().end()) {
226 return false;
227 }
228 if (std::find(innerNode.getOuterNodes().begin(), innerNode.getOuterNodes().end(), &outerNode) != innerNode.getOuterNodes().end()) {
229 return false;
230 }
231
232 outerNode.addInnerNode(innerNode);
233 innerNode.addOuterNode(outerNode);
234 return true;
235 }
236
238 void finalize()
239 {
240 if (m_isFinalized) return;
241 m_nodes.clear();
242 m_nodes.reserve(m_nodeMap.size());
243 m_innerEnds.clear();
244 m_outerEnds.clear();
245 for (const auto& item : m_nodeMap) {
246 m_nodes.push_back(item.second);
247 if (item.second->getInnerNodes().empty()) m_innerEnds.push_back(item.second);
248 if (item.second->getOuterNodes().empty()) m_outerEnds.push_back(item.second);
249 }
250 m_isFinalized = true;
251 }
252
255 std::unordered_map<NodeID, Node*> m_nodeMap;
256
260 std::vector<Node*> m_nodes;
261
264 std::vector<Node*> m_outerEnds;
265
268 std::vector<Node*> m_innerEnds;
269
272
275
278
279 };
280
281}
Node * getNode(NodeID toBeFound)
Returns pointer to the node carrying the entry which is equal to given parameter.
DirectedNode< Belle2::Segment< Belle2::TrackNode >, Belle2::CACell > Node
std::vector< Node * > getInnerEnds()
returns all nodes which have no inner nodes (but outer ones) and therefore are inner ends of the netw...
std::vector< Node * >::iterator begin()
Returns iterator for container: begin.
DirectedNodeNetwork()
************************* CONSTRUCTOR/DESTRUCTOR *************************
std::vector< Node * > & getNodes()
Returns all nodes of the network.
bool addInnerToLastOuterNode(NodeID innerNodeID)
to the last outerNode added, another innerNode will be attached
std::vector< Node * >::iterator end()
Returns iterator for container: end.
void finalize()
Finalizing the NodeNetwork.
static bool createLink(Node &outerNode, Node &innerNode)
************************* INTERNAL MEMBER FUNCTIONS *************************
~DirectedNodeNetwork()
destructor taking care of cleaning up the pointer-mess WARNING only needed when using classic pointer...
unsigned int size() const
Returns number of nodes to be found in the network.
std::vector< Node * > getOuterEnds()
getters:
bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
takes two entry IDs and weaves them into the network
bool isNodeInNetwork(const NodeID nodeID) const
Check if a given entry is already in 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
void clear()
Clear directed node network Called to clear the directed node network if its size grows to large.
The Node-Class.
std::vector< DirectedNode< EntryType, MetaInfoType > * > & getInnerNodes()
************************* PUBLIC MEMBER FUNCTIONS *************************
std::vector< DirectedNode< EntryType, MetaInfoType > * > & getOuterNodes()
Returns links to all outer nodes attached to this one.
void addInnerNode(DirectedNode< EntryType, MetaInfoType > &newNode)
************************* INTERNAL MEMBER FUNCTIONS *************************
void addOuterNode(DirectedNode< EntryType, MetaInfoType > &newNode)
Adds new links to the outward direction.
Abstract base class for different kinds of events.