00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "GeometryMol.h"
00027 #include "MoleculeList.h"
00028 #include "Molecule.h"
00029 #include "Displayable.h"
00030 #include "DispCmds.h"
00031 #include "utilities.h"
00032 #include "VMDApp.h"
00033 #include "TextEvent.h"
00034 #include "CommandQueue.h"
00035 #include "PeriodicTable.h"
00036
00038 class GeometryMonitor : public DrawMoleculeMonitor {
00039 private:
00040 GeometryMol *mygeo;
00041
00042 public:
00043 GeometryMonitor(GeometryMol *g, int id) : mygeo(g), molid(id) { }
00044 void notify(int id) {
00045 mygeo->calculate();
00046 mygeo->update();
00047 }
00048 const int molid;
00049 };
00050
00052 GeometryMol::GeometryMol(int n, int *mols, int *atms, const int *cells,
00053 MoleculeList *mlist, CommandQueue *cq, Displayable *d)
00054 : Displayable(d) {
00055
00056 objIndex = new int[n];
00057 comIndex = new int[n];
00058 cellIndex = new int[3*n];
00059 if (cells) {
00060 memcpy(cellIndex, cells, 3*n*sizeof(int));
00061 } else {
00062 memset(cellIndex, 0, 3*n*sizeof(int));
00063 }
00064 geomValue = 0.0;
00065 numItems = n;
00066 hasValue = TRUE;
00067
00068 my_color = 8;
00069 my_text_size = 1.0f;
00070 my_text_thickness = 1.0f;
00071 my_text_offset[0] = my_text_offset[1] = 0;
00072 my_text_format = "%R%d:%a";
00073
00074 molList = mlist;
00075 cmdqueue = cq;
00076 gmName = NULL;
00077 uniquegmName = NULL;
00078
00079 for(int i=0; i < numItems; i++) {
00080 objIndex[i] = mols[i];
00081 comIndex[i] = atms[i];
00082
00083
00084 if(i > 0 && objIndex[i-1]==objIndex[i] && comIndex[i-1]==comIndex[i] &&
00085 !memcmp(cellIndex+3*i, cellIndex+3*(i-1), 3*sizeof(int))) {
00086
00087
00088 comIndex[0] = (-1);
00089 }
00090
00091 Molecule *m = molList->mol_from_id(mols[i]);
00092 if (m) {
00093 GeometryMonitor *mon = new GeometryMonitor(this, objIndex[i]);
00094 m->register_monitor(mon);
00095 monitors.append(mon);
00096 }
00097 }
00098
00099
00100 sort_items();
00101
00102
00103 geom_set_name();
00104 }
00105
00106
00108 GeometryMol::~GeometryMol(void) {
00109
00110 if(gmName)
00111 delete [] gmName;
00112 if(uniquegmName)
00113 delete [] uniquegmName;
00114 delete [] objIndex;
00115 delete [] comIndex;
00116 delete [] cellIndex;
00117 for (int i=0; i<monitors.num(); i++) {
00118 GeometryMonitor *mon = monitors[i];
00119 Molecule *m = molList->mol_from_id(mon->molid);
00120 if (m) m->unregister_monitor(mon);
00121 delete mon;
00122 }
00123 }
00124
00125
00127
00128 void GeometryMol::atom_full_name(char *buf, Molecule *mol, int ind) {
00129 sprintf(buf, "%-d/%-d", mol->id(), ind);
00130 }
00131
00132 void GeometryMol::atom_short_name(char *buf, Molecule *mol, int ind) {
00133 MolAtom *nameAtom = mol->atom(ind);
00134 sprintf(buf, "%s%d:%s",
00135 mol->resNames.name(nameAtom->resnameindex),
00136 nameAtom->resid,
00137 mol->atomNames.name(nameAtom->nameindex));
00138 }
00139
00140 void GeometryMol::atom_formatted_name(JString &str, Molecule *mol, int ind) {
00141 MolAtom *atom = mol->atom(ind);
00142 str = my_text_format;
00143 char buf[1024];
00144 JString resname = mol->resNames.name(atom->resnameindex);
00145 Timestep *ts = mol->current();
00146 float totalforce = 0.0f;
00147 double physical_time = 0.0f;
00148 if (ts != NULL) {
00149 if (ts->force != NULL) {
00150 float ufx = ts->force[ind*3 ];
00151 float ufy = ts->force[ind*3 + 1];
00152 float ufz = ts->force[ind*3 + 2];
00153 totalforce = sqrtf(ufx*ufx + ufy*ufy + ufz*ufz);
00154 }
00155 physical_time = ts->physical_time;
00156 }
00157
00158
00159 str.gsub("%a", mol->atomNames.name(atom->nameindex));
00160
00161
00162 sprintf(buf, "%d", atom->resid);
00163 str.gsub("%d", buf);
00164
00165
00166 sprintf(buf, "%d", ind);
00167 str.gsub("%i", buf);
00168
00169
00170 sprintf(buf, "%d", ind+1);
00171 str.gsub("%1i", buf);
00172
00173
00174 str.gsub("%e", get_pte_label(atom->atomicnumber));
00175
00176
00177 sprintf(buf, "%4.3f", mol->beta()[ind]);
00178 str.gsub("%b", buf);
00179
00180
00181 str.gsub("%c", mol->chainNames.name(atom->chainindex));
00182
00183
00184 str.gsub("%C", mol->altlocNames.name(atom->altlocindex));
00185
00186
00187 sprintf(buf, "%g", totalforce);
00188 str.gsub("%f", buf);
00189
00190
00191 sprintf(buf, "%d", mol->frame());
00192 str.gsub("%F", buf);
00193
00194
00195 sprintf(buf, "%4.3f", mol->mass()[ind]);
00196 str.gsub("%m", buf);
00197
00198
00199 sprintf(buf, "%d", mol->id());
00200 str.gsub("%n", buf);
00201
00202
00203 str.gsub("%N", mol->molname());
00204
00205
00206 sprintf(buf, "%4.3f", mol->occupancy()[ind]);
00207 str.gsub("%o", buf);
00208
00209
00210 sprintf(buf, "%d", atom->atomicnumber);
00211 str.gsub("%p", buf);
00212
00213
00214 sprintf(buf, "%4.3f", mol->charge()[ind]);
00215 str.gsub("%q", buf);
00216
00217
00218 str.gsub("%R", (const char *)resname);
00219
00220
00221 sprintf(buf, "%c", resname[0]);
00222 str.gsub("%1R", buf);
00223
00224
00225 resname.to_camel();
00226 str.gsub("%r", (const char *)resname);
00227
00228
00229 str.gsub("%s", mol->segNames.name(atom->segnameindex));
00230
00231
00232 str.gsub("%t", mol->atomTypes.name(atom->typeindex));
00233
00234
00235 sprintf(buf, "%g", physical_time);
00236 str.gsub("%T", buf);
00237
00238
00239 if ((ts != NULL) && (ts->pos != NULL)) {
00240 sprintf(buf, "%g", ts->pos[ind*3 ]);
00241 str.gsub("%x", buf);
00242 sprintf(buf, "%g", ts->pos[ind*3 + 1]);
00243 str.gsub("%y", buf);
00244 sprintf(buf, "%g", ts->pos[ind*3 + 2]);
00245 str.gsub("%z", buf);
00246 }
00247 }
00248
00249
00250 void GeometryMol::geom_set_name(void) {
00251 char namebuf[256];
00252 char namebuf2[256];
00253 char cellbuf[256];
00254 Molecule *mol;
00255 register int i;
00256
00257 if(items() < 1)
00258 return;
00259
00260
00261 if((mol = check_mol(objIndex[0], comIndex[0]))) {
00262 atom_full_name(namebuf, mol, comIndex[0]);
00263 atom_short_name(namebuf2, mol, comIndex[0]);
00264 sprintf(cellbuf, "-%d-%d-%d", cellIndex[0], cellIndex[1], cellIndex[2]);
00265 strcat(namebuf, cellbuf);
00266 } else
00267 return;
00268
00269
00270 for(i = 1; i < items(); i++) {
00271 if((mol = check_mol(objIndex[i], comIndex[i]))) {
00272 strcat(namebuf, "/");
00273 atom_full_name(namebuf+strlen(namebuf), mol, comIndex[i]);
00274 strcat(namebuf2, "/");
00275 atom_short_name(namebuf2+strlen(namebuf2), mol, comIndex[i]);
00276 sprintf(cellbuf, "-%d-%d-%d", cellIndex[3*i+0], cellIndex[3*i+1],
00277 cellIndex[3*i+2]);
00278 strcat(namebuf, cellbuf);
00279 } else {
00280 return;
00281 }
00282 }
00283
00284
00285 if(gmName)
00286 delete [] gmName;
00287 if(uniquegmName)
00288 delete [] uniquegmName;
00289
00290 uniquegmName = stringdup(namebuf);
00291 gmName = stringdup(namebuf2);
00292 }
00293
00294
00295
00296
00297 void GeometryMol::sort_items(void) {
00298 register int i,j;
00299
00300
00301 if( (comIndex[0] > comIndex[items()- 1]) ||
00302 (comIndex[0] == comIndex[items()-1] &&
00303 objIndex[0] > objIndex[items()-1]) ) {
00304 for(i=0, j=(items() - 1); i < j; i++, j--) {
00305 int tmpindex = comIndex[i];
00306 comIndex[i] = comIndex[j];
00307 comIndex[j] = tmpindex;
00308 tmpindex = objIndex[i];
00309 objIndex[i] = objIndex[j];
00310 objIndex[j] = tmpindex;
00311 int celltmp[3];
00312 memcpy(celltmp, cellIndex+3*i, 3*sizeof(int));
00313 memcpy(cellIndex+3*i, cellIndex+3*j, 3*sizeof(int));
00314 memcpy(cellIndex+3*j, celltmp, 3*sizeof(int));
00315 }
00316 }
00317 }
00318
00319
00320
00321
00322 Molecule *GeometryMol::check_mol(int m, int a) {
00323
00324 Molecule *mol = molList->mol_from_id(m);
00325
00326 if(!mol || a < 0 || a >= mol->nAtoms)
00327 mol = NULL;
00328
00329 return mol;
00330 }
00331
00332
00333
00334
00335 Molecule *GeometryMol::transformed_atom_coord(int ind, float *pos) {
00336 Molecule *mol;
00337
00338
00339 int a=comIndex[ind];
00340 if((mol = normal_atom_coord(ind, pos)) && mol->atom_displayed(a)) {
00341
00342
00343 (mol->tm).multpoint3d(pos, pos);
00344
00345
00346 return mol;
00347 }
00348
00349
00350 return NULL;
00351 }
00352
00353
00354
00355
00356 Molecule *GeometryMol::normal_atom_coord(int ind, float *pos) {
00357 Timestep *now;
00358 Molecule *mol;
00359
00360 int m=objIndex[ind];
00361 int a=comIndex[ind];
00362 const int *cell = cellIndex+3*ind;
00363
00364
00365 if((mol = check_mol(m, a)) && (now = mol->current())) {
00366 memcpy((void *)pos, (void *)(now->pos + 3*a), 3*sizeof(float));
00367
00368
00369 Matrix4 mat;
00370 now->get_transform_from_cell(cell, mat);
00371 mat.multpoint3d(pos, pos);
00372
00373 return mol;
00374 }
00375
00376
00377 return NULL;
00378 }
00379
00380
00381
00382 void GeometryMol::display_line(float *p1, float *p2, VMDDisplayList *d) {
00383 DispCmdLine cmdLineGeom;
00384 cmdLineGeom.putdata(p1, p2, d);
00385 }
00386
00387
00388
00389 void GeometryMol::display_string(const char *str, VMDDisplayList *d) {
00390 DispCmdTextOffset cmdTextOffset;
00391 cmdTextOffset.putdata(my_text_offset[0], my_text_offset[1], d);
00392
00393 DispCmdTextSize cmdTextSize;
00394 cmdTextSize.putdata(my_text_size, d);
00395
00396 DispCmdText cmdTextGeom;
00397 cmdTextGeom.putdata(valuePos, str, my_text_thickness, d);
00398 }
00399
00401
00402
00403 const char *GeometryMol::name(void) {
00404 return (gmName ? gmName : "");
00405 }
00406
00407
00408
00409
00410 const char *GeometryMol::unique_name(void) {
00411 return (uniquegmName ? uniquegmName : name());
00412 }
00413
00414
00415
00416 int GeometryMol::ok(void) {
00417 register int i;
00418
00419 for(i=0; i < numItems; i++)
00420 if(!check_mol(objIndex[i], comIndex[i]))
00421 return FALSE;
00422
00423 return TRUE;
00424 }
00425
00426
00427
00428
00429
00430
00431 int GeometryMol::calculate_all(ResizeArray<float> &valArray) {
00432 int i, j, n=items();
00433
00434 if (!has_value())
00435 return FALSE;
00436
00437
00438
00439 int maxframes=0;
00440 ResizeArray<int> curframe(n);
00441 for (i=0; i<n; i++) {
00442 Molecule * mol = molList->mol_from_id(objIndex[i]);
00443 if (!mol)
00444 return FALSE;
00445 curframe[i]=mol->frame();
00446 if (curframe[i]<0) {
00447
00448 return FALSE;
00449 }
00450 if (mol->numframes() > maxframes)
00451 maxframes=mol->numframes();
00452 }
00453
00454
00455 for (j=0; j<maxframes; j++) {
00456
00457 for (i=0; i<n; i++) {
00458 Molecule * mol = molList->mol_from_id(objIndex[i]);
00459 if (mol)
00460 mol->override_current_frame(j);
00461 }
00462
00463
00464 valArray.append(calculate());
00465
00466
00467 for (i=0; i<n; i++) {
00468 Molecule * mol = molList->mol_from_id(objIndex[i]);
00469 if (mol)
00470 mol->override_current_frame(curframe[i]);
00471 }
00472 }
00473
00474 return TRUE;
00475 }
00476
00477
00478
00479
00480
00481 void GeometryMol::set_pick_selection(int , int num, int *atoms) {
00482 cmdqueue->runcommand(new PickSelectionEvent(num, atoms));
00483 }
00484
00485 void GeometryMol::set_pick_selection() {
00486 cmdqueue->runcommand(new PickSelectionEvent(0, 0));
00487 }
00488
00489 void GeometryMol::set_pick_value(double newval) {
00490 cmdqueue->runcommand(new PickValueEvent(newval));
00491 }
00492