BALL  1.4.2
 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 #if defined(BALL_HAS_UNORDERED_MAP) || defined(BALL_HAS_HASH_MAP)
150 
151 #ifdef BALL_EXTEND_HASH_IN_STD_NS
152 namespace std
153 {
154 #endif // BALL_EXTEND_HASH_IN_STD_NS
155 
156  namespace BALL_MAP_NAMESPACE {
157  template<>
158  struct hash<BALL::SortedPosition2> : public std::unary_function<BALL::SortedPosition2, size_t>
159  {
160  inline size_t operator()(const BALL::SortedPosition2& p) const
161  {
162  return 5323 * p.a + 1847 * p.b;
163  }
164  };
165 
166  template<>
167  struct hash<BALL::SortedPosition3> : public std::unary_function<BALL::SortedPosition3, size_t>
168  {
169  inline size_t operator()(const BALL::SortedPosition3& p) const
170  {
171  return 5323 * p.a + 1847 * p.b + 2347 * p.c;
172  }
173  };
174  }
175 
176 #ifdef BALL_EXTEND_HASH_IN_STD_NS
177 }
178 #endif // BALL_EXTEND_HASH_IN_STD_NS
179 
180 #endif
181 
182 namespace BALL
183 {
184  class RSComputer;
185  class SolventExcludedSurface;
186  class SESComputer;
187  class SESSingularityCleaner;
188  class TriangulatedSES;
189  class SolventAccessibleSurface;
190  class TriangulatedSAS;
191  class SESTriangulator;
192 
197  {
198  public:
199 
212  friend class RSComputer;
214  friend class SESComputer;
215  friend class SESSingularityCleaner;
217  friend class TriangulatedSES;
218  friend class TriangulatedSAS;
219  friend class SESTriangulator;
220 
222 
223 
226 
231  ReducedSurface();
232 
237  ReducedSurface(const ReducedSurface& reduced_surface, bool = true);
238 
242  ReducedSurface(const std::vector< TSphere3<double> >& spheres,
243  const double& probe_radius);
244 
247  virtual ~ReducedSurface();
248 
250 
253 
257  void operator = (const ReducedSurface& reduced_surface);
258 
262  void set(const ReducedSurface& reduced_surface);
263 
266  void clear();
267 
270  void clean();
271 
273 
276 
280  Size numberOfAtoms() const;
281 
285  Size numberOfVertices() const;
286 
290  Size numberOfEdges() const;
291 
295  Size numberOfFaces() const;
296 
300  double getProbeRadius() const;
301 
306  TSphere3<double> getSphere(Position i) const
307  throw(Exception::IndexOverflow);
308 
313  RSVertex* getVertex(Position i) const
314  throw(Exception::IndexOverflow);
315 
320  RSEdge* getEdge(Position i) const
321  throw(Exception::IndexOverflow);
322 
327  RSFace* getFace(Position i) const
328  throw(Exception::IndexOverflow);
329 
333  void insert(RSVertex* rsvertex);
334 
338  void insert(RSEdge* rsedge);
339 
343  void insert(RSFace* rsface);
344 
348  double getMaximalRadius() const;
349 
353  TSimpleBox3<double> getBoundingBox() const;
354 
359  void deleteSimilarFaces(RSFace* face1, RSFace* face2);
360 
369  bool getAngle(RSFace* face1, RSFace* face2,
370  RSVertex* vertex1, RSVertex* vertex2,
371  TAngle<double>& angle, bool check = false) const;
372 
375  void compute()
376  throw(Exception::GeneralException,
377  Exception::DivisionByZero,
378  Exception::IndexOverflow);
379 
381 
382  private:
383 
384  /*_ Test whether a ReducedSurface object can be copied.
385  */
386  bool canBeCopied(const ReducedSurface& reduced_surface);
387 
388  /*_ Copy a ReducedSurface object.
389  */
390  void copy(const ReducedSurface& reduced_surface);
391 
392  /*_
393  */
394  void correctEdges(RSFace* face1, RSFace* face2,
395  RSEdge* edge1, RSEdge* edge2);
396 
397  /*_
398  */
399  void joinVertices(RSFace* face1, RSFace* face2,
400  RSVertex* vertex1, RSVertex* vertex2);
401 
402  /*_
403  */
404  void findSimilarVertices(RSFace* face1, RSFace* face2,
405  std::vector<RSVertex*>& rsvertex1,
406  std::vector<RSVertex*>& rsvertex2);
407 
408  /*_
409  */
410  void findSimilarEdges(RSFace* face1, RSFace* face2,
411  std::vector<RSEdge*>& rsedge1,
412  std::vector<RSEdge*>& rsedge2);
413 
414  protected:
415 
416  /*_ the number of atoms of the reduced surface
417  */
418  Size number_of_atoms_;
419 
420  /*_ the atoms of the molecule
421  */
422 
423  std::vector< TSphere3<double> > atom_;
424 
425  /*_ probe radius
426  */
427  double probe_radius_;
428 
429  /*_ the number of vertices of the reduced surface
430  */
431  Size number_of_vertices_;
432 
433  /*_ the vertices of the reduced surface
434  */
435  std::vector< RSVertex* > vertices_;
436 
437  /*_ the number of edges of the reduced surface
438  */
439  Size number_of_edges_;
440 
441  /*_ the edges of the reduced surface
442  */
443  std::vector< RSEdge* > edges_;
444 
445  /*_ the number of faces of the reduced surface
446  */
447  Size number_of_faces_;
448 
449  /*_ the faces of the reduced surface
450  */
451  std::vector< RSFace* > faces_;
452 
453  /*_ maximal radius of all atoms
454  */
455  double r_max_;
456 
457  /*_ bounding SimpleBox of the atom centers of the molecule
458  */
459  TSimpleBox3<double> bounding_box_;
460  };
461 
465 
469  BALL_EXPORT std::ostream& operator << (std::ostream& s, const ReducedSurface& rs);
470 
472 
477  {
478  public:
479 
480  BALL_CREATE(RSComputer)
481 
482 
485 
492  {
493  STATUS_OK = 0,
495  STATUS_NOT_TESTED
496  };
497 
504  {
505  STATUS_ON_SURFACE = 0,
507  STATUS_UNKNOWN
508  };
510 
512  {
513  ProbeStatus status[2];
515  };
516 
520 
525  RSComputer();
526 
530 
533  virtual ~RSComputer();
534 
536 
539 
542  void run()
543  throw(Exception::GeneralException,
544  Exception::DivisionByZero,
545  Exception::IndexOverflow);
546 
548 
549 
550  private:
551 
552  /*_ @name Computing reduced surface
553  */
555 
556  /*_
557  */
558  void preProcessing();
559 
560  /*_ Compute a RSComponent.
561  */
562  void getRSComponent()
563  throw(Exception::GeneralException,
564  Exception::DivisionByZero,
565  Exception::IndexOverflow);
566 
567  /*_ Treat all edges of a face.
568  @param face the RSFace to be treated
569  */
570  bool treatFace(RSFace* face)
571  throw(Exception::GeneralException,
572  Exception::DivisionByZero,
573  Exception::IndexOverflow);
574 
575  /*_ Roll over an edge that belongs to only one face and find the other one.
576  @param edge the RSEdge to be treated
577  */
578  bool treatEdge(RSEdge* edge)
579  throw(Exception::GeneralException,
580  Exception::DivisionByZero,
581  Exception::IndexOverflow);
582 
583  /*_ Treat an ambiguous situation.
584  All vertices on an ambiguous atom are deleted with all its edges and
585  faces. The radius of the atom is decreased by 10 EPSILON.
586  @param atom the index of the atom
587  */
588  void correct(Index atom);
589 
590  /*_ Check all new created vertices for extensions
591  */
592  void extendComponent()
593  throw(Exception::GeneralException,
594  Exception::DivisionByZero,
595  Exception::IndexOverflow);
596 
597  /*_ Find a third atom rolling over two vertices starting on a face.
598  From all atoms which can be touched by the probe sphere when it
599  touches the given two vertices we choose the one with smallest
600  rotation angle.
601  If the rotation angle equals zero, the probe sphere can touch four
602  atoms and an exception is thrown.
603  If no atom can be found an exception is thrown.
604  @param vertex1 the first vertex
605  @param vertex2 the second vertex
606  @param face the starting face
607  @param probe the new probe sphere
608  @param phi the rotation angle
609  @return Index index of the found atom
610  */
611  Index thirdAtom(RSVertex* vertex1, RSVertex* vertex2,
612  RSFace* face, TSphere3<double>& probe, TAngle<double>& phi)
613  throw(Exception::GeneralException,
614  Exception::DivisionByZero,
615  Exception::IndexOverflow);
616 
618  /*_ @name Finding a start position
619  */
621 
622  /*_ Find a start position
623  @param vertex a pointer to the found vertex, if only a vertex
624  can be found
625  @param edge a pointer to the found edge, if only an edge can be
626  found
627  @param face a pointer to the found face, if a face can be found
628  @return Position 0, if no start position is found,
629  1, if a single vertex is found,
630  2, if an edge is found,
631  3, if a face is found
632  */
633  Position getStartPosition()
634  throw(Exception::DivisionByZero);
635 
637  /*_ @name Finding a first face
638  */
640 
641  /*_ Try to find a starting face
642  @return RSFace* a pointer to the found face, if a face can be found,
643  NULL otherwise
644  */
645  RSFace* findFirstFace()
646  throw(Exception::DivisionByZero);
647 
648  /*_ Try to find a starting face in a given direction
649  @param direction search in x-direction, if direction is 0,
650  search in y-direction, if direction is 1,
651  search in z-direction, if direction is 2
652  @param extrem search in min direction, if extrem is 0,
653  search in max direction, if extrem is 1
654  @return RSFace* a pointer to the found face, if a face can be found,
655  NULL otherwise
656  */
657  RSFace* findFace(Position direction, Position extrem)
658  throw(Exception::DivisionByZero);
659 
661  /*_ @name Finding a first edge
662  */
664 
665  /*_ Try to find a starting edge
666  @return RSEdge* a pointer to the found edge, if a face can be found,
667  NULL otherwise
668  */
669  RSEdge* findFirstEdge();
670 
671  /*_ Try to find a starting edge in a given direction
672  @param direction search in x-direction, if direction is 0,
673  search in y-direction, if direction is 1,
674  search in z-direction, if direction is 2
675  @param extrem search in min direction, if extrem is 0,
676  search in max direction, if extrem is 1
677  @return RSEdge* a pointer to the found edge, if a face can be found,
678  NULL otherwise
679  */
680  RSEdge* findEdge(Position direction, Position extrem);
681 
683  /*_ @name Finding a first vertex
684  */
686 
687  /*_ Try to find a single atom
688  @return RSVertex* a pointer to the found vertex, if a vertex can be
689  found, NULL otherwise
690  */
691  RSVertex* findFirstVertex();
692 
693  /*_ Find a single atom in a given direction
694  @param direction search in x-direction, if direction is 0,
695  search in y-direction, if direction is 1,
696  search in z-direction, if direction is 2
697  @param extrem search in min direction, if extrem is 0,
698  search in max direction, if extrem is 1
699  @return Index the index of the found atom
700  */
701  Index findFirstAtom(Position direction, Position extrem);
702 
703  /*_ Find a second atom close enougth to the first atom in a given direction
704  @param atom1 the index of the first atom
705  @param direction search in x-direction, if direction is 0,
706  search in y-direction, if direction is 1,
707  search in z-direction, if direction is 2
708  @param extrem search in min direction, if extrem is 0,
709  search in max direction, if extrem is 1
710  @return Index the index of the found atom
711  */
712  Index findSecondAtom(Index atom, Position direction, Position extrem);
713 
714  /*_ Find a second atom close enougth to the first two atoms
715  @param atom1 the index of the first atom
716  @param atom2 the index of the second atom
717  @param atom_list a HashSet of the indices of all candidate atoms
718  @return ::std::list< ::std::pair< Index,TSphere3<double> > >
719  a list of all candidates with their probe spheres
720  */
721  void findThirdAtom(Index atom1, Index atom2, const std::deque<Index>& third,
722  std::deque< std::pair< Index,TSphere3<double> > >& atoms);
723 
725  /*_ @name Some utilities
726  */
728 
729  /*_ Find all atoms close enougth to two given atoms.
730  The indices of all atoms which can be touched by the probe sphere when
731  it touches the given atoms are computed.
732  @param atom1 the index of the first given atom
733  @param atom2 the index of the second given atom
734  @param output_list list of all atoms close enougth to the given atoms
735  */
736  const std::deque<Index>& neighboursOfTwoAtoms(const SortedPosition2& pos);
737 
738  /*_ Find all atoms close enougth to three given atoms.
739  The indices of all atoms which can be touched by the probe sphere when
740  it touches the given atoms are computed.
741  @param atom1 the index of the first given atom
742  @param atom2 the index of the second given atom
743  @param atom3 the index of the third given atom
744  @param output_list list of all atoms close enougth to the given atoms
745  */
746  void neighboursOfThreeAtoms(Index atom1, Index atom2, Index atom3,
747  std::deque<Index>& output_list);
748 
749  /*_ Get the extrem coordinate of a circle in a given direction
750  @param circle the circle
751  @param direction search in x-direction, if direction is 0,
752  search in y-direction, if direction is 1,
753  search in z-direction, if direction is 2
754  @param extrem search in min direction, if extrem is 0,
755  search in max direction, if extrem is 1
756  @return double the extrem coordinate
757  */
758  double getCircleExtremum(const TCircle3<double>& circle,
759  Position direction, Position extrem);
760 
762  /*_ @name Creating / updating edges / faces
763  */
765 
766  /*_ Create a free edge from two vertices if it is a free edge
767  @param vertex1 a pointer to the first vertex
768  @param vertex2 a pointer to the second vertex
769  @return RSEdge* a pointer to the created free edge, if there is one,
770  NULL otherwise
771  */
772  RSEdge* createFreeEdge(RSVertex* vertex1, RSVertex* vertex2);
773 
774  /*_ Get the circle described by the center of the probe sphere and the two
775  contact circles with the atoms when the probe sphere rolls over two
776  atoms
777  @param atom1 the index of the first atom
778  @param atom2 the index of the second atom
779  @param circle1 the circle described by the center of the probe sphere
780  @param circle2 the contact circle with atom1
781  @param circle3 the contact circle with atom2
782  @return bool true, if the probe sphere can touch both atoms,
783  false, otherwise
784  */
785  bool getCircles(Index atom1, Index atom2, TCircle3<double>& circle1,
786  TCircle3<double>& circle2, TCircle3<double>& circle3);
787 
788  /*_ Get the normal vector of the face described by three atoms and a probe
789  @param atom1 the index of the first atom
790  @param atom2 the index of the second atom
791  @param atom3 the index of the third atom
792  @param probe the probe sphere lying on atom1, atom2, atom3
793  @return TVector3<double> the normal vector
794  */
795  TVector3<double> getFaceNormal(const TSphere3<double>& atom1, const TSphere3<double>& atom2,
796  const TSphere3<double>& atom3, const TSphere3<double>& probe);
797 
798  /*_ Update a face and it's edges
799  @param v1 the first vertex of the face
800  @param v2 the second vertex of the face
801  @param v3 the third vertex of the face
802  @param e1 the first edge
803  @param e2 the second edge
804  @param e3 the third edge
805  @param f the face
806  @param probe the probe sphere of the face
807  */
808  void updateFaceAndEdges(RSVertex* v1, RSVertex* v2, RSVertex* v3,
809  RSEdge* e1, RSEdge* e2, RSEdge* e3,
810  RSFace* f, const TSphere3<double>& probe);
811 
812  /*_ Test, whether a face exists or not
813  @param face a pointer to the face to be tested
814  @return RSFace* a pointer to the face, if it exists, otherwise NULL
815  */
816  RSFace* faceExists(RSFace* face, const std::list< RSVertex* >& vertices);
817 
819  /*_ @name Finding a probe sphere
820  */
822 
823  /*_ Get the centers of the probe sphere when it lies on three atoms
824  @param pos the three atom's indices
825  @param c1 the first center
826  @param c2 the second center
827  @return bool true, if the probe sphere can touch the three atoms,
828  false, otherwise
829  */
830  bool centerOfProbe(const SortedPosition3& pos, TVector3<double>& c1, TVector3<double>& c2);
831 
832  /*_ Check,weather a probe sphere is inside an atom
833  @param probe the probe sphere to be tested
834  @return bool true, if the probe sphere is not intersecting any atom
835  false, otherwise
836  */
837  bool checkProbe(const TSphere3<double>& probe, const SortedPosition3& pos);
838 
839  /*_
840  */
841  void correctProbePosition(Position atom);
842 
843  /*_
844  */
845  void correctProbePosition(const SortedPosition3& pos);
846 
847  /*_
848  */
849  void insert(RSVertex* vertex);
850 
851  /*_
852  */
853  void insert(RSEdge* edge);
854 
855  /*_
856  */
857  void insert(RSFace* face);
858 
860 
861  protected:
862 
863 
864  /*_ a pointer to the reduced surface to compute
865  */
867 
868  /*_ for each atom a list of its neighbours
869  */
870  std::vector< std::deque<Index> > neighbours_;
871 
872  /*_ for each atom a status
873  */
874  std::vector< AtomStatus > atom_status_;
875 
876  /*_ for each pair of atoms a list of its neighbours
877  */
878  HashMap< SortedPosition2, std::deque<Index> > neighbours_of_two_;
879 
880  /*_ for each triple of atoms its probe positions
881  */
882  HashMap< SortedPosition3, ProbePosition* > probe_positions_;
883 
884  /*_ all new created vertices which are not yet checked for extensions
885  */
886  HashSet<RSVertex*> new_vertices_;
887 
888  /*_ all new created faces which are not completely treated yet
889  */
890  HashSet<RSFace*> new_faces_;
891 
892  /*_ for each atom a list of the rsvertices of the atom
893  */
894  std::vector< std::list<RSVertex*> > vertices_;
895  };
896 } // namespace BALL
897 
898 #endif // BALL_STRUCTURE_REDUCEDSURFACE_H