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

BaseMolecule.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 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: BaseMolecule.h,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.136 $      $Date: 2013/01/29 19:52:45 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * Base class for all molecules, without display-specific information.  This
00020  * portion of a molecule contains the structural data, and all routines to
00021  * find the structure (backbone, residues, etc).  It contains the
00022  * animation list as well.
00023  *
00024  ***************************************************************************/
00025 #ifndef BASEMOLECULE_H
00026 #define BASEMOLECULE_H
00027 
00028 #ifndef NAMELIST_TEMPLATE_H
00029 #include "NameList.h"
00030 #endif
00031 #ifndef RESIZEARRAY_TEMPLATE_H
00032 #include "ResizeArray.h"
00033 #endif
00034 #include "Atom.h"
00035 #include "Residue.h"
00036 #include "Timestep.h"
00037 #include "Fragment.h"
00038 #include "intstack.h"
00039 
00040 #ifdef VMDWITHCARBS
00041 #include "SmallRing.h"
00042 #include "SmallRingLinkages.h"
00043 #include "inthash.h"
00044 #endif
00045 
00046 #if 0
00047 #define VMDFASTRIBBONS
00048 #endif
00049 
00050 class VolumetricData;
00051 class QMData;
00052 
00057 class BaseMolecule {
00058 public:
00059   //
00060   // public molecular structure data (for ease of access):
00061   //
00062   int nAtoms;                         
00063   int nResidues;                      
00064   int nWaters;                        
00065   int nSegments;                      
00066   int nFragments;                     
00067   int nProteinFragments;              
00068   int nNucleicFragments;              
00069 
00070   NameList<int> atomNames;            
00071   NameList<int> atomTypes;            
00072   NameList<int> resNames;             
00073   NameList<int> chainNames;           
00074   NameList<int> segNames;             
00075   NameList<int> altlocNames;          
00076 
00077   ResizeArray<Residue *> residueList; 
00078   ResizeArray<Fragment *> fragList;   
00079 
00080   ResizeArray<Fragment *> pfragList;  
00081 
00082   ResizeArray<int> pfragCyclic;       
00083 #if defined(VMDFASTRIBBONS)
00084   ResizeArray<int *> pfragCPList;     
00085 
00086 #endif
00087 
00088 
00089   ResizeArray<Fragment *> nfragList;  
00090   ResizeArray<int> nfragCyclic;       
00091 #if defined(VMDFASTRIBBONS)
00092   ResizeArray<int *> nfragCPList;     
00093 
00094 #endif
00095 
00096 #ifdef VMDWITHCARBS
00097   ResizeArray<SmallRing *> smallringList; 
00098 
00099   SmallRingLinkages smallringLinkages; 
00100   int currentMaxRingSize;             
00101   int currentMaxPathLength;           
00102 #endif
00103 
00104   // Extra molecular dynamics structure info not normally needed for
00105   // anything but structure building tasks
00106   ResizeArray<int> angles;            
00107   ResizeArray<int> dihedrals;         
00108   ResizeArray<int> impropers;         
00109   ResizeArray<int> cterms;            
00110 
00111   // Extra (optional) data for this molecule.
00112   // If the name is unassigned then the values can be taken to be zero.
00113   NameList<float *> extraflt;         
00114   NameList<int *> extraint;           
00115 
00116   // more structure topology handling info. assign names to FF types.
00117   ResizeArray<int> angleTypes;        
00118   ResizeArray<int> dihedralTypes;     
00119   ResizeArray<int> improperTypes;     
00120   NameList<int> bondTypeNames;        
00121   NameList<int> angleTypeNames;       
00122   NameList<int> dihedralTypeNames;    
00123   NameList<int> improperTypeNames;    
00124 
00125   // Data related to quantum mechanics simulations.
00126   QMData *qm_data;
00127 
00128   // Interface to standard extra data.  These will exist and be initialized
00129   // to zero when init_atoms is called.
00130 
00132   enum dataset_flag {       
00133                NODATA=0x0000,
00134             INSERTION=0x0001, 
00135             OCCUPANCY=0x0002, 
00136               BFACTOR=0x0004, 
00137                  MASS=0x0008, 
00138                CHARGE=0x0010, 
00139                RADIUS=0x0020, 
00140                ALTLOC=0x0040, 
00141          ATOMICNUMBER=0x0080, 
00142                 BONDS=0x0100, 
00143            BONDORDERS=0x0200,
00144                ANGLES=0x0400,
00145                CTERMS=0x0800, 
00146             BONDTYPES=0x1000,
00147            ANGLETYPES=0x2000 };
00148   
00149   int datasetflags;
00150   void set_dataset_flag(int flag) { 
00151     datasetflags |= flag;
00152   }
00153   void unset_dataset_flag(int flag) {
00154     datasetflags &= (~flag);
00155   }
00156   int test_dataset_flag(int flag) {
00157     return (datasetflags & flag) != 0;
00158   }
00159 
00161   float *radius() { return extraflt.data("radius"); }
00162   float *mass() { return extraflt.data("mass");   }
00163   float *charge() { return extraflt.data("charge"); }
00164   float *beta() { return extraflt.data("beta");   }
00165   float *occupancy() { return extraflt.data("occupancy"); }
00166 
00169   int radii_minmax_need_update;
00170   float radii_min;
00171   float radii_max;
00172   void set_radii_changed() { radii_minmax_need_update = 1; }
00173 
00174   void get_radii_minmax(float &min, float &max) {
00175     const float *r = NULL;
00176     if (radii_minmax_need_update && nAtoms > 0 &&
00177         (r = extraflt.data("radius")) != NULL) {
00178 
00179 #if 1
00180       // use fast 16-byte-aligned min/max routine
00181       minmax_1fv_aligned(r, nAtoms, &radii_min, &radii_max);
00182 #else
00183       // scalar min/max loop
00184       radii_min = r[0];
00185       radii_max = r[0];
00186       for (int i=0; i<nAtoms; i++) {
00187         if (r[i] < radii_min) radii_min = r[i];
00188         if (r[i] > radii_max) radii_max = r[i];
00189       }
00190 #endif
00191       radii_minmax_need_update = 0;
00192     }
00193 
00194     min = radii_min;  
00195     max = radii_max;  
00196   }
00197 
00199   float *bondorders() { return extraflt.data("bondorders"); }
00200   void setbondorder(int atom, int bond, float order);
00201   float getbondorder(int atom, int bond);
00202 
00204   int *bondtypes() { return extraint.data("bondtypes"); }
00205 
00207   void setbondtype(int atom, int bond, int type);
00208 
00210   int  getbondtype(int atom, int bond);
00211 
00213   int has_structure() const { return cur_atom > 0; }
00214 
00216   void clear_bonds(void);
00217 
00219   int count_bonds(void);
00220 
00221 #ifdef VMDWITHCARBS
00222 
00223   void find_small_rings_and_links(int maxpathlength, int maxringsize);
00224 #endif
00225 
00226 private:
00227   const int ID;          
00228 
00229   //
00230   // molecular structure data:
00231   //
00232   int cur_atom;          
00233   MolAtom *atomList;     
00234   int lastbonderratomid; 
00235   int bonderrorcount;    
00236  
00237   //
00238   // routines to determine components of molecular structure
00239   //
00240  
00248   int find_backbone(void);
00249 
00250   // find the residues in the molecule; return number found.
00251   // I look for atoms with the same resid connected to 
00252   // backbone atoms with the same resid (find enough backbone
00253   // atoms, then find atoms connected to them)
00254   int find_connected_backbone(IntStackHandle, int, int, int, int, int *);
00255   void clean_up_connection(IntStackHandle, int, int, int *);
00256   void find_connected_atoms_in_resid(IntStackHandle, int, int, 
00257      int, int, int *);
00258   void find_and_mark(int, int, int,
00259      int *, int *);
00260   int make_uniq_resids(int *flgs); 
00261 
00268   int find_residues(void);
00269   
00271   // This should take place after find_residues to keep
00272   // from mistaking a protein resname as a water resname, maybe
00273   void find_connected_waters(int i, char *tmp);
00274   int find_connected_waters2(void);
00275 
00280   int find_waters(void);
00281 
00287   void find_connected_residues(int num_residues);
00288   
00290   int find_segments(void) { return segNames.num(); }
00291   
00293   int find_connected_fragments();
00294 
00301   int find_fragments(void);
00302 
00303   void find_subfragments_cyclic(ResizeArray<Fragment *> *subfragList, int restype);  
00304   void find_cyclic_subfragments(ResizeArray<Fragment *> *subfragList, ResizeArray<int> *subfragCyclic);
00305  
00307   void find_connected_subfragment(int resnum, int fragnum, char *flgs, 
00308          int endatom, int altendatom, int alt2endatom, int alt3endatom,
00309          int restype, 
00310          ResizeArray<Fragment *> *subfragList);
00311 
00312   void find_subfragments(int startatom, int altstartatom, int alt2startatom,
00313     int endatom, int altendatom, int alt2endatom, int alt3endatom,
00314     int restype, ResizeArray<Fragment *> *subfragList);
00315 
00316   void find_subfragments_topologically(int restype, ResizeArray<Fragment *> *subfragList, int endatom, int altendatom, int alt2endatom, int alt3endatom);
00317 
00318 #if defined(VMDFASTRIBBONS)
00321   void calculate_ribbon_controlpoints();
00322 #endif
00323 
00324 #ifdef VMDWITHCARBS
00325 
00326    int find_small_rings(int maxringsize);
00327    int find_back_edges(ResizeArray<int> &back_edge_src, ResizeArray<int> &back_edge_dest);
00328    int find_connected_subgraph_back_edges(int atomid, ResizeArray<int> &back_edge_src, ResizeArray<int> &back_edge_dest,
00329                                           int *intree_parents);
00330    int find_small_rings_from_back_edges(int maxringsize, ResizeArray<int> &back_edge_src, ResizeArray<int> &back_edge_dest);
00331    int find_small_rings_from_partial(SmallRing *ring, int maxringsize, inthash_t *used_edges, inthash_t *used_atoms);
00332    int get_edge_key(int edge_src, int edge_dest);
00333    
00334    // orientate small rings
00335    void orientate_small_rings(int maxringsize);
00336    void orientate_small_ring(SmallRing &ring,int maxringsize);
00337    
00338    // find links between small rings
00339    int find_orientated_small_ring_linkages(int maxpathlength,int maxringsize);
00340    int find_linkages_for_ring_from_partial(LinkagePath &lp, int maxpathlength, inthash_t *atom_to_ring, inthash_t *multi_ring_atoms, inthash_t *used_atoms);
00341 #endif
00342 
00343 
00344 protected:
00345   char *moleculename;  
00346   int need_find_bonds; 
00347 
00348 public:
00349   // constructor; just sets most things to null.  Derived classes must put
00350   // in structure in 'create' routine.  Typical sequence of creating a
00351   // molecule should be:
00352   //    mol = new Molecule(....)
00353   //    ( specify parameters for creation )
00354   //    mol->create();  ... return success
00355   //    mol->analyze(); ... find information about the structure
00356   BaseMolecule(int);      
00357   virtual ~BaseMolecule(void); 
00358 
00359   //
00360   // routines to develop molecular structure
00361   //
00362   
00365   int init_atoms(int n); 
00366 
00368   void find_bonds_from_timestep() { need_find_bonds = 1; }
00369   void find_unique_bonds_from_timestep() { need_find_bonds = 2; }
00370 
00372   int add_atom(char *name, char *type, int atomicnumber, 
00373                char *resname, int resid,
00374                const char *chainid,const char *segname,
00375                char *insertion = (char *) " ", const char *altloc = "");
00376 
00378   int add_bond(int, int, float, int, int = ATOMNORMAL);
00379 
00381   int add_bond_dupcheck(int, int, float, int);
00382 
00384   void clear_angles(void) { angles.clear(); angleTypes.clear(); }
00385 
00387   int num_angles() { return angles.num() / 3; }
00388 
00391   int add_angle(int a, int b, int c, int type=-1);
00392 
00394   int set_angletype(int a, int type);
00395 
00397   int get_angletype(int a);
00398 
00400   void clear_dihedrals(void) { dihedrals.clear(); dihedralTypes.clear(); }
00401 
00403   int num_dihedrals() { return dihedrals.num() / 4; }
00404 
00407   int add_dihedral(int a, int b, int c, int d, int type=-1);
00408     
00410   int set_dihedraltype(int d, int type);
00411 
00413   int get_dihedraltype(int d);
00414 
00416   void clear_impropers(void) { impropers.clear(); improperTypes.clear(); }
00417 
00419   int num_impropers() { return impropers.num() / 4; }
00420 
00423   int add_improper(int a, int b, int c, int d, int type=-1);
00424   
00426   int set_impropertype(int i, int type);
00428   int get_impropertype(int i);
00429 
00431   void clear_cterms() {cterms.clear();}
00432 
00434   int num_cterms() { return cterms.num() / 8; }
00435 
00437   void add_cterm(int a, int b, int c, int d, 
00438                  int e, int f, int g, int h)  {
00439     cterms.append(a); cterms.append(b); cterms.append(c); cterms.append(d); 
00440     cterms.append(e); cterms.append(f); cterms.append(g); cterms.append(h); 
00441   }
00442   
00444   // (By this time, the molecule is on the MoleculeList!)
00445   void analyze(void);
00446 
00447   //
00448   // query info about the molecule
00449   //
00450   int id(void) const { return ID; } 
00451   const char *molname() const {return moleculename; } 
00452 
00453   // Return the Nth atom, residue, and fragment.  All assume correct index 
00454   // and that the structure has been initialized (for speed).
00455   MolAtom *atom(int n) { return atomList+n; } 
00456   Residue *residue(int);                      
00457   Fragment *fragment(int);                    
00458 
00459   // return the residue or fragment in which the given atom is located.
00460   Residue *atom_residue(int);       
00461   Fragment *atom_fragment(int);     
00462 
00464 
00465   int find_atom_in_residue(int atomnameindex, int residue) {
00466     const ResizeArray<int> &atoms = residueList[residue]->atoms;
00467     int num = atoms.num();
00468     for (int i=0; i<num; i++) {
00469       if (atom(atoms[i])->nameindex == atomnameindex) return atoms[i];
00470     }
00471     return -3;
00472   }
00473 
00474   int find_atom_in_residue(const char *atomname, int residue);
00476 
00478 
00479   float default_charge(char *);
00480   float default_mass(char *);
00481   float default_radius(char *);
00482   float default_occup(void) { return 1.0; }
00483   float default_beta(void) { return 0.0; }
00485 
00487   void add_volume_data(const char *name, const float *o, 
00488     const float *xa, const float *ya, const float *za, int x, int y, int z,
00489     float *voldata); 
00490 
00491   int num_volume_data(); 
00492   const VolumetricData *get_volume_data(int); 
00493   void compute_volume_gradient(VolumetricData *);  
00494 
00495 protected:
00496   ResizeArray<VolumetricData *>volumeList;    
00497 };
00498 
00499 // Hydrogen atom name detection macro
00500 #define IS_HYDROGEN(s) (s[0] == 'H' || (isdigit(s[0]) && s[1] == 'H' ))
00501 
00502 #endif
00503 

Generated on Fri May 17 01:51:59 2013 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002