BALL  1.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
28 namespace 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>
36 
40  template <typename Node, typename Edge>
41  class NodeItem
42  {
43  public:
47 
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>
93  class EdgeItem
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 
161  bool deleteNode(NodeItemType& node);
162  bool deleteEdge(EdgeItemType& edge);
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 
294  typename TSimpleMolecularGraph<Node, Edge>::NodeConstIterator node = G.beginNode();
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>
363  bool TSimpleMolecularGraph<Node, Edge>::deleteEdge(typename TSimpleMolecularGraph<Node, Edge>::EdgeItemType& 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