00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
00109 ResizeArray<Matrix4> instances;
00110
00111
00112
00113 ResizeArray<int> angles;
00114 ResizeArray<int> dihedrals;
00115 ResizeArray<int> impropers;
00116 ResizeArray<int> cterms;
00117
00118
00119
00120 NameList<float *> extraflt;
00121 NameList<int *> extraint;
00122 NameList<unsigned char *> extraflg;
00123
00124
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
00134 QMData *qm_data;
00135
00136
00137
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
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
00193 minmax_1fv_aligned(r, nAtoms, &radii_min, &radii_max);
00194 #else
00195
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
00243
00244 int cur_atom;
00245 MolAtom *atomList;
00246 int lastbonderratomid;
00247 int bonderrorcount;
00248
00249
00250
00251
00252
00260 int find_backbone(void);
00261
00262
00263
00264
00265
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
00283
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
00346 void orientate_small_rings(int maxringsize);
00347 void orientate_small_ring(SmallRing &ring,int maxringsize);
00348
00349
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
00361
00362
00363
00364
00365
00366
00367 BaseMolecule(int);
00368 virtual ~BaseMolecule(void);
00369
00370
00371
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
00458 void analyze(void);
00459
00460
00461
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
00470
00471 int id(void) const { return ID; }
00472 const char *molname() const {return moleculename; }
00473
00474
00475
00476 MolAtom *atom(int n) { return atomList+n; }
00477 Residue *residue(int);
00478 Fragment *fragment(int);
00479
00480
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
00529 #define IS_HYDROGEN(s) (s[0] == 'H' || (isdigit(s[0]) && s[1] == 'H' ))
00530
00531 #endif
00532