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

TclVoltool.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 2007-2011 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: TclVoltool.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.10 $      $Date: 2020/10/15 17:44:27 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  General volumetric data processing routines, particularly supporting MDFF
00019  *
00020  ***************************************************************************/
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <float.h> // FLT_MAX etc
00026 #include "Inform.h"
00027 #include "utilities.h"
00028 //#include "SymbolTable.h"
00029 
00030 #include "AtomSel.h"
00031 #include "VMDApp.h"
00032 #include "MoleculeList.h"
00033 #include "VolumetricData.h"
00034 #include "VolMapCreate.h"
00035 #include "PluginMgr.h"
00036 #include "MolFilePlugin.h"
00037 
00038 #include "CUDAMDFF.h"
00039 #include "MDFF.h"
00040 #include "TclMDFF.h"
00041 #include <math.h>
00042 #include <tcl.h>
00043 #include "TclCommands.h"
00044 #include "Measure.h"
00045 #include "MolFilePlugin.h"
00046 #include "Voltool.h"
00047 
00048 #include <iostream>
00049 #include <string>
00050 #include <sstream>
00051 
00052 void moveby(AtomSel *sel, float *vect, MoleculeList *mlist, float *framepos){
00053   
00054   for (int i=sel->firstsel; i<=sel->lastsel; i++) {
00055     if (sel->on[i]) {
00056       vec_add(framepos + 3L*i, framepos + 3L*i, vect);
00057     }
00058   }
00059 }
00060 
00061 void move(AtomSel *sel, Matrix4 mat, MoleculeList *mlist, float *framepos){
00062   measure_move(sel, framepos, mat);
00063 }
00064 
00065 
00066 double density_calc_cc(VolumetricData *volmapA, VolumetricData *volmapB, double thresholddensity) {
00067 
00068   double cc = 0.0;
00069   cc_threaded(volmapA, volmapB, &cc, thresholddensity);
00070   return cc;
00071 }
00072 
00073 double calc_cc (AtomSel *sel, VolumetricData *volmapA, float resolution, MoleculeList *mlist, float *framepos) {
00074   
00075   float radscale;
00076   double gspacing = 0;
00077   double thresholddensity = 0.1;
00078   int verbose = 0;
00079   float return_cc = 0;
00080 
00081   radscale = 0.2f * resolution;
00082   gspacing = 1.5*radscale;
00083 
00084   int quality = 0;
00085   if (resolution >= 9)
00086     quality = 0;
00087   else
00088     quality = 3;
00089   
00090   Molecule *mymol = mlist->mol_from_id(sel->molid());
00091   const float *radii = mymol->radius();
00092   
00093   int cuda_err = -1;
00094 #if defined(VMDCUDA)
00095   VolumetricData **synthpp = NULL;
00096   VolumetricData **diffpp = NULL;
00097   VolumetricData **spatialccpp = NULL;
00098 
00099   if (getenv("VMDNOCUDA") == NULL) {
00100 
00101     cuda_err = vmd_cuda_compare_sel_refmap(sel, mlist, quality, 
00102                                   radscale, gspacing, 
00103                                   volmapA, synthpp, diffpp, spatialccpp, 
00104                                   &return_cc, thresholddensity, verbose);
00105   }
00106 #endif
00107 
00108   // If CUDA failed, we use CPU fallback, and we have to prevent QuickSurf
00109   // from using the GPU either...
00110   if (cuda_err == -1) {
00111     const int force_cpu_calc=1;
00112     if (verbose)
00113       printf("Computing CC on CPUs...\n");
00114 
00115     if (gspacing == 0) {
00116       gspacing = 1.5*radscale;
00117     }
00118 
00119     QuickSurf *qs = new QuickSurf(force_cpu_calc);
00120     VolumetricData *volmap = NULL;
00121     volmap = qs->calc_density_map(sel, mymol, framepos, radii,
00122                                   quality, (float)radscale, (float)gspacing);
00123     double cc = 0.0;
00124     cc_threaded(volmap, volmapA, &cc, thresholddensity);
00125     return_cc += float(cc);
00126     delete qs;
00127   }
00128   return return_cc;
00129 }
00130 
00131 void do_rotate(int stride, float *com, AtomSel *sel, int amt, float *axis, MoleculeList *mlist, float *framepos){
00132   double amount = DEGTORAD(stride*amt);
00133   Matrix4 mat;
00134   mat.rotate_axis(axis, (float) amount);
00135   move(sel, mat, mlist, framepos);
00136 }
00137 
00138 void do_density_rotate(int stride, int amt, float *axis, VolumetricData *synthvol){
00139 //  float move1[3];
00140 //  vec_scale(move1, -1.0, com);
00141   double amount = DEGTORAD(stride*amt);
00142   Matrix4 mat;
00143   mat.rotate_axis(axis, (float) amount);
00144 //  moveby(sel, move1, mlist, framepos);
00145   vol_move(synthvol, mat.mat);
00146 //  move(sel, mat, mlist, framepos);
00147 //  moveby(sel, com, mlist, framepos);
00148 
00149 }
00150 
00151 void rotate(int stride, int max_rot, float *com, float *returncc, float *bestpos, AtomSel *sel, MoleculeList *mlist, VolumetricData *volmapA, float resolution, float *origin, float *framepos) {
00152   
00153  // float *framepos = sel->coordinates(mlist);
00154  // float bestpos[sel->selected]; 
00155   //float best_cc = -1;
00156 
00157   float move1[3];
00158   vec_scale(move1, -1.0, com);
00159 
00160   for( int x = 0; x < max_rot; x++) {
00161     for( int y = 0; y < max_rot; y++) {
00162       for( int z = 0; z < max_rot; z++) {
00163         
00164         //move sel to vmd origin
00165         moveby(sel, move1, mlist, framepos);
00166         //rotate x
00167         float axisx [3] = {1, 0, 0};
00168         do_rotate(stride, com, sel, x, axisx, mlist, framepos);
00169         //rotate y
00170         float axisy [3] = {0, 1, 0};
00171         do_rotate(stride, com, sel, y, axisy, mlist, framepos);
00172         //rotate z
00173         float axisz [3] = {0, 0, 1};
00174         do_rotate(stride, com, sel, z, axisz, mlist, framepos);
00175         //move sel back to its original com
00176         moveby(sel, com, mlist, framepos);
00177         
00178         float cc = float(calc_cc(sel, volmapA, resolution, mlist, framepos)); 
00179         if (cc > *returncc) {
00180           *returncc = cc;
00181           for (int i=0; i<sel->selected*3L; i++) {
00182            // if (sel->on[i]) {
00183               bestpos[i] = framepos[i];
00184            // }
00185           }
00186         } else if (cc < *returncc) {
00187 //          x++;
00188 //          y++;
00189           z++;
00190         }
00191         for (int i=0; i<sel->selected*3L; i++) {
00192          // if (sel->on[i]) {
00193             framepos[i] = origin[i];
00194          // }
00195         }
00196 
00197       }
00198     } 
00199   }
00200 }
00201 
00202 void density_rotate(int stride, int max_rot, float *com, float *returncc, int *bestrot, VolumetricData *volmapA, VolumetricData *synthvol, float resolution, double *origin, double *dx, double *dy, double *dz) {
00203   
00204   int num = 0;
00205   float move1[3] = {0, 0, 0};
00206   for( int x = 0; x < max_rot; x++) {
00207     for( int y = 0; y < max_rot; y++) {
00208       for( int z = 0; z < max_rot; z++) {
00209         
00210         vol_moveto(synthvol, com, move1);
00211         //rotate x
00212         float axisx [3] = {1, 0, 0};
00213         do_density_rotate(stride, x, axisx, synthvol);  
00214        //do_rotate(stride, com, sel, x, axisx, mlist, framepos);
00215         //rotate y
00216         float axisy [3] = {0, 1, 0};
00217         //do_rotate(stride, com, sel, y, axisy, mlist, framepos);
00218         do_density_rotate(stride, y, axisy, synthvol);  
00219         //rotate z
00220         float axisz [3] = {0, 0, 1};
00221         //do_rotate(stride, com, sel, z, axisz, mlist, framepos);
00222         do_density_rotate(stride, z, axisz, synthvol);  
00223         
00224         float currcom[3];        
00225         vol_com(synthvol, currcom);
00226         vol_moveto(synthvol, currcom, com);
00227        /* 
00228         printf("origin %f %f %f\n", 
00229         synthvol->origin[0],
00230         synthvol->origin[1],
00231         synthvol->origin[2]);
00232         
00233         printf("delta %f %f %f\n", 
00234         synthvol->xaxis[0]/(synthvol->xsize - 1), 
00235         synthvol->xaxis[1]/(synthvol->xsize - 1),
00236         synthvol->xaxis[2]/(synthvol->xsize - 1));
00237         printf("delta %f %f %f\n", 
00238         synthvol->yaxis[0]/(synthvol->ysize - 1), 
00239         synthvol->yaxis[1]/(synthvol->ysize - 1),
00240         synthvol->yaxis[2]/(synthvol->ysize - 1));
00241         printf("delta %f %f %f\n", 
00242         synthvol->zaxis[0]/(synthvol->zsize - 1), 
00243         synthvol->zaxis[1]/(synthvol->zsize - 1),
00244         synthvol->zaxis[2]/(synthvol->zsize - 1));
00245         
00246         volmap_write_dx_file(synthvol, "test.dx");
00247 */
00248        // std::string filename = "output/map-" + std::to_string(num) + ".dx";
00249         //printf("filename: %s\n", filename.c_str());
00250         //volmap_write_dx_file(synthvol, filename.c_str());
00251         num++;
00252         float cc = float(density_calc_cc(volmapA, synthvol, 0.1));
00253   //      printf ("CC: %f\n", cc); 
00254         if (cc > *returncc) {
00255           *returncc = cc;
00256           bestrot[0] = x;
00257           bestrot[1] = y;  
00258           bestrot[2] = z;
00259         //  volmap_write_dx_file(synthvol, "best.dx");
00260             
00261         }
00262         synthvol->origin[0] = origin[0];
00263         synthvol->origin[1] = origin[1];
00264         synthvol->origin[2] = origin[2];
00265         synthvol->xaxis[0] = dx[0]; 
00266         synthvol->xaxis[1] = dx[1]; 
00267         synthvol->xaxis[2] = dx[2]; 
00268         synthvol->yaxis[0] = dy[0]; 
00269         synthvol->yaxis[1] = dy[1]; 
00270         synthvol->yaxis[2] = dy[2]; 
00271         synthvol->zaxis[0] = dz[0]; 
00272         synthvol->zaxis[1] = dz[1]; 
00273         synthvol->zaxis[2] = dz[2]; 
00274         
00275       
00276       }
00277     } 
00278   }
00279 }
00280 
00281 void reset_density(int stride, int *bestrot, VolumetricData *synthvol, float *synthcom, float *framepos, float *com, AtomSel *sel, MoleculeList *mlist) {
00282 
00283   float move1[3];
00284   vec_scale(move1, -1.0, synthcom);
00285   vol_moveto(synthvol, synthcom, move1);
00286 
00287   //rotate density x 
00288   float axisx [3] = {1, 0, 0};
00289   do_density_rotate(stride, bestrot[0], axisx, synthvol);  
00290   //rotate density y
00291   float axisy [3] = {0, 1, 0};
00292   do_density_rotate(stride, bestrot[1], axisy, synthvol);  
00293   //rotate density z
00294   float axisz [3] = {0, 0, 1};
00295   do_density_rotate(stride, bestrot[2], axisz, synthvol);  
00296   
00297   float currcom[3];
00298   vol_com(synthvol, currcom);
00299   vol_moveto(synthvol, currcom, com);
00300   
00301   vec_scale(move1, -1.0, com);
00302   //move sel to vmd origin
00303   moveby(sel, move1, mlist, framepos);
00304   //rotate sel x
00305   do_rotate(stride, com, sel, bestrot[0], axisx, mlist, framepos);
00306   //rotate sel y
00307   do_rotate(stride, com, sel, bestrot[1], axisy, mlist, framepos);
00308   //rotate sel z
00309   do_rotate(stride, com, sel, bestrot[2], axisz, mlist, framepos);
00310   //move sel back to its original com
00311   moveby(sel, com, mlist, framepos);
00312 
00313 }
00314 void reset_origin(float *origin, float *newpos, AtomSel *sel) {
00315   for (int i=0; i<sel->num_atoms*3L; i++) {
00316       origin[i] = newpos[i];
00317   }
00318 }
00319 
00320 int density_com(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00321   if (argc < 3) {
00322     Tcl_SetResult(interp, (char *) "usage: voltool "
00323       "com [options]\n"
00324       "    options:  -i <input map> specifies new density filename to load.\n"
00325       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
00326       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n",
00327       TCL_STATIC);
00328     return TCL_ERROR;
00329   }
00330 
00331   int molid = -1;
00332   int volid = 0;
00333   const char *input_map = NULL;
00334   MoleculeList *mlist = app->moleculeList;
00335   
00336   for (int i=0; i < argc; i++) {
00337     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
00338     if (!strcmp(opt, "-i")) {
00339       if (i == argc-1) {
00340         Tcl_AppendResult(interp, "No input map specified",NULL);
00341         return TCL_ERROR;
00342       }
00343 
00344       FileSpec spec;
00345       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
00346       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
00347       molid = app->molecule_new(input_map,0,1);
00348       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
00349       if (ret_val < 0) return TCL_ERROR;
00350     }
00351 
00352 
00353     if (!strcmp(opt, "-mol")) {
00354       if (i == argc-1) {
00355         Tcl_AppendResult(interp, "No molid specified",NULL);
00356         return TCL_ERROR;
00357       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
00358         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
00359         return TCL_ERROR;
00360       }
00361     }
00362 
00363     if (!strcmp(opt, "-vol")) {
00364       if (i == argc-1){
00365         Tcl_AppendResult(interp, "No volume id specified",NULL);
00366         return TCL_ERROR;
00367       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
00368         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
00369         return TCL_ERROR;
00370       }
00371     }
00372 
00373   }
00374 
00375   VolumetricData *volmapA = NULL;
00376   if (molid > -1) {
00377     Molecule *volmol = mlist->mol_from_id(molid);
00378     if (volmol == NULL) {
00379       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
00380       return TCL_ERROR;
00381     }
00382 
00383     if (volmapA == NULL) 
00384       volmapA = volmol->modify_volume_data(volid);
00385   } else {
00386     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
00387     return TCL_ERROR;
00388   }
00389   if (volmapA == NULL) {
00390     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
00391     return TCL_ERROR;
00392   }
00393   
00394   
00395   float com[3] = {0.0,0.0,0.0};
00396   vol_com(volmapA, com);  
00397  
00398   Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00399   Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(com[0]));
00400   Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(com[1]));
00401   Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(com[2]));
00402 
00403   Tcl_SetObjResult(interp, tcl_result);
00404   return TCL_OK;
00405 }
00406 
00407 int density_move(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00408   if (argc < 3) {
00409     Tcl_SetResult(interp, (char *) "usage: voltool "
00410       "move -mat <4x4 transform matrix to apply to density> [options]\n"
00411       "    options:  -i <input map> specifies new density filename to load.\n"
00412       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
00413       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
00414       "              -o <filename> write density to file.\n",
00415       TCL_STATIC);
00416     return TCL_ERROR;
00417   }
00418 
00419 
00420   int molid = -1;
00421   int volid = 0;
00422   float mat[16];
00423   const char *input_map = NULL;
00424   const char *outputmap = NULL;
00425   MoleculeList *mlist = app->moleculeList;
00426   
00427   for (int i=0; i < argc; i++) {
00428     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
00429     if (!strcmp(opt, "-i")) {
00430       if (i == argc-1) {
00431         Tcl_AppendResult(interp, "No input map specified",NULL);
00432         return TCL_ERROR;
00433       }
00434 
00435       FileSpec spec;
00436       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
00437       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
00438       molid = app->molecule_new(input_map,0,1);
00439       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
00440       if (ret_val < 0) return TCL_ERROR;
00441     }
00442 
00443 
00444     if (!strcmp(opt, "-mol")) {
00445       if (i == argc-1) {
00446         Tcl_AppendResult(interp, "No molid specified",NULL);
00447         return TCL_ERROR;
00448       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
00449         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
00450         return TCL_ERROR;
00451       }
00452     }
00453 
00454     if (!strcmp(opt, "-vol")) {
00455       if (i == argc-1){
00456         Tcl_AppendResult(interp, "No volume id specified",NULL);
00457         return TCL_ERROR;
00458       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
00459         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
00460         return TCL_ERROR;
00461       }
00462     }
00463     
00464     if (!strcmp(opt, "-mat")) {
00465       if (i == argc-1){
00466         Tcl_AppendResult(interp, "No matrix specified",NULL);
00467         return TCL_ERROR;
00468       } else if (tcl_get_matrix(Tcl_GetStringFromObj(objv[0],NULL), interp, objv[i+1], mat) != TCL_OK) {
00469           return TCL_ERROR;
00470       }
00471     }
00472     
00473     if (!strcmp(opt, "-o")) {
00474       if (i == argc-1) {
00475         Tcl_AppendResult(interp, "No output file specified",NULL);
00476         return TCL_ERROR;
00477       } else {
00478         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
00479       }
00480     }
00481 
00482   }
00483   Molecule *volmol = NULL;
00484   VolumetricData *volmapA = NULL;
00485   if (molid > -1) {
00486     volmol = mlist->mol_from_id(molid);
00487     if (volmol == NULL) {
00488       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
00489       return TCL_ERROR;
00490     }
00491 
00492     if (volmapA == NULL) 
00493       volmapA = volmol->modify_volume_data(volid);
00494   } else {
00495     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
00496     return TCL_ERROR;
00497   }
00498   if (volmapA == NULL) {
00499     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
00500     return TCL_ERROR;
00501   }
00502   
00503  
00504   vol_move(volmapA, mat); 
00505   volmol->force_recalc(DrawMolItem::MOL_REGEN);
00506 
00507   if (outputmap != NULL) {
00508     if (!write_file(app, volmol, volid, outputmap)){
00509       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
00510       return TCL_ERROR;
00511     }
00512   }
00513   return TCL_OK;
00514 
00515 }
00516 
00517 int density_moveto(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00518   if (argc < 3) {
00519     Tcl_SetResult(interp, (char *) "usage: voltool "
00520       "moveto -pos {x y z} coordinates to move com to> [options]\n"
00521       "    options:  -i <input map> specifies new density filename to load.\n"
00522       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
00523       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
00524       "              -o <filename> write density to file.\n",
00525       TCL_STATIC);
00526     return TCL_ERROR;
00527   }
00528 
00529 
00530   int molid = -1;
00531   int volid = 0;
00532   double pos[3] = {0.0, 0.0, 0.0};
00533   const char *input_map = NULL;
00534   const char *outputmap = NULL;
00535   MoleculeList *mlist = app->moleculeList;
00536   
00537   for (int i=0; i < argc; i++) {
00538     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
00539     if (!strcmp(opt, "-i")) {
00540       if (i == argc-1) {
00541         Tcl_AppendResult(interp, "No input map specified",NULL);
00542         return TCL_ERROR;
00543       }
00544 
00545       FileSpec spec;
00546       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
00547       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
00548       molid = app->molecule_new(input_map,0,1);
00549       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
00550       if (ret_val < 0) return TCL_ERROR;
00551     }
00552 
00553 
00554     if (!strcmp(opt, "-mol")) {
00555       if (i == argc-1) {
00556         Tcl_AppendResult(interp, "No molid specified",NULL);
00557         return TCL_ERROR;
00558       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
00559         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
00560         return TCL_ERROR;
00561       }
00562     }
00563 
00564     if (!strcmp(opt, "-vol")) {
00565       if (i == argc-1){
00566         Tcl_AppendResult(interp, "No volume id specified",NULL);
00567         return TCL_ERROR;
00568       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
00569         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
00570         return TCL_ERROR;
00571       }
00572     }
00573     
00574     int num1;
00575     Tcl_Obj **vector;
00576     if (!strcmp(opt, "-pos")) {
00577       if (i == argc-1){
00578         Tcl_AppendResult(interp, "No position coordinate specified",NULL);
00579         return TCL_ERROR;
00580       } else if (Tcl_ListObjGetElements(interp, objv[i+1], &num1, &vector) != TCL_OK) {
00581       return TCL_ERROR;
00582       }
00583     
00584       for (int i=0; i<num1; i++) {
00585         if (Tcl_GetDoubleFromObj(interp, vector[i], &pos[i]) != TCL_OK) {
00586           Tcl_SetResult(interp, (char *) "vecscale: non-numeric in vector", TCL_STATIC);
00587           return TCL_ERROR;
00588         }
00589       }
00590     
00591     }
00592     
00593     if (!strcmp(opt, "-o")) {
00594       if (i == argc-1) {
00595         Tcl_AppendResult(interp, "No output file specified",NULL);
00596         return TCL_ERROR;
00597       } else {
00598         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
00599       }
00600     }
00601   }
00602   Molecule *volmol = NULL;
00603   VolumetricData *volmapA = NULL;
00604   if (molid > -1) {
00605     volmol = mlist->mol_from_id(molid);
00606     if (volmol == NULL) {
00607       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
00608       return TCL_ERROR;
00609     }
00610 
00611     if (volmapA == NULL) 
00612       volmapA = volmol->modify_volume_data(volid);
00613   } else {
00614     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
00615     return TCL_ERROR;
00616   }
00617   if (volmapA == NULL) {
00618     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
00619     return TCL_ERROR;
00620   }
00621   
00622  
00623   float com[3] = {0.0,0.0,0.0};
00624   float newpos[3] = {(float)pos[0], (float)pos[1], (float)pos[2]};
00625   vol_com(volmapA, com);  
00626   vol_moveto(volmapA, com, newpos);
00627   volmol->force_recalc(DrawMolItem::MOL_REGEN);
00628 
00629   if (outputmap != NULL) {
00630     if (!write_file(app, volmol, volid, outputmap)){
00631       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
00632       return TCL_ERROR;
00633     }
00634   }
00635   return TCL_OK;
00636 
00637 }
00638 
00639 int fit(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00640   if (argc < 3) {
00641     Tcl_SetResult(interp, (char *) "usage: voltool "
00642       "fit <selection> -res <resolution of map in A> [options]\n"
00643       "    options:  -i <input map> specifies new target density filename to load.\n"
00644       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
00645       "              -thresholddensity <x> (ignores voxels with values below x threshold)\n"
00646       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n",
00647       TCL_STATIC);
00648     return TCL_ERROR;
00649   }
00650 
00651   //atom selection
00652   AtomSel *sel = NULL;
00653   sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00654   if (!sel) {
00655     Tcl_AppendResult(interp, "volmap: no atom selection.", NULL);
00656     return TCL_ERROR;
00657   }
00658   if (!sel->selected) {
00659     Tcl_AppendResult(interp, "volmap: no atoms selected.", NULL);
00660     return TCL_ERROR;
00661   }
00662   if (!app->molecule_valid_id(sel->molid())) {
00663     Tcl_AppendResult(interp, "invalide mol id.", NULL);
00664     return TCL_ERROR;
00665   }
00666 
00667   int ret_val=0;
00668   int molid = -1;
00669   int volid = 0;
00670   double resolution = 0;
00671   const char *input_map = NULL;
00672   MoleculeList *mlist = app->moleculeList;
00673   Molecule *mymol = mlist->mol_from_id(sel->molid());
00674   
00675   //parse arguments
00676   for (int i=0; i < argc; i++) {
00677     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
00678     if (!strcmp(opt, "-i")) {
00679       if (i == argc-1) {
00680         Tcl_AppendResult(interp, "No input map specified",NULL);
00681         return TCL_ERROR;
00682       }
00683 
00684       FileSpec spec;
00685       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
00686       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
00687       molid = app->molecule_new(input_map,0,1);
00688       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
00689       if (ret_val < 0) return TCL_ERROR;
00690     }
00691 
00692     if (!strcmp(opt, "-res")) {
00693       if (i == argc-1){
00694         Tcl_AppendResult(interp, "No resolution specified",NULL);
00695         return TCL_ERROR;
00696       } else if (Tcl_GetDoubleFromObj(interp, objv[i+1], &resolution) != TCL_OK){ 
00697         Tcl_AppendResult(interp, "\n resolution incorrectly specified",NULL);
00698         return TCL_ERROR;
00699       }
00700     }
00701 
00702 
00703     if (!strcmp(opt, "-mol")) {
00704       if (i == argc-1) {
00705         Tcl_AppendResult(interp, "No molid specified",NULL);
00706         return TCL_ERROR;
00707       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
00708         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
00709         return TCL_ERROR;
00710       }
00711     }
00712 
00713     if (!strcmp(opt, "-vol")) {
00714       if (i == argc-1){
00715         Tcl_AppendResult(interp, "No volume id specified",NULL);
00716         return TCL_ERROR;
00717       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
00718         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
00719         return TCL_ERROR;
00720       }
00721     }
00722   }
00723 
00724   VolumetricData *volmapA = NULL;
00725   if (molid > -1) {
00726     Molecule *volmol = mlist->mol_from_id(molid);
00727     if (volmol == NULL) {
00728       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
00729       return TCL_ERROR;
00730     }
00731 
00732     if (volmapA == NULL) 
00733       volmapA = volmol->modify_volume_data(volid);
00734   } else {
00735     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
00736     return TCL_ERROR;
00737   }
00738   if (volmapA == NULL) {
00739     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
00740     return TCL_ERROR;
00741   }
00742   
00743   
00744   float *framepos = sel->coordinates(app->moleculeList);
00745   //compute center of mass 
00746   float com[3];
00747   // get atom masses
00748   const float *weight = mymol->mass();
00749   ret_val = measure_center(sel, framepos, weight, com);
00750   if (ret_val < 0) {
00751     Tcl_AppendResult(interp, "measure center failed",
00752          NULL);
00753     return TCL_ERROR;
00754   }
00755  
00756   //move sel com to 
00757   float dencom[3] = {0.0,0.0,0.0};
00758   float move1[3];
00759   vol_com(volmapA, dencom);
00760   vec_sub(move1, dencom, com);
00761   moveby(sel, move1, mlist, framepos);
00762   //recalc sel com
00763   ret_val = measure_center(sel, framepos, weight, com);
00764   if (ret_val < 0) {
00765     Tcl_AppendResult(interp, "measure center failed",
00766          NULL);
00767     return TCL_ERROR;
00768   }
00769   
00770   //set up for rotational search
00771   float cc = -1;
00772   float *bestpos = new float [sel->num_atoms*3L];
00773   float *origin= new float [sel->num_atoms*3L];
00774   for (int k=0; k<sel->num_atoms*3L; k++) {
00775       origin[k] = framepos[k];
00776       bestpos[k] = framepos[k];
00777   }
00778     
00779 
00780 /*
00781   //fit with map
00782   // use quicksurf to compute simulated density map
00783   float radscale;
00784   double gspacing = 0;
00785   const float *radii = mymol->radius();
00786   radscale = .2*resolution;
00787 
00788   if (gspacing == 0) {
00789     gspacing = 1.5*radscale;
00790   }
00791 
00792   int quality = 0;
00793   if (resolution >= 9)
00794     quality = 0;
00795   else
00796     quality = 3;
00797 
00798   if (verbose)
00799     printf("MDFF dens: radscale %f gspacing %f\n", radscale, gspacing);
00800 
00801   VolumetricData *synthvol=NULL;
00802   int cuda_err = -1;
00803 #if defined(VMDCUDA)
00804   if (getenv("VMDNOCUDA") == NULL) {
00805     cuda_err = vmd_cuda_calc_density(sel, app->moleculeList, quality, radscale, gspacing, &synthvol, NULL, NULL, verbose);
00806   //  delete synthvol;
00807   }
00808 #endif
00809 
00810   // If CUDA failed, we use CPU fallback, and we have to prevent QuickSurf
00811   // from using the GPU either...
00812   if (cuda_err == -1) {
00813     const int force_cpu_calc=1;
00814     QuickSurf *qs = new QuickSurf(force_cpu_calc);
00815     synthvol = qs->calc_density_map(sel, mymol, framepos, radii,
00816                                   quality, (float)radscale, (float)gspacing);
00817 //    volmap_write_dx_file(volmap, outputmap);
00818    // delete synthvol;
00819     delete qs;
00820   }
00821   
00822   float synthcom[3];
00823   vol_com(synthvol, synthcom);
00824 
00825 
00826   int bestrot[3];
00827   double *synthorigin = synthvol->origin;
00828   double *dx = synthvol->xaxis;
00829   double *dy = synthvol->yaxis;
00830   double *dz = synthvol->zaxis;
00831 
00832   int stride = 5;
00833   int max_rot = 360/stride;
00834   density_rotate(stride, max_rot, synthcom, &cc, bestrot, volmapA, synthvol, resolution, synthorigin, dx, dy, dz);
00835   
00836   reset_density(stride, bestrot, synthvol, synthcom, framepos, com, sel, mlist);
00837   
00838   int stride2 = 6;
00839   max_rot = stride/stride2;
00840   density_rotate(stride2, max_rot, synthcom, &cc, bestrot, volmapA, synthvol, resolution, synthorigin, dx, dy, dz);
00841   density_rotate(-stride2, max_rot, synthcom, &cc, bestrot, volmapA, synthvol, resolution, synthorigin, dx, dy, dz);
00842 
00843   int stride3 = 1;
00844   max_rot = stride2/stride3;
00845   density_rotate(stride3, max_rot, synthcom, &cc, bestrot, volmapA, synthvol, resolution, synthorigin, dx, dy, dz);
00846   reset_density(stride3, bestrot, synthvol, synthcom, framepos, com, sel, mlist);
00847   density_rotate(-stride3, max_rot, synthcom, &cc, bestrot, volmapA, synthvol, resolution, synthorigin, dx, dy, dz);
00848 
00849   reset_density(stride3, bestrot, synthvol, synthcom, framepos, com, sel, mlist);
00850 
00851 */
00852 
00853 
00854   //fit with struct
00855   int stride = 24;
00856   int max_rot = 360/stride;
00857   rotate(stride, max_rot, com, &cc, bestpos, sel, mlist, volmapA, 
00858          float(resolution), origin, framepos);
00859   reset_origin(origin, bestpos, sel); 
00860 
00861   int stride2 = 4;
00862   max_rot = stride/stride2;
00863   rotate(stride2, max_rot, com, &cc, bestpos, sel, mlist, volmapA, 
00864          float(resolution), origin, framepos);
00865   rotate(-stride2, max_rot, com, &cc, bestpos, sel, mlist, volmapA, 
00866          float(resolution), origin, framepos);
00867   reset_origin(origin, bestpos, sel); 
00868   
00869   int stride3 = 1;
00870   max_rot = stride2/stride3;
00871   rotate(stride3, max_rot, com, &cc, bestpos, sel, mlist, volmapA, 
00872          float(resolution), origin, framepos);
00873   rotate(-stride3, max_rot, com, &cc, bestpos, sel, mlist, volmapA, 
00874          float(resolution), origin, framepos);
00875   
00876   for (int j=0; j<sel->num_atoms*3L; j++) {
00877       framepos[j] = bestpos[j];
00878   }
00879   
00880   // notify molecule that coordinates changed.
00881   mymol->force_recalc(DrawMolItem::MOL_REGEN);
00882  
00883  // int frame = app->molecule_frame(sel->molid());
00884  // FileSpec speco;
00885  // speco.first = frame;                // write current frame only
00886  // speco.last = frame;                 // write current frame only
00887  // speco.stride = 1;                   // write all selected frames
00888  // speco.waitfor = FileSpec::WAIT_ALL; // wait for all frames to be written
00889  // speco.selection = sel->on;      // write only selected atoms
00890  // app->molecule_savetrajectory(sel->molid(), "fittedi.pdb", "pdb", &speco);
00891   printf("Best CC:%f\n", cc);
00892   return TCL_OK;
00893 }
00894 
00895 int mask(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00896   if (argc < 3) {
00897     Tcl_SetResult(interp, (char *) "usage: voltool "
00898       "mask <selection> [options]\n"
00899       "    options:  -res <resolution of map in A> (Default: 5) \n"
00900       "              -cutoff <cutoff mask distance in A> (Default: 5) \n"
00901       "              -i <input map> specifies new target density filename to load.\n"
00902       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
00903       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
00904       "              -o <filename> write density to file.\n",
00905       TCL_STATIC);
00906     return TCL_ERROR;
00907   }
00908 
00909   //atom selection
00910   AtomSel *sel = NULL;
00911   sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00912   if (!sel) {
00913     Tcl_AppendResult(interp, "volmap: no atom selection.", NULL);
00914     return TCL_ERROR;
00915   }
00916   if (!sel->selected) {
00917     Tcl_AppendResult(interp, "volmap: no atoms selected.", NULL);
00918     return TCL_ERROR;
00919   }
00920   if (!app->molecule_valid_id(sel->molid())) {
00921     Tcl_AppendResult(interp, "invalide mol id.", NULL);
00922     return TCL_ERROR;
00923   }
00924 
00925   int molid = -1;
00926   int volid = 0;
00927   double resolution = 5;
00928   double cutoff = 5;
00929   const char *input_map = NULL;
00930   const char *outputmap = NULL;
00931   MoleculeList *mlist = app->moleculeList;
00932   
00933   //parse arguments
00934   for (int i=0; i < argc; i++) {
00935     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
00936     if (!strcmp(opt, "-i")) {
00937       if (i == argc-1) {
00938         Tcl_AppendResult(interp, "No input map specified",NULL);
00939         return TCL_ERROR;
00940       }
00941 
00942       FileSpec spec;
00943       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
00944       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
00945       molid = app->molecule_new(input_map,0,1);
00946       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
00947       if (ret_val < 0) return TCL_ERROR;
00948     }
00949 
00950     if (!strcmp(opt, "-res")) {
00951       if (i == argc-1){
00952         Tcl_AppendResult(interp, "No resolution specified",NULL);
00953         return TCL_ERROR;
00954       } else if (Tcl_GetDoubleFromObj(interp, objv[i+1], &resolution) != TCL_OK){ 
00955         Tcl_AppendResult(interp, "\n resolution incorrectly specified",NULL);
00956         return TCL_ERROR;
00957       }
00958     }
00959     
00960     if (!strcmp(opt, "-cutoff")) {
00961       if (i == argc-1){
00962         Tcl_AppendResult(interp, "No cutoff specified",NULL);
00963         return TCL_ERROR;
00964       } else if (Tcl_GetDoubleFromObj(interp, objv[i+1], &cutoff) != TCL_OK){ 
00965         Tcl_AppendResult(interp, "\n cutoff incorrectly specified",NULL);
00966         return TCL_ERROR;
00967       }
00968     }
00969 
00970 
00971     if (!strcmp(opt, "-mol")) {
00972       if (i == argc-1) {
00973         Tcl_AppendResult(interp, "No molid specified",NULL);
00974         return TCL_ERROR;
00975       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
00976         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
00977         return TCL_ERROR;
00978       }
00979     }
00980 
00981     if (!strcmp(opt, "-vol")) {
00982       if (i == argc-1){
00983         Tcl_AppendResult(interp, "No volume id specified",NULL);
00984         return TCL_ERROR;
00985       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
00986         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
00987         return TCL_ERROR;
00988       }
00989     }
00990     
00991     if (!strcmp(opt, "-o")) {
00992       if (i == argc-1) {
00993         Tcl_AppendResult(interp, "No output file specified",NULL);
00994         return TCL_ERROR;
00995       } else {
00996         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
00997       }
00998     }
00999   }
01000 
01001   VolumetricData *volmapA = NULL;
01002   if (molid > -1) {
01003     Molecule *volmol = mlist->mol_from_id(molid);
01004     if (volmol == NULL) {
01005       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01006       return TCL_ERROR;
01007     }
01008 
01009     if (volmapA == NULL) 
01010       volmapA = volmol->modify_volume_data(volid);
01011   } else {
01012     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01013     return TCL_ERROR;
01014   }
01015   if (volmapA == NULL) {
01016     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01017     return TCL_ERROR;
01018   }
01019   
01020   
01021   VolMapCreate *volcreate = new VolMapCreateMask(app, sel, (float)resolution, (float)cutoff);
01022   volcreate->compute_all(0, VolMapCreate::COMBINE_AVG, NULL);
01023   VolumetricData *mask = volcreate->volmap;
01024   VolumetricData *newvol = init_new_volume();
01025   bool USE_UNION = false;
01026   bool USE_INTERP = true;
01027   multiply(volmapA, mask, newvol, USE_INTERP, USE_UNION);
01028   
01029   int newvolmolid = init_new_volume_molecule(app, newvol, "masked_map");
01030   Molecule *newvolmol = mlist->mol_from_id(newvolmolid);
01031   
01032   if (outputmap != NULL) {
01033     if (!write_file(app, newvolmol, 0, outputmap)){
01034       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01035       return TCL_ERROR;
01036     }
01037   }
01038    
01039   return TCL_OK;
01040 }
01041 
01042 int density_trim(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01043   if (argc < 3) {
01044     Tcl_SetResult(interp, (char *) "usage: voltool "
01045       "trim -amt {x1 x2 y1 y2 z1 z2} amount to trim from each end in x, y, z axes> [options]\n"
01046       "    options:  -i <input map> specifies new density filename to load.\n"
01047       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01048       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01049       "              -o <filename> write density to file.\n",
01050       TCL_STATIC);
01051     return TCL_ERROR;
01052   }
01053 
01054 
01055   int molid = -1;
01056   int volid = 0;
01057   int trim[6] = {0, 0, 0, 0, 0, 0};
01058   const char *input_map = NULL;
01059   const char *outputmap = NULL;
01060   MoleculeList *mlist = app->moleculeList;
01061   
01062   for (int i=0; i < argc; i++) {
01063     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01064     if (!strcmp(opt, "-i")) {
01065       if (i == argc-1) {
01066         Tcl_AppendResult(interp, "No input map specified",NULL);
01067         return TCL_ERROR;
01068       }
01069 
01070       FileSpec spec;
01071       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01072       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01073       molid = app->molecule_new(input_map,0,1);
01074       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01075       if (ret_val < 0) return TCL_ERROR;
01076     }
01077 
01078 
01079     if (!strcmp(opt, "-mol")) {
01080       if (i == argc-1) {
01081         Tcl_AppendResult(interp, "No molid specified",NULL);
01082         return TCL_ERROR;
01083       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01084         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01085         return TCL_ERROR;
01086       }
01087     }
01088 
01089     if (!strcmp(opt, "-vol")) {
01090       if (i == argc-1){
01091         Tcl_AppendResult(interp, "No volume id specified",NULL);
01092         return TCL_ERROR;
01093       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01094         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01095         return TCL_ERROR;
01096       }
01097     }
01098     
01099     int num1;
01100     Tcl_Obj **vector;
01101     if (!strcmp(opt, "-amt")) {
01102       if (i == argc-1){
01103         Tcl_AppendResult(interp, "No trim amounts specified",NULL);
01104         return TCL_ERROR;
01105       } else if (Tcl_ListObjGetElements(interp, objv[i+1], &num1, &vector) != TCL_OK) {
01106       return TCL_ERROR;
01107       }
01108     
01109       for (int i=0; i<num1; i++) {
01110         if (Tcl_GetIntFromObj(interp, vector[i], &trim[i]) != TCL_OK) {
01111           Tcl_SetResult(interp, (char *) "amt: non-numeric in vector", TCL_STATIC);
01112           return TCL_ERROR;
01113         }
01114       }
01115       if (num1 != 6) {
01116         Tcl_SetResult(interp, (char *) "amt: incorrect number of values in vector", TCL_STATIC);
01117         return TCL_ERROR;
01118       }
01119     
01120     }
01121     
01122     if (!strcmp(opt, "-o")) {
01123       if (i == argc-1) {
01124         Tcl_AppendResult(interp, "No output file specified",NULL);
01125         return TCL_ERROR;
01126       } else {
01127         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01128       }
01129     }
01130   }
01131   Molecule *volmol = NULL;
01132   VolumetricData *volmapA = NULL;
01133   if (molid > -1) {
01134     volmol = mlist->mol_from_id(molid);
01135     if (volmol == NULL) {
01136       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01137       return TCL_ERROR;
01138     }
01139 
01140     if (volmapA == NULL) 
01141       volmapA = volmol->modify_volume_data(volid);
01142   } else {
01143     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01144     return TCL_ERROR;
01145   }
01146   if (volmapA == NULL) {
01147     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01148     return TCL_ERROR;
01149   }
01150   volmapA->pad(-trim[0], -trim[1], -trim[2], -trim[3], -trim[4], -trim[5]); 
01151   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01152   
01153   if (outputmap != NULL) {
01154     if (!write_file(app, volmol, volid, outputmap)){
01155       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01156       return TCL_ERROR;
01157     }
01158   }
01159   return TCL_OK;
01160 
01161 }
01162 
01163 int density_crop(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01164   if (argc < 3) {
01165     Tcl_SetResult(interp, (char *) "usage: voltool "
01166       "crop -amt {minx miny minz maxx maxy maxz} minmax values given in coordinate space.> [options]\n"
01167       "    options:  -i <input map> specifies new density filename to load.\n"
01168       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01169       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01170       "              -o <filename> write density to file.\n",
01171       TCL_STATIC);
01172     return TCL_ERROR;
01173   }
01174 
01175 
01176   int molid = -1;
01177   int volid = 0;
01178   int minmax[6] = {0, 0, 0, 0, 0, 0};
01179   const char *input_map = NULL;
01180   const char *outputmap = NULL;
01181   MoleculeList *mlist = app->moleculeList;
01182   
01183   for (int i=0; i < argc; i++) {
01184     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01185     if (!strcmp(opt, "-i")) {
01186       if (i == argc-1) {
01187         Tcl_AppendResult(interp, "No input map specified",NULL);
01188         return TCL_ERROR;
01189       }
01190 
01191       FileSpec spec;
01192       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01193       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01194       molid = app->molecule_new(input_map,0,1);
01195       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01196       if (ret_val < 0) return TCL_ERROR;
01197     }
01198 
01199 
01200     if (!strcmp(opt, "-mol")) {
01201       if (i == argc-1) {
01202         Tcl_AppendResult(interp, "No molid specified",NULL);
01203         return TCL_ERROR;
01204       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01205         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01206         return TCL_ERROR;
01207       }
01208     }
01209 
01210     if (!strcmp(opt, "-vol")) {
01211       if (i == argc-1){
01212         Tcl_AppendResult(interp, "No volume id specified",NULL);
01213         return TCL_ERROR;
01214       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01215         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01216         return TCL_ERROR;
01217       }
01218     }
01219     
01220     int num1;
01221     Tcl_Obj **vector;
01222     if (!strcmp(opt, "-amt")) {
01223       if (i == argc-1){
01224         Tcl_AppendResult(interp, "No trim amounts specified",NULL);
01225         return TCL_ERROR;
01226       } else if (Tcl_ListObjGetElements(interp, objv[i+1], &num1, &vector) != TCL_OK) {
01227       return TCL_ERROR;
01228       }
01229     
01230       for (int i=0; i<num1; i++) {
01231         if (Tcl_GetIntFromObj(interp, vector[i], &minmax[i]) != TCL_OK) {
01232           Tcl_SetResult(interp, (char *) "amt: non-numeric in vector", TCL_STATIC);
01233           return TCL_ERROR;
01234         }
01235       }
01236       if (num1 != 6) {
01237         Tcl_SetResult(interp, (char *) "amt: incorrect number of values in vector", TCL_STATIC);
01238         return TCL_ERROR;
01239       }
01240     
01241     }
01242     
01243     if (!strcmp(opt, "-o")) {
01244       if (i == argc-1) {
01245         Tcl_AppendResult(interp, "No output file specified",NULL);
01246         return TCL_ERROR;
01247       } else {
01248         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01249       }
01250     }
01251   }
01252   Molecule *volmol = NULL;
01253   VolumetricData *volmapA = NULL;
01254   if (molid > -1) {
01255     volmol = mlist->mol_from_id(molid);
01256     if (volmol == NULL) {
01257       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01258       return TCL_ERROR;
01259     }
01260 
01261     if (volmapA == NULL) 
01262       volmapA = volmol->modify_volume_data(volid);
01263   } else {
01264     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01265     return TCL_ERROR;
01266   }
01267   if (volmapA == NULL) {
01268     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01269     return TCL_ERROR;
01270   }
01271   volmapA->crop(minmax[0], minmax[1], minmax[2], minmax[3], minmax[4], minmax[5]); 
01272   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01273   
01274   if (outputmap != NULL) {
01275     if (!write_file(app, volmol, volid, outputmap)){
01276       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01277       return TCL_ERROR;
01278     }
01279   }
01280   return TCL_OK;
01281 
01282 }
01283 
01284 int density_clamp(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01285   if (argc < 3) {
01286     Tcl_SetResult(interp, (char *) "usage: voltool "
01287       "clamp [options]\n"
01288       "    options:  -min <min voxel value> Defaults to existing min.\n"
01289       "              -max <max voxel value> Defaults to existing max.\n"
01290       "              -i <input map> specifies new density filename to load.\n"
01291       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01292       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01293       "              -o <filename> write density to file.\n",
01294       TCL_STATIC);
01295     return TCL_ERROR;
01296   }
01297 
01298 
01299   int molid = -1;
01300   int volid = 0;
01301   double min = -FLT_MIN;
01302   double max = FLT_MAX;
01303   const char *input_map = NULL;
01304   const char *outputmap = NULL;
01305   MoleculeList *mlist = app->moleculeList;
01306   
01307   for (int i=0; i < argc; i++) {
01308     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01309     if (!strcmp(opt, "-i")) {
01310       if (i == argc-1) {
01311         Tcl_AppendResult(interp, "No input map specified",NULL);
01312         return TCL_ERROR;
01313       }
01314 
01315       FileSpec spec;
01316       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01317       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01318       molid = app->molecule_new(input_map,0,1);
01319       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01320       if (ret_val < 0) return TCL_ERROR;
01321     }
01322 
01323 
01324     if (!strcmp(opt, "-mol")) {
01325       if (i == argc-1) {
01326         Tcl_AppendResult(interp, "No molid specified",NULL);
01327         return TCL_ERROR;
01328       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01329         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01330         return TCL_ERROR;
01331       }
01332     }
01333 
01334     if (!strcmp(opt, "-vol")) {
01335       if (i == argc-1){
01336         Tcl_AppendResult(interp, "No volume id specified",NULL);
01337         return TCL_ERROR;
01338       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01339         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01340         return TCL_ERROR;
01341       }
01342     }
01343     
01344     if (!strcmp(opt, "-min")) {
01345       if (i == argc-1){
01346         Tcl_AppendResult(interp, "No minimum voxel specified",NULL);
01347         return TCL_ERROR;
01348       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &min) != TCL_OK) {
01349         Tcl_AppendResult(interp, "\n minimum voxel incorrectly specified",NULL);
01350         return TCL_ERROR;
01351       }
01352     }
01353     
01354     if (!strcmp(opt, "-max")) {
01355       if (i == argc-1){
01356         Tcl_AppendResult(interp, "No maximum voxel specified",NULL);
01357         return TCL_ERROR;
01358       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &max) != TCL_OK) {
01359         Tcl_AppendResult(interp, "\n maximum voxel incorrectly specified",NULL);
01360         return TCL_ERROR;
01361       }
01362     }
01363     
01364     if (!strcmp(opt, "-o")) {
01365       if (i == argc-1) {
01366         Tcl_AppendResult(interp, "No output file specified",NULL);
01367         return TCL_ERROR;
01368       } else {
01369         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01370       }
01371     }
01372   }
01373   Molecule *volmol = NULL;
01374   VolumetricData *volmapA = NULL;
01375   if (molid > -1) {
01376     volmol = mlist->mol_from_id(molid);
01377     if (volmol == NULL) {
01378       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01379       return TCL_ERROR;
01380     }
01381 
01382     if (volmapA == NULL) 
01383       volmapA = volmol->modify_volume_data(volid);
01384   } else {
01385     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01386     return TCL_ERROR;
01387   }
01388   if (volmapA == NULL) {
01389     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01390     return TCL_ERROR;
01391   }
01392   volmapA->clamp(float(min), float(max)); 
01393   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01394   
01395   if (outputmap != NULL) {
01396     if (!write_file(app, volmol, volid, outputmap)){
01397       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01398       return TCL_ERROR;
01399     }
01400   }
01401   return TCL_OK;
01402 
01403 }
01404 
01405 int density_smult(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01406   if (argc < 3) {
01407     Tcl_SetResult(interp, (char *) "usage: voltool "
01408       "smult -amt <x> multiply every voxel by x. [options]\n"
01409       "    options:  -i <input map> specifies new density filename to load.\n"
01410       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01411       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01412       "              -o <filename> write density to file.\n",
01413       TCL_STATIC);
01414     return TCL_ERROR;
01415   }
01416 
01417 
01418   int molid = -1;
01419   int volid = 0;
01420   double amt = 1;
01421   const char *input_map = NULL;
01422   const char *outputmap = NULL;
01423   MoleculeList *mlist = app->moleculeList;
01424   
01425   for (int i=0; i < argc; i++) {
01426     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01427     if (!strcmp(opt, "-i")) {
01428       if (i == argc-1) {
01429         Tcl_AppendResult(interp, "No input map specified",NULL);
01430         return TCL_ERROR;
01431       }
01432 
01433       FileSpec spec;
01434       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01435       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01436       molid = app->molecule_new(input_map,0,1);
01437       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01438       if (ret_val < 0) return TCL_ERROR;
01439     }
01440 
01441 
01442     if (!strcmp(opt, "-mol")) {
01443       if (i == argc-1) {
01444         Tcl_AppendResult(interp, "No molid specified",NULL);
01445         return TCL_ERROR;
01446       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01447         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01448         return TCL_ERROR;
01449       }
01450     }
01451 
01452     if (!strcmp(opt, "-vol")) {
01453       if (i == argc-1){
01454         Tcl_AppendResult(interp, "No volume id specified",NULL);
01455         return TCL_ERROR;
01456       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01457         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01458         return TCL_ERROR;
01459       }
01460     }
01461     
01462     if (!strcmp(opt, "-amt")) {
01463       if (i == argc-1){
01464         Tcl_AppendResult(interp, "No scaling amount specified",NULL);
01465         return TCL_ERROR;
01466       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &amt) != TCL_OK) {
01467         Tcl_AppendResult(interp, "\n scaling amount incorrectly specified",NULL);
01468         return TCL_ERROR;
01469       }
01470     }
01471     
01472     if (!strcmp(opt, "-o")) {
01473       if (i == argc-1) {
01474         Tcl_AppendResult(interp, "No output file specified",NULL);
01475         return TCL_ERROR;
01476       } else {
01477         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01478       }
01479     }
01480   }
01481   Molecule *volmol = NULL;
01482   VolumetricData *volmapA = NULL;
01483   if (molid > -1) {
01484     volmol = mlist->mol_from_id(molid);
01485     if (volmol == NULL) {
01486       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01487       return TCL_ERROR;
01488     }
01489 
01490     if (volmapA == NULL) 
01491       volmapA = volmol->modify_volume_data(volid);
01492   } else {
01493     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01494     return TCL_ERROR;
01495   }
01496   if (volmapA == NULL) {
01497     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01498     return TCL_ERROR;
01499   }
01500   volmapA->scale_by((float)amt); 
01501   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01502   
01503   if (outputmap != NULL) {
01504     if (!write_file(app, volmol, volid, outputmap)){
01505       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01506       return TCL_ERROR;
01507     }
01508   }
01509   return TCL_OK;
01510 
01511 }
01512 
01513 int density_smooth(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01514   if (argc < 3) {
01515     Tcl_SetResult(interp, (char *) "usage: voltool "
01516       "smooth -sigma <x> radius of guassian blur in x sigmas. [options]\n"
01517       "    options:  -i <input map> specifies new density filename to load.\n"
01518       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01519       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01520       "              -o <filename> write density to file.\n",
01521       TCL_STATIC);
01522     return TCL_ERROR;
01523   }
01524 
01525 
01526   int molid = -1;
01527   int volid = 0;
01528   double sigma = 0;
01529   const char *input_map = NULL;
01530   const char *outputmap = NULL;
01531   MoleculeList *mlist = app->moleculeList;
01532   
01533   for (int i=0; i < argc; i++) {
01534     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01535     if (!strcmp(opt, "-i")) {
01536       if (i == argc-1) {
01537         Tcl_AppendResult(interp, "No input map specified",NULL);
01538         return TCL_ERROR;
01539       }
01540 
01541       FileSpec spec;
01542       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01543       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01544       molid = app->molecule_new(input_map,0,1);
01545       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01546       if (ret_val < 0) return TCL_ERROR;
01547     }
01548 
01549 
01550     if (!strcmp(opt, "-mol")) {
01551       if (i == argc-1) {
01552         Tcl_AppendResult(interp, "No molid specified",NULL);
01553         return TCL_ERROR;
01554       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01555         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01556         return TCL_ERROR;
01557       }
01558     }
01559 
01560     if (!strcmp(opt, "-vol")) {
01561       if (i == argc-1){
01562         Tcl_AppendResult(interp, "No volume id specified",NULL);
01563         return TCL_ERROR;
01564       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01565         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01566         return TCL_ERROR;
01567       }
01568     }
01569     
01570     if (!strcmp(opt, "-sigma")) {
01571       if (i == argc-1){
01572         Tcl_AppendResult(interp, "No scaling amount specified",NULL);
01573         return TCL_ERROR;
01574       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &sigma) != TCL_OK) {
01575         Tcl_AppendResult(interp, "\n scaling amount incorrectly specified",NULL);
01576         return TCL_ERROR;
01577       }
01578     }
01579     
01580     if (!strcmp(opt, "-o")) {
01581       if (i == argc-1) {
01582         Tcl_AppendResult(interp, "No output file specified",NULL);
01583         return TCL_ERROR;
01584       } else {
01585         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01586       }
01587     }
01588   }
01589   Molecule *volmol = NULL;
01590   VolumetricData *volmapA = NULL;
01591   if (molid > -1) {
01592     volmol = mlist->mol_from_id(molid);
01593     if (volmol == NULL) {
01594       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01595       return TCL_ERROR;
01596     }
01597 
01598     if (volmapA == NULL) 
01599       volmapA = volmol->modify_volume_data(volid);
01600   } else {
01601     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01602     return TCL_ERROR;
01603   }
01604   if (volmapA == NULL) {
01605     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01606     return TCL_ERROR;
01607   }
01608   volmapA->gaussian_blur(sigma);
01609   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01610   
01611   if (outputmap != NULL) {
01612     if (!write_file(app, volmol, volid, outputmap)){
01613       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01614       return TCL_ERROR;
01615     }
01616   }
01617   return TCL_OK;
01618 
01619 }
01620 
01621 int density_sadd(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01622   if (argc < 3) {
01623     Tcl_SetResult(interp, (char *) "usage: voltool "
01624       "sadd -amt <x> add x to every voxel. [options]\n"
01625       "    options:  -i <input map> specifies new density filename to load.\n"
01626       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01627       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01628       "              -o <filename> write density to file.\n",
01629       TCL_STATIC);
01630     return TCL_ERROR;
01631   }
01632 
01633 
01634   int molid = -1;
01635   int volid = 0;
01636   double amt = 0;
01637   const char *input_map = NULL;
01638   const char *outputmap = NULL;
01639   MoleculeList *mlist = app->moleculeList;
01640   
01641   for (int i=0; i < argc; i++) {
01642     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01643     if (!strcmp(opt, "-i")) {
01644       if (i == argc-1) {
01645         Tcl_AppendResult(interp, "No input map specified",NULL);
01646         return TCL_ERROR;
01647       }
01648 
01649       FileSpec spec;
01650       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01651       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01652       molid = app->molecule_new(input_map,0,1);
01653       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01654       if (ret_val < 0) return TCL_ERROR;
01655     }
01656 
01657 
01658     if (!strcmp(opt, "-mol")) {
01659       if (i == argc-1) {
01660         Tcl_AppendResult(interp, "No molid specified",NULL);
01661         return TCL_ERROR;
01662       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01663         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01664         return TCL_ERROR;
01665       }
01666     }
01667 
01668     if (!strcmp(opt, "-vol")) {
01669       if (i == argc-1){
01670         Tcl_AppendResult(interp, "No volume id specified",NULL);
01671         return TCL_ERROR;
01672       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01673         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01674         return TCL_ERROR;
01675       }
01676     }
01677     
01678     if (!strcmp(opt, "-amt")) {
01679       if (i == argc-1){
01680         Tcl_AppendResult(interp, "No scaling amount specified",NULL);
01681         return TCL_ERROR;
01682       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &amt) != TCL_OK) {
01683         Tcl_AppendResult(interp, "\n scaling amount incorrectly specified",NULL);
01684         return TCL_ERROR;
01685       }
01686     }
01687     
01688     if (!strcmp(opt, "-o")) {
01689       if (i == argc-1) {
01690         Tcl_AppendResult(interp, "No output file specified",NULL);
01691         return TCL_ERROR;
01692       } else {
01693         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01694       }
01695     }
01696   }
01697   Molecule *volmol = NULL;
01698   VolumetricData *volmapA = NULL;
01699   if (molid > -1) {
01700     volmol = mlist->mol_from_id(molid);
01701     if (volmol == NULL) {
01702       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01703       return TCL_ERROR;
01704     }
01705 
01706     if (volmapA == NULL) 
01707       volmapA = volmol->modify_volume_data(volid);
01708   } else {
01709     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01710     return TCL_ERROR;
01711   }
01712   if (volmapA == NULL) {
01713     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01714     return TCL_ERROR;
01715   }
01716   volmapA->scalar_add((float)amt); 
01717   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01718   
01719   if (outputmap != NULL) {
01720     if (!write_file(app, volmol, volid, outputmap)){
01721       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01722       return TCL_ERROR;
01723     }
01724   }
01725   return TCL_OK;
01726 
01727 }
01728 
01729 int density_range(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01730   if (argc < 3) {
01731     Tcl_SetResult(interp, (char *) "usage: voltool "
01732       "range -minmax {min max} minmax voxel values> [options]\n"
01733       "    options:  -i <input map> specifies new density filename to load.\n"
01734       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01735       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01736       "              -o <filename> write density to file.\n",
01737       TCL_STATIC);
01738     return TCL_ERROR;
01739   }
01740 
01741 
01742   int molid = -1;
01743   int volid = 0;
01744   int minmax[2] = {0, 0};
01745   const char *input_map = NULL;
01746   const char *outputmap = NULL;
01747   MoleculeList *mlist = app->moleculeList;
01748   
01749   for (int i=0; i < argc; i++) {
01750     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01751     if (!strcmp(opt, "-i")) {
01752       if (i == argc-1) {
01753         Tcl_AppendResult(interp, "No input map specified",NULL);
01754         return TCL_ERROR;
01755       }
01756 
01757       FileSpec spec;
01758       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01759       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01760       molid = app->molecule_new(input_map,0,1);
01761       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01762       if (ret_val < 0) return TCL_ERROR;
01763     }
01764 
01765 
01766     if (!strcmp(opt, "-mol")) {
01767       if (i == argc-1) {
01768         Tcl_AppendResult(interp, "No molid specified",NULL);
01769         return TCL_ERROR;
01770       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01771         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01772         return TCL_ERROR;
01773       }
01774     }
01775 
01776     if (!strcmp(opt, "-vol")) {
01777       if (i == argc-1){
01778         Tcl_AppendResult(interp, "No volume id specified",NULL);
01779         return TCL_ERROR;
01780       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01781         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01782         return TCL_ERROR;
01783       }
01784     }
01785     
01786     int num1;
01787     Tcl_Obj **vector;
01788     if (!strcmp(opt, "-minmax")) {
01789       if (i == argc-1){
01790         Tcl_AppendResult(interp, "No trim amounts specified",NULL);
01791         return TCL_ERROR;
01792       } else if (Tcl_ListObjGetElements(interp, objv[i+1], &num1, &vector) != TCL_OK) {
01793       return TCL_ERROR;
01794       }
01795     
01796       for (int i=0; i<num1; i++) {
01797         if (Tcl_GetIntFromObj(interp, vector[i], &minmax[i]) != TCL_OK) {
01798           Tcl_SetResult(interp, (char *) "minmax: non-numeric in vector", TCL_STATIC);
01799           return TCL_ERROR;
01800         }
01801       }
01802       if (num1 != 2) {
01803         Tcl_SetResult(interp, (char *) "minmax: incorrect number of values in vector", TCL_STATIC);
01804         return TCL_ERROR;
01805       }
01806     
01807     }
01808     
01809     if (!strcmp(opt, "-o")) {
01810       if (i == argc-1) {
01811         Tcl_AppendResult(interp, "No output file specified",NULL);
01812         return TCL_ERROR;
01813       } else {
01814         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01815       }
01816     }
01817   }
01818   Molecule *volmol = NULL;
01819   VolumetricData *volmapA = NULL;
01820   if (molid > -1) {
01821     volmol = mlist->mol_from_id(molid);
01822     if (volmol == NULL) {
01823       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01824       return TCL_ERROR;
01825     }
01826 
01827     if (volmapA == NULL) 
01828       volmapA = volmol->modify_volume_data(volid);
01829   } else {
01830     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01831     return TCL_ERROR;
01832   }
01833   if (volmapA == NULL) {
01834     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01835     return TCL_ERROR;
01836   }
01837   
01838   volmapA->rescale_voxel_value_range(float(minmax[0]), float(minmax[1])); 
01839   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01840   
01841   if (outputmap != NULL) {
01842     if (!write_file(app, volmol, volid, outputmap)){
01843       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01844       return TCL_ERROR;
01845     }
01846   }
01847   return TCL_OK;
01848 
01849 }
01850 
01851 int density_downsample(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01852   if (argc < 3) {
01853     Tcl_SetResult(interp, (char *) "usage: voltool "
01854       "downsample [options]\n"
01855       "    options:  -i <input map> specifies new density filename to load.\n"
01856       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01857       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01858       "              -o <filename> write density to file.\n",
01859       TCL_STATIC);
01860     return TCL_ERROR;
01861   }
01862 
01863 
01864   int molid = -1;
01865   int volid = 0;
01866   const char *input_map = NULL;
01867   const char *outputmap = NULL;
01868   MoleculeList *mlist = app->moleculeList;
01869   
01870   for (int i=0; i < argc; i++) {
01871     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01872     if (!strcmp(opt, "-i")) {
01873       if (i == argc-1) {
01874         Tcl_AppendResult(interp, "No input map specified",NULL);
01875         return TCL_ERROR;
01876       }
01877 
01878       FileSpec spec;
01879       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01880       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01881       molid = app->molecule_new(input_map,0,1);
01882       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01883       if (ret_val < 0) return TCL_ERROR;
01884     }
01885 
01886 
01887     if (!strcmp(opt, "-mol")) {
01888       if (i == argc-1) {
01889         Tcl_AppendResult(interp, "No molid specified",NULL);
01890         return TCL_ERROR;
01891       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01892         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01893         return TCL_ERROR;
01894       }
01895     }
01896 
01897     if (!strcmp(opt, "-vol")) {
01898       if (i == argc-1){
01899         Tcl_AppendResult(interp, "No volume id specified",NULL);
01900         return TCL_ERROR;
01901       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
01902         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
01903         return TCL_ERROR;
01904       }
01905     }
01906     
01907     if (!strcmp(opt, "-o")) {
01908       if (i == argc-1) {
01909         Tcl_AppendResult(interp, "No output file specified",NULL);
01910         return TCL_ERROR;
01911       } else {
01912         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
01913       }
01914     }
01915   }
01916   Molecule *volmol = NULL;
01917   VolumetricData *volmapA = NULL;
01918   if (molid > -1) {
01919     volmol = mlist->mol_from_id(molid);
01920     if (volmol == NULL) {
01921       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
01922       return TCL_ERROR;
01923     }
01924 
01925     if (volmapA == NULL) 
01926       volmapA = volmol->modify_volume_data(volid);
01927   } else {
01928     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
01929     return TCL_ERROR;
01930   }
01931   if (volmapA == NULL) {
01932     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01933     return TCL_ERROR;
01934   }
01935 
01936   volmapA->downsample(); 
01937   volmol->force_recalc(DrawMolItem::MOL_REGEN);
01938   
01939   if (outputmap != NULL) {
01940     if (!write_file(app, volmol, volid, outputmap)){
01941       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
01942       return TCL_ERROR;
01943     }
01944   }
01945   return TCL_OK;
01946 
01947 }
01948 
01949 int density_supersample(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01950   if (argc < 3) {
01951     Tcl_SetResult(interp, (char *) "usage: voltool "
01952       "downsample [options]\n"
01953       "    options:  -i <input map> specifies new density filename to load.\n"
01954       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
01955       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
01956       "              -o <filename> write density to file.\n",
01957       TCL_STATIC);
01958     return TCL_ERROR;
01959   }
01960 
01961 
01962   int molid = -1;
01963   int volid = 0;
01964   const char *input_map = NULL;
01965   const char *outputmap = NULL;
01966   MoleculeList *mlist = app->moleculeList;
01967   
01968   for (int i=0; i < argc; i++) {
01969     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01970     if (!strcmp(opt, "-i")) {
01971       if (i == argc-1) {
01972         Tcl_AppendResult(interp, "No input map specified",NULL);
01973         return TCL_ERROR;
01974       }
01975 
01976       FileSpec spec;
01977       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
01978       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
01979       molid = app->molecule_new(input_map,0,1);
01980       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
01981       if (ret_val < 0) return TCL_ERROR;
01982     }
01983 
01984 
01985     if (!strcmp(opt, "-mol")) {
01986       if (i == argc-1) {
01987         Tcl_AppendResult(interp, "No molid specified",NULL);
01988         return TCL_ERROR;
01989       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
01990         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
01991         return TCL_ERROR;
01992       }
01993     }
01994 
01995     if (!strcmp(opt, "-vol")) {
01996       if (i == argc-1){
01997         Tcl_AppendResult(interp, "No volume id specified",NULL);
01998         return TCL_ERROR;
01999       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
02000         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02001         return TCL_ERROR;
02002       }
02003     }
02004     
02005     if (!strcmp(opt, "-o")) {
02006       if (i == argc-1) {
02007         Tcl_AppendResult(interp, "No output file specified",NULL);
02008         return TCL_ERROR;
02009       } else {
02010         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
02011       }
02012     }
02013   }
02014   Molecule *volmol = NULL;
02015   VolumetricData *volmapA = NULL;
02016   if (molid > -1) {
02017     volmol = mlist->mol_from_id(molid);
02018     if (volmol == NULL) {
02019       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02020       return TCL_ERROR;
02021     }
02022 
02023     if (volmapA == NULL) 
02024       volmapA = volmol->modify_volume_data(volid);
02025   } else {
02026     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02027     return TCL_ERROR;
02028   }
02029   if (volmapA == NULL) {
02030     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02031     return TCL_ERROR;
02032   }
02033 
02034   volmapA->supersample(); 
02035   volmol->force_recalc(DrawMolItem::MOL_REGEN);
02036   
02037   if (outputmap != NULL) {
02038     if (!write_file(app, volmol, volid, outputmap)){
02039       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02040       return TCL_ERROR;
02041     }
02042   }
02043   return TCL_OK;
02044 
02045 }
02046 
02047 int density_sigma(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02048   if (argc < 3) {
02049     Tcl_SetResult(interp, (char *) "usage: voltool "
02050       "sigma [options]\n"
02051       "    options:  -i <input map> specifies new density filename to load.\n"
02052       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
02053       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02054       "              -o <filename> write density to file.\n",
02055       TCL_STATIC);
02056     return TCL_ERROR;
02057   }
02058 
02059 
02060   int molid = -1;
02061   int volid = 0;
02062   const char *input_map = NULL;
02063   const char *outputmap = NULL;
02064   MoleculeList *mlist = app->moleculeList;
02065   
02066   for (int i=0; i < argc; i++) {
02067     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02068     if (!strcmp(opt, "-i")) {
02069       if (i == argc-1) {
02070         Tcl_AppendResult(interp, "No input map specified",NULL);
02071         return TCL_ERROR;
02072       }
02073 
02074       FileSpec spec;
02075       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02076       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
02077       molid = app->molecule_new(input_map,0,1);
02078       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
02079       if (ret_val < 0) return TCL_ERROR;
02080     }
02081 
02082 
02083     if (!strcmp(opt, "-mol")) {
02084       if (i == argc-1) {
02085         Tcl_AppendResult(interp, "No molid specified",NULL);
02086         return TCL_ERROR;
02087       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
02088         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02089         return TCL_ERROR;
02090       }
02091     }
02092 
02093     if (!strcmp(opt, "-vol")) {
02094       if (i == argc-1){
02095         Tcl_AppendResult(interp, "No volume id specified",NULL);
02096         return TCL_ERROR;
02097       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
02098         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02099         return TCL_ERROR;
02100       }
02101     }
02102     
02103     if (!strcmp(opt, "-o")) {
02104       if (i == argc-1) {
02105         Tcl_AppendResult(interp, "No output file specified",NULL);
02106         return TCL_ERROR;
02107       } else {
02108         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
02109       }
02110     }
02111   }
02112   Molecule *volmol = NULL;
02113   VolumetricData *volmapA = NULL;
02114   if (molid > -1) {
02115     volmol = mlist->mol_from_id(molid);
02116     if (volmol == NULL) {
02117       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02118       return TCL_ERROR;
02119     }
02120 
02121     if (volmapA == NULL) 
02122       volmapA = volmol->modify_volume_data(volid);
02123   } else {
02124     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02125     return TCL_ERROR;
02126   }
02127   if (volmapA == NULL) {
02128     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02129     return TCL_ERROR;
02130   }
02131 
02132   volmapA->sigma_scale(); 
02133   volmol->force_recalc(DrawMolItem::MOL_REGEN);
02134   
02135   if (outputmap != NULL) {
02136     if (!write_file(app, volmol, volid, outputmap)){
02137       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02138       return TCL_ERROR;
02139     }
02140   }
02141   return TCL_OK;
02142 
02143 }
02144 
02145 int density_mdff_potential(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02146   if (argc < 3) {
02147     Tcl_SetResult(interp, (char *) "usage: voltool "
02148       "pot [options]\n"
02149       "    options:  -threshold <x> clamp density to minimum value of x.\n"
02150       "              -i <input map> specifies new density filename to load.\n"
02151       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
02152       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02153       "              -o <filename> write potential to file.\n",
02154       TCL_STATIC);
02155     return TCL_ERROR;
02156   }
02157 
02158 
02159   int molid = -1;
02160   int volid = 0;
02161   double threshold = 0;
02162   const char *input_map = NULL;
02163   const char *outputmap = NULL;
02164   MoleculeList *mlist = app->moleculeList;
02165   
02166   for (int i=0; i < argc; i++) {
02167     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02168     if (!strcmp(opt, "-i")) {
02169       if (i == argc-1) {
02170         Tcl_AppendResult(interp, "No input map specified",NULL);
02171         return TCL_ERROR;
02172       }
02173 
02174       FileSpec spec;
02175       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02176       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
02177       molid = app->molecule_new(input_map,0,1);
02178       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
02179       if (ret_val < 0) return TCL_ERROR;
02180     }
02181 
02182 
02183     if (!strcmp(opt, "-mol")) {
02184       if (i == argc-1) {
02185         Tcl_AppendResult(interp, "No molid specified",NULL);
02186         return TCL_ERROR;
02187       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
02188         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02189         return TCL_ERROR;
02190       }
02191     }
02192 
02193     if (!strcmp(opt, "-vol")) {
02194       if (i == argc-1){
02195         Tcl_AppendResult(interp, "No volume id specified",NULL);
02196         return TCL_ERROR;
02197       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
02198         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02199         return TCL_ERROR;
02200       }
02201     }
02202     
02203     if (!strcmp(opt, "-threshold")) {
02204       if (i == argc-1){
02205         Tcl_AppendResult(interp, "No scaling amount specified",NULL);
02206         return TCL_ERROR;
02207       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &threshold) != TCL_OK) {
02208         Tcl_AppendResult(interp, "\n scaling amount incorrectly specified",NULL);
02209         return TCL_ERROR;
02210       }
02211     }
02212     
02213     if (!strcmp(opt, "-o")) {
02214       if (i == argc-1) {
02215         Tcl_AppendResult(interp, "No output file specified",NULL);
02216         return TCL_ERROR;
02217       } else {
02218         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
02219       }
02220     }
02221   }
02222   Molecule *volmol = NULL;
02223   VolumetricData *volmapA = NULL;
02224   if (molid > -1) {
02225     volmol = mlist->mol_from_id(molid);
02226     if (volmol == NULL) {
02227       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02228       return TCL_ERROR;
02229     }
02230 
02231     if (volmapA == NULL) 
02232       volmapA = volmol->modify_volume_data(volid);
02233   } else {
02234     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02235     return TCL_ERROR;
02236   }
02237   if (volmapA == NULL) {
02238     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02239     return TCL_ERROR;
02240   }
02241   volmapA->mdff_potential(float(threshold)); 
02242   volmol->force_recalc(DrawMolItem::MOL_REGEN);
02243   
02244   if (outputmap != NULL) {
02245     if (!write_file(app, volmol, volid, outputmap)){
02246       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02247       return TCL_ERROR;
02248     }
02249   }
02250   return TCL_OK;
02251 
02252 }
02253 
02254 int density_histogram(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02255   if (argc < 3) {
02256     Tcl_SetResult(interp, (char *) "usage: voltool "
02257       "hist [options]\n"
02258       "    options:  -nbins <x> number of histogram bins. Defaults to 10.\n"
02259       "              -i <input map> specifies new density filename to load.\n"
02260       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
02261       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n",
02262       TCL_STATIC);
02263     return TCL_ERROR;
02264   }
02265 
02266 
02267   int molid = -1;
02268   int volid = 0;
02269   int nbins = 10;
02270   const char *input_map = NULL;
02271   MoleculeList *mlist = app->moleculeList;
02272   
02273   for (int i=0; i < argc; i++) {
02274     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02275     if (!strcmp(opt, "-i")) {
02276       if (i == argc-1) {
02277         Tcl_AppendResult(interp, "No input map specified",NULL);
02278         return TCL_ERROR;
02279       }
02280 
02281       FileSpec spec;
02282       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02283       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
02284       molid = app->molecule_new(input_map,0,1);
02285       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
02286       if (ret_val < 0) return TCL_ERROR;
02287     }
02288 
02289 
02290     if (!strcmp(opt, "-mol")) {
02291       if (i == argc-1) {
02292         Tcl_AppendResult(interp, "No molid specified",NULL);
02293         return TCL_ERROR;
02294       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
02295         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02296         return TCL_ERROR;
02297       }
02298     }
02299 
02300     if (!strcmp(opt, "-vol")) {
02301       if (i == argc-1){
02302         Tcl_AppendResult(interp, "No volume id specified",NULL);
02303         return TCL_ERROR;
02304       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
02305         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02306         return TCL_ERROR;
02307       }
02308     }
02309     
02310     if (!strcmp(opt, "-nbins")) {
02311       if (i == argc-1){
02312         Tcl_AppendResult(interp, "No number of bins specified",NULL);
02313         return TCL_ERROR;
02314       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &nbins) != TCL_OK) {
02315         Tcl_AppendResult(interp, "\n number of bins incorrectly specified",NULL);
02316         return TCL_ERROR;
02317       }
02318     }
02319     
02320   }
02321   Molecule *volmol = NULL;
02322   VolumetricData *volmapA = NULL;
02323   if (molid > -1) {
02324     volmol = mlist->mol_from_id(molid);
02325     if (volmol == NULL) {
02326       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02327       return TCL_ERROR;
02328     }
02329 
02330     if (volmapA == NULL) 
02331       volmapA = volmol->modify_volume_data(volid);
02332   } else {
02333     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02334     return TCL_ERROR;
02335   }
02336   if (volmapA == NULL) {
02337     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02338     return TCL_ERROR;
02339   }
02340   
02341   long *bins = new long[nbins]; 
02342   float *midpts = new float[nbins]; 
02343   histogram(volmapA, nbins, bins, midpts); 
02344   
02345   // convert the results of the lowlevel call to tcl lists
02346   // and build a list from them as return value.
02347   Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02348   for (int j=0; j < nbins; j++) {
02349       Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(midpts[j]));
02350       Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewIntObj(bins[j]));
02351   }
02352   Tcl_SetObjResult(interp, tcl_result);
02353   delete[] bins;
02354   delete[] midpts;
02355   return TCL_OK;
02356 
02357 }
02358 
02359 int density_info(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02360   if (argc < 3) {
02361     Tcl_SetResult(interp, (char *) "usage: voltool "
02362       "info [origin | cellaxes | cellvolume | xsize | ysize | zsize | minmax | mean | sigma | integral] [options]\n"
02363       "    options:  -i <input map> specifies new density filename to load.\n"
02364       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
02365       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n",
02366       TCL_STATIC);
02367     return TCL_ERROR;
02368   }
02369 
02370 
02371   int molid = -1;
02372   int volid = 0;
02373   enum INFO_MODE {
02374     NONE,
02375     origin,
02376     cellaxes,
02377     cellvolume,
02378     xsize,
02379     ysize,
02380     zsize,
02381     minmax,
02382     mean,
02383     sigma,
02384     integral
02385   };
02386   INFO_MODE mode = NONE;
02387 
02388   const char *input_map = NULL;
02389   MoleculeList *mlist = app->moleculeList;
02390   
02391   for (int i=0; i < argc; i++) {
02392     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02393     if (!strcmp(opt, "-i")) {
02394       if (i == argc-1) {
02395         Tcl_AppendResult(interp, "No input map specified",NULL);
02396         return TCL_ERROR;
02397       }
02398 
02399       FileSpec spec;
02400       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02401       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
02402       molid = app->molecule_new(input_map,0,1);
02403       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
02404       if (ret_val < 0) return TCL_ERROR;
02405     }
02406 
02407 
02408     if (!strcmp(opt, "-mol")) {
02409       if (i == argc-1) {
02410         Tcl_AppendResult(interp, "No molid specified",NULL);
02411         return TCL_ERROR;
02412       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
02413         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02414         return TCL_ERROR;
02415       }
02416     }
02417 
02418     if (!strcmp(opt, "-vol")) {
02419       if (i == argc-1){
02420         Tcl_AppendResult(interp, "No volume id specified",NULL);
02421         return TCL_ERROR;
02422       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
02423         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02424         return TCL_ERROR;
02425       }
02426     }
02427     
02428     if (!strcmp(opt, "origin")) {
02429       mode = origin;
02430     }
02431     if (!strcmp(opt, "cellaxes")) {
02432       mode = cellaxes;
02433     }
02434     if (!strcmp(opt, "cellvolume")) {
02435       mode = cellvolume;
02436     }
02437     if (!strcmp(opt, "xsize")) {
02438       mode = xsize;
02439     }
02440     if (!strcmp(opt, "ysize")) {
02441       mode = ysize;
02442     }
02443     if (!strcmp(opt, "zsize")) {
02444       mode = zsize;
02445     }
02446     if (!strcmp(opt, "minmax")) {
02447       mode = minmax;
02448     }
02449     if (!strcmp(opt, "mean")) {
02450       mode = mean;
02451     }
02452     if (!strcmp(opt, "sigma")) {
02453       mode = sigma;
02454     }
02455     if (!strcmp(opt, "integral")) {
02456       mode = integral;
02457     }
02458     
02459   }
02460   Molecule *volmol = NULL;
02461   VolumetricData *volmapA = NULL;
02462   if (molid > -1) {
02463     volmol = mlist->mol_from_id(molid);
02464     if (volmol == NULL) {
02465       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02466       return TCL_ERROR;
02467     }
02468 
02469     if (volmapA == NULL) 
02470       volmapA = volmol->modify_volume_data(volid);
02471   } else {
02472     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02473     return TCL_ERROR;
02474   }
02475   if (volmapA == NULL) {
02476     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02477     return TCL_ERROR;
02478   }
02479   
02480   switch(mode)
02481   {
02482     case origin: { 
02483       // convert the results of the lowlevel call to tcl lists
02484       // and build a list from them as return value.
02485       Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02486       for (int j=0; j < 3; j++) {
02487           Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(volmapA->origin[j]));
02488       }
02489       Tcl_SetObjResult(interp, tcl_result);
02490       break;
02491     }
02492     case cellaxes: {
02493       Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02494       Tcl_Obj *tcl_axis = NULL;
02495       int iax = 0, jax = 0;
02496       double cellaxes[3][3];
02497       volmapA->cell_axes(cellaxes[0], cellaxes[1], cellaxes[2]);
02498       for (iax = 0; iax < 3; iax++) {
02499         tcl_axis = Tcl_NewListObj(0, NULL);
02500         for (jax = 0; jax < 3; jax++) {
02501           Tcl_ListObjAppendElement(interp, tcl_axis,
02502                                    Tcl_NewDoubleObj(cellaxes[iax][jax]));
02503         }
02504         Tcl_ListObjAppendElement(interp, tcl_result, tcl_axis);
02505       }
02506       Tcl_SetObjResult(interp, tcl_result);
02507       break;
02508     }
02509     case cellvolume: {
02510       double vol = volmapA->cell_volume();
02511       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(vol));
02512       break;
02513     }
02514     case xsize: {
02515       Tcl_SetObjResult(interp, Tcl_NewIntObj(volmapA->xsize));
02516       break;
02517     }
02518     case ysize: {
02519       Tcl_SetObjResult(interp, Tcl_NewIntObj(volmapA->ysize));
02520       break;
02521      }
02522     case zsize: {
02523       Tcl_SetObjResult(interp, Tcl_NewIntObj(volmapA->zsize));
02524       break;
02525     }
02526     case minmax: {
02527       float min, max;
02528       volmapA->datarange(min, max);
02529       Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02530       Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(min));
02531       Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(max));
02532       Tcl_SetObjResult(interp, tcl_result);
02533       break;
02534     }
02535     case mean: {
02536       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(volmapA->mean()));
02537       break;
02538     }
02539     case sigma: {
02540       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(volmapA->sigma()));
02541       break;
02542     }
02543     case integral: {
02544       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(volmapA->integral()));
02545       break;
02546     }
02547     case NONE: {
02548       Tcl_AppendResult(interp, "No mode correctly specified",NULL);
02549       return TCL_ERROR;
02550     }
02551   }
02552   return TCL_OK;      
02553 }
02554 
02555 int density_binmask(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02556   if (argc < 3) {
02557     Tcl_SetResult(interp, (char *) "usage: voltool "
02558       "binmask [options]\n"
02559       "    options:  -threshold <thresold value> set values above threshold to 1. Defaults to 0.\n"
02560       "              -i <input map> specifies new density filename to load.\n"
02561       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
02562       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02563       "              -o <filename> write density to file.\n",
02564       TCL_STATIC);
02565     return TCL_ERROR;
02566   }
02567 
02568   
02569   int molid = -1;
02570   int volid = 0;
02571   double threshold = 0.0;
02572   const char *input_map = NULL;
02573   const char *outputmap = NULL;
02574   MoleculeList *mlist = app->moleculeList;
02575   
02576   for (int i=0; i < argc; i++) {
02577     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02578     if (!strcmp(opt, "-i")) {
02579       if (i == argc-1) {
02580         Tcl_AppendResult(interp, "No input map specified",NULL);
02581         return TCL_ERROR;
02582       }
02583 
02584       FileSpec spec;
02585       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02586       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
02587       molid = app->molecule_new(input_map,0,1);
02588       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
02589       if (ret_val < 0) return TCL_ERROR;
02590     }
02591 
02592 
02593     if (!strcmp(opt, "-mol")) {
02594       if (i == argc-1) {
02595         Tcl_AppendResult(interp, "No molid specified",NULL);
02596         return TCL_ERROR;
02597       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
02598         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02599         return TCL_ERROR;
02600       }
02601     }
02602 
02603     if (!strcmp(opt, "-vol")) {
02604       if (i == argc-1){
02605         Tcl_AppendResult(interp, "No volume id specified",NULL);
02606         return TCL_ERROR;
02607       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
02608         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02609         return TCL_ERROR;
02610       }
02611     }
02612     
02613     if (!strcmp(opt, "-o")) {
02614       if (i == argc-1) {
02615         Tcl_AppendResult(interp, "No output file specified",NULL);
02616         return TCL_ERROR;
02617       } else {
02618         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
02619       }
02620     }
02621     
02622     if (!strcmp(opt, "-threshold")) {
02623       if (i == argc-1){
02624         Tcl_AppendResult(interp, "No threshold specified",NULL);
02625         return TCL_ERROR;
02626       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &threshold) != TCL_OK) {
02627         Tcl_AppendResult(interp, "\n threshold incorrectly specified",NULL);
02628         return TCL_ERROR;
02629       }
02630     }
02631   }
02632   
02633   
02634   Molecule *volmol = NULL;
02635   VolumetricData *volmapA = NULL;
02636   if (molid > -1) {
02637     volmol = mlist->mol_from_id(molid);
02638     if (volmol == NULL) {
02639       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02640       return TCL_ERROR;
02641     }
02642 
02643     if (volmapA == NULL) 
02644       volmapA = volmol->modify_volume_data(volid);
02645   } else {
02646     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02647     return TCL_ERROR;
02648   }
02649   if (volmapA == NULL) {
02650     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02651     return TCL_ERROR;
02652   }
02653 
02654   volmapA->binmask(float(threshold)); 
02655   volmol->force_recalc(DrawMolItem::MOL_REGEN);
02656   
02657   if (outputmap != NULL) {
02658     if (!write_file(app, volmol, volid, outputmap)){
02659       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02660       return TCL_ERROR;
02661     }
02662   }
02663   return TCL_OK;
02664 
02665 }
02666 
02667 int density_add(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02668   if (argc < 3) {
02669     Tcl_SetResult(interp, (char *) "usage: voltool "
02670       "add [options]\n"
02671       "    input options:  -i1 <input map> specifies new density filename to load.\n"
02672       "              -mol1 <molid> specifies an already loaded density's molid for use as target\n"
02673       "              -vol1 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02674       "              -i2 <input map> specifies new density filename to load.\n"
02675       "              -mol2 <molid> specifies an already loaded density's molid for use as target\n"
02676       "              -vol2 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02677       "    options: \n"
02678       "              -union use union of input maps for operation\n"
02679       "              -nointerp do not use interpolation for operation\n"
02680       "              -o <filename> write density to file.\n",
02681       TCL_STATIC);
02682     return TCL_ERROR;
02683   }
02684 
02685 
02686   int molid1 = -1;
02687   int volid1 = 0;
02688   const char *input_map1 = NULL;
02689   int molid2 = -1;
02690   int volid2 = 0;
02691   const char *input_map2 = NULL;
02692   
02693   bool USE_UNION = false;
02694   bool USE_INTERP = true; 
02695   const char *outputmap = NULL;
02696   MoleculeList *mlist = app->moleculeList;
02697   
02698   for (int i=0; i < argc; i++) {
02699     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02700     if (!strcmp(opt, "-i1")) {
02701       if (i == argc-1) {
02702         Tcl_AppendResult(interp, "No input map specified",NULL);
02703         return TCL_ERROR;
02704       }
02705 
02706       FileSpec spec;
02707       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02708       input_map1 = Tcl_GetStringFromObj(objv[1+i], NULL);
02709       molid1 = app->molecule_new(input_map1,0,1);
02710       int ret_val = app->molecule_load(molid1, input_map1,app->guess_filetype(input_map1),&spec);
02711       if (ret_val < 0) return TCL_ERROR;
02712     }
02713 
02714 
02715     if (!strcmp(opt, "-mol1")) {
02716       if (i == argc-1) {
02717         Tcl_AppendResult(interp, "No molid specified",NULL);
02718         return TCL_ERROR;
02719       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid1) != TCL_OK) {
02720         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02721         return TCL_ERROR;
02722       }
02723     }
02724 
02725     if (!strcmp(opt, "-vol1")) {
02726       if (i == argc-1){
02727         Tcl_AppendResult(interp, "No volume id specified",NULL);
02728         return TCL_ERROR;
02729       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid1) != TCL_OK) {
02730         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02731         return TCL_ERROR;
02732       }
02733     }
02734     
02735     if (!strcmp(opt, "-i2")) {
02736       if (i == argc-1) {
02737         Tcl_AppendResult(interp, "No input map specified",NULL);
02738         return TCL_ERROR;
02739       }
02740 
02741       FileSpec spec;
02742       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02743       input_map2 = Tcl_GetStringFromObj(objv[1+i], NULL);
02744       molid2 = app->molecule_new(input_map2,0,1);
02745       int ret_val = app->molecule_load(molid2, input_map2,app->guess_filetype(input_map2),&spec);
02746       if (ret_val < 0) return TCL_ERROR;
02747     }
02748 
02749 
02750     if (!strcmp(opt, "-mol2")) {
02751       if (i == argc-1) {
02752         Tcl_AppendResult(interp, "No molid specified",NULL);
02753         return TCL_ERROR;
02754       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid2) != TCL_OK) {
02755         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02756         return TCL_ERROR;
02757       }
02758     }
02759 
02760     if (!strcmp(opt, "-vol2")) {
02761       if (i == argc-1){
02762         Tcl_AppendResult(interp, "No volume id specified",NULL);
02763         return TCL_ERROR;
02764       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid2) != TCL_OK) {
02765         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02766         return TCL_ERROR;
02767       }
02768     }
02769     
02770     if (!strcmp(opt, "-union")) {
02771       USE_UNION = true;
02772     }
02773     
02774     if (!strcmp(opt, "-nointerp")) {
02775       USE_INTERP = false;
02776     }
02777     
02778     if (!strcmp(opt, "-o")) {
02779       if (i == argc-1) {
02780         Tcl_AppendResult(interp, "No output file specified",NULL);
02781         return TCL_ERROR;
02782       } else {
02783         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
02784       }
02785     }
02786   }
02787   
02788   Molecule *volmol1 = NULL;
02789   VolumetricData *volmapA = NULL;
02790   if (molid1 > -1) {
02791     volmol1 = mlist->mol_from_id(molid1);
02792     if (volmol1 == NULL) {
02793       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02794       return TCL_ERROR;
02795     }
02796 
02797     if (volmapA == NULL) 
02798       volmapA = volmol1->modify_volume_data(volid1);
02799   } else {
02800     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02801     return TCL_ERROR;
02802   }
02803   if (volmapA == NULL) {
02804     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02805     return TCL_ERROR;
02806   }
02807  
02808   Molecule *volmol2 = NULL;
02809   VolumetricData *volmapB = NULL;
02810   if (molid2 > -1) {
02811     volmol2 = mlist->mol_from_id(molid2);
02812     if (volmol2 == NULL) {
02813       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02814       return TCL_ERROR;
02815     }
02816 
02817     if (volmapB == NULL) 
02818       volmapB = volmol2->modify_volume_data(volid2);
02819   } else {
02820     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02821     return TCL_ERROR;
02822   }
02823   if (volmapB == NULL) {
02824     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02825     return TCL_ERROR;
02826   }
02827   
02828   VolumetricData *newvol = init_new_volume();
02829   add(volmapA, volmapB, newvol, USE_INTERP, USE_UNION);
02830   int newvolmolid = init_new_volume_molecule(app, newvol, "add_map");
02831   Molecule *newvolmol = mlist->mol_from_id(newvolmolid);
02832 
02833   if (outputmap != NULL) {
02834     if (!write_file(app, newvolmol, 0, outputmap)){
02835       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02836       return TCL_ERROR;
02837     }
02838   }
02839   return TCL_OK;
02840 
02841 }
02842 
02843 int density_subtract(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02844   if (argc < 3) {
02845     Tcl_SetResult(interp, (char *) "usage: voltool "
02846       "diff [options]\n"
02847       "    input options:  -i1 <input map> specifies new density filename to load.\n"
02848       "              -mol1 <molid> specifies an already loaded density's molid for use as target\n"
02849       "              -vol1 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02850       "              -i2 <input map> specifies new density filename to load.\n"
02851       "              -mol2 <molid> specifies an already loaded density's molid for use as target\n"
02852       "              -vol2 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
02853       "    options: \n"
02854       "              -union use union of input maps for operation\n"
02855       "              -nointerp do not use interpolation for operation\n"
02856       "              -o <filename> write density to file.\n",
02857       TCL_STATIC);
02858     return TCL_ERROR;
02859   }
02860 
02861 
02862   int molid1 = -1;
02863   int volid1 = 0;
02864   const char *input_map1 = NULL;
02865   int molid2 = -1;
02866   int volid2 = 0;
02867   const char *input_map2 = NULL;
02868   
02869   bool USE_UNION = false;
02870   bool USE_INTERP = true; 
02871   const char *outputmap = NULL;
02872   MoleculeList *mlist = app->moleculeList;
02873   
02874   for (int i=0; i < argc; i++) {
02875     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02876     if (!strcmp(opt, "-i1")) {
02877       if (i == argc-1) {
02878         Tcl_AppendResult(interp, "No input map specified",NULL);
02879         return TCL_ERROR;
02880       }
02881 
02882       FileSpec spec;
02883       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02884       input_map1 = Tcl_GetStringFromObj(objv[1+i], NULL);
02885       molid1 = app->molecule_new(input_map1,0,1);
02886       int ret_val = app->molecule_load(molid1, input_map1,app->guess_filetype(input_map1),&spec);
02887       if (ret_val < 0) return TCL_ERROR;
02888     }
02889 
02890 
02891     if (!strcmp(opt, "-mol1")) {
02892       if (i == argc-1) {
02893         Tcl_AppendResult(interp, "No molid specified",NULL);
02894         return TCL_ERROR;
02895       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid1) != TCL_OK) {
02896         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02897         return TCL_ERROR;
02898       }
02899     }
02900 
02901     if (!strcmp(opt, "-vol1")) {
02902       if (i == argc-1){
02903         Tcl_AppendResult(interp, "No volume id specified",NULL);
02904         return TCL_ERROR;
02905       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid1) != TCL_OK) {
02906         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02907         return TCL_ERROR;
02908       }
02909     }
02910     
02911     if (!strcmp(opt, "-i2")) {
02912       if (i == argc-1) {
02913         Tcl_AppendResult(interp, "No input map specified",NULL);
02914         return TCL_ERROR;
02915       }
02916 
02917       FileSpec spec;
02918       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
02919       input_map2 = Tcl_GetStringFromObj(objv[1+i], NULL);
02920       molid2 = app->molecule_new(input_map2,0,1);
02921       int ret_val = app->molecule_load(molid2, input_map2,app->guess_filetype(input_map2),&spec);
02922       if (ret_val < 0) return TCL_ERROR;
02923     }
02924 
02925 
02926     if (!strcmp(opt, "-mol2")) {
02927       if (i == argc-1) {
02928         Tcl_AppendResult(interp, "No molid specified",NULL);
02929         return TCL_ERROR;
02930       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid2) != TCL_OK) {
02931         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
02932         return TCL_ERROR;
02933       }
02934     }
02935 
02936     if (!strcmp(opt, "-vol2")) {
02937       if (i == argc-1){
02938         Tcl_AppendResult(interp, "No volume id specified",NULL);
02939         return TCL_ERROR;
02940       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid2) != TCL_OK) {
02941         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
02942         return TCL_ERROR;
02943       }
02944     }
02945     
02946     if (!strcmp(opt, "-union")) {
02947       USE_UNION = true;
02948     }
02949     
02950     if (!strcmp(opt, "-nointerp")) {
02951       USE_INTERP = false;
02952     }
02953     
02954     if (!strcmp(opt, "-o")) {
02955       if (i == argc-1) {
02956         Tcl_AppendResult(interp, "No output file specified",NULL);
02957         return TCL_ERROR;
02958       } else {
02959         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
02960       }
02961     }
02962   }
02963   
02964   Molecule *volmol1 = NULL;
02965   VolumetricData *volmapA = NULL;
02966   if (molid1 > -1) {
02967     volmol1 = mlist->mol_from_id(molid1);
02968     if (volmol1 == NULL) {
02969       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02970       return TCL_ERROR;
02971     }
02972 
02973     if (volmapA == NULL) 
02974       volmapA = volmol1->modify_volume_data(volid1);
02975   } else {
02976     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02977     return TCL_ERROR;
02978   }
02979   if (volmapA == NULL) {
02980     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
02981     return TCL_ERROR;
02982   }
02983  
02984   Molecule *volmol2 = NULL;
02985   VolumetricData *volmapB = NULL;
02986   if (molid2 > -1) {
02987     volmol2 = mlist->mol_from_id(molid2);
02988     if (volmol2 == NULL) {
02989       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
02990       return TCL_ERROR;
02991     }
02992 
02993     if (volmapB == NULL) 
02994       volmapB = volmol2->modify_volume_data(volid2);
02995   } else {
02996     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
02997     return TCL_ERROR;
02998   }
02999   if (volmapB == NULL) {
03000     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03001     return TCL_ERROR;
03002   }
03003   
03004   VolumetricData *newvol = init_new_volume();
03005   subtract(volmapA, volmapB, newvol, USE_INTERP, USE_UNION);
03006   int newvolmolid = init_new_volume_molecule(app, newvol, "diff_map");
03007   Molecule *newvolmol = mlist->mol_from_id(newvolmolid);
03008 
03009   if (outputmap != NULL) {
03010     if (!write_file(app, newvolmol, 0, outputmap)){
03011       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03012       return TCL_ERROR;
03013     }
03014   }
03015   
03016   return TCL_OK;
03017 
03018 }
03019 
03020 int density_multiply(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03021   if (argc < 3) {
03022     Tcl_SetResult(interp, (char *) "usage: voltool "
03023       "mult [options]\n"
03024       "    input options:  -i1 <input map> specifies new density filename to load.\n"
03025       "              -mol1 <molid> specifies an already loaded density's molid for use as target\n"
03026       "              -vol1 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03027       "              -i2 <input map> specifies new density filename to load.\n"
03028       "              -mol2 <molid> specifies an already loaded density's molid for use as target\n"
03029       "              -vol2 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03030       "    options: \n"
03031       "              -union use union of input maps for operation\n"
03032       "              -nointerp do not use interpolation for operation\n"
03033       "              -o <filename> write density to file.\n",
03034       TCL_STATIC);
03035     return TCL_ERROR;
03036   }
03037 
03038 
03039   int molid1 = -1;
03040   int volid1 = 0;
03041   const char *input_map1 = NULL;
03042   int molid2 = -1;
03043   int volid2 = 0;
03044   const char *input_map2 = NULL;
03045   
03046   bool USE_UNION = false;
03047   bool USE_INTERP = true; 
03048   const char *outputmap = NULL;
03049   MoleculeList *mlist = app->moleculeList;
03050   
03051   for (int i=0; i < argc; i++) {
03052     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
03053     if (!strcmp(opt, "-i1")) {
03054       if (i == argc-1) {
03055         Tcl_AppendResult(interp, "No input map specified",NULL);
03056         return TCL_ERROR;
03057       }
03058 
03059       FileSpec spec;
03060       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03061       input_map1 = Tcl_GetStringFromObj(objv[1+i], NULL);
03062       molid1 = app->molecule_new(input_map1,0,1);
03063       int ret_val = app->molecule_load(molid1, input_map1,app->guess_filetype(input_map1),&spec);
03064       if (ret_val < 0) return TCL_ERROR;
03065     }
03066 
03067 
03068     if (!strcmp(opt, "-mol1")) {
03069       if (i == argc-1) {
03070         Tcl_AppendResult(interp, "No molid specified",NULL);
03071         return TCL_ERROR;
03072       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid1) != TCL_OK) {
03073         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03074         return TCL_ERROR;
03075       }
03076     }
03077 
03078     if (!strcmp(opt, "-vol1")) {
03079       if (i == argc-1){
03080         Tcl_AppendResult(interp, "No volume id specified",NULL);
03081         return TCL_ERROR;
03082       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid1) != TCL_OK) {
03083         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03084         return TCL_ERROR;
03085       }
03086     }
03087     
03088     if (!strcmp(opt, "-i2")) {
03089       if (i == argc-1) {
03090         Tcl_AppendResult(interp, "No input map specified",NULL);
03091         return TCL_ERROR;
03092       }
03093 
03094       FileSpec spec;
03095       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03096       input_map2 = Tcl_GetStringFromObj(objv[1+i], NULL);
03097       molid2 = app->molecule_new(input_map2,0,1);
03098       int ret_val = app->molecule_load(molid2, input_map2,app->guess_filetype(input_map2),&spec);
03099       if (ret_val < 0) return TCL_ERROR;
03100     }
03101 
03102 
03103     if (!strcmp(opt, "-mol2")) {
03104       if (i == argc-1) {
03105         Tcl_AppendResult(interp, "No molid specified",NULL);
03106         return TCL_ERROR;
03107       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid2) != TCL_OK) {
03108         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03109         return TCL_ERROR;
03110       }
03111     }
03112 
03113     if (!strcmp(opt, "-vol2")) {
03114       if (i == argc-1){
03115         Tcl_AppendResult(interp, "No volume id specified",NULL);
03116         return TCL_ERROR;
03117       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid2) != TCL_OK) {
03118         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03119         return TCL_ERROR;
03120       }
03121     }
03122     
03123     if (!strcmp(opt, "-union")) {
03124       USE_UNION = true;
03125     }
03126     
03127     if (!strcmp(opt, "-nointerp")) {
03128       USE_INTERP = false;
03129     }
03130     
03131     if (!strcmp(opt, "-o")) {
03132       if (i == argc-1) {
03133         Tcl_AppendResult(interp, "No output file specified",NULL);
03134         return TCL_ERROR;
03135       } else {
03136         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
03137       }
03138     }
03139   }
03140   
03141   Molecule *volmol1 = NULL;
03142   VolumetricData *volmapA = NULL;
03143   if (molid1 > -1) {
03144     volmol1 = mlist->mol_from_id(molid1);
03145     if (volmol1 == NULL) {
03146       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03147       return TCL_ERROR;
03148     }
03149 
03150     if (volmapA == NULL) 
03151       volmapA = volmol1->modify_volume_data(volid1);
03152   } else {
03153     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03154     return TCL_ERROR;
03155   }
03156   if (volmapA == NULL) {
03157     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03158     return TCL_ERROR;
03159   }
03160  
03161   Molecule *volmol2 = NULL;
03162   VolumetricData *volmapB = NULL;
03163   if (molid2 > -1) {
03164     volmol2 = mlist->mol_from_id(molid2);
03165     if (volmol2 == NULL) {
03166       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03167       return TCL_ERROR;
03168     }
03169 
03170     if (volmapB == NULL) 
03171       volmapB = volmol2->modify_volume_data(volid2);
03172   } else {
03173     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03174     return TCL_ERROR;
03175   }
03176   if (volmapB == NULL) {
03177     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03178     return TCL_ERROR;
03179   }
03180   
03181   VolumetricData *newvol = init_new_volume();
03182   multiply(volmapA, volmapB, newvol, USE_INTERP, USE_UNION);
03183   int newvolmolid = init_new_volume_molecule(app, newvol, "mult_map");
03184   Molecule *newvolmol = mlist->mol_from_id(newvolmolid);
03185 
03186   if (outputmap != NULL) {
03187     if (!write_file(app, newvolmol, 0, outputmap)){
03188       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03189       return TCL_ERROR;
03190     }
03191   }
03192   return TCL_OK;
03193 
03194 }
03195 
03196 int density_average(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03197   if (argc < 3) {
03198     Tcl_SetResult(interp, (char *) "usage: voltool "
03199       "average [options]\n"
03200       "    input options:  -i1 <input map> specifies new density filename to load.\n"
03201       "              -mol1 <molid> specifies an already loaded density's molid for use as target\n"
03202       "              -vol1 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03203       "              -i2 <input map> specifies new density filename to load.\n"
03204       "              -mol2 <molid> specifies an already loaded density's molid for use as target\n"
03205       "              -vol2 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03206       "    options: \n"
03207       "              -union use union of input maps for operation\n"
03208       "              -nointerp do not use interpolation for operation\n"
03209       "              -o <filename> write density to file.\n",
03210       TCL_STATIC);
03211     return TCL_ERROR;
03212   }
03213 
03214 
03215   int molid1 = -1;
03216   int volid1 = 0;
03217   const char *input_map1 = NULL;
03218   int molid2 = -1;
03219   int volid2 = 0;
03220   const char *input_map2 = NULL;
03221   
03222   bool USE_UNION = false;
03223   bool USE_INTERP = true; 
03224   const char *outputmap = NULL;
03225   MoleculeList *mlist = app->moleculeList;
03226   
03227   for (int i=0; i < argc; i++) {
03228     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
03229     if (!strcmp(opt, "-i1")) {
03230       if (i == argc-1) {
03231         Tcl_AppendResult(interp, "No input map specified",NULL);
03232         return TCL_ERROR;
03233       }
03234 
03235       FileSpec spec;
03236       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03237       input_map1 = Tcl_GetStringFromObj(objv[1+i], NULL);
03238       molid1 = app->molecule_new(input_map1,0,1);
03239       int ret_val = app->molecule_load(molid1, input_map1,app->guess_filetype(input_map1),&spec);
03240       if (ret_val < 0) return TCL_ERROR;
03241     }
03242 
03243 
03244     if (!strcmp(opt, "-mol1")) {
03245       if (i == argc-1) {
03246         Tcl_AppendResult(interp, "No molid specified",NULL);
03247         return TCL_ERROR;
03248       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid1) != TCL_OK) {
03249         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03250         return TCL_ERROR;
03251       }
03252     }
03253 
03254     if (!strcmp(opt, "-vol1")) {
03255       if (i == argc-1){
03256         Tcl_AppendResult(interp, "No volume id specified",NULL);
03257         return TCL_ERROR;
03258       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid1) != TCL_OK) {
03259         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03260         return TCL_ERROR;
03261       }
03262     }
03263     
03264     if (!strcmp(opt, "-i2")) {
03265       if (i == argc-1) {
03266         Tcl_AppendResult(interp, "No input map specified",NULL);
03267         return TCL_ERROR;
03268       }
03269 
03270       FileSpec spec;
03271       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03272       input_map2 = Tcl_GetStringFromObj(objv[1+i], NULL);
03273       molid2 = app->molecule_new(input_map2,0,1);
03274       int ret_val = app->molecule_load(molid2, input_map2,app->guess_filetype(input_map2),&spec);
03275       if (ret_val < 0) return TCL_ERROR;
03276     }
03277 
03278 
03279     if (!strcmp(opt, "-mol2")) {
03280       if (i == argc-1) {
03281         Tcl_AppendResult(interp, "No molid specified",NULL);
03282         return TCL_ERROR;
03283       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid2) != TCL_OK) {
03284         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03285         return TCL_ERROR;
03286       }
03287     }
03288 
03289     if (!strcmp(opt, "-vol2")) {
03290       if (i == argc-1){
03291         Tcl_AppendResult(interp, "No volume id specified",NULL);
03292         return TCL_ERROR;
03293       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid2) != TCL_OK) {
03294         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03295         return TCL_ERROR;
03296       }
03297     }
03298     
03299     if (!strcmp(opt, "-union")) {
03300       USE_UNION = true;
03301     }
03302     
03303     if (!strcmp(opt, "-nointerp")) {
03304       USE_INTERP = false;
03305     }
03306     
03307     if (!strcmp(opt, "-o")) {
03308       if (i == argc-1) {
03309         Tcl_AppendResult(interp, "No output file specified",NULL);
03310         return TCL_ERROR;
03311       } else {
03312         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
03313       }
03314     }
03315   }
03316   
03317   Molecule *volmol1 = NULL;
03318   VolumetricData *volmapA = NULL;
03319   if (molid1 > -1) {
03320     volmol1 = mlist->mol_from_id(molid1);
03321     if (volmol1 == NULL) {
03322       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03323       return TCL_ERROR;
03324     }
03325 
03326     if (volmapA == NULL) 
03327       volmapA = volmol1->modify_volume_data(volid1);
03328   } else {
03329     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03330     return TCL_ERROR;
03331   }
03332   if (volmapA == NULL) {
03333     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03334     return TCL_ERROR;
03335   }
03336  
03337   Molecule *volmol2 = NULL;
03338   VolumetricData *volmapB = NULL;
03339   if (molid2 > -1) {
03340     volmol2 = mlist->mol_from_id(molid2);
03341     if (volmol2 == NULL) {
03342       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03343       return TCL_ERROR;
03344     }
03345 
03346     if (volmapB == NULL) 
03347       volmapB = volmol2->modify_volume_data(volid2);
03348   } else {
03349     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03350     return TCL_ERROR;
03351   }
03352   if (volmapB == NULL) {
03353     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03354     return TCL_ERROR;
03355   }
03356   
03357   VolumetricData *newvol = init_new_volume();
03358   average(volmapA, volmapB, newvol, USE_INTERP, USE_UNION);
03359   int newvolmolid = init_new_volume_molecule(app, newvol, "avg_map");
03360   Molecule *newvolmol = mlist->mol_from_id(newvolmolid);
03361   
03362   if (outputmap != NULL) {
03363     if (!write_file(app, newvolmol, 0, outputmap)){
03364       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03365       return TCL_ERROR;
03366     }
03367   }
03368   return TCL_OK;
03369 
03370 }
03371 
03372 int density_correlate(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03373   if (argc < 3) {
03374     Tcl_SetResult(interp, (char *) "usage: voltool "
03375       "correlate [options] \n"
03376       "    input options:  -i1 <input map> specifies new density filename to load.\n"
03377       "              -mol1 <molid> specifies an already loaded density's molid for use as target\n"
03378       "              -vol1 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03379       "              -i2 <input map> specifies new density filename to load.\n"
03380       "              -mol2 <molid> specifies an already loaded density's molid for use as target\n"
03381       "              -vol2 <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03382       "    options: \n"
03383       "              -thresholddensity <x> (ignores voxels with values below x threshold)\n",
03384       TCL_STATIC);
03385     return TCL_ERROR;
03386   }
03387 
03388 
03389   int molid1 = -1;
03390   int volid1 = 0;
03391   const char *input_map1 = NULL;
03392   int molid2 = -1;
03393   int volid2 = 0;
03394   const char *input_map2 = NULL;
03395   double thresholddensity = -FLT_MAX;
03396   
03397   MoleculeList *mlist = app->moleculeList;
03398   
03399   for (int i=0; i < argc; i++) {
03400     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
03401     if (!strcmp(opt, "-i1")) {
03402       if (i == argc-1) {
03403         Tcl_AppendResult(interp, "No input map specified",NULL);
03404         return TCL_ERROR;
03405       }
03406 
03407       FileSpec spec;
03408       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03409       input_map1 = Tcl_GetStringFromObj(objv[1+i], NULL);
03410       molid1 = app->molecule_new(input_map1,0,1);
03411       int ret_val = app->molecule_load(molid1, input_map1,app->guess_filetype(input_map1),&spec);
03412       if (ret_val < 0) return TCL_ERROR;
03413     }
03414 
03415 
03416     if (!strcmp(opt, "-mol1")) {
03417       if (i == argc-1) {
03418         Tcl_AppendResult(interp, "No molid specified",NULL);
03419         return TCL_ERROR;
03420       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid1) != TCL_OK) {
03421         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03422         return TCL_ERROR;
03423       }
03424     }
03425 
03426     if (!strcmp(opt, "-vol1")) {
03427       if (i == argc-1){
03428         Tcl_AppendResult(interp, "No volume id specified",NULL);
03429         return TCL_ERROR;
03430       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid1) != TCL_OK) {
03431         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03432         return TCL_ERROR;
03433       }
03434     }
03435     
03436     if (!strcmp(opt, "-i2")) {
03437       if (i == argc-1) {
03438         Tcl_AppendResult(interp, "No input map specified",NULL);
03439         return TCL_ERROR;
03440       }
03441 
03442       FileSpec spec;
03443       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03444       input_map2 = Tcl_GetStringFromObj(objv[1+i], NULL);
03445       molid2 = app->molecule_new(input_map2,0,1);
03446       int ret_val = app->molecule_load(molid2, input_map2,app->guess_filetype(input_map2),&spec);
03447       if (ret_val < 0) return TCL_ERROR;
03448     }
03449 
03450 
03451     if (!strcmp(opt, "-mol2")) {
03452       if (i == argc-1) {
03453         Tcl_AppendResult(interp, "No molid specified",NULL);
03454         return TCL_ERROR;
03455       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid2) != TCL_OK) {
03456         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03457         return TCL_ERROR;
03458       }
03459     }
03460 
03461     if (!strcmp(opt, "-vol2")) {
03462       if (i == argc-1){
03463         Tcl_AppendResult(interp, "No volume id specified",NULL);
03464         return TCL_ERROR;
03465       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid2) != TCL_OK) {
03466         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03467         return TCL_ERROR;
03468       }
03469     }
03470     
03471     if (!strcmp(opt, "-thresholddensity")) {
03472       if (i == argc-1){
03473         Tcl_AppendResult(interp, "No threshold specified",NULL);
03474         return TCL_ERROR;
03475       } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &thresholddensity) != TCL_OK) {
03476         Tcl_AppendResult(interp, "\n threshold incorrectly specified",NULL);
03477         return TCL_ERROR;
03478       }
03479     }
03480     
03481   }
03482   
03483   Molecule *volmol1 = NULL;
03484   VolumetricData *volmapA = NULL;
03485   if (molid1 > -1) {
03486     volmol1 = mlist->mol_from_id(molid1);
03487     if (volmol1 == NULL) {
03488       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03489       return TCL_ERROR;
03490     }
03491 
03492     if (volmapA == NULL) 
03493       volmapA = volmol1->modify_volume_data(volid1);
03494   } else {
03495     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03496     return TCL_ERROR;
03497   }
03498   if (volmapA == NULL) {
03499     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03500     return TCL_ERROR;
03501   }
03502  
03503   Molecule *volmol2 = NULL;
03504   VolumetricData *volmapB = NULL;
03505   if (molid2 > -1) {
03506     volmol2 = mlist->mol_from_id(molid2);
03507     if (volmol2 == NULL) {
03508       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03509       return TCL_ERROR;
03510     }
03511 
03512     if (volmapB == NULL) 
03513       volmapB = volmol2->modify_volume_data(volid2);
03514   } else {
03515     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03516     return TCL_ERROR;
03517   }
03518   if (volmapB == NULL) {
03519     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03520     return TCL_ERROR;
03521   }
03522   
03523   double return_cc = 0.0;
03524   cc_threaded(volmapA, volmapB, &return_cc, thresholddensity);
03525 
03526   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(return_cc));
03527   return TCL_OK;
03528 }
03529 
03530 int density_save(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03531   if (argc < 3) {
03532     Tcl_SetResult(interp, (char *) "usage: voltool "
03533       "write [options]\n"
03534       "    options:  -i <input map> specifies new density filename to load.\n"
03535       "              -mol <molid> specifies an already loaded density's molid for use as target\n"
03536       "              -vol <volume id> specifies an already loaded density's volume id for use as target. Defaults to 0.\n"
03537       "              -o <filename> write density to file.\n",
03538       TCL_STATIC);
03539     return TCL_ERROR;
03540   }
03541 
03542 
03543   int molid = -1;
03544   int volid = 0;
03545   const char *input_map = NULL;
03546   const char *outputmap = NULL;
03547   MoleculeList *mlist = app->moleculeList;
03548   
03549   for (int i=0; i < argc; i++) {
03550     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
03551     if (!strcmp(opt, "-i")) {
03552       if (i == argc-1) {
03553         Tcl_AppendResult(interp, "No input map specified",NULL);
03554         return TCL_ERROR;
03555       }
03556 
03557       FileSpec spec;
03558       spec.waitfor = FileSpec::WAIT_BACK; // shouldn't this be waiting for all?
03559       input_map = Tcl_GetStringFromObj(objv[1+i], NULL);
03560       molid = app->molecule_new(input_map,0,1);
03561       int ret_val = app->molecule_load(molid, input_map,app->guess_filetype(input_map),&spec);
03562       if (ret_val < 0) return TCL_ERROR;
03563     }
03564 
03565 
03566     if (!strcmp(opt, "-mol")) {
03567       if (i == argc-1) {
03568         Tcl_AppendResult(interp, "No molid specified",NULL);
03569         return TCL_ERROR;
03570       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
03571         Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
03572         return TCL_ERROR;
03573       }
03574     }
03575 
03576     if (!strcmp(opt, "-vol")) {
03577       if (i == argc-1){
03578         Tcl_AppendResult(interp, "No volume id specified",NULL);
03579         return TCL_ERROR;
03580       } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
03581         Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
03582         return TCL_ERROR;
03583       }
03584     }
03585     
03586     if (!strcmp(opt, "-o")) {
03587       if (i == argc-1) {
03588         Tcl_AppendResult(interp, "No output file specified",NULL);
03589         return TCL_ERROR;
03590       } else {
03591         outputmap = Tcl_GetStringFromObj(objv[i+1], NULL);
03592       }
03593     }
03594   }
03595   Molecule *volmol = NULL;
03596   VolumetricData *volmapA = NULL;
03597   if (molid > -1) {
03598     volmol = mlist->mol_from_id(molid);
03599     if (volmol == NULL) {
03600       Tcl_AppendResult(interp, "\n invalid molecule specified",NULL);
03601       return TCL_ERROR;
03602     }
03603 
03604     if (volmapA == NULL) 
03605       volmapA = volmol->modify_volume_data(volid);
03606   } else {
03607     Tcl_AppendResult(interp, "\n no target volume specified",NULL);
03608     return TCL_ERROR;
03609   }
03610   if (volmapA == NULL) {
03611     Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03612     return TCL_ERROR;
03613   }
03614 
03615 
03616   if (outputmap != NULL) {
03617     if (!write_file(app, volmol, volid, outputmap)){
03618       Tcl_AppendResult(interp, "\n no target volume correctly specified",NULL);
03619       return TCL_ERROR;
03620     }
03621   }
03622   
03623   return TCL_OK;
03624 }
03625 
03626 int obj_voltool(ClientData cd, Tcl_Interp *interp, int argc,
03627                             Tcl_Obj * const objv[]){
03628   if (argc < 2) {
03629     Tcl_SetResult(interp,
03630     (char *) "Usage: voltool <command> [args...]\n"
03631       "Commands:\n"
03632       "map operations using an atomic structure:\n"
03633       "fit          -- rigid body fitting\n"
03634       "cc           -- calculates the cross-correlation coefficient between a map and structure\n"
03635       "sim          -- creates a simulated map from an atomic structure\n"
03636       "mask         -- masks a map around an atomic structure\n"
03637       "operations on one map:\n"
03638       "write        -- write volumetric data to a file\n"
03639       "com          -- get center of mass of density\n"
03640       "moveto       -- move density com to a specified coordinate\n"
03641       "move         -- apply specified 4x4 transformation matrix to density\n"
03642       "trim         -- trim edges of a density\n"
03643       "crop         -- crop density to values given in coordinate space\n"
03644       "clamp        -- clamp out of range voxel values\n"
03645       "smult        -- multiply every voxel by a scaling factor\n"
03646       "sadd         -- add a scaling factor to every voxel\n"
03647       "range        -- fit voxel values to a given range\n"
03648       "downsample   -- downsample by x2 (x8 total reduction)\n"
03649       "supersample  -- supersample by x2 (x8 total increase)\n"
03650       "sigma        -- transform map to sigma scale\n"
03651       "binmask      -- make a binary mask of the map\n"
03652       "smooth       -- 3D gaussian blur\n"
03653       "pot          -- convert a density map to an MDFF potential\n"  
03654       "hist         -- calculate a histogram of the density map\n"  
03655       "info         -- get information about the density map\n"  
03656       "operations on two maps:\n"
03657       "add          -- add two maps together\n"
03658       "diff         -- subtract map2 from map1\n"
03659       "mult         -- multiply map1 and map2\n"
03660       "avg          -- average two input maps into one\n"
03661       "correlate    -- calculates the cross-correlation coefficient between two maps\n"
03662       ,
03663       TCL_STATIC);
03664     return TCL_ERROR;
03665   }
03666   char *argv1 = Tcl_GetStringFromObj(objv[1],NULL);
03667 
03668   VMDApp *app = (VMDApp *)cd;
03669   if (!strupncmp(argv1, "fit", CMDLEN))
03670     return fit(app, argc-1, objv+1, interp);
03671   if (!strupncmp(argv1, "sim", CMDLEN))
03672     return mdff_sim(app, argc-1, objv+1, interp);
03673   if (!strupncmp(argv1, "cc", CMDLEN))
03674     return mdff_cc(app, argc-1, objv+1, interp);
03675   if (!strupncmp(argv1, "com", CMDLEN))
03676     return density_com(app, argc-1, objv+1, interp);
03677   if (!strupncmp(argv1, "moveto", CMDLEN))
03678     return density_moveto(app, argc-1, objv+1, interp);
03679   if (!strupncmp(argv1, "move", CMDLEN))
03680     return density_move(app, argc-1, objv+1, interp);
03681   if (!strupncmp(argv1, "trim", CMDLEN))
03682     return density_trim(app, argc-1, objv+1, interp);
03683   if (!strupncmp(argv1, "crop", CMDLEN))
03684     return density_crop(app, argc-1, objv+1, interp);
03685   if (!strupncmp(argv1, "clamp", CMDLEN))
03686     return density_clamp(app, argc-1, objv+1, interp);
03687   if (!strupncmp(argv1, "smult", CMDLEN))
03688     return density_smult(app, argc-1, objv+1, interp);
03689   if (!strupncmp(argv1, "sadd", CMDLEN))
03690     return density_sadd(app, argc-1, objv+1, interp);
03691   if (!strupncmp(argv1, "range", CMDLEN))
03692     return density_range(app, argc-1, objv+1, interp);
03693   if (!strupncmp(argv1, "downsample", CMDLEN))
03694     return density_downsample(app, argc-1, objv+1, interp);
03695   if (!strupncmp(argv1, "supersample", CMDLEN))
03696     return density_supersample(app, argc-1, objv+1, interp);
03697   if (!strupncmp(argv1, "sigma", CMDLEN))
03698     return density_sigma(app, argc-1, objv+1, interp);
03699   if (!strupncmp(argv1, "binmask", CMDLEN))
03700     return density_binmask(app, argc-1, objv+1, interp);
03701   if (!strupncmp(argv1, "smooth", CMDLEN))
03702     return density_smooth(app, argc-1, objv+1, interp);
03703   if (!strupncmp(argv1, "add", CMDLEN))
03704     return density_add(app, argc-1, objv+1, interp);
03705   if (!strupncmp(argv1, "diff", CMDLEN))
03706     return density_subtract(app, argc-1, objv+1, interp);
03707   if (!strupncmp(argv1, "mult", CMDLEN))
03708     return density_multiply(app, argc-1, objv+1, interp);
03709   if (!strupncmp(argv1, "avg", CMDLEN))
03710     return density_average(app, argc-1, objv+1, interp);
03711   if (!strupncmp(argv1, "correlate", CMDLEN))
03712     return density_correlate(app, argc-1, objv+1, interp);
03713   if (!strupncmp(argv1, "pot", CMDLEN))
03714     return density_mdff_potential(app, argc-1, objv+1, interp);
03715   if (!strupncmp(argv1, "hist", CMDLEN))
03716     return density_histogram(app, argc-1, objv+1, interp);
03717   if (!strupncmp(argv1, "info", CMDLEN))
03718     return density_info(app, argc-1, objv+1, interp);
03719   if (!strupncmp(argv1, "mask", CMDLEN))
03720     return mask(app, argc-1, objv+1, interp);
03721   if (!strupncmp(argv1, "write", CMDLEN))
03722     return density_save(app, argc-1, objv+1, interp);
03723 
03724   Tcl_SetResult(interp, (char *) "Type 'voltool' for summary of usage\n", TCL_VOLATILE);
03725   return TCL_OK;
03726 }

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