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

TclFastPBC.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: TclFastPBC.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.5 $       $Date: 2021/10/29 04:51:39 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Fast PBC wrapping code
00019  ***************************************************************************/
00020 
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #include <tcl.h>
00024 // #include <ctype.h>
00025 #include "TclCommands.h"
00026 #include "AtomSel.h"
00027 #include "VMDApp.h"
00028 #include "MoleculeList.h"
00029 #include "utilities.h"
00030 #include "config.h"
00031 #include "Atom.h"
00032 #include "Molecule.h"
00033 #include "Measure.h"
00034 #include "FastPBC.h"
00035 
00036 //Compound is the type of compounding: 1=fragment, 2=residue.
00037 //mol is the molecule we are operating on. Should come from app->moleculeList->mol_from_id(sel->molid());
00038 //sel is the atomselection we are working on.
00039 //indexlist and fragmentmap are the output pointers. NOTE: It is the caller's responsibility to delete indexlist and fragmentmap.
00040 static int compoundmapper (int compound, Molecule *mol, AtomSel *sel, int *&indexlist, int *&fragmentmap) {
00041   indexlist = new int[sel->selected];
00042   switch (compound) {
00043     case 1:
00044     fragmentmap = new int[mol->nFragments+1]; break;
00045     case 2:
00046     fragmentmap = new int[mol->nResidues+1]; break;
00047     default:
00048     //This should never happen. Ever.
00049     printf("This should have never happened. Josh is sorry.\n Compound was passed with argument %d\n", compound);
00050     return TCL_ERROR;
00051   }
00052   int *idxptr = indexlist;
00053   int *frag = fragmentmap;
00054   *frag = 0;
00055   int i, j, k, l;
00056   int count;
00057   if (compound == 1) {
00058     for (i = 0; (i < mol->nFragments); i++) {
00059       count = 0;
00060       Fragment *f = mol->fragment(i);
00061       for (j = 0; j < f->residues.num(); j++) {
00062         Residue *r = mol->residue(f->residues[j]);
00063         for (k = 0; k < r->atoms.num(); k++) {
00064           l = r->atoms[k];
00065           if (sel->on[l]) {
00066             count++;
00067             *idxptr = l;
00068             idxptr++;
00069           }
00070         }
00071       }
00072       if (count > 0) {
00073         frag++;
00074         *frag = count + *(frag-1);
00075       }
00076     }
00077   } else if (compound == 2) {
00078     for (j = 0; j < mol->nResidues; j++) {
00079       count = 0;
00080       Residue *r = mol->residue(j);
00081       for (k = 0; k < r->atoms.num(); k++) {
00082         l = r->atoms[k];
00083         if (sel->on[l]) {
00084           count++;
00085           *idxptr = l;
00086           idxptr++;
00087         }
00088       }
00089       if (count > 0) {
00090         frag++;
00091         *frag = count + *(frag-1);
00092       }
00093     }
00094   }
00095   return (frag - fragmentmap);
00096 }
00097 
00098 int check_timesteps(Tcl_Interp *interp, Molecule *mol, int first, int last){
00099   int maxframes = mol->numframes();
00100 
00101   if (maxframes == 0 || first < 0 || first > last ||
00102       last >= maxframes) {
00103     Tcl_AppendResult(interp, "fastpbc wrap: invalid frame range: ", first, " to ", last, NULL);
00104       return TCL_ERROR;
00105   }
00106   Timestep *ts;
00107   int f;
00108   for (f=first; f<=last; f++) {
00109     ts = mol->get_frame(f);
00110     if (ts->a_length <= 0 || ts->b_length <= 0 || ts->c_length <= 0) {
00111       Tcl_AppendResult(interp, "fastpbc: frame : ", f, " has no periodic box defined", NULL);
00112       return TCL_ERROR;
00113     }
00114     if (ts->alpha != 90 || ts->beta != 90 || ts->gamma != 90) {
00115       Tcl_AppendResult(interp, "fastpbc: frame : ", f, " has a non-orthogonal box!", NULL);
00116       return TCL_ERROR;
00117     }
00118   }
00119   return TCL_OK;
00120 }
00121 
00152 static int fpbc_wrap(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00153   int first = 0;  //start with first frame by default
00154   int last = -1;  //finish with last frame by default
00155   int i, j;
00156   bool gpu = true;
00157   int compound = 0;
00158   float center[3] = {0,0,0};
00159   //Parse arguments!
00160   if (argc < 2) {
00161     Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [first <first>] [last <last>] [center [list x y z]]");
00162     return TCL_ERROR;
00163   }
00164   AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00165   AtomSel *centersel = NULL;
00166   if (!sel) {
00167     Tcl_SetResult(interp, (char *) "fastpbc wrap: no atom selection", TCL_STATIC);
00168     return TCL_ERROR;
00169   }
00170   for (i=2; i<argc; i+=2) {
00171     char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00172     if (!strupncmp(argvcur, "first", CMDLEN)) {
00173       if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00174         Tcl_AppendResult(interp, "fastpbc wrap: bad first frame value", NULL);
00175         return TCL_ERROR;
00176       }
00177     } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00178       if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00179         Tcl_AppendResult(interp, "fastpbc wrap: bad last frame value", NULL);
00180         return TCL_ERROR;
00181       }
00182     } else if (!strupncmp(argvcur, "center", CMDLEN)) {
00183       int num_vect;
00184       Tcl_Obj **vec;
00185       Tcl_Obj *vecobj = objv[i+1];
00186       if (Tcl_ListObjGetElements(interp, vecobj, &num_vect, &vec) != TCL_OK) {
00187         return TCL_ERROR;
00188       }
00189       if (num_vect != 3) {
00190         Tcl_SetResult(interp, (char *) "fastpbc wrap: center vector can only be of length 3", TCL_STATIC);
00191         return TCL_ERROR;
00192       }
00193       for (j=0; j<3; j++) {
00194         double tmp;
00195         if (Tcl_GetDoubleFromObj(interp, vec[j], &tmp) != TCL_OK) {
00196           Tcl_SetResult(interp, (char *)"fastpbc wrap: non-numeric in vector", TCL_STATIC);
00197           return TCL_ERROR;
00198         }
00199         center[j] = (float)tmp;
00200       }
00201     } else if (!strupncmp(argvcur, "centersel", CMDLEN)) {
00202       centersel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[i+1],NULL));
00203       if (!centersel) {
00204         Tcl_SetResult(interp, (char *) "fastpbc wrap: no atom selection for centersel", TCL_STATIC);
00205         return TCL_ERROR;
00206       }
00207 
00208     } else if (!strupncmp(argvcur, "nogpu", CMDLEN)) {
00209       i--;
00210       gpu = false;
00211     } else if (!strupncmp(argvcur, "compound", CMDLEN)) {
00212       char *compoundarg = Tcl_GetStringFromObj(objv[i+1],NULL);
00213       if (!strupncmp(compoundarg, "fragment", CMDLEN)) {
00214         compound=1;
00215       } else if (!strupncmp(compoundarg, "residue", CMDLEN)) {
00216         compound=2;
00217       } else {
00218         Tcl_AppendResult(interp, "fastpbc wrap: invalid compound syntax, no such keyword: ", compoundarg, NULL);
00219         return TCL_ERROR;
00220       }
00221     } else {
00222       Tcl_AppendResult(interp, "fastpbc wrap: invalid syntax, no such keyword: ", argvcur, NULL);
00223       return TCL_ERROR;
00224     }
00225   }
00226   Molecule *mol = app->moleculeList->mol_from_id(sel->molid());
00227   int maxframes = mol->numframes();
00228   if (last < 0)
00229     last = maxframes-1;
00230   int err = check_timesteps(interp, mol, first, last);
00231   if (err == TCL_ERROR)
00232     return TCL_ERROR;
00233   float *weight = NULL;
00234   if (centersel != NULL) {
00235     if (centersel->molid() != sel->molid()) {
00236        Tcl_AppendResult(interp, "fastpbc wrap: selections are from different molecules", NULL);
00237       return TCL_ERROR;
00238     }
00239     //Find the center for this timestep and atomselection.
00240     weight = new float[centersel->selected];
00241     {
00242       int ret_val = tcl_get_weights(interp, app, centersel, Tcl_NewStringObj("mass\0",-1), weight);
00243       if (ret_val < 0) {
00244         Tcl_AppendResult(interp, "fastpbc wrap: ", measure_error(ret_val),
00245              NULL);
00246         delete [] weight;
00247         return TCL_ERROR;
00248       }
00249     }
00250   }
00251   //End parse arguments.
00252   int *indexlist = NULL;
00253   int *compoundmap = NULL;
00254   int fnum = 0;
00255   if (compound) {
00256     fnum = compoundmapper (compound, mol, sel, indexlist, compoundmap);
00257   }
00258   // if compound, moving will require mass weighting.  find the array storing mass values
00259   float *massarr;
00260   if (compound) { massarr = mol->mass(); }
00261   if (compound) {
00262     if (gpu)
00263       fpbc_exec_wrapcompound(mol, first, last, fnum, compoundmap, sel->selected, indexlist, weight, centersel, center, massarr);
00264     else
00265       fpbc_exec_wrapcompound_cpu(mol, first, last, fnum, compoundmap, sel->selected, indexlist, weight, centersel, center, massarr);
00266   }
00267   else {
00268     //Create the indexlist
00269     indexlist = new int[sel->selected];
00270     j = 0;
00271     for (i=sel->firstsel; i<=sel->lastsel; i++) {
00272       if (sel->on[i]) {
00273         indexlist[j++] = i;
00274       }
00275     }
00276     if (gpu)
00277       fpbc_exec_wrapatomic(mol, first, last, sel->selected, indexlist, weight, centersel, center);
00278     else
00279       fpbc_exec_wrapatomic_cpu(mol, first, last, sel->selected, indexlist, weight, centersel, center);
00280   }
00281   if (weight != NULL) {
00282     delete [] weight;
00283   }
00284   if (indexlist != NULL) {
00285     delete [] indexlist;
00286   }
00287   if (compoundmap != NULL) {
00288     delete [] compoundmap;
00289   }
00290   //Force a redraw since the atoms have moved.
00291   mol->force_recalc(DrawMolItem::MOL_REGEN);
00292   return TCL_OK;
00293 }
00294 
00295 
00296 
00297 
00298 
00299 
00326 static int fpbc_unwrap(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00327   int first = 0;  // start with first frame by default
00328   int last = -1;  // finish with last frame by default
00329   int i, j;
00330   bool gpu = true;
00331   //parameter handling
00332   if (argc < 2) {
00333     Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [first <first>] [last <last>]");
00334     return TCL_ERROR;
00335   }
00336   AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00337   if (!sel) {
00338     Tcl_SetResult(interp, (char *) "fastpbc unwrap: no atom selection", TCL_STATIC);
00339     return TCL_ERROR;
00340   }
00341 
00342   for (i=2; i<argc; i+=2) {
00343     char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00344     if (!strupncmp(argvcur, "first", CMDLEN)) {
00345       if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00346         Tcl_AppendResult(interp, "fastpbc unwrap: bad first frame value", NULL);
00347         return TCL_ERROR;
00348       }
00349     } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00350       if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00351         Tcl_AppendResult(interp, "fastpbc unwrap: bad last frame value", NULL);
00352         return TCL_ERROR;
00353       }
00354     } else if (!strupncmp(argvcur, "nogpu", CMDLEN)) {
00355       i--;
00356       gpu = false;
00357     } else {
00358       Tcl_AppendResult(interp, "fastpbc unwrap: invalid syntax, no such keyword: ", argvcur, NULL);
00359       return TCL_ERROR;
00360     }
00361   }
00362   Molecule *mol = app->moleculeList->mol_from_id(sel->molid());
00363   int maxframes = mol->numframes();
00364   if (last < 0)
00365     last = maxframes-1;
00366   if (last == first) {
00367         Tcl_AppendResult(interp, "fastpbc unwrap: first and last frames must be distinct", NULL);
00368       return TCL_ERROR;
00369   }
00370   int err = check_timesteps(interp, mol, first, last);
00371   if (err == TCL_ERROR)
00372     return TCL_ERROR;
00373         int *indexlist = new int[sel->selected];
00374   j = 0;
00375   for (i=sel->firstsel; i<=sel->lastsel; i++) {
00376     if (sel->on[i]) {
00377       indexlist[j++] = i;
00378     }
00379   }
00380   //Begin unwrapping!
00381   //Keep the current and previous timesteps, and make sure that every atom jumps by no more than half the boxlength.
00382   if (gpu)
00383     fpbc_exec_unwrap(mol, first, last, sel->selected, indexlist);
00384   else
00385     fpbc_exec_unwrap_cpu(mol, first, last, sel->selected, indexlist);
00386   if (indexlist != NULL) {
00387     delete [] indexlist;
00388   }
00389   //Force a redraw since the atoms have moved.
00390   mol->force_recalc(DrawMolItem::MOL_REGEN);
00391   return TCL_OK;
00392 }
00393 
00411 static int fpbc_join(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00412   int first = 0;  // start with first frame by default
00413   int last = -1;  // finish with last frame by default
00414   int i;
00415   bool gpu = true;
00416   int compound = 1; //Default to fragment.
00417   //Deal with input.
00418   if (argc < 2) {
00419     Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [first <first>] [last <last>] [compound residue/fragment]");
00420     return TCL_ERROR;
00421   }
00422   AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00423   if (!sel) {
00424     Tcl_SetResult(interp, (char *) "fastpbc join: no atom selection", TCL_STATIC);
00425     return TCL_ERROR;
00426   }
00427 
00428   for (i=2; i<argc; i+=2) {
00429     char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00430     if (!strupncmp(argvcur, "first", CMDLEN)) {
00431       if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00432         Tcl_AppendResult(interp, "fastpbc join: bad first frame value", NULL);
00433         return TCL_ERROR;
00434       }
00435     } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00436       if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00437         Tcl_AppendResult(interp, "fastpbc join: bad last frame value", NULL);
00438         return TCL_ERROR;
00439       }
00440     } else if (!strupncmp(argvcur, "nogpu", CMDLEN)) {
00441       i--;
00442       gpu = false;
00443     } else if (!strupncmp(argvcur, "compound", CMDLEN)) {
00444       char *compoundarg = Tcl_GetStringFromObj(objv[i+1],NULL);
00445       if (!strupncmp(compoundarg, "fragment", CMDLEN)) {
00446         compound=1;
00447       } else if (!strupncmp(compoundarg, "residue", CMDLEN)) {
00448         compound=2;
00449       } else {
00450         Tcl_AppendResult(interp, "fastpbc join: invalid compound syntax, no such keyword: ", compoundarg, NULL);
00451         return TCL_ERROR;
00452       }
00453     } else {
00454       Tcl_AppendResult(interp, "fastpbc join: invalid syntax, no such keyword: ", argvcur, NULL);
00455       return TCL_ERROR;
00456     }
00457   }
00458   Molecule *mol = app->moleculeList->mol_from_id(sel->molid());
00459   int maxframes = mol->numframes();
00460   if (last < 0)
00461     last = maxframes-1;
00462   int err = check_timesteps(interp, mol, first, last);
00463   if (err == TCL_ERROR)
00464     return TCL_ERROR;
00465   int *indexlist = NULL;
00466   int *compoundmap = NULL;
00467   int fnum = 0;
00468   if (compound) {
00469     fnum = compoundmapper (compound, mol, sel, indexlist, compoundmap);
00470   }
00471   if (gpu)
00472     fpbc_exec_join(mol, first, last, fnum, compoundmap, sel->selected, indexlist);
00473   else
00474     fpbc_exec_join_cpu(mol, first, last, fnum, compoundmap, sel->selected, indexlist);
00475   if (indexlist != NULL) {
00476     delete [] indexlist;
00477   }
00478   if (compoundmap != NULL) {
00479     delete [] compoundmap;
00480   }
00481   //Force a redraw since the atoms have moved.
00482   mol->force_recalc(DrawMolItem::MOL_REGEN);
00483   return TCL_OK;
00484 }
00485 //recenter <sel> <centersel> [first <first>] [last <last>] [compound residue/fragment]
00486 static int fpbc_recenter(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00487   int first = 0;  // start with first frame by default
00488   int last = -1;  // finish with last frame by default
00489   int i, j;
00490   bool gpu = true;
00491   int compound = 0; //Default to atomic wrap.
00492   //Deal with input.
00493   if (argc < 3) {
00494     Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> <centersel> [first <first>] [last <last>] [compound residue/fragment]");
00495     return TCL_ERROR;
00496   }
00497   AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00498   if (!sel) {
00499     Tcl_SetResult(interp, (char *) "fastpbc recenter: no atom selection", TCL_STATIC);
00500     return TCL_ERROR;
00501   }
00502   AtomSel *csel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
00503   if (!sel) {
00504     Tcl_SetResult(interp, (char *) "fastpbc recenter: no center atom selection", TCL_STATIC);
00505     return TCL_ERROR;
00506   }
00507   for (i=3; i<argc; i+=2) {
00508     char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00509     if (!strupncmp(argvcur, "first", CMDLEN)) {
00510       if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00511         Tcl_AppendResult(interp, "fastpbc recenter: bad first frame value", NULL);
00512         return TCL_ERROR;
00513       }
00514     } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00515       if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00516         Tcl_AppendResult(interp, "fastpbc recenter: bad last frame value", NULL);
00517         return TCL_ERROR;
00518       }
00519     } else if (!strupncmp(argvcur, "nogpu", CMDLEN)) {
00520       i--;
00521       gpu = false;
00522     } else if (!strupncmp(argvcur, "compound", CMDLEN)) {
00523       char *compoundarg = Tcl_GetStringFromObj(objv[i+1],NULL);
00524       if (!strupncmp(compoundarg, "fragment", CMDLEN)) {
00525         compound=1;
00526       } else if (!strupncmp(compoundarg, "residue", CMDLEN)) {
00527         compound=2;
00528       } else {
00529         Tcl_AppendResult(interp, "fastpbc recenter: invalid compound syntax, no such keyword: ", compoundarg, NULL);
00530         return TCL_ERROR;
00531       }
00532     } else {
00533       Tcl_AppendResult(interp, "fastpbc recenter: invalid syntax, no such keyword: ", argvcur, NULL);
00534       return TCL_ERROR;
00535     }
00536   }
00537 
00538   Molecule *mol = app->moleculeList->mol_from_id(sel->molid());
00539   int maxframes = mol->numframes();
00540   if (last < 0)
00541     last = maxframes-1;
00542 
00543   int err = check_timesteps(interp, mol, first, last);
00544   if (err == TCL_ERROR)
00545     return TCL_ERROR;
00546   if (csel->molid() != sel->molid()) {
00547     Tcl_AppendResult(interp, "fastpbc recenter: selections are from different molecules", NULL);
00548     return TCL_ERROR;
00549   }
00550   float *weight = new float[csel->selected];
00551   int ret_val = tcl_get_weights(interp, app, csel, Tcl_NewStringObj("mass\0",-1), weight);
00552   if (ret_val < 0) {
00553     Tcl_AppendResult(interp, "fastpbc recenter: ", measure_error(ret_val),NULL);
00554     delete [] weight;
00555     return TCL_ERROR;
00556   }
00557   int *indexlist = NULL;
00558   int *centeridxlist = new int[csel->selected];
00559   j = 0;
00560   for (i=csel->firstsel; i<=csel->lastsel; i++) {
00561     if (csel->on[i]) {
00562       centeridxlist[j++] = i;
00563     }
00564   }
00565   // if compound, moving will require mass weighting.  find the array storing mass values
00566   float *massarr = NULL;
00567   if (compound) { massarr = mol->mass(); }
00568   int *compoundmap = NULL;
00569   int fnum = 0;
00570   if (compound) {
00571     fnum = compoundmapper (compound, mol, sel, indexlist, compoundmap);
00572   }
00573   else {
00574     //Create the indexlist
00575     indexlist = new int[sel->selected];
00576     j = 0;
00577     for (i=sel->firstsel; i<=sel->lastsel; i++) {
00578       if (sel->on[i]) {
00579         indexlist[j++] = i;
00580       }
00581     }
00582   }
00583   if (gpu)
00584     fpbc_exec_recenter(mol, first, last, csel->selected, centeridxlist, fnum, compoundmap, sel->selected, indexlist, weight, csel, massarr);
00585   else
00586     fpbc_exec_recenter_cpu(mol, first, last, csel->selected, centeridxlist, fnum, compoundmap, sel->selected, indexlist, weight, csel, massarr);
00587   if (weight != NULL) {
00588     delete [] weight;
00589   }
00590   if (indexlist != NULL) {
00591     delete [] indexlist;
00592   }
00593   if (centeridxlist != NULL) {
00594     delete [] centeridxlist;
00595   }
00596   if (compoundmap != NULL) {
00597     delete [] compoundmap;
00598   }
00599   //Force a redraw since the atoms have moved.
00600   mol->force_recalc(DrawMolItem::MOL_REGEN);
00601   return TCL_OK;
00602 }
00614 int obj_fastpbc(ClientData cd, Tcl_Interp *interp, int argc,
00615                             Tcl_Obj * const objv[]) {
00616   if (argc < 2) {
00617     Tcl_SetResult(interp,
00618       (char *) "usage: fastpbc <command> [args...]\n"
00619       "\nFastPBC Commands:\n"
00620       "  wrap <sel> [first <first>] [last <last>] [center [list x y z]] [centersel <sel>]\n"
00621       "      [compound residue/fragment]-- (re)wraps trajectory\n"
00622       "  unwrap <sel> [first <first>] [last <last>] -- prevents atoms from \"jumping\" during\n"
00623       "      a trajectory across a periodic boundary\n"
00624       "  join <sel> [first <first>] [last <last>] [compound residue/fragment]\n"
00625       "      -- Eliminates long bonds within a compound (by default, by fragment)\n"
00626       "  recenter <sel> <centersel> [first <first>] [last <last>] [compound residue/fragment]\n"
00627       "      --Identical to an unwrap followed by a wrap. The unwrap is applied only to centersel,\n"
00628       "      and the wrap is also centered on centersel\n",
00629       TCL_STATIC);
00630     return TCL_ERROR;
00631   }
00632   VMDApp *app = (VMDApp *)cd;
00633   char *argv1 = Tcl_GetStringFromObj(objv[1],NULL);
00634   if (!strupncmp(argv1, "wrap", CMDLEN))
00635     return fpbc_wrap(app, argc-1, objv+1, interp);
00636   else if (!strupncmp(argv1, "unwrap", CMDLEN))
00637     return fpbc_unwrap(app, argc-1, objv+1, interp);
00638   else if (!strupncmp(argv1, "join", CMDLEN))
00639     return fpbc_join(app, argc-1, objv+1, interp);
00640   else if (!strupncmp(argv1, "recenter", CMDLEN))
00641     return fpbc_recenter(app, argc-1, objv+1, interp);
00642   Tcl_SetResult(interp, (char *) "Type 'fastpbc' for summary of usage\n", TCL_VOLATILE);
00643   return TCL_OK;
00644 }
00645 
00646 
00647 

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