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

BaseMolecule.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: BaseMolecule.h,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.151 $      $Date: 2020/10/28 15:09:56 $
00015  *
00016  ***************************************************************************/
00027 #ifndef BASEMOLECULE_H
00028 #define BASEMOLECULE_H
00029 
00030 #ifndef NAMELIST_TEMPLATE_H
00031 #include "NameList.h"
00032 #endif
00033 #ifndef RESIZEARRAY_TEMPLATE_H
00034 #include "ResizeArray.h"
00035 #endif
00036 #include "Atom.h"
00037 #include "Residue.h"
00038 #include "Timestep.h"
00039 #include "Fragment.h"
00040 #include "Matrix4.h"
00041 #include "intstack.h"
00042 
00043 #ifdef VMDWITHCARBS
00044 #include "SmallRing.h"
00045 #include "SmallRingLinkages.h"
00046 #include "inthash.h"
00047 #endif
00048 
00049 #if 0
00050 #define VMDFASTRIBBONS
00051 #endif
00052 
00053 class VolumetricData;
00054 class QMData;
00055 
00061 class BaseMolecule {
00062 public:
00063   //
00064   // public molecular structure data (for ease of access):
00065   //
00066   int nAtoms;                         
00067   int nResidues;                      
00068   int nWaters;                        
00069   int nSegments;                      
00070   int nFragments;                     
00071   int nProteinFragments;              
00072   int nNucleicFragments;              
00073 
00074   NameList<int> atomNames;            
00075   NameList<int> atomTypes;            
00076   NameList<int> resNames;             
00077   NameList<int> chainNames;           
00078   NameList<int> segNames;             
00079   NameList<int> altlocNames;          
00080 
00081   ResizeArray<Residue *> residueList; 
00082   ResizeArray<Fragment *> fragList;   
00083 
00084   ResizeArray<Fragment *> pfragList;  
00085 
00086   ResizeArray<int> pfragCyclic;       
00087 #if defined(VMDFASTRIBBONS)
00088   ResizeArray<int *> pfragCPList;     
00089 
00090 #endif
00091 
00092 
00093   ResizeArray<Fragment *> nfragList;  
00094   ResizeArray<int> nfragCyclic;       
00095 #if defined(VMDFASTRIBBONS)
00096   ResizeArray<int *> nfragCPList;     
00097 
00098 #endif
00099 
00100 #ifdef VMDWITHCARBS
00101   ResizeArray<SmallRing *> smallringList; 
00102 
00103   SmallRingLinkages smallringLinkages; 
00104   int currentMaxRingSize;             
00105   int currentMaxPathLength;           
00106 #endif
00107 
00108   // Molecule instance transformation matrices, not including self
00109   ResizeArray<Matrix4> instances;     
00110 
00111   // Extra molecular dynamics structure info not normally needed for
00112   // anything but structure building tasks
00113   ResizeArray<int> angles;            
00114   ResizeArray<int> dihedrals;         
00115   ResizeArray<int> impropers;         
00116   ResizeArray<int> cterms;            
00117 
00118   // Extra (optional) data for this molecule.
00119   // If the name is unassigned then the values can be taken to be zero.
00120   NameList<float *> extraflt;         
00121   NameList<int *> extraint;           
00122   NameList<unsigned char *> extraflg; 
00123 
00124   // more structure topology handling info. assign names to FF types.
00125   ResizeArray<int> angleTypes;        
00126   ResizeArray<int> dihedralTypes;     
00127   ResizeArray<int> improperTypes;     
00128   NameList<int> bondTypeNames;        
00129   NameList<int> angleTypeNames;       
00130   NameList<int> dihedralTypeNames;    
00131   NameList<int> improperTypeNames;    
00132 
00133   // Data related to quantum mechanics simulations.
00134   QMData *qm_data;
00135 
00136   // Interface to standard extra data.  These will exist and be initialized
00137   // to zero when init_atoms is called.
00138 
00140   enum dataset_flag {       
00141                NODATA=0x0000,
00142             INSERTION=0x0001, 
00143             OCCUPANCY=0x0002, 
00144               BFACTOR=0x0004, 
00145                  MASS=0x0008, 
00146                CHARGE=0x0010, 
00147                RADIUS=0x0020, 
00148                ALTLOC=0x0040, 
00149          ATOMICNUMBER=0x0080, 
00150                 BONDS=0x0100, 
00151            BONDORDERS=0x0200,
00152                ANGLES=0x0400,
00153                CTERMS=0x0800, 
00154             BONDTYPES=0x1000,
00155            ANGLETYPES=0x2000,
00156             ATOMFLAGS=0x4000 };
00157   
00158   int datasetflags;
00159   void set_dataset_flag(int flag) { 
00160     datasetflags |= flag;
00161   }
00162   void unset_dataset_flag(int flag) {
00163     datasetflags &= (~flag);
00164   }
00165   int test_dataset_flag(int flag) {
00166     return (datasetflags & flag) != 0;
00167   }
00168 
00170   float *radius() { return extraflt.data("radius"); }
00171   float *mass() { return extraflt.data("mass");   }
00172   float *charge() { return extraflt.data("charge"); }
00173   float *beta() { return extraflt.data("beta");   }
00174   float *occupancy() { return extraflt.data("occupancy"); }
00175 
00176   // per-atom flags array
00177   unsigned char *flags() { return extraflg.data("flags"); }
00178 
00181   int radii_minmax_need_update;
00182   float radii_min;
00183   float radii_max;
00184   void set_radii_changed() { radii_minmax_need_update = 1; }
00185 
00186   void get_radii_minmax(float &min, float &max) {
00187     const float *r = NULL;
00188     if (radii_minmax_need_update && nAtoms > 0 &&
00189         (r = extraflt.data("radius")) != NULL) {
00190 
00191 #if 1
00192       // use fast 16-byte-aligned min/max routine
00193       minmax_1fv_aligned(r, nAtoms, &radii_min, &radii_max);
00194 #else
00195       // scalar min/max loop
00196       radii_min = r[0];
00197       radii_max = r[0];
00198       for (int i=0; i<nAtoms; i++) {
00199         if (r[i] < radii_min) radii_min = r[i];
00200         if (r[i] > radii_max) radii_max = r[i];
00201       }
00202 #endif
00203       radii_minmax_need_update = 0;
00204     }
00205 
00206     min = radii_min;  
00207     max = radii_max;  
00208   }
00209 
00211   float *bondorders() { return extraflt.data("bondorders"); }
00212   void setbondorder(int atom, int bond, float order);
00213   float getbondorder(int atom, int bond);
00214 
00216   int *bondtypes() { return extraint.data("bondtypes"); }
00217 
00219   void setbondtype(int atom, int bond, int type);
00220 
00222   int  getbondtype(int atom, int bond);
00223 
00225   int has_structure() const { return cur_atom > 0; }
00226 
00228   void clear_bonds(void);
00229 
00231   int count_bonds(void);
00232 
00233 #ifdef VMDWITHCARBS
00234 
00235   void find_small_rings_and_links(int maxpathlength, int maxringsize);
00236 #endif
00237 
00238 private:
00239   const int ID;          
00240 
00241   //
00242   // molecular structure data:
00243   //
00244   int cur_atom;          
00245   MolAtom *atomList;     
00246   int lastbonderratomid; 
00247   int bonderrorcount;    
00248  
00249   //
00250   // routines to determine components of molecular structure
00251   //
00252  
00260   int find_backbone(void);
00261 
00262   // find the residues in the molecule; return number found.
00263   // I look for atoms with the same resid connected to 
00264   // backbone atoms with the same resid (find enough backbone
00265   // atoms, then find atoms connected to them)
00266   int find_connected_backbone(IntStackHandle, int, int, int, int, int *);
00267   void clean_up_connection(IntStackHandle, int, int, int *);
00268   void find_connected_atoms_in_resid(IntStackHandle, int, int, 
00269      int, int, int *);
00270   void find_and_mark(IntStackHandle, int, int, int, int *, int *);
00271   int make_uniq_resids(int *flgs); 
00272 
00279   int find_residues(void);
00280   
00282   // This should take place after find_residues to keep
00283   // from mistaking a protein resname as a water resname, maybe
00284   void find_connected_waters(int i, char *tmp);
00285   int find_connected_waters2(void);
00286 
00291   int find_waters(void);
00292 
00298   void find_connected_residues(int num_residues);
00299   
00301   int find_segments(void) { return segNames.num(); }
00302   
00304   int find_connected_fragments();
00305 
00312   int find_fragments(void);
00313 
00314   void find_subfragments_cyclic(ResizeArray<Fragment *> *subfragList, int restype);  
00315   void find_cyclic_subfragments(ResizeArray<Fragment *> *subfragList, ResizeArray<int> *subfragCyclic);
00316  
00318   void find_connected_subfragment(int resnum, int fragnum, char *flgs, 
00319          int endatom, int altendatom, int alt2endatom, int alt3endatom,
00320          int restype, 
00321          ResizeArray<Fragment *> *subfragList);
00322 
00323   void find_subfragments(int startatom, int altstartatom, int alt2startatom,
00324     int endatom, int altendatom, int alt2endatom, int alt3endatom,
00325     int restype, ResizeArray<Fragment *> *subfragList);
00326 
00327   void find_subfragments_topologically(int restype, ResizeArray<Fragment *> *subfragList, int endatom, int altendatom, int alt2endatom, int alt3endatom);
00328 
00329 #if defined(VMDFASTRIBBONS)
00332   void calculate_ribbon_controlpoints();
00333 #endif
00334 
00335 #ifdef VMDWITHCARBS
00336 
00337    int find_small_rings(int maxringsize);
00338    int find_back_edges(ResizeArray<int> &back_edge_src, ResizeArray<int> &back_edge_dest);
00339    int find_connected_subgraph_back_edges(int atomid, ResizeArray<int> &back_edge_src, ResizeArray<int> &back_edge_dest,
00340                                           int *intree_parents);
00341    int find_small_rings_from_back_edges(int maxringsize, ResizeArray<int> &back_edge_src, ResizeArray<int> &back_edge_dest);
00342    int find_small_rings_from_partial(SmallRing *ring, int maxringsize, inthash_t *used_edges, inthash_t *used_atoms);
00343    int get_edge_key(int edge_src, int edge_dest);
00344    
00345    // orientate small rings
00346    void orientate_small_rings(int maxringsize);
00347    void orientate_small_ring(SmallRing &ring,int maxringsize);
00348    
00349    // find links between small rings
00350    int find_orientated_small_ring_linkages(int maxpathlength,int maxringsize);
00351    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);
00352 #endif
00353 
00354 
00355 protected:
00356   char *moleculename;  
00357   int need_find_bonds; 
00358 
00359 public:
00360   // constructor; just sets most things to null.  Derived classes must put
00361   // in structure in 'create' routine.  Typical sequence of creating a
00362   // molecule should be:
00363   //    mol = new Molecule(....)
00364   //    ( specify parameters for creation )
00365   //    mol->create();  ... return success
00366   //    mol->analyze(); ... find information about the structure
00367   BaseMolecule(int);      
00368   virtual ~BaseMolecule(void); 
00369 
00370   //
00371   // routines to develop molecular structure
00372   //
00373   
00376   int init_atoms(int n); 
00377 
00379   void find_bonds_from_timestep() { need_find_bonds = 1; }
00380   void find_unique_bonds_from_timestep() { need_find_bonds = 2; }
00381 
00383   int add_atoms(int natoms, 
00384                 const char *name, const char *type, int atomicnumber, 
00385                 const char *resname, int resid,
00386                 const char *chainid, const char *segname,
00387                 const char *insertion = (char *) " ", 
00388                 const char *altloc = "");
00389 
00391   int add_bond(int, int, float, int, int = ATOMNORMAL);
00392 
00394   int add_bond_dupcheck(int, int, float, int);
00395 
00397   void clear_angles(void) { angles.clear(); angleTypes.clear(); }
00398 
00400   int num_angles() { return int(angles.num() / 3); }
00401 
00404   int add_angle(int a, int b, int c, int type=-1);
00405 
00407   int set_angletype(int a, int type);
00408 
00410   int get_angletype(int a);
00411 
00413   void clear_dihedrals(void) { dihedrals.clear(); dihedralTypes.clear(); }
00414 
00416   int num_dihedrals() { return int(dihedrals.num() / 4); }
00417 
00420   int add_dihedral(int a, int b, int c, int d, int type=-1);
00421     
00423   int set_dihedraltype(int d, int type);
00424 
00426   int get_dihedraltype(int d);
00427 
00429   void clear_impropers(void) { impropers.clear(); improperTypes.clear(); }
00430 
00432   int num_impropers() { return int(impropers.num() / 4); }
00433 
00436   int add_improper(int a, int b, int c, int d, int type=-1);
00437   
00439   int set_impropertype(int i, int type);
00441   int get_impropertype(int i);
00442 
00444   void clear_cterms() {cterms.clear();}
00445 
00447   int num_cterms() { return int(cterms.num() / 8); }
00448 
00450   void add_cterm(int a, int b, int c, int d, 
00451                  int e, int f, int g, int h)  {
00452     cterms.append(a); cterms.append(b); cterms.append(c); cterms.append(d); 
00453     cterms.append(e); cterms.append(f); cterms.append(g); cterms.append(h); 
00454   }
00455   
00457   // (By this time, the molecule is on the MoleculeList!)
00458   void analyze(void);
00459 
00460   //
00461   // interfaces to add/query/delete instance transformation matrices
00462   //
00463   void add_instance(Matrix4 & inst) { instances.append(inst); }
00464   int num_instances(void) { return int(instances.num()); }
00465   void clear_instances(void) { instances.clear(); }
00466 
00467 
00468   //
00469   // query info about the molecule
00470   //
00471   int id(void) const { return ID; } 
00472   const char *molname() const {return moleculename; } 
00473 
00474   // Return the Nth atom, residue, and fragment.  All assume correct index 
00475   // and that the structure has been initialized (for speed).
00476   MolAtom *atom(int n) { return atomList+n; } 
00477   Residue *residue(int);                      
00478   Fragment *fragment(int);                    
00479 
00480   // return the residue or fragment in which the given atom is located.
00481   Residue *atom_residue(int);       
00482   Fragment *atom_fragment(int);     
00483 
00485 
00486   int find_atom_in_residue(int atomnameindex, int residue) {
00487     const ResizeArray<int> &atoms = residueList[residue]->atoms;
00488     int num = int(atoms.num());
00489     for (int i=0; i<num; i++) {
00490       if (atom(atoms[i])->nameindex == atomnameindex) return atoms[i];
00491     }
00492     return -3;
00493   }
00494 
00495   int find_atom_in_residue(const char *atomname, int residue);
00497 
00499 
00500   float default_charge(const char *);
00501   float default_mass(const char *);
00502   float default_radius(const char *);
00503   float default_occup(void) { return 1.0; }
00504   float default_beta(void) { return 0.0; }
00506 
00508   void add_volume_data(const char *name, const float *o, 
00509     const float *xa, const float *ya, const float *za, int x, int y, int z,
00510     float *voldata, float *gradient=NULL, float *variance=NULL); 
00511 
00512   void add_volume_data(const char *name, const double *o, 
00513     const double *xa, const double *ya, const double *za, int x, int y, int z,
00514     float *voldata); 
00515 
00517   void remove_volume_data(int idx);
00518 
00519   int num_volume_data(); 
00520   const VolumetricData *get_volume_data(int); 
00521   VolumetricData *modify_volume_data(int); 
00522   void compute_volume_gradient(VolumetricData *);  
00523 
00524 protected:
00525   ResizeArray<VolumetricData *>volumeList;    
00526 };
00527 
00528 // Hydrogen atom name detection macro
00529 #define IS_HYDROGEN(s) (s[0] == 'H' || (isdigit(s[0]) && s[1] == 'H' ))
00530 
00531 #endif
00532 

Generated on Fri Apr 19 02:43:46 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002