Chemical Data Processing Library C++ API - Version 1.4.0
SpatialEntityAlignment.hpp
Go to the documentation of this file.
1 /*
2  * SpatialEntityAlignment.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_SPATIALENTITYALIGNMENT_HPP
30 #define CDPL_CHEM_SPATIALENTITYALIGNMENT_HPP
31 
32 #include <cstddef>
33 #include <algorithm>
34 #include <vector>
35 #include <set>
36 #include <unordered_set>
37 #include <functional>
38 
39 #include <boost/functional/hash.hpp>
40 
43 #include "CDPL/Math/Matrix.hpp"
44 #include "CDPL/Math/Vector.hpp"
46 
47 
48 namespace CDPL
49 {
50 
51  namespace Chem
52  {
53 
69  template <typename T>
71  {
72 
73  typedef TopologicalEntityAlignment<T> TopologicalAlignment;
74 
75  public:
79  typedef T EntityType;
80 
85 
90 
94  typedef std::function<const Math::Vector3D&(const EntityType&)> Entity3DCoordinatesFunction;
95 
99  typedef std::function<double(const EntityType&)> EntityWeightFunction;
100 
104  typedef typename TopologicalAlignment::EntityMatchFunction EntityMatchFunction;
105 
109  typedef typename TopologicalAlignment::EntityPairMatchFunction EntityPairMatchFunction;
110 
115 
120 
126  void setMinTopologicalMappingSize(std::size_t min_size);
127 
134 
140 
146 
152 
158 
164 
170 
176 
182 
189 
195 
201  void performExhaustiveSearch(bool exhaustive);
202 
209 
215  void addEntity(const EntityType& entity, bool first_set);
216 
221  void clearEntities(bool first_set);
222 
227  std::size_t getNumEntities(bool first_set) const;
228 
234  ConstEntityIterator getEntitiesBegin(bool first_set) const;
235 
241  ConstEntityIterator getEntitiesEnd(bool first_set) const;
242 
250  const EntityType& getEntity(std::size_t idx, bool first_set) const;
251 
257 
262  void reset();
263 
272  const Math::Matrix4D& getTransform() const;
273 
279 
280  private:
281  void init();
282 
283  Util::STPairArray* allocTopMapping();
284 
285  struct TopMappingCmpFunc
286  {
287 
288  bool operator()(const Util::STPairArray* m1, const Util::STPairArray* m2) const
289  {
290  return (m1->getSize() > m2->getSize());
291  }
292  };
293 
294  struct TopMappingHashFunc
295  {
296 
297  std::size_t operator()(const Util::STPairArray* m) const
298  {
299  return boost::hash_value(m->getData());
300  }
301  };
302 
303  struct TopMappingEqCmpFunc
304  {
305 
306  bool operator()(const Util::STPairArray* m1, const Util::STPairArray* m2) const
307  {
308  return (m1->getData() == m2->getData());
309  }
310  };
311 
312  typedef Util::ObjectStack<Util::STPairArray> TopMappingCache;
313  typedef std::vector<Math::Vector3D> Vector3DArray;
314  typedef std::vector<double> DoubleArray;
315  typedef std::multiset<Util::STPairArray*, TopMappingCmpFunc> TopMappingSet;
316  typedef typename TopMappingSet::iterator TopMappingSetIterator;
317  typedef std::unordered_set<const Util::STPairArray*, TopMappingHashFunc, TopMappingEqCmpFunc> TopMappingHashSet;
318 
319  TopologicalAlignment topAlignment;
320  TopMappingSet topMappings;
321  TopMappingSetIterator nextTopMappingIter;
322  Util::STPairArray* currTopMapping;
323  TopologicalAlignmentConstraintFunction topAlignConstrFunc;
324  Entity3DCoordinatesFunction coordsFunc;
325  EntityWeightFunction weightFunc;
326  Math::KabschAlgorithm<double> kabschAlgorithm;
327  Vector3DArray firstSetCoords;
328  DoubleArray firstSetWeights;
329  Vector3DArray secondSetCoords;
330  DoubleArray secondSetWeights;
331  Math::DMatrix refPoints;
332  Math::DMatrix alignedPoints;
333  Math::DVector almntWeights;
334  Math::Matrix4D transform;
335  std::size_t minTopMappingSize;
336  bool changes;
337  bool exhaustiveMode;
338  TopMappingHashSet seenTopMappings;
339  TopMappingCache topMappingCache;
340  };
341  } // namespace Chem
342 } // namespace CDPL
343 
344 
345 // Implementation
346 
347 template <typename T>
349  minTopMappingSize(3), changes(true), exhaustiveMode(true), topMappingCache(5000)
350 {
351  currTopMapping = allocTopMapping();
352 }
353 
354 template <typename T>
356 {
357  minTopMappingSize = min_size;
358  changes = true;
359 }
360 
361 template <typename T>
363 {
364  return minTopMappingSize;
365 }
366 
367 template <typename T>
369 {
370  coordsFunc = func;
371  changes = true;
372 }
373 
374 template <typename T>
377 {
378  return coordsFunc;
379 }
380 
381 template <typename T>
383 {
384  weightFunc = func;
385  changes = true;
386 }
387 
388 template <typename T>
391 {
392  return weightFunc;
393 }
394 
395 template <typename T>
397 {
398  topAlignConstrFunc = func;
399  changes = true;
400 }
401 
402 template <typename T>
405 {
406  return topAlignConstrFunc;
407 }
408 
409 template <typename T>
411 {
412  topAlignment.setEntityMatchFunction(func);
413 }
414 
415 template <typename T>
418 {
419  return topAlignment.getEntityMatchFunction();
420 }
421 
422 template <typename T>
424 {
425  topAlignment.setEntityPairMatchFunction(func);
426 }
427 
428 template <typename T>
431 {
432  return topAlignment.getEntityPairMatchFunction();
433 }
434 
435 template <typename T>
437 {
438  exhaustiveMode = exhaustive;
439  changes = true;
440 }
441 
442 template <typename T>
444 {
445  return exhaustiveMode;
446 }
447 
448 template <typename T>
450 {
451  return topAlignment.getNumEntities(first_set);
452 }
453 
454 template <typename T>
456 {
457  topAlignment.addEntity(entity, first_set);
458  changes = true;
459 }
460 
461 template <typename T>
463 {
464  topAlignment.clearEntities(first_set);
465  changes = true;
466 }
467 
468 template <typename T>
471 {
472  return topAlignment.getEntitiesBegin(first_set);
473 }
474 
475 template <typename T>
478 {
479  return topAlignment.getEntitiesEnd(first_set);
480 }
481 
482 template <typename T>
484 CDPL::Chem::SpatialEntityAlignment<T>::getEntity(std::size_t idx, bool first_set) const
485 {
486  return topAlignment.getEntity(idx, first_set);
487 }
488 
489 template <typename T>
491 {
492  changes = true;
493 }
494 
495 template <typename T>
497 {
498  if (changes)
499  init();
500 
501  if (firstSetCoords.empty() || secondSetCoords.empty())
502  return false;
503 
504  bool have_weights = !firstSetWeights.empty();
505  std::size_t min_sub_mpg_size = (minTopMappingSize < 3 ? minTopMappingSize : std::size_t(3));
506 
507  while (nextTopMappingIter != topMappings.end()) {
508  currTopMapping = *nextTopMappingIter;
509 
510  std::size_t num_points = currTopMapping->getSize();
511 
512  refPoints.resize(3, num_points, false);
513  alignedPoints.resize(3, num_points, false);
514 
515  if (have_weights)
516  almntWeights.resize(num_points, 1.0);
517 
518  std::size_t i = 0;
519 
520  for (Util::STPairArray::ConstElementIterator it = currTopMapping->getElementsBegin(), end = currTopMapping->getElementsEnd();
521  it != end; ++it, i++) {
522 
523  std::size_t first_idx = it->first;
524  std::size_t sec_idx = it->second;
525 
526  column(refPoints, i) = firstSetCoords[first_idx];
527  column(alignedPoints, i) = secondSetCoords[sec_idx];
528 
529  if (have_weights)
530  almntWeights(i) = std::max(firstSetWeights[first_idx], secondSetWeights[sec_idx]);
531  }
532 
533  if (exhaustiveMode && (num_points > min_sub_mpg_size)) {
534  Util::STPairArray* sub_mpg = 0;
535 
536  for (std::size_t j = 0; j < num_points; j++) {
537  if (!sub_mpg)
538  sub_mpg = allocTopMapping();
539 
540  sub_mpg->clear();
541 
542  for (std::size_t k = 0; k < num_points; k++)
543  if (k != j)
544  sub_mpg->addElement(currTopMapping->getElement(k));
545 
546  if (!seenTopMappings.insert(sub_mpg).second) {
547  continue;
548  }
549 
550  topMappings.insert(sub_mpg);
551  sub_mpg = 0;
552  }
553 
554  if (sub_mpg)
555  topMappingCache.put();
556  }
557 
558  if (!have_weights) {
559  if (!kabschAlgorithm.align(alignedPoints, refPoints)) {
560  ++nextTopMappingIter;
561  continue;
562  }
563 
564  } else if (!kabschAlgorithm.align(alignedPoints, refPoints, almntWeights)) {
565  ++nextTopMappingIter;
566  continue;
567  }
568 
569  transform.assign(kabschAlgorithm.getTransform());
570  ++nextTopMappingIter;
571 
572  return true;
573  }
574 
575  return false;
576 }
577 
578 template <typename T>
580 {
581  return transform;
582 }
583 
584 template <typename T>
587 {
588  return *currTopMapping;
589 }
590 
591 template <typename T>
593 {
594  firstSetCoords.clear();
595  secondSetCoords.clear();
596 
597  firstSetWeights.clear();
598  secondSetWeights.clear();
599 
600  if (coordsFunc) {
601  for (ConstEntityIterator it = getEntitiesBegin(true), end = getEntitiesEnd(true); it != end; ++it) {
602  const EntityType& entity = *it;
603 
604  firstSetCoords.push_back(coordsFunc(entity));
605 
606  if (weightFunc)
607  firstSetWeights.push_back(weightFunc(entity));
608  }
609 
610  for (ConstEntityIterator it = getEntitiesBegin(false), end = getEntitiesEnd(false); it != end; ++it) {
611  const EntityType& entity = *it;
612 
613  secondSetCoords.push_back(coordsFunc(entity));
614 
615  if (weightFunc)
616  secondSetWeights.push_back(weightFunc(entity));
617  }
618  }
619 
620  topAlignment.reset();
621  topMappingCache.putAll();
622  seenTopMappings.clear();
623  topMappings.clear();
624 
625  currTopMapping = allocTopMapping();
626 
627  while (topAlignment.nextAlignment(*currTopMapping)) {
628  if (currTopMapping->getSize() < minTopMappingSize)
629  continue;
630 
631  if (topAlignConstrFunc && !topAlignConstrFunc(*currTopMapping))
632  continue;
633 
634  topMappings.insert(currTopMapping);
635  currTopMapping = allocTopMapping();
636  }
637 
638  currTopMapping->clear();
639 
640  nextTopMappingIter = topMappings.begin();
641  changes = false;
642 }
643 
644 template <typename T>
647 {
648  return topMappingCache.get();
649 }
650 
651 #endif // CDPL_CHEM_SPATIALENTITYALIGNMENT_HPP
Implementation of the Kabsch algorithm.
Definition of matrix data types.
Definition of class CDPL::Util::ObjectStack.
Definition of class CDPL::Chem::TopologicalEntityAlignment.
Definition of vector data types.
Computes a spatial alignment between two sets of 3D entities by combining topological entity matching...
Definition: SpatialEntityAlignment.hpp:71
const EntityType & getEntity(std::size_t idx, bool first_set) const
Returns a non-const reference to the stored entity at index idx in the specified set.
Definition: SpatialEntityAlignment.hpp:484
ConstEntityIterator getEntitiesBegin(bool first_set) const
Returns a constant iterator pointing to the beginning of the entities stored in the specified set.
Definition: SpatialEntityAlignment.hpp:470
bool exhaustiveSearchPerformed() const
Tells whether or not additional topological entity mappings (derived from the found max....
Definition: SpatialEntityAlignment.hpp:443
ConstEntityIterator getEntitiesEnd(bool first_set) const
Returns a constant iterator pointing to the end of the entities stored in the specified set.
Definition: SpatialEntityAlignment.hpp:477
void setEntity3DCoordinatesFunction(const Entity3DCoordinatesFunction &func)
Specifies a function for the retrieval of entity 3D coordinates.
Definition: SpatialEntityAlignment.hpp:368
void addEntity(const EntityType &entity, bool first_set)
Adds an entity to the specified entity set.
Definition: SpatialEntityAlignment.hpp:455
void performExhaustiveSearch(bool exhaustive)
Specifies whether additional topological entity mappings (derived from the found max....
Definition: SpatialEntityAlignment.hpp:436
void setTopAlignmentConstraintFunction(const TopologicalAlignmentConstraintFunction &func)
Specifies a function for restricting allowed topological entity alignments.
Definition: SpatialEntityAlignment.hpp:396
void clearEntities(bool first_set)
Removes all entities in the specified entity set.
Definition: SpatialEntityAlignment.hpp:462
virtual ~SpatialEntityAlignment()
Virtual destructor.
Definition: SpatialEntityAlignment.hpp:119
const EntityMatchFunction & getEntityMatchFunction() const
Returns the function that was registered for restricting allowed entity mappings.
Definition: SpatialEntityAlignment.hpp:417
TopologicalAlignment::ConstEntityIterator ConstEntityIterator
A constant iterator over the stored entities.
Definition: SpatialEntityAlignment.hpp:84
TopologicalAlignment::EntityMatchFunction EntityMatchFunction
Generic wrapper class used to store a user-defined topological entity match constraint function.
Definition: SpatialEntityAlignment.hpp:104
void reset()
Discards the current alignment search state so that the next call to nextAlignment() restarts the top...
Definition: SpatialEntityAlignment.hpp:490
std::size_t getMinTopologicalMappingSize()
Returns the minimum number of topologically mapped entities that is required to enable a subsequent s...
Definition: SpatialEntityAlignment.hpp:362
bool nextAlignment()
Searches for the next alignment solution.
Definition: SpatialEntityAlignment.hpp:496
void setMinTopologicalMappingSize(std::size_t min_size)
Specifies the minimum number of topologically mapped entities that is required to enable a subsequent...
Definition: SpatialEntityAlignment.hpp:355
std::function< double(const EntityType &)> EntityWeightFunction
Generic wrapper class used to store a user-defined entity alignment weight function.
Definition: SpatialEntityAlignment.hpp:99
const Entity3DCoordinatesFunction & getEntity3DCoordinatesFunction() const
Returns the function that was registered for the retrieval of entity 3D coordinates.
Definition: SpatialEntityAlignment.hpp:376
void setEntityPairMatchFunction(const EntityPairMatchFunction &func)
Specifies a function for checking the compatibility of entity pairs in the search for alignment solut...
Definition: SpatialEntityAlignment.hpp:423
const Math::Matrix4D & getTransform() const
Returns the alignment transformation matrix that was calculated in the last successful call to nextAl...
Definition: SpatialEntityAlignment.hpp:579
std::function< bool(const Util::STPairArray &)> TopologicalAlignmentConstraintFunction
Generic wrapper class used to store a user-defined predicate to restrict allowed topological entity a...
Definition: SpatialEntityAlignment.hpp:89
const TopologicalAlignmentConstraintFunction & getTopAlignmentConstraintFunction() const
Returns the function that was registered for restricting allowed topological entity alignments.
Definition: SpatialEntityAlignment.hpp:404
const EntityPairMatchFunction & getEntityPairMatchFunction() const
Returns the function that was registered for checking the compatibility of entity pairs.
Definition: SpatialEntityAlignment.hpp:430
TopologicalAlignment::EntityPairMatchFunction EntityPairMatchFunction
Generic wrapper class used to store a user-defined entity pair match constraint function.
Definition: SpatialEntityAlignment.hpp:109
void setEntityMatchFunction(const EntityMatchFunction &func)
Specifies a function for restricting allowed entity mappings in the search for alignment solutions.
Definition: SpatialEntityAlignment.hpp:410
std::size_t getNumEntities(bool first_set) const
Returns the number of entities in the specified alignment entity set.
Definition: SpatialEntityAlignment.hpp:449
void setEntityWeightFunction(const EntityWeightFunction &func)
Specifies a function for the retrieval of entity weights for spatial alignment.
Definition: SpatialEntityAlignment.hpp:382
std::function< const Math::Vector3D &(const EntityType &)> Entity3DCoordinatesFunction
Generic wrapper class used to store a user-defined entity 3D coordinates function.
Definition: SpatialEntityAlignment.hpp:94
T EntityType
The actual entity type.
Definition: SpatialEntityAlignment.hpp:79
const EntityWeightFunction & getEntityWeightFunction() const
Returns the function that was registered for the retrieval of entity weights for spatial alignment.
Definition: SpatialEntityAlignment.hpp:390
SpatialEntityAlignment()
Constructs the SpatialEntityAlignment instance.
Definition: SpatialEntityAlignment.hpp:348
const Util::STPairArray & getTopologicalMapping() const
Returns the topological entity mapping resulting from the last successful call to nextAlignment().
Definition: SpatialEntityAlignment.hpp:586
Computes a topological alignment between two sets of arbitrary entities by performing a maximum commo...
Definition: TopologicalEntityAlignment.hpp:65
boost::indirect_iterator< typename EntitySet::const_iterator, const EntityType > ConstEntityIterator
A constant iterator over the stored entities.
Definition: TopologicalEntityAlignment.hpp:81
Dynamic array class providing amortized constant time access to arbitrary elements.
Definition: Array.hpp:92
void clear()
Erases all elements.
Definition: Array.hpp:743
StorageType::const_iterator ConstElementIterator
A constant random access iterator used to iterate over the elements of the array.
Definition: Array.hpp:128
std::size_t getSize() const
Returns the number of elements stored in the array.
Definition: Array.hpp:707
void addElement(const ValueType &value=ValueType())
Inserts a new element at the end of the array.
Definition: Array.hpp:768
constexpr unsigned int T
Specifies Hydrogen (Tritium).
Definition: AtomType.hpp:67
constexpr unsigned int m
Specifies that the stereocenter has m configuration.
Definition: CIPDescriptor.hpp:116
Matrix< double > DMatrix
Unbounded dense matrix holding floating-point values of type double..
Definition: Matrix.hpp:3469
VectorArray< Vector3D > Vector3DArray
Array storing vectors of type Math::Vector3D.
Definition: VectorArray.hpp:87
MatrixColumn< M > column(MatrixExpression< M > &e, typename MatrixColumn< M >::SizeType j)
Returns a mutable column proxy for column j of the matrix expression e.
Definition: MatrixProxy.hpp:1400
CMatrix< double, 4, 4 > Matrix4D
Bounded 4×4 matrix holding floating-point values of type double.
Definition: Matrix.hpp:3509
Vector< double > DVector
Unbounded dense vector holding floating-point values of type double.
Definition: Vector.hpp:3268
CVector< double, 3 > Vector3D
Bounded 3 element vector holding floating-point values of type double.
Definition: Vector.hpp:3218
void transform(VectorArray< CVector< T, Dim > > &va, const CMatrix< T1, Dim, Dim > &xform)
Transforms each -dimensional vector in the array with the -dimensional square matrix xform.
Definition: VectorArrayFunctions.hpp:54
Array< STPair > STPairArray
Array storing pairs of unsigned integers of type std::size_t.
Definition: Array.hpp:593
The namespace of the Chemical Data Processing Library.