Chemical Data Processing Library C++ API - Version 1.2.0
Atom2DCoordinatesCalculator.hpp
Go to the documentation of this file.
1 /*
2  * Atom2DCoordinatesCalculator.hpp
3  *
4  * This file is part of the Chemical Data Processing Toolkit
5  *
6  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; see the file COPYING. If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
29 #ifndef CDPL_CHEM_ATOM2DCOORDINATESCALCULATOR_HPP
30 #define CDPL_CHEM_ATOM2DCOORDINATESCALCULATOR_HPP
31 
32 #include <cstddef>
33 #include <vector>
34 #include <list>
35 #include <deque>
36 #include <map>
37 #include <utility>
38 
39 #include <boost/unordered_set.hpp>
40 
41 #include "CDPL/Chem/APIPrefix.hpp"
43 #include "CDPL/Math/Matrix.hpp"
44 #include "CDPL/Util/BitSet.hpp"
47 
48 
49 namespace CDPL
50 {
51 
52  namespace Chem
53  {
54 
55  class Atom;
56  class Bond;
57  class MolecularGraph;
58  class Fragment;
59 
64  {
65 
66  public:
71 
82 
84 
86 
95  void calculate(const MolecularGraph& molgraph, Math::Vector2DArray& coords);
96 
97  private:
98  class RingInfo
99  {
100 
101  public:
102  void init(const MolecularGraph*, const Fragment&, std::size_t, std::size_t);
103 
104  const Fragment& getFragment() const;
105 
106  const Util::BitSet& getAtomMask() const;
107  const Util::BitSet& getBondMask() const;
108 
109  double getPriority() const;
110  void setPriority(double);
111 
112  std::size_t getSize() const;
113 
114  private:
115  const Fragment* fragment;
116  Util::BitSet atomMask;
117  Util::BitSet bondMask;
118  double priority;
119  };
120 
121  class LGNode;
122 
123  class LGEdge
124  {
125 
126  public:
127  enum Type
128  {
129 
130  BOND_EDGE,
131  SPIRO_EDGE
132  };
133 
134  void init(const MolecularGraph*, const Atom*, LGNode*, LGNode*);
135  void init(const MolecularGraph*, const Bond*, LGNode*, LGNode*);
136 
137  const Atom* getSpiroCenter() const;
138  const Bond* getBond() const;
139 
140  LGNode* otherNode(const LGNode*) const;
141 
142  Type getType() const;
143 
144  bool hasConfigConstraint() const;
145  bool configConstraintFulfilled(const Math::Vector2DArray&) const;
146 
147  private:
148  bool initConfigInfo();
149 
150  const MolecularGraph* molGraph;
151  const Atom* spiroCenter;
152  const Bond* bond;
153  LGNode* node1;
154  LGNode* node2;
155  Type type;
156  bool hasConfig;
157  unsigned int configuration;
158  const Atom* configRefAtoms[2];
159  };
160 
161  typedef std::vector<std::size_t> AtomIndexList;
162  typedef std::vector<const Bond*> BondList;
163  typedef std::vector<LGNode*> NodeList;
164 
165  class LGNode
166  {
167 
168  public:
169  enum Type
170  {
171 
172  RING_SYS = 0x1,
173  CHAIN_ATOM = 0x2,
174  END_ATOM = 0x3
175  };
176 
177  enum Direction
178  {
179 
180  UP,
181  DOWN
182  };
183 
184  virtual ~LGNode() {}
185 
186  void init(const MolecularGraph* molgraph);
187 
188  virtual void addEdge(const Atom*, const LGEdge*) = 0;
189 
190  virtual void getChildNodes(NodeList&) const = 0;
191 
192  virtual void init() = 0;
193 
194  virtual void createChildLayouts() = 0;
195 
196  virtual double getPriority() const = 0;
197 
198  virtual std::size_t getChainID() const = 0;
199 
200  virtual void layout() = 0;
201  virtual bool layout(double, const Math::Vector2D&, std::size_t&, std::size_t, bool) = 0;
202 
203  virtual bool layoutChildNodes(std::size_t&, std::size_t, bool) = 0;
204 
205  virtual Type getType() const = 0;
206 
207  virtual double getAngularDemand(const Atom*) const;
208 
209  virtual bool setParentEdge(const LGEdge*, Direction) = 0;
210 
211  protected:
212  std::size_t countAtomCollisions(const AtomIndexList&, const AtomIndexList&, const Math::Vector2DArray&);
213  std::size_t countAtomCollisionsForAtom(std::size_t, const AtomIndexList&, const Math::Vector2DArray&);
214 
215  std::size_t countBondCollisions(const BondList&, const BondList&, const Math::Vector2DArray&);
216  std::size_t countBondCollisionsForBond(const Bond*, const BondList&, const Math::Vector2DArray&);
217 
218  std::size_t countAtomBondCollisions(const AtomIndexList&, const BondList&, const Math::Vector2DArray&);
219  std::size_t countBondCollisionsForAtom(std::size_t, const BondList&, const Math::Vector2DArray&);
220 
221  std::size_t countBondAtomCollisions(const BondList&, const AtomIndexList&, const Math::Vector2DArray&);
222  std::size_t countAtomCollisionsForBond(const Bond*, const AtomIndexList&, const Math::Vector2DArray&);
223 
224  bool testAtomBondCollision(std::size_t, const Bond*, const Math::Vector2DArray&);
225 
227  {
228 
229  NodeLayoutInfo(const LGEdge* edge, double angle):
230  edge(edge), angle(angle) {}
231 
232  const LGEdge* edge;
233  double angle;
234  };
235 
236  typedef std::vector<NodeLayoutInfo> NodeLayoutInfoList;
237  typedef std::pair<double, double> AngleRange;
238 
239  class EdgePriorityGreaterCmpFunc;
240 
241  class LinkedNodePriorityLessCmpFunc;
242  class LinkedNodePriorityEqualCmpFunc;
243 
244  class NodeLayoutInfoListEqualCmpFunc;
245 
246  const MolecularGraph* molGraph;
247  };
248 
249  typedef std::list<RingInfo*> RingInfoList;
250  typedef std::vector<const LGEdge*> EdgeList;
251 
252  class RingSysNode : public LGNode
253  {
254 
255  public:
256  RingSysNode();
257 
258  void init(const MolecularGraph*, const RingInfo*, Math::Vector2DArray&,
259  AtomIndexList&, BondList&);
260 
261  const Util::BitSet& getAtomMask() const;
262  const Util::BitSet& getBondMask() const;
263 
264  bool containsAtom(std::size_t) const;
265 
266  bool addRing(const RingInfo*);
267 
268  void addEdge(const Atom*, const LGEdge*);
269 
270  void getChildNodes(NodeList&) const;
271 
272  void init();
273 
274  double getPriority() const;
275 
276  std::size_t getChainID() const;
277 
278  void layout();
279  bool layout(double, const Math::Vector2D&, std::size_t&, std::size_t, bool);
280 
281  bool layoutChildNodes(std::size_t&, std::size_t, bool);
282 
283  Type getType() const;
284 
285  double getAngularDemand(const Atom*) const;
286 
287  bool setParentEdge(const LGEdge*, Direction);
288 
289  private:
290  bool layoutChildNodes(double, double, bool, double, std::size_t&, std::size_t, bool);
291  bool layoutChildNodes(std::size_t, std::size_t&, std::size_t, bool);
292 
293  void createChildLayouts();
294  void createChildLayouts(const Atom*, EdgeList&);
295 
296  bool layout(std::size_t, const Math::Vector2D&, double, bool, double, std::size_t&, std::size_t);
297 
298  void transformCoords(std::size_t, const Math::Vector2D&, double, bool, double);
299 
300  double transformEdgeAngle(double) const;
301 
302  void copyCoords();
303 
304  void commitAtomAndBondList() const;
305 
306  void calcCoords();
307 
308  void calcCoordsForRing(const RingInfo*);
309  void calcCoordsForRingSegment(const RingInfo*);
310 
311  void refineLayout();
312 
313  void initSpringLayoutParams();
314  void performSpringLayout();
315 
316  void performDistGeomLayout();
317  bool needDistGeomLayout() const;
318  bool addBondStereoDGConstraints(const RingInfo* ring_info);
319  void addBondAngleDGConstraints(const RingInfo* ring_info);
320  void addDefaultDGConstraints();
321 
322  const Chem::Atom* getExoBondAtom(const RingInfo* ring_info, const Atom& atom, std::size_t rings_nbrs[2]) const;
323 
324  Math::Vector2D computePartialDerivatives(std::size_t) const;
325  Math::Vector2D computePartialDerivative(std::size_t, std::size_t) const;
326 
327  bool layoutFinished(bool, double, double&, double&) const;
328 
329  void distributeWeightFactors(std::size_t, double, const Math::ULMatrix&);
330 
331  void calcFreeSweeps();
332 
333  bool getNextRingSegment(const RingInfo*);
334 
335  double calcCongestionFactor(const Math::Vector2D&) const;
336  double calcCongestionFactor(const Math::Vector2D&, const Util::BitSet&) const;
337 
338  typedef Util::DGCoordinatesGenerator<2, double> DGCoordsGenerator;
339  typedef std::pair<std::size_t, std::size_t> DistConstraintKey;
340  typedef boost::unordered_set<DistConstraintKey> DistConstraintKeySet;
341  typedef std::vector<const RingInfo*> RingInfoList;
342  typedef std::list<const RingInfo*> RingLayoutQueue;
343  typedef std::map<const Atom*, EdgeList> EdgeListMap;
344  typedef std::map<const Atom*, AngleRange> AngleRangeMap;
345  typedef std::deque<std::size_t> RingSegment;
346  typedef std::vector<std::vector<NodeLayoutInfoList> > NodeLayoutInfoListTable;
347  typedef std::vector<std::size_t> LayoutIndexTable;
348  typedef std::vector<const Atom*> AtomTable;
349  typedef std::vector<Math::Vector2D> EnergyDerivativeTable;
350  typedef std::vector<double> WeightFactorTable;
351 
352  Util::BitSet atomMask;
353  Util::BitSet bondMask;
354  Util::BitSet procAtomMask;
355  Util::BitSet tmpBitMask;
356  double priority;
357  RingInfoList ringList;
358  RingLayoutQueue ringLayoutQueue;
359  RingSegment ringSegment;
360  EdgeListMap edgeListMap;
361  AngleRangeMap freeSweepMap;
362  AtomIndexList atomList;
363  BondList bondList;
364  AtomIndexList* procAtomList;
365  BondList* procBondList;
366  Math::Vector2DArray localCoords;
367  Math::Vector2DArray* outputCoords;
368  const LGEdge* parentEdge;
369  const Atom* parentEdgeAtom;
370  EdgeList parentEdgeAtomEdges;
371  NodeLayoutInfoListTable childLayouts;
372  LayoutIndexTable childLayoutIndexTable;
373  AtomTable edgeAtomTable;
374  Math::Vector2D parentPos;
375  std::size_t rsysLayoutIndex;
376  double parentEdgeAngle;
377  double rsysRotAngle;
378  double rsysAxisAngle;
379  bool flipped;
380  WeightFactorTable layoutWeightFactors;
381  EnergyDerivativeTable layoutEnergyDerivatives;
382  Math::DMatrix layoutAtomDistances;
383  Math::DMatrix layoutSpringStrengths;
384  DGCoordsGenerator dgCoordsGenerator;
385  DistConstraintKeySet setDistConstraints;
386  };
387 
388  class AtomNode : public LGNode
389  {
390 
391  public:
392  void init(const MolecularGraph*, const Atom*, double, Math::Vector2DArray&, AtomIndexList&, BondList&);
393 
394  void addEdge(const Atom*, const LGEdge*);
395 
396  const Atom* getAtom() const;
397  std::size_t getAtomIndex() const;
398 
399  void getChildNodes(NodeList&) const;
400 
401  void init();
402 
403  double getPriority() const;
404 
405  std::size_t getChainID() const;
406 
407  void setChainID(std::size_t);
408 
409  void layout();
410  bool layout(double, const Math::Vector2D&, std::size_t&, std::size_t, bool);
411 
412  bool layoutChildNodes(std::size_t&, std::size_t, bool);
413 
414  Type getType() const;
415 
416  bool setParentEdge(const LGEdge*, Direction);
417 
418  private:
419  struct LayoutParameters
420  {
421 
422  LayoutParameters(std::size_t num_colls):
423  numCollisions(num_colls) {}
424 
425  std::size_t numCollisions;
426  double bondLength;
427  double edgeAngle;
428  };
429 
430  void layout(double, double, const Math::Vector2D&, std::size_t, std::size_t, LayoutParameters&);
431 
432  std::size_t getChildNodeTypePattern() const;
433 
434  void createChildLayouts();
435 
436  void createChildLayoutsD1();
437  void createChildLayoutsD2();
438  void createChildLayoutsD3();
439  void createChildLayoutsD4();
440  void createChildLayoutsDN();
441 
442  void removeChildLayoutSymmetryDuplicates();
443 
444  void removeParentEdge();
445 
446  void sortChildEdges();
447 
448  typedef std::vector<NodeLayoutInfoList> NodeLayoutInfoListTable;
449 
450  const Atom* atom;
451  std::size_t atomIndex;
452  bool isHydrogen;
453  Type type;
454  double priority;
455  std::size_t chainID;
456  AtomIndexList* procAtomList;
457  BondList* procBondList;
458  Math::Vector2DArray* outputCoords;
459  Direction chainDirection;
460  double parentEdgeAngle;
461  EdgeList edges;
462  const LGEdge* parentEdge;
463  NodeLayoutInfoListTable childLayouts;
464  std::size_t childLayoutIndex;
465  Direction childChainDirections[4];
466  };
467 
468  typedef std::pair<Math::Vector2D, Math::Vector2D> BoundingBox;
469 
470  void init(const MolecularGraph&, Math::Vector2DArray&);
471 
472  void extractRingInformation();
473 
474  void calcAtomPriorities();
475  void calcRingPriorities();
476 
477  void layoutComponents(Math::Vector2DArray&);
478  void layoutComponent(const Fragment&, Math::Vector2DArray&);
479 
480  void alignComponents(Math::Vector2DArray&);
481 
482  void moveComponent(const BoundingBox&, double, double, const Fragment&, Math::Vector2DArray&);
483  void addPoint(BoundingBox&, const Math::Vector2D&) const;
484  void calcBounds(BoundingBox&, const Fragment&, Math::Vector2DArray&) const;
485 
486  void createLayoutTree(const Fragment&, Math::Vector2DArray&);
487  void createRingSysNodes(const Fragment&, Math::Vector2DArray&);
488  void createAtomNodes(const Fragment&, Math::Vector2DArray&);
489  void createBondEdges(const Fragment&);
490  void createSpiroEdges(const Fragment&);
491 
492  void setAtomNodeChainIDs();
493 
494  void findLongestNodePath(AtomNode*, const AtomNode*);
495 
496  void createBFSNodeList();
497  void initNodes() const;
498 
499  void layoutNodes();
500  bool layoutChildNodes(std::size_t);
501 
502  LGEdge* allocEdge(const Atom*, LGNode*, LGNode*);
503  LGEdge* allocEdge(const Bond*, LGNode*, LGNode*);
504 
505  RingInfo* allocRingInfo(const Fragment&);
506  RingSysNode* allocRingSysNode(const RingInfo*, Math::Vector2DArray&);
507 
508  AtomNode* allocAtomNode(const Atom*, Math::Vector2DArray&);
509 
510  void freeAllocEdges();
511  void freeAllocRingInfos();
512  void freeAllocRingSysNodes();
513  void freeAllocAtomNodes();
514 
515  typedef std::vector<AtomNode*> AtomNodeList;
516  typedef std::vector<std::size_t> AtomPriorityTable;
517  typedef Util::ObjectStack<RingInfo> RingInfoCache;
518  typedef Util::ObjectStack<RingSysNode> RingSysNodeCache;
519  typedef Util::ObjectStack<AtomNode> AtomNodeCache;
520  typedef Util::ObjectStack<LGEdge> EdgeCache;
521  typedef std::vector<RingSysNode*> RingSysNodeList;
522 
523  const MolecularGraph* molGraph;
524  RingInfoCache ringInfoCache;
525  RingSysNodeCache ringSysNodeCache;
526  AtomNodeCache atomNodeCache;
527  EdgeCache edgeCache;
528  EdgeList edgeList;
529  RingInfoList ringList;
530  RingSysNodeList ringSysNodeList;
531  AtomNodeList atomNodeList;
532  RingInfoList tmpRingList;
533  NodeList bfsNodeList;
534  AtomNodeList atomNodeTable;
535  AtomNodeList longestAtomNodePath;
536  AtomNodeList currAtomNodePath;
537  AtomIndexList procAtomList;
538  BondList procBondList;
539  Util::BitSet atomMask;
540  Util::BitSet ringAtomMask;
541  Util::BitSet tmpBitMask;
542  AtomPriorityTable atomPriorityTable;
543  std::size_t numAtoms;
544  std::size_t numBonds;
545  bool strictLayoutGeometry;
546  std::size_t numLayoutCollisions;
547  std::size_t maxNumLayoutCollisions;
548  std::size_t backtrackingCount;
549  };
550  } // namespace Chem
551 } // namespace CDPL
552 
553 #endif // CDPL_CHEM_ATOM2DCOORDINATESCALCULATOR_HPP
Definition of the type CDPL::Util::BitSet.
Definition of the preprocessor macro CDPL_CHEM_API.
#define CDPL_CHEM_API
Tells the compiler/linker which classes, functions and variables are part of the library API.
Implementation of a distance geometry based coordinates generator.
Definition of matrix data types.
Definition of the class CDPL::Util::ObjectStack.
Definition of the class CDPL::Math::VectorArray.
Atom2DCoordinatesCalculator.
Definition: Atom2DCoordinatesCalculator.hpp:64
Atom2DCoordinatesCalculator(const MolecularGraph &molgraph, Math::Vector2DArray &coords)
Constructs the Atom2DCoordinatesCalculator instance and calculates 2D-coordinates for the atoms of th...
Atom2DCoordinatesCalculator()
Constructs the Atom2DCoordinatesCalculator instance.
Atom2DCoordinatesCalculator & operator=(const Atom2DCoordinatesCalculator &)=delete
void calculate(const MolecularGraph &molgraph, Math::Vector2DArray &coords)
Calculates 2D-coordinates for the atoms of the molecular graph molgraph.
Atom2DCoordinatesCalculator(const Atom2DCoordinatesCalculator &)=delete
Atom.
Definition: Atom.hpp:52
Fragment.
Definition: Fragment.hpp:52
MolecularGraph.
Definition: MolecularGraph.hpp:52
CDPL_BIOMOL_API const std::string & getChainID(const Chem::Atom &atom)
CDPL_BIOMOL_API void setChainID(Chem::Atom &atom, const std::string &id)
constexpr unsigned int DOWN
Specifies that the bond is directed downwards.
Definition: BondDirection.hpp:67
constexpr unsigned int UP
Specifies that the bond is directed upwards.
Definition: BondDirection.hpp:60
CDPL_CHEM_API unsigned int getType(const Atom &atom)
Matrix< unsigned long > ULMatrix
An unbounded dense matrix holding unsigned integers of type unsigned long.
Definition: Matrix.hpp:1824
CVector< double, 2 > Vector2D
A bounded 2 element vector holding floating point values of type double.
Definition: Vector.hpp:1632
VectorArray< Vector2D > Vector2DArray
An array of Math::Vector2D objects.
Definition: VectorArray.hpp:79
boost::dynamic_bitset BitSet
A dynamic bitset class.
Definition: BitSet.hpp:46
The namespace of the Chemical Data Processing Library.
Definition: Atom2DCoordinatesCalculator.hpp:227
const LGEdge * edge
Definition: Atom2DCoordinatesCalculator.hpp:232
double angle
Definition: Atom2DCoordinatesCalculator.hpp:233
NodeLayoutInfo(const LGEdge *edge, double angle)
Definition: Atom2DCoordinatesCalculator.hpp:229