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 
202  void performExhaustiveSearch(bool exhaustive);
203 
211 
217  void addEntity(const EntityType& entity, bool first_set);
218 
223  void clearEntities(bool first_set);
224 
229  std::size_t getNumEntities(bool first_set) const;
230 
236  ConstEntityIterator getEntitiesBegin(bool first_set) const;
237 
243  ConstEntityIterator getEntitiesEnd(bool first_set) const;
244 
252  const EntityType& getEntity(std::size_t idx, bool first_set) const;
253 
259 
264  void reset();
265 
274  const Math::Matrix4D& getTransform() const;
275 
281 
282  private:
283  void init();
284 
285  Util::STPairArray* allocTopMapping();
286 
287  struct TopMappingCmpFunc
288  {
289 
290  bool operator()(const Util::STPairArray* m1, const Util::STPairArray* m2) const
291  {
292  return (m1->getSize() > m2->getSize());
293  }
294  };
295 
296  struct TopMappingHashFunc
297  {
298 
299  std::size_t operator()(const Util::STPairArray* m) const
300  {
301  return boost::hash_value(m->getData());
302  }
303  };
304 
305  struct TopMappingEqCmpFunc
306  {
307 
308  bool operator()(const Util::STPairArray* m1, const Util::STPairArray* m2) const
309  {
310  return (m1->getData() == m2->getData());
311  }
312  };
313 
314  typedef Util::ObjectStack<Util::STPairArray> TopMappingCache;
315  typedef std::vector<Math::Vector3D> Vector3DArray;
316  typedef std::vector<double> DoubleArray;
317  typedef std::multiset<Util::STPairArray*, TopMappingCmpFunc> TopMappingSet;
318  typedef typename TopMappingSet::iterator TopMappingSetIterator;
319  typedef std::unordered_set<const Util::STPairArray*, TopMappingHashFunc, TopMappingEqCmpFunc> TopMappingHashSet;
320 
321  TopologicalAlignment topAlignment;
322  TopMappingSet topMappings;
323  TopMappingSetIterator nextTopMappingIter;
324  Util::STPairArray* currTopMapping;
325  TopologicalAlignmentConstraintFunction topAlignConstrFunc;
326  Entity3DCoordinatesFunction coordsFunc;
327  EntityWeightFunction weightFunc;
328  Math::KabschAlgorithm<double> kabschAlgorithm;
329  Vector3DArray firstSetCoords;
330  DoubleArray firstSetWeights;
331  Vector3DArray secondSetCoords;
332  DoubleArray secondSetWeights;
333  Math::DMatrix refPoints;
334  Math::DMatrix alignedPoints;
335  Math::DVector almntWeights;
336  Math::Matrix4D transform;
337  std::size_t minTopMappingSize;
338  bool changes;
339  bool exhaustiveMode;
340  TopMappingHashSet seenTopMappings;
341  TopMappingCache topMappingCache;
342  };
343  } // namespace Chem
344 } // namespace CDPL
345 
346 
347 // Implementation
348 
349 template <typename T>
351  minTopMappingSize(3), changes(true), exhaustiveMode(true), topMappingCache(5000)
352 {
353  currTopMapping = allocTopMapping();
354 }
355 
356 template <typename T>
358 {
359  minTopMappingSize = min_size;
360  changes = true;
361 }
362 
363 template <typename T>
365 {
366  return minTopMappingSize;
367 }
368 
369 template <typename T>
371 {
372  coordsFunc = func;
373  changes = true;
374 }
375 
376 template <typename T>
379 {
380  return coordsFunc;
381 }
382 
383 template <typename T>
385 {
386  weightFunc = func;
387  changes = true;
388 }
389 
390 template <typename T>
393 {
394  return weightFunc;
395 }
396 
397 template <typename T>
399 {
400  topAlignConstrFunc = func;
401  changes = true;
402 }
403 
404 template <typename T>
407 {
408  return topAlignConstrFunc;
409 }
410 
411 template <typename T>
413 {
414  topAlignment.setEntityMatchFunction(func);
415 }
416 
417 template <typename T>
420 {
421  return topAlignment.getEntityMatchFunction();
422 }
423 
424 template <typename T>
426 {
427  topAlignment.setEntityPairMatchFunction(func);
428 }
429 
430 template <typename T>
433 {
434  return topAlignment.getEntityPairMatchFunction();
435 }
436 
437 template <typename T>
439 {
440  exhaustiveMode = exhaustive;
441  changes = true;
442 }
443 
444 template <typename T>
446 {
447  return exhaustiveMode;
448 }
449 
450 template <typename T>
452 {
453  return topAlignment.getNumEntities(first_set);
454 }
455 
456 template <typename T>
458 {
459  topAlignment.addEntity(entity, first_set);
460  changes = true;
461 }
462 
463 template <typename T>
465 {
466  topAlignment.clearEntities(first_set);
467  changes = true;
468 }
469 
470 template <typename T>
473 {
474  return topAlignment.getEntitiesBegin(first_set);
475 }
476 
477 template <typename T>
480 {
481  return topAlignment.getEntitiesEnd(first_set);
482 }
483 
484 template <typename T>
486 CDPL::Chem::SpatialEntityAlignment<T>::getEntity(std::size_t idx, bool first_set) const
487 {
488  return topAlignment.getEntity(idx, first_set);
489 }
490 
491 template <typename T>
493 {
494  changes = true;
495 }
496 
497 template <typename T>
499 {
500  if (changes)
501  init();
502 
503  if (firstSetCoords.empty() || secondSetCoords.empty())
504  return false;
505 
506  bool have_weights = !firstSetWeights.empty();
507  std::size_t min_sub_mpg_size = (minTopMappingSize < 3 ? minTopMappingSize : std::size_t(3));
508 
509  while (nextTopMappingIter != topMappings.end()) {
510  currTopMapping = *nextTopMappingIter;
511 
512  std::size_t num_points = currTopMapping->getSize();
513 
514  refPoints.resize(3, num_points, false);
515  alignedPoints.resize(3, num_points, false);
516 
517  if (have_weights)
518  almntWeights.resize(num_points, 1.0);
519 
520  std::size_t i = 0;
521 
522  for (Util::STPairArray::ConstElementIterator it = currTopMapping->getElementsBegin(), end = currTopMapping->getElementsEnd();
523  it != end; ++it, i++) {
524 
525  std::size_t first_idx = it->first;
526  std::size_t sec_idx = it->second;
527 
528  column(refPoints, i) = firstSetCoords[first_idx];
529  column(alignedPoints, i) = secondSetCoords[sec_idx];
530 
531  if (have_weights)
532  almntWeights(i) = std::max(firstSetWeights[first_idx], secondSetWeights[sec_idx]);
533  }
534 
535  if (exhaustiveMode && (num_points > min_sub_mpg_size)) {
536  Util::STPairArray* sub_mpg = 0;
537 
538  for (std::size_t j = 0; j < num_points; j++) {
539  if (!sub_mpg)
540  sub_mpg = allocTopMapping();
541 
542  sub_mpg->clear();
543 
544  for (std::size_t k = 0; k < num_points; k++)
545  if (k != j)
546  sub_mpg->addElement(currTopMapping->getElement(k));
547 
548  if (!seenTopMappings.insert(sub_mpg).second) {
549  continue;
550  }
551 
552  topMappings.insert(sub_mpg);
553  sub_mpg = 0;
554  }
555 
556  if (sub_mpg)
557  topMappingCache.put();
558  }
559 
560  if (!have_weights) {
561  if (!kabschAlgorithm.align(alignedPoints, refPoints)) {
562  ++nextTopMappingIter;
563  continue;
564  }
565 
566  } else if (!kabschAlgorithm.align(alignedPoints, refPoints, almntWeights)) {
567  ++nextTopMappingIter;
568  continue;
569  }
570 
571  transform.assign(kabschAlgorithm.getTransform());
572  ++nextTopMappingIter;
573 
574  return true;
575  }
576 
577  return false;
578 }
579 
580 template <typename T>
582 {
583  return transform;
584 }
585 
586 template <typename T>
589 {
590  return *currTopMapping;
591 }
592 
593 template <typename T>
595 {
596  firstSetCoords.clear();
597  secondSetCoords.clear();
598 
599  firstSetWeights.clear();
600  secondSetWeights.clear();
601 
602  if (coordsFunc) {
603  for (ConstEntityIterator it = getEntitiesBegin(true), end = getEntitiesEnd(true); it != end; ++it) {
604  const EntityType& entity = *it;
605 
606  firstSetCoords.push_back(coordsFunc(entity));
607 
608  if (weightFunc)
609  firstSetWeights.push_back(weightFunc(entity));
610  }
611 
612  for (ConstEntityIterator it = getEntitiesBegin(false), end = getEntitiesEnd(false); it != end; ++it) {
613  const EntityType& entity = *it;
614 
615  secondSetCoords.push_back(coordsFunc(entity));
616 
617  if (weightFunc)
618  secondSetWeights.push_back(weightFunc(entity));
619  }
620  }
621 
622  topAlignment.reset();
623  topMappingCache.putAll();
624  seenTopMappings.clear();
625  topMappings.clear();
626 
627  currTopMapping = allocTopMapping();
628 
629  while (topAlignment.nextAlignment(*currTopMapping)) {
630  if (currTopMapping->getSize() < minTopMappingSize)
631  continue;
632 
633  if (topAlignConstrFunc && !topAlignConstrFunc(*currTopMapping))
634  continue;
635 
636  topMappings.insert(currTopMapping);
637  currTopMapping = allocTopMapping();
638  }
639 
640  currTopMapping->clear();
641 
642  nextTopMappingIter = topMappings.begin();
643  changes = false;
644 }
645 
646 template <typename T>
649 {
650  return topMappingCache.get();
651 }
652 
653 #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 entities (with 3D coordinates) by composing topologi...
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:486
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:472
bool exhaustiveSearchPerformed() const
Tells whether topological mappings are enumerated exhaustively before spatial alignment.
Definition: SpatialEntityAlignment.hpp:445
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:479
void setEntity3DCoordinatesFunction(const Entity3DCoordinatesFunction &func)
Specifies a function for the retrieval of entity 3D-coordinates.
Definition: SpatialEntityAlignment.hpp:370
void addEntity(const EntityType &entity, bool first_set)
Adds an entity to the specified alignment entity set.
Definition: SpatialEntityAlignment.hpp:457
void performExhaustiveSearch(bool exhaustive)
Specifies whether topological mappings shall be enumerated exhaustively before spatial alignment,...
Definition: SpatialEntityAlignment.hpp:438
void setTopAlignmentConstraintFunction(const TopologicalAlignmentConstraintFunction &func)
Specifies a function for restricting allowed topological entity alignments.
Definition: SpatialEntityAlignment.hpp:398
void clearEntities(bool first_set)
Removes all entities in the specified alignment entity set.
Definition: SpatialEntityAlignment.hpp:464
virtual ~SpatialEntityAlignment()
Virtual destructor.
Definition: SpatialEntityAlignment.hpp:119
const EntityMatchFunction & getEntityMatchFunction() const
Returns the function that was registered for restricting allowed topological entity mappings.
Definition: SpatialEntityAlignment.hpp:419
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:492
std::size_t getMinTopologicalMappingSize()
Returns the minimum number of topologically mapped entities that is required to enable a subsequent s...
Definition: SpatialEntityAlignment.hpp:364
bool nextAlignment()
Searches for the next alignment solution.
Definition: SpatialEntityAlignment.hpp:498
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:357
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:378
void setEntityPairMatchFunction(const EntityPairMatchFunction &func)
Specifies a function for checking the compatibility of entity-pairs in the search for alignment solut...
Definition: SpatialEntityAlignment.hpp:425
const Math::Matrix4D & getTransform() const
Returns the alignment transformation matrix that was calculated in the last successful call to nextAl...
Definition: SpatialEntityAlignment.hpp:581
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:406
const EntityPairMatchFunction & getEntityPairMatchFunction() const
Returns the function that was registered for checking the compatibility of entity-pairs.
Definition: SpatialEntityAlignment.hpp:432
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 topological entity mappings in the search for alignment ...
Definition: SpatialEntityAlignment.hpp:412
std::size_t getNumEntities(bool first_set) const
Returns the number of entities in the specified alignment entity set.
Definition: SpatialEntityAlignment.hpp:451
void setEntityWeightFunction(const EntityWeightFunction &func)
Specifies a function for the retrieval of entity weights for spatial alignment.
Definition: SpatialEntityAlignment.hpp:384
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:392
SpatialEntityAlignment()
Constructs the SpatialEntityAlignment instance.
Definition: SpatialEntityAlignment.hpp:350
const Util::STPairArray & getTopologicalMapping() const
Returns the topological entity mapping resulting from the last successful call to nextAlignment().
Definition: SpatialEntityAlignment.hpp:588
Computes a topological alignment between two sets of entities by reducing the alignment problem to a ...
Definition: TopologicalEntityAlignment.hpp:64
boost::indirect_iterator< typename EntitySet::const_iterator, const EntityType > ConstEntityIterator
A constant iterator over the stored entities.
Definition: TopologicalEntityAlignment.hpp:80
Dynamic array class providing amortized constant time access to arbitrary elements.
Definition: Array.hpp:92
void clear()
Erases all elements.
Definition: Array.hpp:740
StorageType::const_iterator ConstElementIterator
A constant random access iterator used to iterate over the elements of the array.
Definition: Array.hpp:125
std::size_t getSize() const
Returns the number of elements stored in the array.
Definition: Array.hpp:704
void addElement(const ValueType &value=ValueType())
Inserts a new element at the end of the array.
Definition: Array.hpp:765
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:3145
VectorArray< Vector3D > Vector3DArray
Array storing vectors of type Math::Vector3D.
Definition: VectorArray.hpp:85
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:1259
CMatrix< double, 4, 4 > Matrix4D
Bounded 4x4 matrix holding floating point values of type double.
Definition: Matrix.hpp:3185
Vector< double > DVector
Unbounded dense vector holding floating point values of type double.
Definition: Vector.hpp:2987
CVector< double, 3 > Vector3D
Bounded 3 element vector holding floating point values of type double.
Definition: Vector.hpp:2937
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:590
The namespace of the Chemical Data Processing Library.