BALL 1.5.0
simpleMolecularGraph.h
Go to the documentation of this file.
1// -*- Mode: C++; tab-width: 2; -*-
2// vi: set ts=2:
3//
4
5#ifndef BALL_STRUCTURE_SIMPLEMOLECULARGRAPH_H
6#define BALL_STRUCTURE_SIMPLEMOLECULARGRAPH_H
7
8#ifndef BALL_KERNEL_ATOM_H
9# include <BALL/KERNEL/atom.h>
10#endif
11
12#ifndef BALL_KERNEL_BOND_H
13# include <BALL/KERNEL/bond.h>
14#endif
15
16#ifndef BALL_STRUCTURE_MOLECULE_H
17# include <BALL/KERNEL/molecule.h>
18#endif
19
20#ifndef BALL_STRUCTURE_FRAGMENT_H
21# include <BALL/KERNEL/fragment.h>
22#endif
23
24#include <list>
25#include <iostream>
26#include <algorithm>
27
28namespace BALL
29{
30 // forward declarations to resolve nasty dependencies
31 template <typename Node, typename Edge>
32 class EdgeItem;
33
34 template <typename Node, typename Edge>
35 class TSimpleMolecularGraph;
36
40 template <typename Node, typename Edge>
42 {
43 public:
49
52
54 typedef typename std::list<EdgeItem<Node, Edge>*>::iterator Iterator;
56 typedef typename std::list<EdgeItem<Node, Edge>*>::const_iterator ConstIterator;
58
59 friend class TSimpleMolecularGraph<Node, Edge>;
60
61 NodeItem() ;
62 NodeItem(const Atom& atom) ;
63
64 Node& getData() ;
65 const Node& getData() const ;
66 void setData(const Node& data) ;
67
68 const Atom* getAtom() const ;
69 Atom* getAtom() ;
70
71 Iterator begin() ;
72 ConstIterator begin() const ;
73 Iterator end() ;
74 ConstIterator end() const ;
75
76 Size getDegree() const ;
77
78 bool operator == (const NodeItem& item) const ;
79 bool operator != (const NodeItem& item) const ;
80
81 protected:
82
83 void deleteEdge_(EdgeItemType* item)
84 ;
85
86 Node data_;
88 std::list<EdgeItemType*> adjacent_edges_;
89 };
90
91
92 template <typename Node, typename Edge>
94 {
95 public:
98 typedef typename std::list<NodeItem<Node, Edge>*>::iterator Iterator;
99 typedef typename std::list<NodeItem<Node, Edge>*>::const_iterator ConstIterator;
100
102 : bond_(0), source_(0), target_(0)
103 {}
104
105 EdgeItem(const Bond& bond);
106 EdgeItem(const Bond& bond, NodeItemType* source, NodeItemType* target);
107
110 const NodeItemType& getSource() const {return *source_;}
111 const NodeItemType& getTarget() const {return *target_;}
112
113 Node& getData() {return data_;}
114 const Node& getData() const {return data_;}
115 void setData(const Edge& data) { data_ = data; };
116
117 Bond* getBond() { return bond_; }
118 const Bond* getBond() const { return bond_; }
119
120 bool operator == (const EdgeItem& item) const { return (bond_ == item.bond_); }
121 bool operator != (const EdgeItem& item) const { return (bond_ != item.bond_); }
122
123 protected:
124 Edge data_;
128 };
129
130 template <typename Node, typename Edge>
132 : bond_(const_cast<Bond*>(&bond))
133 {
134 }
135
136 template <typename Node, typename Edge>
138 : bond_(const_cast<Bond*>(&bond)),
139 source_(first),
140 target_(second)
141 {
142 }
143
144 template <typename Node, typename Edge>
146 {
147 public:
150 typedef typename std::list<NodeItemType>::iterator NodeIterator;
151 typedef typename std::list<NodeItemType>::const_iterator NodeConstIterator;
152 typedef typename std::list<EdgeItemType>::iterator EdgeIterator;
153 typedef typename std::list<EdgeItemType>::const_iterator EdgeConstIterator;
154
156 TSimpleMolecularGraph(const Molecule& molecule) ;
157
158 bool newNode(const Atom& atom) ;
159 bool newEdge(const Bond& bond) ;
160
163
164 bool deleteNode(const Atom& atom);
165 bool deleteEdge(const Bond& bond);
166
167 NodeIterator beginNode() { return nodes_.begin(); }
168 NodeConstIterator beginNode() const { return nodes_.begin(); }
169 EdgeIterator beginEdge() { return edges_.begin(); }
170 EdgeConstIterator beginEdge() const { return edges_.begin(); }
171 NodeIterator endNode() { return nodes_.end(); }
172 NodeConstIterator endNode() const { return nodes_.end(); }
173 EdgeIterator endEdge() { return edges_.end(); }
174 EdgeConstIterator endEdge() const { return edges_.end(); }
175
176 bool has(const Atom& atom) const { return atom_to_node_.has(const_cast<Atom*>(&atom)); }
177 bool has(const Bond& bond) const { return bond_to_edge_.has(const_cast<Bond*>(&bond)); }
178
179 NodeItemType& getNode(Position index) { return nodes_[index]; };
180 const NodeItemType& getNode(Position index) const { return nodes_[index]; };
181 EdgeItemType& getEdge(Position index) { return edges_[index]; };
182 const EdgeItemType& getEdge(Position index) const { return edges_[index]; };
183
186 Size getNumberOfNodes() const ;
187
190 Size getNumberOfEdges() const ;
191
192 protected:
193 std::list<NodeItemType> nodes_;
194 std::list<EdgeItemType> edges_;
197 };
198
203
204 template <typename Node, typename Edge>
206
207 : nodes_(),
208 edges_(),
209 atom_to_node_(),
210 bond_to_edge_()
211 {
212 }
213
214 template <typename Node, typename Edge>
216
217 : nodes_(),
218 edges_(),
219 atom_to_node_(),
220 bond_to_edge_()
221 {
222 AtomConstIterator ai = molecule.beginAtom();
224 for (; +ai; ++ai)
225 {
226 newNode(*ai);
227 }
228 for (ai = molecule.beginAtom(); +ai; ++ai)
229 {
230 for (bi = ai->beginBond(); +bi; ++bi)
231 {
232 if (bi->getFirstAtom() == &*ai)
233 {
234 newEdge(*bi);
235 }
236 }
237 }
238 }
239
240 template <typename Node, typename Edge>
242
243 {
244 Atom* atom_ptr = const_cast<Atom*>(&atom);
245
246 if (atom_to_node_.has(atom_ptr))
247 {
248 return false;
249 }
250
251 nodes_.push_back(NodeItemType(atom));
252 atom_to_node_.insert(std::pair<Atom*, NodeItemType*>(atom_ptr, &(nodes_.back())));
253
254 return true;
255 }
256
257 template <typename Node, typename Edge>
259
260 {
261 // Create convenience aliases for atoms.
262 Atom* first = const_cast<Atom*>(bond.getFirstAtom());
263 Atom* second = const_cast<Atom*>(bond.getSecondAtom());
264
265 // Make sure we have atoms/nodes for this bond/edge.
266 if (!atom_to_node_.has(first) || !atom_to_node_.has(second))
267 {
268 return false;
269 }
270
271 // Make sure not to create the same edge twice.
272 if (bond_to_edge_.has(const_cast<Bond*>(&bond)))
273 {
274 return true;
275 }
276
277 // Create the new edge und add it to the hash map relating
278 // the bond to the edge.
279 NodeItemType* first_item = atom_to_node_[first];
280 NodeItemType* second_item = atom_to_node_[second];
281 edges_.push_back(EdgeItemType(bond, first_item, second_item));
282 bond_to_edge_.insert(std::pair<Bond*, EdgeItemType*>(const_cast<Bond*>(&bond), &edges_.back()));
283 first_item->adjacent_edges_.push_back(&edges_.back());
284 second_item->adjacent_edges_.push_back(&edges_.back());
285
286 return true;
287 }
288
289 template <typename Node, typename Edge>
290 std::ostream& operator << (std::ostream& os, const TSimpleMolecularGraph<Node, Edge>& G)
291 {
292 os << "Nodes:" << std::endl;
293
295 Size count = 0;
296 for (; node != G.endNode(); ++node)
297 {
298 os << count++ << ": " << node->getAtom()->getFullName() << " [" << node->getDegree() << "] '" << node->getAtom() << "'" << std::endl;
299 }
300
301 os << "Edges:" << std::endl;
302
304 count = 0;
305 for (; edge != G.endEdge(); ++edge)
306 {
307 os << count++ << ": " << edge->getSource().getAtom() << "-" << edge->getTarget().getAtom() << " '" << edge->getBond() << "'" << std::endl;
308 }
309
310 return os;
311 }
312
313 template <typename Node, typename Edge>
315 {
316 if (!atom_to_node_.has(const_cast<Atom*>(&atom)))
317 {
318 return false;
319 }
320
321 return deleteNode(*atom_to_node_[const_cast<Atom*>(&atom)]);
322 }
323
324 template <typename Node, typename Edge>
326 {
327 if (!bond_to_edge_.has(const_cast<Bond*>(&bond)))
328 {
329 return false;
330 }
331
332 return deleteEdge(*bond_to_edge_[const_cast<Bond*>(&bond)]);
333 }
334
335 template <typename Node, typename Edge>
337 {
338 NodeIterator node_it = std::find(nodes_.begin(), nodes_.end(), node);
339 if (node_it == nodes_.end())
340 {
341 return false;
342 }
343
344 bool remove = true;
345 while (remove)
346 {
347 remove = false;
348 typename NodeItemType::Iterator edge(node.begin());
349 for (; edge != node.end(); ++edge)
350 {
351 deleteEdge(**edge);
352 break;
353 }
354 }
355
356 atom_to_node_.erase(node_it->getAtom());
357 nodes_.erase(node_it);
358
359 return true;
360 }
361
362 template <typename Node, typename Edge>
364 {
365 typename std::list<EdgeItemType>::iterator edge_it = std::find(edges_.begin(), edges_.end(), edge);
366 if (edge_it == edges_.end())
367 {
368 return false;
369 }
370 edge.getSource().deleteEdge_(&edge);
371 edge.getTarget().deleteEdge_(&edge);
372 bond_to_edge_.erase(edge_it->getBond());
373 edges_.erase(edge_it);
374
375 return true;
376 }
377
378
379 template <typename Node, typename Edge>
381
382 : atom_(0)
383 {
384 }
385
386 template <typename Node, typename Edge>
388
389 : atom_(const_cast<Atom*>(&atom))
390 {
391 }
392
393 template <typename Node, typename Edge>
395
396 {
397 return data_;
398 }
399
400 template <typename Node, typename Edge>
401 const Node& NodeItem<Node, Edge>::getData() const
402
403 {
404 return data_;
405 }
406
407
408 template <typename Node, typename Edge>
409 void NodeItem<Node, Edge>::setData(const Node& data)
410
411 {
412 data_ = data;
413 }
414
415
416 template <typename Node, typename Edge>
418
419 {
420 return atom_;
421 }
422
423 template <typename Node, typename Edge>
425
426 {
427 return atom_;
428 }
429
430 template <typename Node, typename Edge>
432
433 {
434 return adjacent_edges_.begin();
435 }
436
437 template <typename Node, typename Edge>
439
440 {
441 return adjacent_edges_.begin();
442 }
443
444 template <typename Node, typename Edge>
446
447 {
448 return adjacent_edges_.end();
449 }
450
451 template <typename Node, typename Edge>
453
454 {
455 return adjacent_edges_.end();
456 }
457
458 template <typename Node, typename Edge>
460
461 {
462 return (Size)adjacent_edges_.size();
463 }
464
465 template <typename Node, typename Edge>
467
468 {
469 return (atom_ == item.atom_);
470 }
471
472 template <typename Node, typename Edge>
474
475 {
476 return (atom_ != item.atom_);
477 }
478
479 template <typename Node, typename Edge>
481
482 {
483 Iterator it(std::find(adjacent_edges_.begin(), adjacent_edges_.end(), item));
484 if (it != adjacent_edges_.end())
485 {
486 adjacent_edges_.erase(it);
487 }
488 }
489
490 template <typename Node, typename Edge>
493
494 {
495 return nodes_.size();
496 }
497
498 template <typename Node, typename Edge>
501
502 {
503 return edges_.size();
504 }
505
506
507} // namespace BALL
508
509#endif // BALL_STRUCTURE_MOLECULARGRAPH_H
#define BALL_INLINE
Definition: debug.h:15
BALL_EXPORT std::ostream & operator<<(std::ostream &os, const Exception::GeneralException &e)
Definition: constants.h:13
TSimpleMolecularGraph< Index, Index > SimpleMolecularGraph
HashMap class based on the STL map (containing serveral convenience functions)
Definition: hashMap.h:74
const Atom * getFirstAtom() const
Return a pointer to the first atom.
const Atom * getSecondAtom() const
Return a pointer to the second atom.
void setData(const Edge &data)
std::list< NodeItem< Node, Edge > * >::const_iterator ConstIterator
EdgeItem< Node, Edge > EdgeItemType
const NodeItemType & getSource() const
NodeItemType & getTarget()
NodeItemType & getSource()
const NodeItemType & getTarget() const
NodeItemType * source_
bool operator==(const EdgeItem &item) const
const Bond * getBond() const
bool operator!=(const EdgeItem &item) const
NodeItem< Node, Edge > NodeItemType
EdgeItem(const Bond &bond)
const Node & getData() const
EdgeItem(const Bond &bond, NodeItemType *source, NodeItemType *target)
NodeItemType * target_
std::list< NodeItem< Node, Edge > * >::iterator Iterator
NodeItem< Node, Edge > NodeItemType
bool has(const Bond &bond) const
std::list< EdgeItemType >::const_iterator EdgeConstIterator
bool deleteNode(NodeItemType &node)
bool has(const Atom &atom) const
std::list< NodeItemType >::iterator NodeIterator
HashMap< Bond *, EdgeItemType * > bond_to_edge_
HashMap< Atom *, NodeItemType * > atom_to_node_
std::list< NodeItemType >::const_iterator NodeConstIterator
NodeConstIterator beginNode() const
const NodeItemType & getNode(Position index) const
NodeItemType & getNode(Position index)
bool newNode(const Atom &atom)
EdgeItemType & getEdge(Position index)
bool deleteEdge(EdgeItemType &edge)
std::list< EdgeItemType >::iterator EdgeIterator
EdgeConstIterator endEdge() const
std::list< NodeItemType > nodes_
NodeConstIterator endNode() const
std::list< EdgeItemType > edges_
EdgeConstIterator beginEdge() const
const EdgeItemType & getEdge(Position index) const
EdgeItem< Node, Edge > EdgeItemType
bool newEdge(const Bond &bond)
const Atom * getAtom() const
bool operator!=(const NodeItem &item) const
Size getDegree() const
std::list< EdgeItem< Node, Edge > * >::iterator Iterator
NodeItem< Node, Edge > NodeItemType
void deleteEdge_(EdgeItemType *item)
bool operator==(const NodeItem &item) const
void setData(const Node &data)
std::list< EdgeItemType * > adjacent_edges_
EdgeItem< Node, Edge > EdgeItemType
std::list< EdgeItem< Node, Edge > * >::const_iterator ConstIterator