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

NanoShaperInterface.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: NanoShaperInterface.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.16 $       $Date: 2020/07/08 04:37:16 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Start NanoSHaper and talk to it.
00019  *
00020  ***************************************************************************/
00021 
00022 #include "utilities.h"
00023 #include "vmdsock.h"
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 
00028 #if defined(ARCH_AIX4)
00029 #include <strings.h>
00030 #endif
00031 
00032 #if defined(__irix)
00033 #include <bstring.h>
00034 #endif
00035 
00036 #if defined(__hpux)
00037 #include <time.h>
00038 #endif
00039 
00040 #include "NanoShaperInterface.h"
00041 #include "Inform.h"
00042 
00043 
00044 void NanoShaperInterface::clear() {
00045   atomids.clear();
00046   faces.clear();
00047   coords.clear();
00048   norms.clear();
00049 }
00050 
00051 
00052 // mark a file for destruction when the object goes out of scope
00053 class VMDTempFile {
00054 private:
00055   const char *m_filename;
00056 public:
00057   VMDTempFile(const char *fname) {
00058     m_filename = stringdup(fname);
00059   }
00060   ~VMDTempFile() {
00061     vmd_delete_file(m_filename);
00062     delete [] m_filename;
00063   }
00064 };
00065 
00066 
00067 int NanoShaperInterface::compute_from_file(int surftype, float gspacing,
00068                                            float probe_radius,
00069                                            float skin_parm,
00070                                            float blob_parm, 
00071                                            int n, int *ids, float *xyzr, 
00072                                            int *flgs) {
00073   const char *nsbin = "NanoShaper";
00074 
00075   // generate output file name and try to create
00076   char *dirname = vmd_tempfile("");
00077 
00078   int uid = vmd_getuid();
00079   int rnd = vmd_random() % 999;
00080 
00081   char *filebase = new char[strlen(dirname) + 100];
00082   sprintf(filebase, "%svmdns.u%d.%d.", dirname, uid, rnd);
00083   delete [] dirname;
00084 
00085   char *pfilename = new char[strlen(filebase) + 100];
00086   char *ofilename = new char[strlen(filebase) + 100];
00087   sprintf(pfilename, "%sprm", filebase);
00088   sprintf(ofilename, "%sxyzr", filebase);
00089 
00090   FILE *pfile = fopen(pfilename, "wt");
00091   if (!pfile) {
00092     delete [] filebase;
00093     delete [] pfilename;
00094     delete [] ofilename;
00095     msgErr << "Failed to create NanoShaper parameter input file" << sendmsg;
00096     return 0;  // failure
00097   }
00098 
00099   const char *surfstr = "ses";
00100   const char *modestr = "normal";
00101   switch(surftype) {
00102     case NS_SURF_SES:
00103       surfstr = "ses";
00104       modestr = "normal";
00105       break;
00106 
00107     case NS_SURF_SKIN:
00108       surfstr = "skin";
00109       modestr = "normal";
00110       break;
00111 
00112     case NS_SURF_BLOBBY:
00113       surfstr = "blobby";
00114       modestr = "normal";
00115       break;
00116 
00117     case NS_SURF_POCKETS:
00118       surfstr = "pockets";
00119       modestr = "pockets";
00120       break;
00121   }
00122 
00123   //
00124   // Emit surface calculation configuration into NS input file
00125   // 
00126   fprintf(pfile, "Operative_Mode = %s\n", modestr);
00127   fprintf(pfile, "Pocket_Radius_Small = %.1f\n", 1.4);
00128   fprintf(pfile, "Pocket_Radius_Big = %.1f\n", 3.0);
00129   fprintf(pfile, "Surface = %s\n", surfstr);
00130 
00131   if (gspacing < 0.05f)
00132     gspacing = 0.05f;
00133   fprintf(pfile, "Grid_scale = %.1f\n", 1.0f/gspacing);
00134 
00135   fprintf(pfile, "XYZR_FileName = %s\n", ofilename);
00136   fprintf(pfile, "Probe_Radius = %.1f\n", probe_radius);
00137   fprintf(pfile, "Skin_Surface_Parameter = %.2f\n", skin_parm);
00138   fprintf(pfile, "Blobbyness = %.1f\n", blob_parm);
00139 
00140   // enable all to emulate MSMS
00141   fprintf(pfile, "Compute_Vertex_Normals = true\n");
00142   fprintf(pfile, "Save_Mesh_MSMS_Format = true\n");
00143   fprintf(pfile, "Vertex_Atom_Info = true\n");
00144  
00145   // various parameters copied from example input file
00146   fprintf(pfile, "Grid_perfil = %.1f\n", 70.0);
00147   fprintf(pfile, "Build_epsilon_maps = false\n");
00148   fprintf(pfile, "Build_status_map = true\n");
00149   fprintf(pfile, "Smooth_Mesh = true\n");
00150   fprintf(pfile, "Triangulation = true\n");
00151 
00152   // SD: optimized value for big structures
00153   fprintf(pfile, "Max_Probes_Self_Intersections = 5000\n");
00154 
00155   fprintf(pfile, "Self_Intersections_Grid_Coefficient = 5.0\n");
00156   fprintf(pfile, "Accurate_Triangulation = true\n");
00157 
00158   // Tell NS to store all files by appending to a base filename provided
00159   // by the caller, so we don't end up with problems on multi-user systems
00160   // or when multiple VMD sessions are running concurrently on the same
00161   // machine.  VMD chooses the base filename via OS temp file APIs.
00162   fprintf(pfile, "Root_FileName = %s\n", filebase);
00163 
00164   // SD: optimized value for big structures
00165   fprintf(pfile, "Max_skin_patches_per_auxiliary_grid_2d_cell = 2000\n");
00166 
00167   fclose(pfile);
00168 
00169   FILE *ofile = fopen(ofilename, "wt");
00170   if (!ofile) {
00171     delete [] ofilename;
00172     msgErr << "Failed to create NanoShaper atom xyzr input file" << sendmsg;
00173     return 0;  // failure
00174   }
00175 
00176   char *facetfilename = new char[strlen(filebase) + 100];
00177   char *vertfilename = new char[strlen(filebase) + 100];
00178   char *errfilename = new char[strlen(filebase) + 100];
00179   char *expfilename = new char[strlen(filebase) + 100];
00180   char *expindfilename = new char[strlen(filebase) + 100];
00181   char *areafilename = new char[strlen(filebase) + 100];
00182   sprintf(facetfilename, "%striangulatedSurf.face", filebase);
00183   sprintf(vertfilename, "%striangulatedSurf.vert", filebase);
00184   sprintf(errfilename, "%sstderror.txt", filebase);
00185   sprintf(expfilename, "%sexposed.xyz", filebase);
00186   sprintf(expindfilename, "%sexposedIndices.txt", filebase);
00187   sprintf(areafilename, "%striangleAreas.txt", filebase);
00188 
00189   // temporary files we want to make sure to clean up
00190   VMDTempFile ptemp(pfilename);
00191   VMDTempFile otemp(ofilename);
00192   VMDTempFile ftemp(facetfilename);
00193   VMDTempFile vtemp(vertfilename);
00194   VMDTempFile errtemp(errfilename);
00195   VMDTempFile exptemp(expfilename);
00196   VMDTempFile expindtemp(expindfilename);
00197   VMDTempFile areatemp(areafilename);
00198 
00199   //
00200   // write atom coordinates and radii to the file we send to NanoShaper 
00201   //
00202   for (int i=0; i<n; i++) {
00203     fprintf(ofile, "%f %f %f %f\n", 
00204             xyzr[4L*i], xyzr[4L*i+1], xyzr[4L*i+2], xyzr[4L*i+3]);
00205   }
00206   fclose(ofile);
00207 
00208   //
00209   // call NanoShaper to calculate the surface for the given atoms
00210   //
00211   char *nscmd = new char[2*strlen(ofilename) + strlen(nsbin) + 100];
00212   sprintf(nscmd, "\"%s\" %s", nsbin, pfilename);
00213   vmd_system(nscmd);    
00214   delete [] nscmd;
00215   delete [] pfilename;
00216 
00217   // 
00218   // read NanoShaper output files
00219   //
00220   if (surftype == NS_SURF_POCKETS) {
00221     // XXX pockets feature not complete yet
00222     msgErr << "NanoShaper pockets mode currently unimplemented" << sendmsg;
00223     return 0;
00224   } else {
00225     // Read output files for one of the normal surface modes
00226 
00227     // read facets
00228     FILE *facetfile = fopen(facetfilename, "r");
00229     if (!facetfile) {
00230       msgErr << "Cannot read NanoShaper facet file: " << facetfilename << sendmsg;
00231       return 0;  // failed
00232     }
00233     NanoShaperFace face;
00234 
00235     // eat text comments and counts
00236     char trash[256] = { 0 };
00237     if (fgets(trash, sizeof(trash), facetfile) == NULL)
00238       return 0; // failed
00239     if (fgets(trash, sizeof(trash), facetfile) == NULL)
00240       return 0; // failed
00241     if (fgets(trash, sizeof(trash), facetfile) == NULL)
00242       return 0; // failed
00243 
00244     while (fscanf(facetfile, "%d %d %d %d %d",
00245           face.vertex+0, face.vertex+1, face.vertex+2, &face.surface_type,
00246           &face.anaface) == 5) {
00247       face.component = 0;  // XXX Unused by VMD, so why store?
00248       face.vertex[0]--;
00249       face.vertex[1]--;
00250       face.vertex[2]--;
00251       faces.append(face);
00252     }
00253     fclose(facetfile);
00254 
00255     msgInfo << "NanoShaper face count: " << faces.num() << sendmsg;
00256 
00257     // read verts
00258     FILE *vertfile = fopen(vertfilename, "r");
00259     if (!vertfile) {
00260       msgErr << "Cannot read NanoShaper vertex file: " << vertfilename << sendmsg;
00261       return 0;  // failed
00262     }
00263     NanoShaperCoord norm, coord;
00264     int atomid;  // 1-based atom index
00265     int l0fa;    // number of of the level 0 SES face
00266     int l;       // SES face level? (1/2/3)
00267 
00268     // eat text comments and counts
00269     if (fgets(trash, sizeof(trash), vertfile) == NULL)
00270       return 0; // failed
00271     if (fgets(trash, sizeof(trash), vertfile) == NULL)
00272       return 0; // failed
00273     if (fgets(trash, sizeof(trash), vertfile) == NULL)
00274       return 0; // failed
00275 
00276     while (fscanf(vertfile, "%f %f %f %f %f %f %d %d %d",
00277           coord.x+0, coord.x+1, coord.x+2, 
00278           norm.x+0, norm.x+1, norm.x+2, 
00279           &l0fa, &atomid, &l) == 9) {
00280       norms.append(norm);
00281       coords.append(coord);
00282       atomids.append(atomid-1);
00283     }
00284     fclose(vertfile);
00285 
00286     msgInfo << "NanoShaper vert count: " << norms.num() << sendmsg;
00287 
00288     if (ids) {
00289       for (int i=0; i<atomids.num(); i++) {
00290         atomids[i] = ids[atomids[i]];
00291       }
00292     }
00293   } 
00294 
00295   return 1; // success
00296 }
00297 
00298 

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