29 #ifndef CDPL_CHEM_ATOM2DCOORDINATESCALCULATOR_HPP
30 #define CDPL_CHEM_ATOM2DCOORDINATESCALCULATOR_HPP
39 #include <boost/unordered_set.hpp>
100 const Fragment& getFragment()
const;
105 double getPriority()
const;
106 void setPriority(
double);
108 std::size_t getSize()
const;
130 void init(
const MolecularGraph*,
const Atom*, LGNode*, LGNode*);
131 void init(
const MolecularGraph*,
const Bond*, LGNode*, LGNode*);
133 const Atom* getSpiroCenter()
const;
134 const Bond* getBond()
const;
136 LGNode* otherNode(
const LGNode*)
const;
140 bool hasConfigConstraint()
const;
144 bool initConfigInfo();
146 const MolecularGraph* molGraph;
147 const Atom* spiroCenter;
153 unsigned int configuration;
154 const Atom* configRefAtoms[2];
157 typedef std::vector<std::size_t> AtomIndexList;
158 typedef std::vector<const Bond*> BondList;
159 typedef std::vector<LGNode*> NodeList;
182 void init(
const MolecularGraph* molgraph);
184 virtual void addEdge(
const Atom*,
const LGEdge*) = 0;
186 virtual void getChildNodes(NodeList&)
const = 0;
188 virtual void init() = 0;
190 virtual void createChildLayouts() = 0;
192 virtual double getPriority()
const = 0;
196 virtual void layout() = 0;
197 virtual bool layout(
double,
const Math::Vector2D&, std::size_t&, std::size_t,
bool) = 0;
199 virtual bool layoutChildNodes(std::size_t&, std::size_t,
bool) = 0;
201 virtual Type
getType()
const = 0;
203 virtual double getAngularDemand(
const Atom*)
const;
205 virtual bool setParentEdge(
const LGEdge*, Direction) = 0;
208 std::size_t countAtomCollisions(
const AtomIndexList&,
const AtomIndexList&,
const Math::Vector2DArray&);
209 std::size_t countAtomCollisionsForAtom(std::size_t,
const AtomIndexList&,
const Math::Vector2DArray&);
211 std::size_t countBondCollisions(
const BondList&,
const BondList&,
const Math::Vector2DArray&);
212 std::size_t countBondCollisionsForBond(
const Bond*,
const BondList&,
const Math::Vector2DArray&);
214 std::size_t countAtomBondCollisions(
const AtomIndexList&,
const BondList&,
const Math::Vector2DArray&);
215 std::size_t countBondCollisionsForAtom(std::size_t,
const BondList&,
const Math::Vector2DArray&);
217 std::size_t countBondAtomCollisions(
const BondList&,
const AtomIndexList&,
const Math::Vector2DArray&);
218 std::size_t countAtomCollisionsForBond(
const Bond*,
const AtomIndexList&,
const Math::Vector2DArray&);
226 edge(edge), angle(angle) {}
232 typedef std::vector<NodeLayoutInfo> NodeLayoutInfoList;
233 typedef std::pair<double, double> AngleRange;
235 class EdgePriorityGreaterCmpFunc;
237 class LinkedNodePriorityLessCmpFunc;
238 class LinkedNodePriorityEqualCmpFunc;
240 class NodeLayoutInfoListEqualCmpFunc;
245 typedef std::list<RingInfo*> RingInfoList;
246 typedef std::vector<const LGEdge*> EdgeList;
248 class RingSysNode :
public LGNode
255 AtomIndexList&, BondList&);
260 bool containsAtom(std::size_t)
const;
262 bool addRing(
const RingInfo*);
264 void addEdge(
const Atom*,
const LGEdge*);
266 void getChildNodes(NodeList&)
const;
270 double getPriority()
const;
275 bool layout(
double,
const Math::Vector2D&, std::size_t&, std::size_t,
bool);
277 bool layoutChildNodes(std::size_t&, std::size_t,
bool);
281 double getAngularDemand(
const Atom*)
const;
283 bool setParentEdge(
const LGEdge*, Direction);
286 bool layoutChildNodes(
double,
double,
bool,
double, std::size_t&, std::size_t,
bool);
287 bool layoutChildNodes(std::size_t, std::size_t&, std::size_t,
bool);
289 void createChildLayouts();
290 void createChildLayouts(
const Atom*, EdgeList&);
292 bool layout(std::size_t,
const Math::Vector2D&,
double,
bool,
double, std::size_t&, std::size_t);
294 void transformCoords(std::size_t,
const Math::Vector2D&,
double,
bool,
double);
296 double transformEdgeAngle(
double)
const;
300 void commitAtomAndBondList()
const;
304 void calcCoordsForRing(
const RingInfo*);
305 void calcCoordsForRingSegment(
const RingInfo*);
309 void initSpringLayoutParams();
310 void performSpringLayout();
312 void performDistGeomLayout();
313 bool needDistGeomLayout()
const;
314 bool addBondStereoDGConstraints(
const RingInfo* ring_info);
315 void addBondAngleDGConstraints(
const RingInfo* ring_info);
316 void addDefaultDGConstraints();
318 const Chem::Atom* getExoBondAtom(
const RingInfo* ring_info,
const Atom& atom, std::size_t rings_nbrs[2])
const;
321 Math::Vector2D computePartialDerivative(std::size_t, std::size_t)
const;
323 bool layoutFinished(
bool,
double,
double&,
double&)
const;
325 void distributeWeightFactors(std::size_t,
double,
const Math::ULMatrix&);
327 void calcFreeSweeps();
329 bool getNextRingSegment(
const RingInfo*);
335 typedef std::pair<std::size_t, std::size_t> DistConstraintKey;
336 typedef boost::unordered_set<DistConstraintKey> DistConstraintKeySet;
337 typedef std::vector<const RingInfo*> RingInfoList;
338 typedef std::list<const RingInfo*> RingLayoutQueue;
339 typedef std::map<const Atom*, EdgeList> EdgeListMap;
340 typedef std::map<const Atom*, AngleRange> AngleRangeMap;
341 typedef std::deque<std::size_t> RingSegment;
342 typedef std::vector<std::vector<NodeLayoutInfoList> > NodeLayoutInfoListTable;
343 typedef std::vector<std::size_t> LayoutIndexTable;
344 typedef std::vector<const Atom*> AtomTable;
345 typedef std::vector<Math::Vector2D> EnergyDerivativeTable;
346 typedef std::vector<double> WeightFactorTable;
353 RingInfoList ringList;
354 RingLayoutQueue ringLayoutQueue;
355 RingSegment ringSegment;
356 EdgeListMap edgeListMap;
357 AngleRangeMap freeSweepMap;
358 AtomIndexList atomList;
360 AtomIndexList* procAtomList;
361 BondList* procBondList;
364 const LGEdge* parentEdge;
365 const Atom* parentEdgeAtom;
366 EdgeList parentEdgeAtomEdges;
367 NodeLayoutInfoListTable childLayouts;
368 LayoutIndexTable childLayoutIndexTable;
369 AtomTable edgeAtomTable;
371 std::size_t rsysLayoutIndex;
372 double parentEdgeAngle;
374 double rsysAxisAngle;
376 WeightFactorTable layoutWeightFactors;
377 EnergyDerivativeTable layoutEnergyDerivatives;
380 DGCoordsGenerator dgCoordsGenerator;
381 DistConstraintKeySet setDistConstraints;
384 class AtomNode :
public LGNode
390 void addEdge(
const Atom*,
const LGEdge*);
392 const Atom* getAtom()
const;
393 std::size_t getAtomIndex()
const;
395 void getChildNodes(NodeList&)
const;
399 double getPriority()
const;
406 bool layout(
double,
const Math::Vector2D&, std::size_t&, std::size_t,
bool);
408 bool layoutChildNodes(std::size_t&, std::size_t,
bool);
412 bool setParentEdge(
const LGEdge*, Direction);
415 struct LayoutParameters
418 LayoutParameters(std::size_t num_colls):
419 numCollisions(num_colls) {}
421 std::size_t numCollisions;
426 void layout(
double,
double,
const Math::Vector2D&, std::size_t, std::size_t, LayoutParameters&);
428 std::size_t getChildNodeTypePattern()
const;
430 void createChildLayouts();
432 void createChildLayoutsD1();
433 void createChildLayoutsD2();
434 void createChildLayoutsD3();
435 void createChildLayoutsD4();
436 void createChildLayoutsDN();
438 void removeChildLayoutSymmetryDuplicates();
440 void removeParentEdge();
442 void sortChildEdges();
444 typedef std::vector<NodeLayoutInfoList> NodeLayoutInfoListTable;
447 std::size_t atomIndex;
452 AtomIndexList* procAtomList;
453 BondList* procBondList;
455 Direction chainDirection;
456 double parentEdgeAngle;
458 const LGEdge* parentEdge;
459 NodeLayoutInfoListTable childLayouts;
460 std::size_t childLayoutIndex;
461 Direction childChainDirections[4];
464 typedef std::pair<Math::Vector2D, Math::Vector2D> BoundingBox;
466 Atom2DCoordinatesCalculator(
const Atom2DCoordinatesCalculator&);
468 Atom2DCoordinatesCalculator& operator=(
const Atom2DCoordinatesCalculator&);
472 void extractRingInformation();
474 void calcAtomPriorities();
475 void calcRingPriorities();
482 void moveComponent(
const BoundingBox&,
double,
double,
const Fragment&,
Math::Vector2DArray&);
489 void createBondEdges(
const Fragment&);
490 void createSpiroEdges(
const Fragment&);
492 void setAtomNodeChainIDs();
494 void findLongestNodePath(AtomNode*,
const AtomNode*);
496 void createBFSNodeList();
497 void initNodes()
const;
500 bool layoutChildNodes(std::size_t);
502 LGEdge* allocEdge(
const Atom*, LGNode*, LGNode*);
503 LGEdge* allocEdge(
const Bond*, LGNode*, LGNode*);
505 RingInfo* allocRingInfo(
const Fragment&);
510 void freeAllocEdges();
511 void freeAllocRingInfos();
512 void freeAllocRingSysNodes();
513 void freeAllocAtomNodes();
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;
523 const MolecularGraph* molGraph;
524 RingInfoCache ringInfoCache;
525 RingSysNodeCache ringSysNodeCache;
526 AtomNodeCache atomNodeCache;
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;
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;
553 #endif // CDPL_CHEM_ATOM2DCOORDINATESCALCULATOR_HPP