BALL  1.4.79
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
reducedSurface.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_REDUCEDSURFACE_H
6 #define BALL_STRUCTURE_REDUCEDSURFACE_H
7 
8 #ifndef BALL_MATHC_COMMON_H
9 # include <BALL/MATHS/common.h>
10 #endif
11 
12 #ifndef BALL_MATHS_SIMPLEBOX3_H
13 # include <BALL/MATHS/simpleBox3.h>
14 #endif
15 
16 #ifndef BALL_MATHS_CIRCLE3_H
17 # include <BALL/MATHS/circle3.h>
18 #endif
19 
20 #ifndef BALL_MATHS_SPHERE_H
21 # include <BALL/MATHS/sphere3.h>
22 #endif
23 
24 #ifndef BALL_MATHS_VECTOR3_H
25 # include <BALL/MATHS/vector3.h>
26 #endif
27 
28 #ifndef BALL_DATATYPE_HASHSET_H
29 # include <BALL/DATATYPE/hashMap.h>
30 #endif
31 
32 #ifndef BALL_DATATYPE_HASHSET_H
33 # include <BALL/DATATYPE/hashSet.h>
34 #endif
35 
36 #ifndef BALL_COMMON_EXCEPTION_H
37 # include <BALL/COMMON/exception.h>
38 #endif
39 
40 #ifndef BALL_STRUCTURE_RSEDGE_H
41 # include <BALL/STRUCTURE/RSEdge.h>
42 #endif
43 
44 #ifndef BALL_STRUCTURE_RSFACE_H
45 # include <BALL/STRUCTURE/RSFace.h>
46 #endif
47 
48 #ifndef BALL_STRUCTURE_RSVERTEX_H
49 # include <BALL/STRUCTURE/RSVertex.h>
50 #endif
51 
52 #include <set>
53 #include <list>
54 #include <deque>
55 #include <vector>
56 
57 namespace BALL
58 {
60  {
62  : a(a1), b(a2)
63  {
64  if (a > b) std::swap(a, b);
65  }
66 
67  bool operator==(const SortedPosition2& pos) const
68  {
69  return (a == pos.a) && (b == pos.b);
70  }
71 
72  bool operator<(const SortedPosition2& pos) const
73  {
74  bool result;
75 
76  if (a < pos.a)
77  {
78  result = true;
79  }
80  else if (a > pos.a)
81  {
82  result = false;
83  }
84  else
85  {
86  result = b < pos.b;
87  }
88 
89  return result;
90  }
91 
94  };
95 
97  {
99  : a(a1), b(a2), c(a3)
100  {
101  if (a > b) std::swap(a, b);
102  if (a > c) std::swap(a, c);
103  if (b > c) std::swap(b, c);
104  }
105 
106  bool operator==(const SortedPosition3& pos) const
107  {
108  return (a == pos.a) && (b == pos.b) && (c == pos.c);
109  }
110 
111  bool operator<(const SortedPosition3& pos) const
112  {
113  bool result;
114 
115  if (a < pos.a)
116  {
117  result = true;
118  }
119  else if (a > pos.a)
120  {
121  result = false;
122  }
123  else
124  {
125  // a == pos.a, check b next
126  if (b < pos.b)
127  {
128  result = true;
129  }
130  else if ( b > pos.b)
131  {
132  result = false;
133  }
134  else
135  {
136  result = c < pos.c;
137  }
138  }
139 
140  return result;
141  }
142 
146  };
147 }
148 
149 namespace boost
150 {
151  template<>
152  struct hash<BALL::SortedPosition2>
153  {
154  inline size_t operator()(const BALL::SortedPosition2& p) const
155  {
156  size_t seed = 0;
157 
158  boost::hash_combine(seed, p.a);
159  boost::hash_combine(seed, p.b);
160 
161  return seed;
162  }
163  };
164 
165  template<>
166  struct hash<BALL::SortedPosition3>
167  {
168  inline size_t operator()(const BALL::SortedPosition3& p) const
169  {
170  size_t seed = 0;
171 
172  boost::hash_combine(seed, p.a);
173  boost::hash_combine(seed, p.b);
174  boost::hash_combine(seed, p.c);
175 
176  return seed;
177  }
178  };
179 }
180 
181 namespace BALL
182 {
183  class RSComputer;
184  class SolventExcludedSurface;
185  class SESComputer;
186  class SESSingularityCleaner;
187  class TriangulatedSES;
188  class SolventAccessibleSurface;
189  class TriangulatedSAS;
190  class SESTriangulator;
191 
196  {
197  public:
198 
211  friend class RSComputer;
213  friend class SESComputer;
214  friend class SESSingularityCleaner;
216  friend class TriangulatedSES;
217  friend class TriangulatedSAS;
218  friend class SESTriangulator;
219 
221 
222 
225 
230  ReducedSurface();
231 
236  ReducedSurface(const ReducedSurface& reduced_surface, bool = true);
237 
241  ReducedSurface(const std::vector< TSphere3<double> >& spheres,
242  const double& probe_radius);
243 
246  virtual ~ReducedSurface();
247 
249 
252 
256  void operator = (const ReducedSurface& reduced_surface);
257 
261  void set(const ReducedSurface& reduced_surface);
262 
265  void clear();
266 
269  void clean();
270 
272 
275 
279  Size numberOfAtoms() const;
280 
284  Size numberOfVertices() const;
285 
289  Size numberOfEdges() const;
290 
294  Size numberOfFaces() const;
295 
299  double getProbeRadius() const;
300 
305  TSphere3<double> getSphere(Position i) const
306  throw(Exception::IndexOverflow);
307 
312  RSVertex* getVertex(Position i) const
313  throw(Exception::IndexOverflow);
314 
319  RSEdge* getEdge(Position i) const
320  throw(Exception::IndexOverflow);
321 
326  RSFace* getFace(Position i) const
327  throw(Exception::IndexOverflow);
328 
332  void insert(RSVertex* rsvertex);
333 
337  void insert(RSEdge* rsedge);
338 
342  void insert(RSFace* rsface);
343 
347  double getMaximalRadius() const;
348 
352  TSimpleBox3<double> getBoundingBox() const;
353 
358  void deleteSimilarFaces(RSFace* face1, RSFace* face2);
359 
368  bool getAngle(RSFace* face1, RSFace* face2,
369  RSVertex* vertex1, RSVertex* vertex2,
370  TAngle<double>& angle, bool check = false) const;
371 
374  void compute()
375  throw(Exception::GeneralException,
376  Exception::DivisionByZero,
377  Exception::IndexOverflow);
378 
380 
381  private:
382 
383  /*_ Test whether a ReducedSurface object can be copied.
384  */
385  bool canBeCopied(const ReducedSurface& reduced_surface);
386 
387  /*_ Copy a ReducedSurface object.
388  */
389  void copy(const ReducedSurface& reduced_surface);
390 
391  /*_
392  */
393  void correctEdges(RSFace* face1, RSFace* face2,
394  RSEdge* edge1, RSEdge* edge2);
395 
396  /*_
397  */
398  void joinVertices(RSFace* face1, RSFace* face2,
399  RSVertex* vertex1, RSVertex* vertex2);
400 
401  /*_
402  */
403  void findSimilarVertices(RSFace* face1, RSFace* face2,
404  std::vector<RSVertex*>& rsvertex1,
405  std::vector<RSVertex*>& rsvertex2);
406 
407  /*_
408  */
409  void findSimilarEdges(RSFace* face1, RSFace* face2,
410  std::vector<RSEdge*>& rsedge1,
411  std::vector<RSEdge*>& rsedge2);
412 
413  protected:
414 
415  /*_ the number of atoms of the reduced surface
416  */
417  Size number_of_atoms_;
418 
419  /*_ the atoms of the molecule
420  */
421 
422  std::vector< TSphere3<double> > atom_;
423 
424  /*_ probe radius
425  */
426  double probe_radius_;
427 
428  /*_ the number of vertices of the reduced surface
429  */
430  Size number_of_vertices_;
431 
432  /*_ the vertices of the reduced surface
433  */
434  std::vector< RSVertex* > vertices_;
435 
436  /*_ the number of edges of the reduced surface
437  */
438  Size number_of_edges_;
439 
440  /*_ the edges of the reduced surface
441  */
442  std::vector< RSEdge* > edges_;
443 
444  /*_ the number of faces of the reduced surface
445  */
446  Size number_of_faces_;
447 
448  /*_ the faces of the reduced surface
449  */
450  std::vector< RSFace* > faces_;
451 
452  /*_ maximal radius of all atoms
453  */
454  double r_max_;
455 
456  /*_ bounding SimpleBox of the atom centers of the molecule
457  */
458  TSimpleBox3<double> bounding_box_;
459  };
460 
464 
468  BALL_EXPORT std::ostream& operator << (std::ostream& s, const ReducedSurface& rs);
469 
471 
476  {
477  public:
478 
479  BALL_CREATE(RSComputer)
480 
481 
484 
491  {
492  STATUS_OK = 0,
494  STATUS_NOT_TESTED
495  };
496 
503  {
504  STATUS_ON_SURFACE = 0,
506  STATUS_UNKNOWN
507  };
509 
511  {
512  ProbeStatus status[2];
514  };
515 
519 
524  RSComputer();
525 
529 
532  virtual ~RSComputer();
533 
535 
538 
541  void run()
542  throw(Exception::GeneralException,
543  Exception::DivisionByZero,
544  Exception::IndexOverflow);
545 
547 
548 
549  private:
550 
551  /*_ @name Computing reduced surface
552  */
554 
555  /*_
556  */
557  void preProcessing();
558 
559  /*_ Compute a RSComponent.
560  */
561  void getRSComponent()
562  throw(Exception::GeneralException,
563  Exception::DivisionByZero,
564  Exception::IndexOverflow);
565 
566  /*_ Treat all edges of a face.
567  @param face the RSFace to be treated
568  */
569  bool treatFace(RSFace* face)
570  throw(Exception::GeneralException,
571  Exception::DivisionByZero,
572  Exception::IndexOverflow);
573 
574  /*_ Roll over an edge that belongs to only one face and find the other one.
575  @param edge the RSEdge to be treated
576  */
577  bool treatEdge(RSEdge* edge)
578  throw(Exception::GeneralException,
579  Exception::DivisionByZero,
580  Exception::IndexOverflow);
581 
582  /*_ Treat an ambiguous situation.
583  All vertices on an ambiguous atom are deleted with all its edges and
584  faces. The radius of the atom is decreased by 10 EPSILON.
585  @param atom the index of the atom
586  */
587  void correct(Index atom);
588 
589  /*_ Check all new created vertices for extensions
590  */
591  void extendComponent()
592  throw(Exception::GeneralException,
593  Exception::DivisionByZero,
594  Exception::IndexOverflow);
595 
596  /*_ Find a third atom rolling over two vertices starting on a face.
597  From all atoms which can be touched by the probe sphere when it
598  touches the given two vertices we choose the one with smallest
599  rotation angle.
600  If the rotation angle equals zero, the probe sphere can touch four
601  atoms and an exception is thrown.
602  If no atom can be found an exception is thrown.
603  @param vertex1 the first vertex
604  @param vertex2 the second vertex
605  @param face the starting face
606  @param probe the new probe sphere
607  @param phi the rotation angle
608  @return Index index of the found atom
609  */
610  Index thirdAtom(RSVertex* vertex1, RSVertex* vertex2,
611  RSFace* face, TSphere3<double>& probe, TAngle<double>& phi)
612  throw(Exception::GeneralException,
613  Exception::DivisionByZero,
614  Exception::IndexOverflow);
615 
617  /*_ @name Finding a start position
618  */
620 
621  /*_ Find a start position
622  @param vertex a pointer to the found vertex, if only a vertex
623  can be found
624  @param edge a pointer to the found edge, if only an edge can be
625  found
626  @param face a pointer to the found face, if a face can be found
627  @return Position 0, if no start position is found,
628  1, if a single vertex is found,
629  2, if an edge is found,
630  3, if a face is found
631  */
632  Position getStartPosition()
633  throw(Exception::DivisionByZero);
634 
636  /*_ @name Finding a first face
637  */
639 
640  /*_ Try to find a starting face
641  @return RSFace* a pointer to the found face, if a face can be found,
642  NULL otherwise
643  */
644  RSFace* findFirstFace()
645  throw(Exception::DivisionByZero);
646 
647  /*_ Try to find a starting face in a given direction
648  @param direction search in x-direction, if direction is 0,
649  search in y-direction, if direction is 1,
650  search in z-direction, if direction is 2
651  @param extrem search in min direction, if extrem is 0,
652  search in max direction, if extrem is 1
653  @return RSFace* a pointer to the found face, if a face can be found,
654  NULL otherwise
655  */
656  RSFace* findFace(Position direction, Position extrem)
657  throw(Exception::DivisionByZero);
658 
660  /*_ @name Finding a first edge
661  */
663 
664  /*_ Try to find a starting edge
665  @return RSEdge* a pointer to the found edge, if a face can be found,
666  NULL otherwise
667  */
668  RSEdge* findFirstEdge();
669 
670  /*_ Try to find a starting edge in a given direction
671  @param direction search in x-direction, if direction is 0,
672  search in y-direction, if direction is 1,
673  search in z-direction, if direction is 2
674  @param extrem search in min direction, if extrem is 0,
675  search in max direction, if extrem is 1
676  @return RSEdge* a pointer to the found edge, if a face can be found,
677  NULL otherwise
678  */
679  RSEdge* findEdge(Position direction, Position extrem);
680 
682  /*_ @name Finding a first vertex
683  */
685 
686  /*_ Try to find a single atom
687  @return RSVertex* a pointer to the found vertex, if a vertex can be
688  found, NULL otherwise
689  */
690  RSVertex* findFirstVertex();
691 
692  /*_ Find a single atom in a given direction
693  @param direction search in x-direction, if direction is 0,
694  search in y-direction, if direction is 1,
695  search in z-direction, if direction is 2
696  @param extrem search in min direction, if extrem is 0,
697  search in max direction, if extrem is 1
698  @return Index the index of the found atom
699  */
700  Index findFirstAtom(Position direction, Position extrem);
701 
702  /*_ Find a second atom close enougth to the first atom in a given direction
703  @param atom1 the index of the first atom
704  @param direction search in x-direction, if direction is 0,
705  search in y-direction, if direction is 1,
706  search in z-direction, if direction is 2
707  @param extrem search in min direction, if extrem is 0,
708  search in max direction, if extrem is 1
709  @return Index the index of the found atom
710  */
711  Index findSecondAtom(Index atom, Position direction, Position extrem);
712 
713  /*_ Find a second atom close enougth to the first two atoms
714  @param atom1 the index of the first atom
715  @param atom2 the index of the second atom
716  @param atom_list a HashSet of the indices of all candidate atoms
717  @return ::std::list< ::std::pair< Index,TSphere3<double> > >
718  a list of all candidates with their probe spheres
719  */
720  void findThirdAtom(Index atom1, Index atom2, const std::deque<Index>& third,
721  std::deque< std::pair< Index,TSphere3<double> > >& atoms);
722 
724  /*_ @name Some utilities
725  */
727 
728  /*_ Find all atoms close enougth to two given atoms.
729  The indices of all atoms which can be touched by the probe sphere when
730  it touches the given atoms are computed.
731  @param atom1 the index of the first given atom
732  @param atom2 the index of the second given atom
733  @param output_list list of all atoms close enougth to the given atoms
734  */
735  const std::deque<Index>& neighboursOfTwoAtoms(const SortedPosition2& pos);
736 
737  /*_ Find all atoms close enougth to three given atoms.
738  The indices of all atoms which can be touched by the probe sphere when
739  it touches the given atoms are computed.
740  @param atom1 the index of the first given atom
741  @param atom2 the index of the second given atom
742  @param atom3 the index of the third given atom
743  @param output_list list of all atoms close enougth to the given atoms
744  */
745  void neighboursOfThreeAtoms(Index atom1, Index atom2, Index atom3,
746  std::deque<Index>& output_list);
747 
748  /*_ Get the extrem coordinate of a circle in a given direction
749  @param circle the circle
750  @param direction search in x-direction, if direction is 0,
751  search in y-direction, if direction is 1,
752  search in z-direction, if direction is 2
753  @param extrem search in min direction, if extrem is 0,
754  search in max direction, if extrem is 1
755  @return double the extrem coordinate
756  */
757  double getCircleExtremum(const TCircle3<double>& circle,
758  Position direction, Position extrem);
759 
761  /*_ @name Creating / updating edges / faces
762  */
764 
765  /*_ Create a free edge from two vertices if it is a free edge
766  @param vertex1 a pointer to the first vertex
767  @param vertex2 a pointer to the second vertex
768  @return RSEdge* a pointer to the created free edge, if there is one,
769  NULL otherwise
770  */
771  RSEdge* createFreeEdge(RSVertex* vertex1, RSVertex* vertex2);
772 
773  /*_ Get the circle described by the center of the probe sphere and the two
774  contact circles with the atoms when the probe sphere rolls over two
775  atoms
776  @param atom1 the index of the first atom
777  @param atom2 the index of the second atom
778  @param circle1 the circle described by the center of the probe sphere
779  @param circle2 the contact circle with atom1
780  @param circle3 the contact circle with atom2
781  @return bool true, if the probe sphere can touch both atoms,
782  false, otherwise
783  */
784  bool getCircles(Index atom1, Index atom2, TCircle3<double>& circle1,
785  TCircle3<double>& circle2, TCircle3<double>& circle3);
786 
787  /*_ Get the normal vector of the face described by three atoms and a probe
788  @param atom1 the index of the first atom
789  @param atom2 the index of the second atom
790  @param atom3 the index of the third atom
791  @param probe the probe sphere lying on atom1, atom2, atom3
792  @return TVector3<double> the normal vector
793  */
794  TVector3<double> getFaceNormal(const TSphere3<double>& atom1, const TSphere3<double>& atom2,
795  const TSphere3<double>& atom3, const TSphere3<double>& probe);
796 
797  /*_ Update a face and it's edges
798  @param v1 the first vertex of the face
799  @param v2 the second vertex of the face
800  @param v3 the third vertex of the face
801  @param e1 the first edge
802  @param e2 the second edge
803  @param e3 the third edge
804  @param f the face
805  @param probe the probe sphere of the face
806  */
807  void updateFaceAndEdges(RSVertex* v1, RSVertex* v2, RSVertex* v3,
808  RSEdge* e1, RSEdge* e2, RSEdge* e3,
809  RSFace* f, const TSphere3<double>& probe);
810 
811  /*_ Test, whether a face exists or not
812  @param face a pointer to the face to be tested
813  @return RSFace* a pointer to the face, if it exists, otherwise NULL
814  */
815  RSFace* faceExists(RSFace* face, const std::list< RSVertex* >& vertices);
816 
818  /*_ @name Finding a probe sphere
819  */
821 
822  /*_ Get the centers of the probe sphere when it lies on three atoms
823  @param pos the three atom's indices
824  @param c1 the first center
825  @param c2 the second center
826  @return bool true, if the probe sphere can touch the three atoms,
827  false, otherwise
828  */
829  bool centerOfProbe(const SortedPosition3& pos, TVector3<double>& c1, TVector3<double>& c2);
830 
831  /*_ Check,weather a probe sphere is inside an atom
832  @param probe the probe sphere to be tested
833  @return bool true, if the probe sphere is not intersecting any atom
834  false, otherwise
835  */
836  bool checkProbe(const TSphere3<double>& probe, const SortedPosition3& pos);
837 
838  /*_
839  */
840  void correctProbePosition(Position atom);
841 
842  /*_
843  */
844  void correctProbePosition(const SortedPosition3& pos);
845 
846  /*_
847  */
848  void insert(RSVertex* vertex);
849 
850  /*_
851  */
852  void insert(RSEdge* edge);
853 
854  /*_
855  */
856  void insert(RSFace* face);
857 
859 
860  protected:
861 
862 
863  /*_ a pointer to the reduced surface to compute
864  */
866 
867  /*_ for each atom a list of its neighbours
868  */
869  std::vector< std::deque<Index> > neighbours_;
870 
871  /*_ for each atom a status
872  */
873  std::vector< AtomStatus > atom_status_;
874 
875  /*_ for each pair of atoms a list of its neighbours
876  */
877  HashMap< SortedPosition2, std::deque<Index> > neighbours_of_two_;
878 
879  /*_ for each triple of atoms its probe positions
880  */
881  HashMap< SortedPosition3, ProbePosition* > probe_positions_;
882 
883  /*_ all new created vertices which are not yet checked for extensions
884  */
885  HashSet<RSVertex*> new_vertices_;
886 
887  /*_ all new created faces which are not completely treated yet
888  */
889  HashSet<RSFace*> new_faces_;
890 
891  /*_ for each atom a list of the rsvertices of the atom
892  */
893  std::vector< std::list<RSVertex*> > vertices_;
894  };
895 } // namespace BALL
896 
897 #endif // BALL_STRUCTURE_REDUCEDSURFACE_H
#define BALL_CREATE(name)
Definition: create.h:62
SortedPosition3(Position a1, Position a2, Position a3)
size_t operator()(const BALL::SortedPosition3 &p) const
BALL_EXPORT AtomList atoms(const AtomContainer &fragment, const String &expression=String())
bool operator==(const SortedPosition3 &pos) const
bool operator<(const SortedPosition3 &pos) const
SortedPosition2(Position a1, Position a2)
bool operator==(const SortedPosition2 &pos) const
bool operator<(const SortedPosition2 &pos) const
size_t operator()(const BALL::SortedPosition2 &p) const
HashMap class based on the STL map (containing serveral convenience functions)
Definition: hashMap.h:73
#define BALL_EXPORT
Definition: COMMON/global.h:50