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

cmd_label.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2008 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 #include <string.h>
00010 #include <ctype.h>
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <tcl.h>
00014 #include "config.h"
00015 #include "GeometryList.h"
00016 #include "GeometryMol.h"
00017 #include "utilities.h"
00018 #include "VMDApp.h"
00019 
00020 static int find_atom_from_name(Tcl_Interp *interp, const char *str, int *molid,
00021                                int *atomid) {
00022   // string must be of format ##/## where ## are numbers.
00023 
00024   // find first occurence of '/'
00025   const char *slash = strchr(str, '/');
00026   if (!slash) {
00027     Tcl_AppendResult(interp, "Illegal format: ", str, NULL); 
00028     return -1;
00029   }
00030 
00031   // make sure we have digits
00032   if (slash == str) {
00033     Tcl_AppendResult(interp, "Missing molecule specification: ", str, NULL); 
00034     return -1;
00035   }
00036   if (strlen(slash+1) == 0) {
00037     Tcl_AppendResult(interp, "Missing atom specification: ", str, NULL); 
00038     return -1;
00039   }
00040   const char *s;
00041   for (s = str; s < slash; s++) {
00042     if (!isdigit(*s)) {
00043       Tcl_AppendResult(interp, "Illegal molecule specification: ", str, NULL); 
00044       return -1;
00045     }
00046   }
00047   for (s = slash+1; *s; s++) {
00048     if (!isdigit(*s)) {
00049       Tcl_AppendResult(interp, "Illegal atom specification: ", str, NULL); 
00050       return -1;
00051     }
00052   }
00053 
00054   // Looks ok; extract the molecule and atom
00055   char *buf = new char[slash-str + 1];
00056   strncpy(buf, str, slash-str);
00057   buf[slash-str] = '\0';
00058   *molid = atoi(buf);
00059   *atomid = atoi(slash+1);
00060   return 0;
00061 }
00062 
00063 
00064 int text_cmd_label(ClientData cd, Tcl_Interp *interp, int argc,
00065                      const char *argv[]) {
00066 
00067   VMDApp *app = (VMDApp *)cd;
00068 
00069   if (argc < 2) {
00070     Tcl_SetResult(interp,
00071       (char *)
00072       "label add [Atoms|Bonds|Angles|Dihedrals] {atoms as <molid>/<atomid>}\n"
00073       "label addspring <molid> <atomid> <atomid> <k>\n"
00074       "label list              -- return label categories\n"
00075       "label list <category>   -- return id's of labels in given category\n"
00076       "label [show|hide|delete] <category> [index] -- \n\tControl specific label or all labels in category\n"
00077       "label graph <category> <index> -- Return a list of values for the given label\n\tfor all animation frames\n"
00078       "label textsize [<newsize>]\n" ,
00079       TCL_STATIC);
00080     return TCL_ERROR;
00081   }
00082   if(!strupncmp(argv[1], "add", CMDLEN)) {
00083     if(argc > 3) {
00084       int n = argc-3;
00085       const char **items = argv+3; 
00086       int *molid= new int[n];
00087       int *atmid = new int[n];
00088       int i;
00089       for(i=0; i < n; i++) {
00090         if (find_atom_from_name(interp, items[i], molid+i, atmid+i))
00091           break;
00092       }
00093       int rc = -1;
00094       if(i == n) {  // all successfully parsed
00095         rc = app->label_add(argv[2], argc-3, molid, atmid, NULL, 0.0f, 1);
00096       }
00097       delete [] molid;
00098       delete [] atmid;
00099       if (rc < 0) {
00100         Tcl_AppendResult(interp, "\nUnable to add label.", NULL);
00101         return TCL_ERROR;
00102       }
00103     }
00104     else
00105       return TCL_ERROR;
00106 
00107   }
00108   else if(!strupncmp(argv[1],"addspring",CMDLEN)) { /* add a spring */
00109     if(argc != 6) {
00110       Tcl_AppendResult(interp, "usage: label addspring <molid> <atomid> <atomid> <k>", NULL);
00111       return TCL_ERROR;
00112     }
00113     int molid[2];
00114     int atomid[2];
00115     float k;
00116     sscanf(argv[2],"%d",molid); /* convert all of the args to numbers */
00117     sscanf(argv[3],"%d",atomid);
00118     sscanf(argv[4],"%d",atomid+1);
00119     sscanf(argv[5],"%f",&k);
00120     molid[1]=molid[0];
00121     if (app->label_add("Springs", 2, molid, atomid, NULL, k, 1) < 0) {
00122       Tcl_AppendResult(interp, "Unable to add spring.", NULL);
00123       return TCL_ERROR;
00124     }
00125   }
00126   else if(!strupncmp(argv[1], "list", CMDLEN)) {
00127     if(argc == 3) {
00128       int cat =  app->geometryList->geom_list_index(argv[2]);
00129       if (cat < 0) {
00130         Tcl_AppendResult(interp, "graph list category '", argv[2], 
00131                          "' was not found", NULL);
00132         return TCL_ERROR;
00133       }
00134       // go through the list by hand
00135       GeomListPtr glist = app->geometryList->geom_list(cat);
00136       int gnum = glist->num();
00137       char s[30];
00138       GeometryMol *g;
00139       for (int i=0; i<gnum; i++) {
00140         g = (*glist)[i];
00141         Tcl_AppendResult(interp, i==0 ? "" : " ",   "{", NULL);
00142         for (int j=0; j<g->items(); j++) {
00143           // append the molecule id/atom index
00144           sprintf(s, "%d %d", g -> obj_index(j), g -> com_index(j));
00145           Tcl_AppendElement(interp, s);
00146         }
00147         // and the value and the status
00148         sprintf(s, "%f", g->ok() ? g->calculate() : 0.0);
00149         Tcl_AppendElement(interp, s);
00150         Tcl_AppendElement(interp, g -> displayed() ?  "show" : "hide");
00151         Tcl_AppendResult(interp, "}", NULL);
00152       }
00153       return TCL_OK;
00154     }
00155     else if (argc == 2) {
00156       // return the main categories
00157       for (int i=0; i<app->geometryList -> num_lists(); i++) {
00158         Tcl_AppendElement(interp,  app->geometryList -> geom_list_name(i));
00159       }
00160       return TCL_OK;
00161     } else
00162       return TCL_ERROR;
00163 
00164   } else if(!strupncmp(argv[1], "show", CMDLEN) ||
00165             !strupncmp(argv[1], "hide", CMDLEN)) {
00166     int item;
00167     if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN)))
00168       item = (-1);
00169     else if(argc == 4) {
00170       if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00171           Tcl_AppendResult(interp, " in label ", argv[1],  NULL);
00172           return TCL_ERROR;
00173       }
00174     } else
00175       return TCL_ERROR;
00176     
00177     app->label_show(argv[2], item, !strupncmp(argv[1], "show", CMDLEN));
00178     // XXX check return code
00179 
00180   } else if(!strupncmp(argv[1], "delete", CMDLEN)) {
00181     int item;
00182     if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN))) {
00183       item = (-1);
00184     } else if(argc == 4) {
00185       if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00186               Tcl_AppendResult(interp, " in label ", argv[1],  NULL);
00187               return TCL_ERROR;
00188       }
00189     } else {
00190       return TCL_ERROR;
00191     } 
00192 
00193     app->label_delete(argv[2], item);
00194     // XXX check return code
00195 
00196   } else if(!strupncmp(argv[1], "graph", CMDLEN) && argc > 3) {
00197     int item;
00198     if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00199       return TCL_ERROR;
00200     };
00201     // find the geometry
00202     int cat =  app->geometryList->geom_list_index(argv[2]);
00203     if (cat < 0) {
00204       Tcl_AppendResult(interp, "Invalid geometry type: ", argv[2], NULL);
00205       return TCL_ERROR;
00206     }
00207     // get the correct geometry pointer
00208     GeomListPtr glist = app->geometryList -> geom_list(cat);
00209     int gnum = glist -> num();
00210     if (item < 0 || item >= gnum) {
00211       sprintf(interp -> result, "label %s index %d out of range",
00212               argv[2], item);
00213       return TCL_ERROR;
00214     }
00215     // compute all the values
00216     GeometryMol *g = (*glist)[item];
00217     if (!g->has_value()) {
00218       Tcl_AppendResult(interp, "Geometry type ", argv[2], " has no values to graph.", NULL);
00219       return TCL_ERROR;
00220     }
00221     ResizeArray<float> gValues(1024);
00222     if (!g->calculate_all(gValues)) {
00223       interp->result = (char *) "label has no value";
00224       return TCL_ERROR;
00225     }
00226     if (argc > 4) {
00227       // save the values in the given filename
00228       const char *filename = argv[4];
00229       FILE *outfile = fopen(filename, "w");
00230       if (!outfile) {
00231         Tcl_AppendResult(interp, "Cannot write graph data to file ",
00232           filename, NULL);
00233         return TCL_ERROR;
00234       }
00235       for (int i=0; i<gValues.num(); i++) {
00236         fprintf(outfile, "%f  %f\n", float(i), gValues[i]);
00237       }
00238       fclose(outfile);
00239     } else {
00240       char s[20];
00241             for (int count = 0; count < gValues.num(); count++) {
00242               sprintf(s, "%f", gValues[count]);
00243               Tcl_AppendElement(interp, s);
00244             }
00245     }
00246   } else if (!strupncmp(argv[1], "textsize", CMDLEN)) {
00247     if (argc == 2) {
00248       // return the current size
00249       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(app->label_get_textsize()));
00250       return TCL_OK;
00251     } else if (argc == 3) {
00252       // set new size
00253       double newsize = 1;
00254       if (Tcl_GetDouble(interp, argv[2], &newsize) != TCL_OK)
00255         return TCL_ERROR;
00256       if (!app->label_set_textsize((float) newsize)) {
00257         Tcl_AppendResult(interp, "label textsize: Unable to set size to ",
00258             argv[2], NULL);
00259         return TCL_ERROR;
00260       }
00261     } else {
00262       Tcl_SetResult(interp, "label textsize: wrong number of arguments",
00263           TCL_STATIC);
00264       return TCL_ERROR;
00265     }
00266   } else if (!strupncmp(argv[1], "textoffset", CMDLEN)) {
00267     if (argc == 4) {
00268       // return current offset;
00269       const char *geomtype = argv[2];
00270       int geom;
00271       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00272       const float *offset = app->geometryList->getTextOffset(geomtype, geom);
00273       if (!offset) {
00274         Tcl_SetResult(interp, "label textoffset: Invalid geometry specified", TCL_STATIC);
00275         return TCL_ERROR;
00276       }
00277       Tcl_Obj *result = Tcl_NewListObj(0, NULL);
00278       Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[0]));
00279       Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[1]));
00280       Tcl_SetObjResult(interp, result);
00281     } else if (argc == 5) {
00282       const char *geomtype = argv[2];
00283       int geom;
00284       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00285       float x, y;
00286       if (sscanf(argv[4], "%f %f", &x, &y) != 2) {
00287         Tcl_AppendResult(interp, "Could not understand argument to label textoffset:", argv[2], NULL);
00288         return TCL_ERROR;
00289       }
00290       if (!app->label_set_textoffset(geomtype, geom, x, y)) {
00291         Tcl_SetResult(interp, "label textoffset: Invalid geometry specified", TCL_STATIC);
00292         return TCL_ERROR;
00293       }
00294     } else {
00295       Tcl_SetResult(interp, "label textoffset: wrong number of arguments",
00296           TCL_STATIC);
00297       return TCL_ERROR;
00298     }
00299   } else if (!strupncmp(argv[1], "textformat", CMDLEN)) {
00300     if (argc == 4) {
00301       // return current format
00302       const char *geomtype = argv[2];
00303       int geom;
00304       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00305       const char *format = app->geometryList->getTextFormat(geomtype, geom);
00306       if (!format) {
00307         Tcl_SetResult(interp, "label textformat: Invalid geometry specified", TCL_STATIC);
00308         return TCL_ERROR;
00309       }
00310       Tcl_SetResult(interp, (char *)format, TCL_VOLATILE);
00311     } else if (argc == 5) {
00312       const char *geomtype = argv[2];
00313       int geom;
00314       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00315       if (!app->label_set_textformat(geomtype, geom, argv[4])) {
00316         Tcl_SetResult(interp, "label textformat failed.", TCL_STATIC);
00317         return TCL_ERROR;
00318       }
00319     } else {
00320       Tcl_SetResult(interp, "label textoffset: wrong number of arguments",
00321           TCL_STATIC);
00322       return TCL_ERROR;
00323     }
00324   }
00325   return TCL_OK;
00326 }

Generated on Thu Jul 24 01:27:05 2008 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002