Belle II Software  release-05-02-19
DirectedNodeNetwork.h
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Jakob Lettenbichler, Felix Metzner *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #pragma once
11 
12 #include <vector>
13 #include <unordered_map>
14 
15 #include <framework/logging/Logger.h>
16 
17 #include <tracking/trackFindingVXD/segmentNetwork/DirectedNode.h>
18 
19 
20 namespace Belle2 {
29  template<typename EntryType, typename MetaInfoType>
30  class DirectedNodeNetwork {
31  protected:
33  using Node = DirectedNode<EntryType, MetaInfoType>;
35  using NodeID = std::int64_t;
36 
37  public:
44  {
45  m_nodeMap.reserve(40000);
46  m_nodes.reserve(40000);
47  }
48 
49 
53  {
54  for (auto nodePointer : m_nodeMap) {
55  delete nodePointer.second;
56  }
57  m_nodeMap.clear();
58  }
59 
60 
64  bool addNode(NodeID nodeID, EntryType& newEntry)
65  {
66  if (m_nodeMap.count(nodeID) == 0) {
67  // cppcheck-suppress stlFindInsert
68  m_nodeMap.emplace(nodeID, new Node(newEntry));
69  m_isFinalized = false;
70  return true;
71  }
72  return false;
73  }
74 
75 
77  bool addInnerToLastOuterNode(NodeID innerNodeID)
78  {
79  // check if entry does not exist, constructed with ID=-1
80  if (m_lastOuterNodeID < 0) {
81  B2WARNING("Last OuterNode is not yet in this network! CurrentNetworkSize is: " << size());
82  return false;
83  }
84  // check if entries are identical (catch loops):
85  if (m_lastOuterNodeID == innerNodeID) {
86  B2WARNING("LastOuterNode and innerEntry are identical! Aborting linking-process");
87  return false;
88  }
89 
90  if (linkNodes(m_lastOuterNodeID, innerNodeID)) {
91  return true;
92  }
93  B2WARNING("Last OuterNode and innerEntry were already in the network and were already connected."
94  "This is a sign for unintended behavior!");
95  return false;
96  }
97 
98 
100  bool addOuterToLastInnerNode(NodeID outerNodeID)
101  {
102  // check if entry does not exist, constructed with ID=-1
103  if (m_lastInnerNodeID < 0) {
104  B2WARNING("Last InnerNode is not yet in this network! CurrentNetworkSize is: " << size());
105  return false;
106  }
107  // check if entries are identical (catch loops):
108  if (outerNodeID == m_lastInnerNodeID) {
109  B2WARNING("OuterEntry and lastInnerNode are identical! Aborting linking-process");
110  return false;
111  }
112 
113  if (linkNodes(outerNodeID, m_lastInnerNodeID)) {
114  return true;
115  }
116 
117  B2WARNING("Last InnerNode and outerEntry were already in the network and were already connected."
118  "This is a sign for unintended behavior!");
119  return false;
120  }
121 
122 
124  bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
125  {
126  m_isFinalized = false;
127  // check if entries are identical (catch loops):
128  if (outerNodeID == innerNodeID) {
129  B2WARNING("OuterNodeID and innerNodeID are identical! Aborting linking-process");
130  return false;
131  }
132  if (m_nodeMap.count(innerNodeID) == 0 or m_nodeMap.count(outerNodeID) == 0) {
133  B2WARNING("Trying to link Nodes that are not present yet");
134  return false;
135  }
136 
137  m_lastOuterNodeID = outerNodeID;
138  m_lastInnerNodeID = innerNodeID;
139 
140  return createLink(*(m_nodeMap[outerNodeID]), *(m_nodeMap[innerNodeID]));
141  }
142 
143 
145  inline bool isNodeInNetwork(const NodeID nodeID) const
146  {
147  return m_nodeMap.count(nodeID);
148  }
149 
150 
155  void clear()
156  {
157  m_nodes.clear();
158  // Clearing the unordered_map is important as the following modules will process the event
159  // if it still contains entries.
160  for (auto nodePointer : m_nodeMap) {
161  delete nodePointer.second;
162  }
163  m_nodeMap.clear();
164  }
165 
166 
168 
169  std::vector<Node*> getOuterEnds()
170  {
171  if (!m_isFinalized) finalize();
172  return m_outerEnds;
173  }
174 
175 
177  std::vector<Node*> getInnerEnds()
178  {
179  if (!m_isFinalized) finalize();
180  return m_innerEnds;
181  }
182 
183 
186  Node* getNode(NodeID toBeFound)
187  {
188  if (m_nodeMap.count(toBeFound)) return m_nodeMap.at(toBeFound);
189  else return nullptr;
190  }
191 
193  std::vector<Node* >& getNodes()
194  {
195  if (!m_isFinalized) finalize();
196  return m_nodes;
197  }
198 
199 
201  typename std::vector<Node* >::iterator begin()
202  {
203  if (!m_isFinalized) finalize();
204  return m_nodes.begin();
205  }
206 
207 
209  typename std::vector<Node* >::iterator end()
210  {
211  if (!m_isFinalized) finalize();
212  return m_nodes.end();
213  }
214 
215 
217  inline unsigned int size() const { return m_nodeMap.size(); }
218 
219 
220  protected:
223  static bool createLink(Node& outerNode, Node& innerNode)
224  {
225  // not successful if one of them was already added to the other one:
226  if (std::find(outerNode.getInnerNodes().begin(), outerNode.getInnerNodes().end(), &innerNode) != outerNode.getInnerNodes().end()) {
227  return false;
228  }
229  if (std::find(innerNode.getOuterNodes().begin(), innerNode.getOuterNodes().end(), &outerNode) != innerNode.getOuterNodes().end()) {
230  return false;
231  }
232 
233  outerNode.addInnerNode(innerNode);
234  innerNode.addOuterNode(outerNode);
235  return true;
236  }
237 
239  void finalize()
240  {
241  if (m_isFinalized) return;
242  m_nodes.clear();
243  m_nodes.reserve(m_nodeMap.size());
244  m_innerEnds.clear();
245  m_outerEnds.clear();
246  for (const auto& item : m_nodeMap) {
247  m_nodes.push_back(item.second);
248  if (item.second->getInnerNodes().empty()) m_innerEnds.push_back(item.second);
249  if (item.second->getOuterNodes().empty()) m_outerEnds.push_back(item.second);
250  }
251  m_isFinalized = true;
252  }
253 
256  std::unordered_map<NodeID, Node*> m_nodeMap;
257 
260 
263 
265  bool m_isFinalized;
266 
270  std::vector<Node*> m_nodes;
271 
274  std::vector<Node*> m_outerEnds;
275 
278  std::vector<Node*> m_innerEnds;
279  };
281 }
Belle2::DirectedNodeNetwork::finalize
void finalize()
Finalizing the NodeNetwork.
Definition: DirectedNodeNetwork.h:247
Belle2::DirectedNodeNetwork::Node
DirectedNode< EntryType, MetaInfoType > Node
Defining abbreviation for the used directed node type pack.
Definition: DirectedNodeNetwork.h:41
Belle2::DirectedNodeNetwork::NodeID
std::int64_t NodeID
NodeID should be some unique integer.
Definition: DirectedNodeNetwork.h:43
Belle2::DirectedNodeNetwork::m_nodes
std::vector< Node * > m_nodes
After the network is finalized this vector will also carry all nodes to be able to keep the old inter...
Definition: DirectedNodeNetwork.h:278
Belle2::DirectedNodeNetwork::getOuterEnds
std::vector< Node * > getOuterEnds()
getters:
Definition: DirectedNodeNetwork.h:177
Belle2::DirectedNodeNetwork::isNodeInNetwork
bool isNodeInNetwork(const NodeID nodeID) const
Check if a given entry is already in the network.
Definition: DirectedNodeNetwork.h:153
Belle2::DirectedNodeNetwork::m_outerEnds
std::vector< Node * > m_outerEnds
keeps track of current outerEnds (nodes which have no outerNodes) entries are the NodeIDs of the node...
Definition: DirectedNodeNetwork.h:282
Belle2::DirectedNodeNetwork::~DirectedNodeNetwork
~DirectedNodeNetwork()
destructor taking care of cleaning up the pointer-mess WARNING only needed when using classic pointer...
Definition: DirectedNodeNetwork.h:60
Belle2::DirectedNodeNetwork::size
unsigned int size() const
Returns number of nodes to be found in the network.
Definition: DirectedNodeNetwork.h:225
Belle2::DirectedNodeNetwork::m_lastInnerNodeID
NodeID m_lastInnerNodeID
temporal storage for last inner node added, used for speed-up
Definition: DirectedNodeNetwork.h:270
Belle2::DirectedNodeNetwork::begin
std::vector< Node * >::iterator begin()
Returns iterator for container: begin.
Definition: DirectedNodeNetwork.h:209
Belle2::DirectedNodeNetwork::clear
void clear()
Clear directed node network Called to clear the directed node network if its size grows to large.
Definition: DirectedNodeNetwork.h:163
Belle2::DirectedNodeNetwork::m_isFinalized
bool m_isFinalized
keeps track of the state of the network to fill the vectors m_nodes, m_outerEnds, m_innerEnds only if...
Definition: DirectedNodeNetwork.h:273
Belle2::DirectedNodeNetwork::m_innerEnds
std::vector< Node * > m_innerEnds
keeps track of current innerEnds (nodes which have no innerNodes) entries are the NodeIds of the node...
Definition: DirectedNodeNetwork.h:286
Belle2::DirectedNodeNetwork::addOuterToLastInnerNode
bool addOuterToLastInnerNode(NodeID outerNodeID)
to the last innerNode added, another outerNode will be attached
Definition: DirectedNodeNetwork.h:108
Belle2::DirectedNodeNetwork::linkNodes
bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
takes two entry IDs and weaves them into the network
Definition: DirectedNodeNetwork.h:132
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::DirectedNodeNetwork::getNode
Node * getNode(NodeID toBeFound)
Returns pointer to the node carrying the entry which is equal to given parameter.
Definition: DirectedNodeNetwork.h:194
Belle2::DirectedNodeNetwork::m_lastOuterNodeID
NodeID m_lastOuterNodeID
temporal storage for last outer node added, used for speed-up
Definition: DirectedNodeNetwork.h:267
Belle2::DirectedNodeNetwork::getInnerEnds
std::vector< Node * > getInnerEnds()
returns all nodes which have no inner nodes (but outer ones) and therefore are inner ends of the netw...
Definition: DirectedNodeNetwork.h:185
Belle2::DirectedNodeNetwork::getNodes
std::vector< Node * > & getNodes()
Returns all nodes of the network.
Definition: DirectedNodeNetwork.h:201
Belle2::DirectedNodeNetwork::m_nodeMap
std::unordered_map< NodeID, Node * > m_nodeMap
************************* DATA MEMBERS *************************
Definition: DirectedNodeNetwork.h:264
Belle2::DirectedNodeNetwork::DirectedNodeNetwork
DirectedNodeNetwork()
************************* CONSTRUCTOR/DESTRUCTOR *************************
Definition: DirectedNodeNetwork.h:48
Belle2::DirectedNodeNetwork::createLink
static bool createLink(Node &outerNode, Node &innerNode)
************************* INTERNAL MEMBER FUNCTIONS *************************
Definition: DirectedNodeNetwork.h:231
Belle2::DirectedNodeNetwork::end
std::vector< Node * >::iterator end()
Returns iterator for container: end.
Definition: DirectedNodeNetwork.h:217
Belle2::DirectedNodeNetwork::addNode
bool addNode(NodeID nodeID, EntryType &newEntry)
************************* PUBLIC MEMBER FUNCTIONS *************************
Definition: DirectedNodeNetwork.h:72
Belle2::DirectedNodeNetwork::addInnerToLastOuterNode
bool addInnerToLastOuterNode(NodeID innerNodeID)
to the last outerNode added, another innerNode will be attached
Definition: DirectedNodeNetwork.h:85