Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

MeasureSymmetry.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: MeasureSymmetry.h,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.34 $       $Date: 2020/10/28 17:42:35 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  * Thy Symmetry class is the work horse behind the "measure symmetry"
00019  * command which guesses the pointgroup of a selection and returns the
00020  * according symmetry elements (mirror planes rotary axes, rotary reflection
00021  * axes). The algorithm is is fairly forgiving about molecules where atoms
00022  * are perturbed from the ideal position and tries its best to guess the
00023  * correct point group anyway. 
00024  * The 'forgivingness' can be controlled with the sigma parameter which is
00025  * the average allowed deviation from the ideal position.
00026  * Works nice on my 30 non-patholocical test cases. A pathological case
00027  * would for instance be a system with more than only a few atoms (say 15)
00028  * where only one atom distinguishes between two point groups.
00029  * If your selection contains more than a certain number of atoms then only
00030  * that much randomly chosen atoms are used to find planes and axes in order
00031  * to save time.
00032  *
00033  ***************************************************************************/
00034 
00035 #ifndef MEASURESYMMETRY_H
00036 #define MEASURESYMMETRY_H
00037 
00038 #include "ResizeArray.h"
00039 
00040 // Flags for trans_overlap() specifying wether atoms that underwent
00041 // an identical transformation should be skipped in the evaluation.
00042 #define SKIP_IDENTICAL   1
00043 #define NOSKIP_IDENTICAL 0
00044 
00045 // Rotary axis classification
00046 #define PRINCIPAL_AXIS     1
00047 #define PERPENDICULAR_AXIS 2
00048 
00049 // Maximum order for Cn and S2n axes
00050 #define MAXORDERCN 8
00051 
00052 
00053 typedef struct plane {
00054   float v[3];
00055   float overlap;
00056   int weight;
00057   int type;
00058 } Plane;
00059 
00060 typedef struct axis {
00061   float v[3];
00062   float overlap;
00063   int order;
00064   int weight;
00065   int type;
00066 } Axis;
00067 
00068 // Summary of existing symmetry elements
00069 typedef struct elementsummary {
00070   char inv;     // inversion center (0/1)?
00071   char sigma;   // number of sigma planes
00072   char Cinf;    // number of infinite order axes (0/1)
00073   // Numbers of C and S axes with order 2, 3, 4, ... repectively
00074   char C[MAXORDERCN+1]; // 0,1 unused; accessed by order 2, ... MAXORDERCN;
00075   char S[MAXORDERCN*2+1];
00076 } ElementSummary;
00077 
00078 typedef struct bond {
00079   int atom0;
00080   int atom1;
00081   float order;
00082   float length;
00083 } Bond;
00084 
00085 typedef struct bondlist {
00086   int numbonds;
00087   int *bondto;
00088   float *length;
00089 } Bondlist;
00090 
00091 
00092 class Symmetry {
00093 private:
00094   AtomSel *sel;              
00095   MoleculeList *mlist;
00096 
00097   float *coor;               
00098   float *bondsum;            
00099   float rcom[3];             
00100   float inertiaeigenval[3];  
00101   float inertiaaxes[3][3];   
00102   int uniqueprimary[3];      
00103   int numverticalplanes;     
00104   int numdihedralplanes;     
00105   int horizontalplane;       
00106   int maxaxisorder;          
00107   int maxrotreflorder;       
00108   int maxnatoms;             
00109   int checkbonds;            
00110   int verbose;               
00111   int *atomtype;             
00112   int *atomindex;            
00113   int *uniqueatoms;          
00114   float *idealcoor;          
00115 
00116   char *elementsummarystring;    
00117   char *missingelementstring;    
00118   char *additionalelementstring; 
00119 
00120   Matrix4 orient;            
00121 
00122   // Summarized numbers of elements in table form.
00123   ElementSummary elementsummary;
00124 
00125   int   maxweight;           
00126                              // XXX seems to be set but never used;
00127   float maxoverlap;          
00128   float rmsd;                
00129 
00130   int pointgroup;            
00131 
00132  
00133   int pointgrouporder;       
00134 
00135  
00136   ResizeArray<Plane> planes;         
00137   ResizeArray<Axis>  axes;           
00138   ResizeArray<Axis>  rotreflections; 
00139   ResizeArray<Bond>  bonds;          
00140 
00141   Bondlist *bondsperatom;  
00142 
00143 
00144   bool linear;        
00145   bool planar;        
00146   bool inversion;     
00147   bool sphericaltop;  
00148   bool symmetrictop;  
00149 
00150 
00152   int iterate_element_search();
00153 
00155   void find_symmetry_elements();
00156 
00158   void find_elements_from_inertia();
00159 
00161   void find_planes();
00162 
00164   void find_axes_from_plane_intersections();
00165 
00167   void find_C2axes();
00168   void find_axes(int order);
00169 
00170 
00172   void check_add_inversion();   
00173 
00176   void check_add_plane(const float *normal, int weight=1);
00177 
00180   void check_add_axis(const float *testaxis, int order);
00181 
00184   void check_add_rotary_reflection(const float *testaxis, int maxorder);
00185 
00186 
00188   void classify_planes();
00189 
00191   void classify_axes();
00192 
00194   void purge_planes(float cutoff);
00195 
00197   void purge_axes(float cutoff);
00198 
00200   void purge_rotreflections(float cutoff);
00201 
00203   void prune_planes(int *keep);
00204 
00206   void prune_axes(int *keep);
00207 
00209   void prune_rotreflections(int *keep);
00210 
00212   void assign_axis_orders();
00213 
00215   void assign_prelimaxis_orders(int order);
00216 
00218   int axis_order(const float *axis, float *overlap);
00219 
00221   void sort_axes();
00222 
00224   void sort_planes();
00225 
00227   void print_statistics();
00228 
00230   void build_element_summary();
00231 
00233   void build_element_summary_string(ElementSummary summary, char *(&sestring));
00234 
00236   void compare_element_summary(const char *pointgroupname);
00237 
00239   void print_element_summary(const char *pointgroupname);
00240 
00243   void idealize_elements();
00244 
00247   int idealize_angle(const float *refaxis, const float *hub,
00248                     const float *myaxis, float *idealaxis, int reforder);
00249 
00251   void idealize_coordinates();
00252 
00254   int average_coordinates(Matrix4 *trans);
00255 
00257   // transformation trans.
00258   int check_bondsum(int j, int m, Matrix4 *trans);
00259 
00261   void identify_transformed_atoms(Matrix4 *trans, int &nmatches, int *(&matchlist));
00262 
00264   float ideal_coordinate_rmsd ();
00265 
00268   int ideal_coordinate_sanity();
00269 
00271   void unique_coordinates();
00272 
00274   int* unique_coordinates(Matrix4 *trans);
00275 
00277   void collapse_axis(const float *axis, int order, int refatom, const int *matchlist, int *(&connectedunique));
00278 
00280   int pointgroup_rank(int pg, int order);
00281 
00283   void orient_molecule();
00284 
00286   void determine_pointgroup();
00287 
00289   inline int find_collinear_axis(const float *myaxis);
00290 
00292   inline int plane_exists(const float *myplane);
00293 
00295   int is_planar(const float *axis);
00296 
00298   void assign_bonds();
00299 
00303   void assign_bondvectors();
00304 
00306   void wrap_unconnected_unique_atoms(int root, const int *matchlist, int *(&connectedunique));
00307 
00308   // Find all unique atoms that are connnected to root
00309   void find_connected_unique_atoms(int *(&connectedunique), int root);
00310 
00313   void draw_transformed_mol(Matrix4 rot);
00314 
00315 public:
00316   Symmetry(AtomSel *sel, MoleculeList *mlist, int verbosity);
00317   ~Symmetry(void);
00318 
00319   float sigma;     // atomic overlap tolerance
00320   float collintol; // collinearity tolerance in radians
00321   float orthogtol; // coplanarity tolerance in radians
00322 
00323   // Check if center of mass is an inversion center.
00324   float score_inversion();
00325 
00327   float score_axis(const float *testaxis, int order);
00328 
00330   float score_plane(const float *normal);
00331 
00333   float score_rotary_reflection(const float *testaxis, int order);
00334 
00337   void impose(int have_inversion, 
00338               int nplanes, const float *planev,
00339               int naxes, const float *axisv, const int *axisorder,
00340               int nrotrefl, const float* rotreflv,
00341               const int *rotreflorder);
00342 
00344   int guess(float mysigma);
00345 
00347   void get_pointgroup(char pg[8], int *order);
00348 
00350   float get_rmsd() { return rmsd; }
00351 
00353   float* get_inertia_axes()      { return &(inertiaaxes[0][0]); }
00354 
00356   float* get_inertia_eigenvals() { return &(inertiaeigenval[0]); }
00357 
00359   int*   get_inertia_unique()    { return &(uniqueprimary[0]); }
00360 
00362   int  get_axisorder(int n);
00363 
00365   int  get_rotreflectorder(int n);
00366 
00368   Matrix4* get_orientation() { return &orient; }
00369 
00371   const char *get_element_summary()     { return elementsummarystring; }
00372 
00374   const char *get_missing_elements()    { return missingelementstring; }
00375 
00377   const char *get_additional_elements() { return additionalelementstring; }
00378 
00380   void set_maxnumatoms(int n) { maxnatoms = n; }
00381 
00383   void set_overlaptol(float tol) { sigma = tol; }
00384 
00386   void set_checkbonds(int flag) { checkbonds = flag; }
00387 
00389   int numplanes()     { return int(planes.num()); }
00390 
00392   int numaxes()       { return int(axes.num()); }
00393 
00395   int numprimaryaxes();
00396 
00398   int numrotreflect() { return int(rotreflections.num()); }
00399 
00401   int numS2n();
00402 
00404   int has_inversion() { return inversion; }
00405 
00407   int is_spherical_top() { return sphericaltop; }
00408 
00410   int is_symmetric_top() { return symmetrictop; }
00411 
00413   float* center_of_mass() { return rcom; }
00414 
00416   float* plane(int i)      { return (float *) &(planes[i].v); }
00417 
00419   float* axis(int i)       { return (float *) &(axes[i].v); }
00420 
00422   float* rotreflect(int i) { return (float *) &(rotreflections[i].v); }
00423 
00425   int get_planetype(int i)     { return planes[i].type; }
00426 
00428   int get_axistype(int i)      { return axes[i].type; }
00429 
00431   int get_rotrefltype(int i)   { return rotreflections[i].type; }
00432 
00434   float *idealpos(int i)   { return idealcoor+3*i; }
00435 
00437   int get_unique_atom(int i)   { return uniqueatoms[i]; }
00438 };
00439 
00440 
00441 
00447 int measure_trans_overlap(AtomSel *sel, MoleculeList *mlist, const Matrix4 *trans,
00448                           float sigma, bool skipident, int maxnatoms, float &overlap);
00449 
00450 
00451 int measure_pointset_overlap(const float *posA, int natomsA, int *flagsA,
00452                              const float *posB, int natomsB, int *flagsB,
00453                              float sigma, float pairdist, float &similarity);
00454 
00455 
00456 
00457 
00458 #endif

Generated on Tue Apr 16 02:45:32 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002