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

GeometryMol.C

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: GeometryMol.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.59 $ $Date: 2020年07月08日 04:40:23 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 *
00019 * A base class for all Geometry objects which measure information about
00020 * atoms in a molecule. A molecule Geometry monitor is assumed to operate
00021 * on N atoms, and be able to calculate a single floating-point value for
00022 * those atoms. (i.e. the angle formed by three atoms in space)
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[3L*n];
00059 if (cells) {
00060 memcpy(cellIndex, cells, 3L*n*sizeof(int));
00061 } else {
00062 memset(cellIndex, 0, 3L*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 // make sure an atom is not repeated in this list
00084 if(i > 0 && objIndex[i-1]==objIndex[i] && comIndex[i-1]==comIndex[i] &&
00085 !memcmp(cellIndex+3L*i, cellIndex+3L*(i-1), 3L*sizeof(int))) {
00086 // set a bogus value for the first atom index, to make the
00087 // check_mol routine fail
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 // sort the items properly
00100 sort_items();
00101 
00102 // create the name for this object
00103 geom_set_name();
00104 }
00105 
00106 
00108 GeometryMol::~GeometryMol(void) {
00109 // delete name if necessary
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 // '%a' atom name
00159 str.gsub("%a", mol->atomNames.name(atom->nameindex));
00160 
00161 // '%d' resid
00162 sprintf(buf, "%d", atom->resid);
00163 str.gsub("%d", buf);
00164 
00165 // '%i' atom index (0-based)
00166 sprintf(buf, "%d", ind);
00167 str.gsub("%i", buf);
00168 
00169 // '%1i' atom index (1-based)
00170 sprintf(buf, "%d", ind+1);
00171 str.gsub("%1i", buf);
00172 
00173 // '%e' atomic element
00174 str.gsub("%e", get_pte_label(atom->atomicnumber));
00175 
00176 // '%b' beta 
00177 sprintf(buf, "%4.3f", mol->beta()[ind]);
00178 str.gsub("%b", buf);
00179 
00180 // '%c' chain
00181 str.gsub("%c", mol->chainNames.name(atom->chainindex));
00182 
00183 // '%C' conformation
00184 str.gsub("%C", mol->altlocNames.name(atom->altlocindex));
00185 
00186 // '%f' user-applied force
00187 sprintf(buf, "%g", totalforce);
00188 str.gsub("%f", buf);
00189 
00190 // '%F' current trajectory frame 
00191 sprintf(buf, "%d", mol->frame());
00192 str.gsub("%F", buf);
00193 
00194 // '%m' mass 
00195 sprintf(buf, "%4.3f", mol->mass()[ind]);
00196 str.gsub("%m", buf);
00197 
00198 // '%n' molecule index
00199 sprintf(buf, "%d", mol->id());
00200 str.gsub("%n", buf);
00201 
00202 // '%N' molecule name
00203 str.gsub("%N", mol->molname()); 
00204 
00205 // '%o' occupancy
00206 sprintf(buf, "%4.3f", mol->occupancy()[ind]);
00207 str.gsub("%o", buf);
00208 
00209 // '%p' atom periodic element number
00210 sprintf(buf, "%d", atom->atomicnumber);
00211 str.gsub("%p", buf);
00212 
00213 // '%q' atom charge
00214 sprintf(buf, "%4.3f", mol->charge()[ind]);
00215 str.gsub("%q", buf);
00216 
00217 // '%R' resname in upper-case
00218 str.gsub("%R", (const char *)resname);
00219 
00220 // '%1R' 1-char resname in upper-case
00221 sprintf(buf, "%c", resname[0]);
00222 str.gsub("%1R", buf);
00223 
00224 // '%r' resname in camel case
00225 resname.to_camel();
00226 str.gsub("%r", (const char *)resname);
00227 
00228 // '%s' segname
00229 str.gsub("%s", mol->segNames.name(atom->segnameindex));
00230 
00231 // '%t' atom type
00232 str.gsub("%t", mol->atomTypes.name(atom->typeindex));
00233 
00234 // '%T' physical time 
00235 sprintf(buf, "%g", physical_time);
00236 str.gsub("%T", buf);
00237 
00238 // '%x', '%y', '%z'
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 // set the name of this item
00250 void GeometryMol::geom_set_name(void) {
00251 char namebuf[256] = { 0 };
00252 char namebuf2[256] = { 0 };
00253 char cellbuf[256] = { 0 };
00254 Molecule *mol;
00255 int i;
00256 
00257 if(items() < 1)
00258 return;
00259 
00260 // put first name in string
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 // put rest of names in string in format: n1/n2/n3/.../nN
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[3L*i+0], cellIndex[3L*i+1],
00277 cellIndex[3L*i+2]);
00278 strcat(namebuf, cellbuf);
00279 } else {
00280 return;
00281 }
00282 }
00283 
00284 // now make a copy of this name
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 // sort the elements in the list, so that the lowest atom index is first
00296 // (but preserve the relative order, i.e. a-b-c or c-b-a)
00297 void GeometryMol::sort_items(void) {
00298 int i,j;
00299 
00300 // swap order if first component index > last component index
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+3L*i, 3L*sizeof(int));
00313 memcpy(cellIndex+3L*i, cellIndex+3L*j, 3L*sizeof(int));
00314 memcpy(cellIndex+3L*j, celltmp, 3L*sizeof(int));
00315 }
00316 }
00317 }
00318 
00319 
00320 // check whether the given molecule & atom index is OK
00321 // if OK, return Molecule pointer; otherwise, return NULL
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 // for the given Molecule, find the TRANSFORMED coords for the given atom
00334 // return Molecule pointer if successful, NULL otherwise.
00335 Molecule *GeometryMol::transformed_atom_coord(int ind, float *pos) {
00336 Molecule *mol;
00337 
00338 // only return value if molecule is legal and atom is displayed
00339 int a=comIndex[ind];
00340 if((mol = normal_atom_coord(ind, pos)) && mol->atom_displayed(a)) {
00341 
00342 // now multiply it by the molecule's tranformation matrix
00343 (mol->tm).multpoint3d(pos, pos);
00344 
00345 // calculation was successful; return the molecule pointer
00346 return mol;
00347 }
00348 
00349 // if here, error (i.e. atom not displayed, or not proper mol id)
00350 return NULL;
00351 }
00352 
00353 
00354 // for the given Molecule, find the UNTRANSFORMED coords for the given atom
00355 // return Molecule pointer if successful, NULL otherwise.
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+3L*ind;
00363 
00364 // get the molecule pointer, and get the coords for the current timestep
00365 if((mol = check_mol(m, a)) && (now = mol->current())) {
00366 memcpy((void *)pos, (void *)(now->pos + 3L*a), 3L*sizeof(float));
00367 
00368 // Apply periodic image transformation before returning
00369 Matrix4 mat;
00370 now->get_transform_from_cell(cell, mat);
00371 mat.multpoint3d(pos, pos);
00372 
00373 return mol;
00374 }
00375 
00376 // if here, error (i.e. atom not displayed, or not proper mol id)
00377 return NULL;
00378 }
00379 
00380 
00381 // draws a line between the two given points
00382 void GeometryMol::display_line(float *p1, float *p2, VMDDisplayList *d) {
00383 DispCmdLine cmdLineGeom;
00384 cmdLineGeom.putdata(p1, p2, d);
00385 }
00386 
00387 
00388 // print given text at current valuePos position
00389 void GeometryMol::display_string(const char *str, VMDDisplayList *d) {
00390 DispCmdText cmdTextGeom;
00391 cmdTextGeom.putdata(valuePos, str, my_text_thickness, my_text_size,
00392 my_text_offset[0], my_text_offset[1], d);
00393 }
00394 
00396 
00397 // return the name of this geometry marker; by default, just blank
00398 const char *GeometryMol::name(void) {
00399 return (gmName ? gmName : "");
00400 }
00401 
00402 
00403 // return 'unique' name of the marker, which should be different than
00404 // other names for different markers of this same type
00405 const char *GeometryMol::unique_name(void) {
00406 return (uniquegmName ? uniquegmName : name());
00407 }
00408 
00409 
00410 // check whether the geometry value can still be calculated
00411 int GeometryMol::ok(void) {
00412 int i;
00413 
00414 for(i=0; i < numItems; i++)
00415 if(!check_mol(objIndex[i], comIndex[i]))
00416 return FALSE;
00417 
00418 return TRUE;
00419 }
00420 
00421 
00422 // calculate a whole list of items, if this object can do so. Return success.
00423 // We must loop over the maximum number of frames for the set of molecules
00424 // involved in the label in order for multi-molecule labels
00425 // to be correcty updated.
00426 int GeometryMol::calculate_all(ResizeArray<float> &valArray) {
00427 int i, j, n=items();
00428 
00429 if (!has_value())
00430 return FALSE;
00431 
00432 // find the highest number of frames in any molecule in the label, and
00433 // cache the current frame so we can restore it later
00434 int maxframes=0;
00435 ResizeArray<int> curframe(n);
00436 for (i=0; i<n; i++) {
00437 Molecule * mol = molList->mol_from_id(objIndex[i]);
00438 if (!mol)
00439 return FALSE; // WHAT?? should never happen
00440 curframe[i]=mol->frame();
00441 if (curframe[i]<0) {
00442 // then this molecule has no frames, so we can't calculate anything
00443 return FALSE;
00444 }
00445 if (mol->numframes() > maxframes)
00446 maxframes=mol->numframes();
00447 }
00448 
00449 // go through all the frames, calculating values
00450 for (j=0; j<maxframes; j++) {
00451 /* override frame */
00452 for (i=0; i<n; i++) {
00453 Molecule * mol = molList->mol_from_id(objIndex[i]);
00454 if (mol)
00455 mol->override_current_frame(j); // paranoia
00456 }
00457 
00458 /* calculate value */
00459 valArray.append(calculate());
00460 
00461 /* restore frame */
00462 for (i=0; i<n; i++) {
00463 Molecule * mol = molList->mol_from_id(objIndex[i]);
00464 if (mol)
00465 mol->override_current_frame(curframe[i]); // paranoia
00466 }
00467 }
00468 
00469 return TRUE;
00470 }
00471 
00472 
00473 // save the text of a selection to the interpreter variable "vmd_pick_selection"
00474 // The format is of the form "index %d %d %d .... %d" for each atom picked.
00475 // (If nothing is picked, the text is "none")
00476 void GeometryMol::set_pick_selection(int , int num, int *atoms) {
00477 cmdqueue->runcommand(new PickSelectionEvent(num, atoms));
00478 }
00479 
00480 void GeometryMol::set_pick_selection() {
00481 cmdqueue->runcommand(new PickSelectionEvent(0, 0));
00482 }
00483 
00484 void GeometryMol::set_pick_value(double newval) {
00485 cmdqueue->runcommand(new PickValueEvent(newval));
00486 }
00487 

Generated on Tue Nov 18 02:47:10 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /