Example #1
0
 void
 DisplayDevice::find_pbc_images (const VMDDisplayList *cmdList,
     ResizeArray<Matrix4> &pbcImages)
 {
   if (cmdList->pbc == PBC_NONE)
   {
     pbcImages.append (Matrix4 ());
     return;
   }
   ResizeArray<int> pbcCells;
   find_pbc_cells (cmdList, pbcCells);
   for (int i = 0; i < pbcCells.num (); i += 3)
   {
     int nx = pbcCells[i];
     int ny = pbcCells[i + 1];
     int nz = pbcCells[i + 2];
     Matrix4 mat;
     for (int i1 = 1; i1 <= nx; i1++)
       mat.multmatrix (cmdList->transX);
     for (int i2 = -1; i2 >= nx; i2--)
       mat.multmatrix (cmdList->transXinv);
     for (int i3 = 1; i3 <= ny; i3++)
       mat.multmatrix (cmdList->transY);
     for (int i4 = -1; i4 >= ny; i4--)
       mat.multmatrix (cmdList->transYinv);
     for (int i5 = 1; i5 <= nz; i5++)
       mat.multmatrix (cmdList->transZ);
     for (int i6 = -1; i6 >= nz; i6--)
       mat.multmatrix (cmdList->transZinv);
     pbcImages.append (mat);
   }
 }
void DisplayDevice::find_pbc_cells(const VMDDisplayList *cmdList, 
                                    ResizeArray<int> &pbcCells) {
  int pbc = cmdList->pbc;
  if (pbc == PBC_NONE) {
    pbcCells.append(0);
    pbcCells.append(0);
    pbcCells.append(0);
  } else {
    int npbc = cmdList->npbc;
    int nx = pbc & PBC_X ? npbc : 0;
    int ny = pbc & PBC_Y ? npbc : 0;
    int nz = pbc & PBC_Z ? npbc : 0;
    int nox = pbc & PBC_OPX ? -npbc : 0;
    int noy = pbc & PBC_OPY ? -npbc : 0;
    int noz = pbc & PBC_OPZ ? -npbc : 0;
    int i, j, k;
    for (i=nox; i<=nx; i++) {
      for (j=noy; j<=ny; j++) {
        for (k=noz; k<=nz; k++) {
          if (! (pbc & PBC_NOSELF && !i && !j && !k)) {
            pbcCells.append(i);
            pbcCells.append(j);
            pbcCells.append(k);
          }
        }
      }
    }
  }
}
Example #3
0
static void mol_delete_cb(Fl_Widget *w, void *v) {
  VMDApp *app = (VMDApp *)w->user_data();
  MolBrowser *browser = (MolBrowser *)v;
  ResizeArray<int> idlist;
  for (int i=0; i<browser->size(); i++) {
    if (browser->selected(i+1)) {
      idlist.append(app->molecule_id(i));
    }
  }
  for (int j=0; j<idlist.num(); j++)
    app->molecule_delete(idlist[j]);
}
Example #4
0
/* return the list of exclusions from the file */
void GromacsTopFile::getExclusions(int* atomi, int* atomj) const {
    for(int i =0; i < exclusions_atom_i.size(); i++) {
	atomi[i] = exclusions_atom_i[i];
	atomj[i] = exclusions_atom_j[i];
    }
  return;
}
Example #5
0
ResizeArray<JString *> *generic_get_names(const T &devList) {

  ResizeArray<JString *> *names = SensorConfig::getnames();
  ResizeArray<JString *> *devnames = new ResizeArray<JString *>;
  for (int i=0; i<names->num(); i++) {
    JString *jstr = (*names)[i];
    SensorConfig config(*jstr);
    const char *type = config.gettype();
    if (devList.typecode(type) >= 0)
      devnames->append(jstr); 
    else
      delete jstr;
  } 
  delete names;
  return devnames;
}
Example #6
0
void PSDisplayDevice::render(const VMDDisplayList *display_list) {
   DepthSortObject depth_obj;
   char *cmd_ptr;
   int draw;
   int tok;
   int nc;
   float a[3], b[3], c[3], d[3];
   float cent[3];
   float r;
   Matrix4 ident;
   float textsize=1.0f; // default text size

   // first we want to clear the transformation matrix stack
   while (transMat.num())
      transMat.pop();

   // push on the identity matrix
   transMat.push(ident);

   // load the display list's transformation matrix
   super_multmatrix(display_list->mat.mat);

   // Now we need to calculate the normalized position of the light
   // so we can compute angles of surfaces to that light for shading
   norm_light[0] = lightState[0].pos[0];
   norm_light[1] = lightState[0].pos[1];
   norm_light[2] = lightState[0].pos[2];
   if (norm_light[0] || norm_light[1] || norm_light[2])
      vec_normalize(norm_light);

   // Computer periodic images
   ResizeArray<Matrix4> pbcImages;
   find_pbc_images(display_list, pbcImages);
   int nimages = pbcImages.num();

   for (int pbcimage = 0; pbcimage < nimages; pbcimage++) {
     transMat.dup();
     super_multmatrix(pbcImages[pbcimage].mat);

   // Loop through the display list and add each object to our
   // depth-sort list for final rendering.
   VMDDisplayList::VMDLinkIter cmditer;
   display_list->first(&cmditer);
   while ((tok = display_list->next(&cmditer, cmd_ptr)) != DLASTCOMMAND) {
      draw = 0;
      nc = -1;

      switch (tok) {
         case DPOINT:
            // allocate memory
            depth_obj.points = (float *) malloc(sizeof(float) * 2);
            if (!depth_obj.points) {
               // memory error
               if (!memerror) {
                  memerror = 1;
                  msgErr << "PSDisplayDevice: Out of memory. Some " <<
                     "objects were not drawn." << sendmsg;
               }
               break;
            }

            // copy data
            depth_obj.npoints = 1;
            depth_obj.color = colorIndex;
            (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a);
            memcpy(depth_obj.points, a, sizeof(float) * 2);

            // compute the distance to the eye
            depth_obj.dist = compute_dist(a);

            // valid object to depth sort
            draw = 1;
            break;

         case DSPHERE:
         {
            (transMat.top()).multpoint3d(((DispCmdSphere *) cmd_ptr)->pos_r, c);
            r = scale_radius(((DispCmdSphere *) cmd_ptr)->pos_r[3]);

            sphere_approx(c, r);
            break;
         }

         case DSPHEREARRAY:
         {
            DispCmdSphereArray *sa = (DispCmdSphereArray *) cmd_ptr;
            int cIndex, rIndex; // cIndex: index of colors & centers
                                // rIndex: index of radii.
            float * centers;
            float * radii;
            float * colors;
            sa->getpointers(centers, radii, colors);

            set_sphere_res(sa->sphereres);

            for (cIndex = 0, rIndex=0; rIndex < sa->numspheres; 
                 cIndex+=3, rIndex++)
            {
                colorIndex = nearest_index(colors[cIndex],
                                           colors[cIndex+1],
                                           colors[cIndex+2]);
                (transMat.top()).multpoint3d(&centers[cIndex] , c);
                r = scale_radius(radii[rIndex]);

                sphere_approx(c, r);
            }

            break;
         }   

         case DLINE:
            // check for zero-length line (degenerate)
            if (!memcmp(((DispCmdLine *) cmd_ptr)->pos1,
                        ((DispCmdLine *) cmd_ptr)->pos2,
                        sizeof(float) * 3)) {
               // degenerate line
               break;
            }

            // allocate memory
            depth_obj.points = (float *) malloc(sizeof(float) * 4);
            if (!depth_obj.points) {
               // memory error
               if (!memerror) {
                  memerror = 1;
                  msgErr << "PSDisplayDevice: Out of memory. Some " <<
                     "objects were not drawn." << sendmsg;
               }
               break;
            }

            // copy data
            depth_obj.npoints = 2;
            depth_obj.color = colorIndex;
            (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos1, a);
            (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos2, b);
            memcpy(depth_obj.points, a, sizeof(float) * 2);
            memcpy(&depth_obj.points[2], b, sizeof(float) * 2);

            // compute the centerpoint of the object
            cent[0] = (a[0] + b[0]) / 2;
            cent[1] = (a[1] + b[1]) / 2;
            cent[2] = (a[2] + b[2]) / 2;

            // compute the distance to the eye
            depth_obj.dist = compute_dist(cent);

            // valid object to depth sort
            draw = 1;
            break;

         case DLINEARRAY:
           {
            // XXX much replicated code from DLINE
            float *v = (float *)cmd_ptr;
            int nlines = (int)v[0];
            v++;
            for (int i=0; i<nlines; i++) {
              // check for degenerate line
              if (!memcmp(v,v+3,3*sizeof(float)))
                break;

              // allocate memory
              depth_obj.points = (float *) malloc(sizeof(float) * 4);
              if (!depth_obj.points) {
                 // memory error
                 if (!memerror) {
                    memerror = 1;
                    msgErr << "PSDisplayDevice: Out of memory. Some " <<
                       "objects were not drawn." << sendmsg;
                 }
                 break;
              }

              // copy data
              depth_obj.npoints = 2;
              depth_obj.color = colorIndex;
              (transMat.top()).multpoint3d(v, a);
              (transMat.top()).multpoint3d(v+3, b);
              memcpy(depth_obj.points, a, sizeof(float) * 2);
              memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
  
              // compute the centerpoint of the object
              cent[0] = (a[0] + b[0]) / 2;
              cent[1] = (a[1] + b[1]) / 2;
              cent[2] = (a[2] + b[2]) / 2;
  
              // compute the distance to the eye
              depth_obj.dist = compute_dist(cent);
 
              // we'll add the object here, since we have multiple objects 
              draw = 0;
              memusage += sizeof(float) * 2 * depth_obj.npoints;
              points += depth_obj.npoints;
              objects++;
              depth_list.append(depth_obj);

              v += 6;
            } 
           }
           break;           

         case DPOLYLINEARRAY:
           {
            // XXX much replicated code from DLINE / DLINEARRAY
            float *v = (float *)cmd_ptr;
            int nverts = (int)v[0];
            v++;
            for (int i=0; i<nverts-1; i++) {
              // check for degenerate line
              if (!memcmp(v,v+3,3*sizeof(float)))
                break;

              // allocate memory
              depth_obj.points = (float *) malloc(sizeof(float) * 4);
              if (!depth_obj.points) {
                 // memory error
                 if (!memerror) {
                    memerror = 1;
                    msgErr << "PSDisplayDevice: Out of memory. Some " <<
                       "objects were not drawn." << sendmsg;
                 }
                 break;
              }

              // copy data
              depth_obj.npoints = 2;
              depth_obj.color = colorIndex;
              (transMat.top()).multpoint3d(v, a);
              (transMat.top()).multpoint3d(v+3, b);
              memcpy(depth_obj.points, a, sizeof(float) * 2);
              memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
  
              // compute the centerpoint of the object
              cent[0] = (a[0] + b[0]) / 2;
              cent[1] = (a[1] + b[1]) / 2;
              cent[2] = (a[2] + b[2]) / 2;
  
              // compute the distance to the eye
              depth_obj.dist = compute_dist(cent);
 
              // we'll add the object here, since we have multiple objects 
              draw = 0;
              memusage += sizeof(float) * 2 * depth_obj.npoints;
              points += depth_obj.npoints;
              objects++;
              depth_list.append(depth_obj);

              v += 3;
            } 
           }
           break;           
 
         case DCYLINDER:
         {
            int res;

            (transMat.top()).multpoint3d((float *) cmd_ptr, a);
            (transMat.top()).multpoint3d(&((float *) cmd_ptr)[3], b);
            r = scale_radius(((float *) cmd_ptr)[6]);
            res = (int) ((float *) cmd_ptr)[7];

            cylinder_approx(a, b, r, res, (int) ((float *) cmd_ptr)[8]);
            break;
         }

         case DCONE:
         {
            (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos1, a);
            (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos2, b);
            float r1 = scale_radius(((DispCmdCone *) cmd_ptr)->radius);
            float r2 = scale_radius(((DispCmdCone *) cmd_ptr)->radius2);

            // XXX current implementation can't draw truncated cones.
            if (r2 > 0.0f) {
              msgWarn << "PSDisplayDevice) can't draw truncated cones" 
                      << sendmsg;
            }
            cone_approx(a, b, r1);
            break;
         }

        case DTEXTSIZE:
          textsize = ((DispCmdTextSize *)cmd_ptr)->size;
          break;

        case DTEXT:
        {
            float* pos = (float *)cmd_ptr;
#if 0
            // thickness not implemented yet
            float thickness = pos[3];    // thickness is stored in 4th slot
#endif
            char* txt = (char *)(pos+4);
            int   txtlen = strlen(txt);
            // allocate memory
            depth_obj.points = (float *) malloc(sizeof(float) * 2);
            depth_obj.text   = (char  *) malloc(sizeof(char) * (txtlen+1));
            if ( !(depth_obj.points || depth_obj.text) ) {
              // memory error
              if (!memerror) {
                 memerror = 1;
                 msgErr << "PSDisplayDevice: Out of memory. Some " <<
                    "objects were not drawn." << sendmsg;
              }
              break;
           }

            // copy data
            depth_obj.npoints = 1;
            depth_obj.color = colorIndex;
            (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a);
            memcpy(depth_obj.points, a, sizeof(float) * 2);
            strcpy(depth_obj.text , txt);

            // note scale factor, stored into "light_scale", so we didn't
            // have to add a new structure member just for this.
            depth_obj.light_scale = textsize * 15;

            // compute the distance to the eye
            depth_obj.dist = compute_dist(a);

            // valid object to depth sort
            draw = 1;
            break;
         }

         case DTRIANGLE:
            // check for degenerate triangle
            if (!memcmp(((DispCmdTriangle *) cmd_ptr)->pos1,
                        ((DispCmdTriangle *) cmd_ptr)->pos2,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2,
                        ((DispCmdTriangle *) cmd_ptr)->pos3,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2,
                        ((DispCmdTriangle *) cmd_ptr)->pos3,
                        sizeof(float) * 3)) {
               // degenerate triangle
               break;
            }

            // allocate memory
            depth_obj.points = (float *) malloc(sizeof(float) * 6);
            if (!depth_obj.points) {
               // memory error
               if (!memerror) {
                  memerror = 1;
                  msgErr << "PSDisplayDevice: Out of memory. Some " <<
                     "objects were not drawn." << sendmsg;
               }
               break;
            }

            // copy data
            depth_obj.npoints = 3;
            depth_obj.color = (nc >= 0) ? nc : colorIndex;
            (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos1, a);
            (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos2, b);
            (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos3, c);
            memcpy(depth_obj.points, a, sizeof(float) * 2);
            memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
            memcpy(&depth_obj.points[4], c, sizeof(float) * 2);

            // compute the centerpoint of the object
            cent[0] = (a[0] + b[0] + c[0]) / 3;
            cent[1] = (a[1] + b[1] + c[1]) / 3;
            cent[2] = (a[2] + b[2] + c[2]) / 3;

            // compute the distance to the eye for depth sorting
            depth_obj.dist = compute_dist(cent);

            // compute a light shading factor
            depth_obj.light_scale = compute_light(a, b, c);

            // valid object to depth sort
            draw = 1;
            break;

         case DTRIMESH_C4F_N3F_V3F:
            // call a separate routine to break up the mesh into
            // its component triangles
            decompose_mesh((DispCmdTriMesh *) cmd_ptr);
            break;

         case DTRISTRIP:
            // call a separate routine to break up the strip into
            // its component triangles
            decompose_tristrip((DispCmdTriStrips *) cmd_ptr);
            break;

         case DSQUARE:
            // check for degenerate quadrilateral
            if (!memcmp(((DispCmdSquare *) cmd_ptr)->pos1,
                        ((DispCmdSquare *) cmd_ptr)->pos2,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdSquare *) cmd_ptr)->pos1,
                        ((DispCmdSquare *) cmd_ptr)->pos3,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdSquare *) cmd_ptr)->pos1,
                        ((DispCmdSquare *) cmd_ptr)->pos4,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdSquare *) cmd_ptr)->pos2,
                        ((DispCmdSquare *) cmd_ptr)->pos3,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdSquare *) cmd_ptr)->pos2,
                        ((DispCmdSquare *) cmd_ptr)->pos4,
                        sizeof(float) * 3) ||
                !memcmp(((DispCmdSquare *) cmd_ptr)->pos3,
                        ((DispCmdSquare *) cmd_ptr)->pos4,
                        sizeof(float) * 3)) {
               // degenerate quadrilateral
               break;
            }

            // allocate memory
            depth_obj.points = (float *) malloc(sizeof(float) * 8);
            if (!depth_obj.points) {
               // memory error
               if (!memerror) {
                  memerror = 1;
                  msgErr << "PSDisplayDevice: Out of memory. Some " <<
                     "objects were not drawn." << sendmsg;
               }
               break;
            }

            // copy data
            depth_obj.npoints = 4;
            depth_obj.color = colorIndex;
            (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos1, a);
            (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos2, b);
            (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos3, c);
            (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos4, d);
            memcpy(depth_obj.points, a, sizeof(float) * 2);
            memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
            memcpy(&depth_obj.points[4], c, sizeof(float) * 2);
            memcpy(&depth_obj.points[6], d, sizeof(float) * 2);

            // compute the centerpoint of the object
            cent[0] = (a[0] + b[0] + c[0] + d[0]) / 4;
            cent[1] = (a[1] + b[1] + c[1] + d[1]) / 4;
            cent[2] = (a[2] + b[2] + c[2] + d[2]) / 4;

            // compute the distance to the eye for depth sorting
            depth_obj.dist = compute_dist(cent);

            // compute a light shading factor
            depth_obj.light_scale = compute_light(a, b, c);

            // valid object to depth sort
            draw = 1;
            break;

         case DCOLORINDEX:
            colorIndex = ((DispCmdColorIndex *) cmd_ptr)->color;
            break;

         case DSPHERERES:
            set_sphere_res(((int *) cmd_ptr)[0]);
            break;

         default:
            // unknown object, so just skip it
            break;
      }

      // if we have a valid object to add to the depth sort list
      if (draw && depth_obj.npoints) {
         memusage += sizeof(float) * 2 * depth_obj.npoints;
         if ( depth_obj.text )
           memusage += sizeof(char) * (1+strlen(depth_obj.text));
         points += depth_obj.npoints;
         objects++;
         depth_list.append(depth_obj);
      }

      depth_obj.npoints = 0;
      depth_obj.points = NULL;

   } // while (tok != DLASTCOMMAND)

     transMat.pop();
   } // end for() [periodic images]
}
Example #7
0
extern "C" void * bondsearchthread(void *voidparms) {
  int i, j, aindex;
  int paircount = 0;

  bondsearchthrparms *parms = (bondsearchthrparms *) voidparms;

  const int threadid = parms->threadid;
  const int threadcount = parms->threadcount;
  wkf_mutex_t *pairlistmutex = parms->pairlistmutex;
  const float *pos = parms->pos;
  const float *radii = parms->radii;
  const int totb = parms->totb;
  const int **boxatom = (const int **) parms->boxatom;
  const int *numinbox = parms->numinbox;
  const int **nbrlist = (const int **) parms->nbrlist; 
  const int maxpairs = parms->maxpairs;
  const float pairdist = parms->pairdist;

  ResizeArray<int> *pairs = new ResizeArray<int>;
  float sqdist = pairdist * pairdist;

  wkfmsgtimer *msgt = wkf_msg_timer_create(5);
  for (aindex = threadid; (aindex < totb) && (paircount < maxpairs); aindex+=threadcount) {
    const int *tmpbox, *nbr;
    tmpbox = boxatom[aindex];
    int anbox = numinbox[aindex];

    if (((aindex & 255) == 0) && wkf_msg_timer_timeout(msgt)) {
      char tmpbuf[128];
      sprintf(tmpbuf, "%6.2f", (100.0f * aindex) / (float) totb);
//  XXX: we have to use printf here as msgInfo is not thread-safe.
//  msgInfo << "vmd_gridsearch_bonds (thread " << threadid << "): " 
//          << tmpbuf << "% complete" << sendmsg;
      printf("vmd_gridsearch_bonds (thread %d): %s %% complete\n", 
        threadid, tmpbuf); 
    }

    for (nbr = nbrlist[aindex]; (*nbr != -1) && (paircount < maxpairs); nbr++) {
      int nnbr=*nbr;
      const int *nbrbox = boxatom[nnbr];
      int nbox=numinbox[nnbr];
      int self = (aindex == nnbr) ? 1 : 0;

      for (i=0; (i<anbox) && (paircount < maxpairs); i++) {
        int ind1 = tmpbox[i];
        const float *p1 = pos + 3L*ind1;

        // skip over self and already-tested atoms
        int startj = (self) ? i+1 : 0;

        for (j=startj; (j<nbox) && (paircount < maxpairs); j++) {
          int ind2 = nbrbox[j];
          const float *p2 = pos + 3L*ind2;
          float dx = p1[0] - p2[0];
          float dy = p1[1] - p2[1];
          float dz = p1[2] - p2[2];
          float ds2 = dx*dx + dy*dy + dz*dz;

          // perform distance test, but ignore pairs between atoms
          // with nearly identical coords
          if ((ds2 > sqdist) || (ds2 < 0.001))
            continue;

          if (radii) { // Do atom-specific distance check
            float cut = 0.6f * (radii[ind1] + radii[ind2]);
            if (ds2 > cut*cut)
              continue;
          }

          pairs->append(ind1);
          pairs->append(ind2);
          paircount++;
        }
      }
    }
  }

  // setup results pairlist node
  GridSearchPairlist *head;
  head = (GridSearchPairlist *) malloc(sizeof(GridSearchPairlist));
  head->next = NULL;
  head->pairlist = pairs;

  wkf_mutex_lock(pairlistmutex);   // lock pairlist before update
  parms->head = head;
  wkf_mutex_unlock(pairlistmutex); // unlock pairlist after update

  wkf_msg_timer_destroy(msgt);

  return NULL;
}
Example #8
0
void ComputeDPMEMaster::recvData(ComputeDPMEDataMsg *msg)
{ 
  DebugM(4,"ComputeDPMEMaster::recvData() " << msg->numParticles
	<< " particles from node " << msg->node << "\n");

  {
    homeNode.add(msg->node);
    Pme2Particle *data_ptr = localData + numLocalAtoms;
    for ( int j = 0; j < msg->numParticles; ++j, ++data_ptr ) {
      *data_ptr = msg->particles[j];
    }
    numLocalAtoms += msg->numParticles;
    endForNode.add(numLocalAtoms);
    delete msg;
  }

  if ( homeNode.size() < numWorkingPes ) return;  // messages outstanding

  DebugM(4,"ComputeDPMEMaster::recvData() running serial code.\n");

  // single processor version

  Lattice lattice = host->getFlags()->lattice;
  SimParameters * simParams = Node::Object()->simParameters;
  int i;

  AtomInfo atom_info;
  atom_info.numatoms = numLocalAtoms;
  atom_info.atompnt = 0;  // not used
  atom_info.freepnt = 0;  // not used
  atom_info.nlocal = numLocalAtoms;
  atom_info.nother = 0;

  if ( ! lattice.orthogonal() ) {
    NAMD_die("DPME only supports orthogonal PBC's.");
  }

  BoxInfo box_info;
  box_info.box.x = lattice.a().x;
  box_info.box.y = lattice.b().y;
  box_info.box.z = lattice.c().z;
  box_info.box.origin = 0.;  // why only one number?
  box_info.prd.x = box_info.box.x;
  box_info.prd.y = box_info.box.y;
  box_info.prd.z = box_info.box.z;
  box_info.prd2.x = 0.5 * box_info.box.x;
  box_info.prd2.y = 0.5 * box_info.box.y;
  box_info.prd2.z = 0.5 * box_info.box.z;
  box_info.cutoff = simParams->cutoff;
  box_info.rs = simParams->cutoff;
  box_info.mc2.x = 2. * ( box_info.prd.x - box_info.cutoff );
  box_info.mc2.y = 2. * ( box_info.prd.y - box_info.cutoff );
  box_info.mc2.z = 2. * ( box_info.prd.z - box_info.cutoff );
  box_info.ewaldcof = ComputeNonbondedUtil::ewaldcof;
  box_info.dtol = simParams->PMETolerance;
  for (i = 0; i <= 8; i++) {
    box_info.recip[i] = 0.; /* assume orthogonal box */
  }
  box_info.recip[0] = 1.0/box_info.box.x;
  box_info.recip[4] = 1.0/box_info.box.y;
  box_info.recip[8] = 1.0/box_info.box.z;

  GridInfo grid_info;
  grid_info.order = simParams->PMEInterpOrder;
  grid_info.nfftgrd.x = simParams->PMEGridSizeX;
  grid_info.nfftgrd.y = simParams->PMEGridSizeY;
  grid_info.nfftgrd.z = simParams->PMEGridSizeZ;
  grid_info.nfft = 0;
  grid_info.volume = lattice.volume();

  PeInfo pe_info;  // hopefully this isn't used for anything
  pe_info.myproc.node = 0;
  pe_info.myproc.nprocs = 1;
  pe_info.myproc.ncube = 0;
  pe_info.inst_node[0] = 0;
  pe_info.igrid = 0;

  PmeVector *localResults;
  double recip_vir[6];
  int time_count = 0;
  int tsteps = 1;
  double mytime = 0.;

  // perform calculations
  BigReal electEnergy = 0;

  // calculate self energy
  Pme2Particle *data_ptr = localData;
  for(i=0; i<numLocalAtoms; ++i)
  {
    electEnergy += data_ptr->cg * data_ptr->cg;
    ++data_ptr;
  }
  electEnergy *= -1. * box_info.ewaldcof / SQRT_PI;

  DebugM(4,"Ewald self energy: " << electEnergy << "\n");

  DebugM(4,"Calling dpme_eval_recip().\n");

  double pme_start_time = 0;
  if ( runcount == 1 ) pme_start_time = CmiTimer();

  electEnergy += dpme_eval_recip( atom_info, localData - 1, &localResults,
			recip_vir, grid_info, box_info, pe_info,
			time_count, tsteps, &mytime );

  if ( runcount == 1 ) {
    iout << iINFO << "PME reciprocal sum CPU time per evaluation: "
         << (CmiTimer() - pme_start_time) << "\n" << endi;
  }

  DebugM(4,"Returned from dpme_eval_recip().\n");

  // REVERSE SIGN OF VIRIAL RETURNED BY DPME
  for(i=0; i<6; ++i) recip_vir[i] *= -1.;

  // send out reductions
  DebugM(4,"Timestep : " << host->getFlags()->step << "\n");
  DebugM(4,"Reciprocal sum energy: " << electEnergy << "\n");
  DebugM(4,"Reciprocal sum virial: " << recip_vir[0] << " " <<
	recip_vir[1] << " " << recip_vir[2] << " " << recip_vir[3] << " " <<
	recip_vir[4] << " " << recip_vir[5] << "\n");
  reduction->item(REDUCTION_ELECT_ENERGY_SLOW) += electEnergy;
  reduction->item(REDUCTION_VIRIAL_SLOW_XX) += (BigReal)(recip_vir[0]);
  reduction->item(REDUCTION_VIRIAL_SLOW_XY) += (BigReal)(recip_vir[1]);
  reduction->item(REDUCTION_VIRIAL_SLOW_XZ) += (BigReal)(recip_vir[2]);
  reduction->item(REDUCTION_VIRIAL_SLOW_YX) += (BigReal)(recip_vir[1]);
  reduction->item(REDUCTION_VIRIAL_SLOW_YY) += (BigReal)(recip_vir[3]);
  reduction->item(REDUCTION_VIRIAL_SLOW_YZ) += (BigReal)(recip_vir[4]);
  reduction->item(REDUCTION_VIRIAL_SLOW_ZX) += (BigReal)(recip_vir[2]);
  reduction->item(REDUCTION_VIRIAL_SLOW_ZY) += (BigReal)(recip_vir[4]);
  reduction->item(REDUCTION_VIRIAL_SLOW_ZZ) += (BigReal)(recip_vir[5]);
  reduction->submit();

  PmeVector *results_ptr = localResults + 1;

  numLocalAtoms = 0;
  for ( i = 0; i < homeNode.size(); ++i ) {
    ComputeDPMEResultsMsg *msg = new ComputeDPMEResultsMsg;
    msg->node = homeNode[i];
    msg->numParticles = endForNode[i] - numLocalAtoms;
    msg->forces = new PmeVector[msg->numParticles];
    for ( int j = 0; j < msg->numParticles; ++j, ++results_ptr ) {
      msg->forces[j] = *results_ptr;
    }
    numLocalAtoms = endForNode[i];
    host->comm->sendComputeDPMEResults(msg,homeNode[i]);
  }

  // reset
  runcount += 1;
  numLocalAtoms = 0;
  homeNode.resize(0);
  endForNode.resize(0);

}
Example #9
0
// To write an X3DOM-compatible scene file, we cannot include
// LineProperties nodes.
void X3DOMDisplayDevice::text(float *pos, float size, float thickness,
                               const char *str) {
  float textpos[3];
  float textsize;
  hersheyhandle hh;

  // transform the world coordinates
  (transMat.top()).multpoint3d(pos, textpos);
  textsize = size * 1.5f;

  ResizeArray<int>   idxs; 
  ResizeArray<float> pnts;
  idxs.clear();
  pnts.clear();

  int idx=0;
  while (*str != '\0') {
    float lm, rm, x, y;
    int draw;
    x=y=0.0f;
    draw=0;

    hersheyDrawInitLetter(&hh, *str, &lm, &rm);
    textpos[0] -= lm * textsize;

    while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
      float pt[3];

      if (draw) {
        // add another connected point to the line strip
        idxs.append(idx);

        pt[0] = textpos[0] + textsize * x;
        pt[1] = textpos[1] + textsize * y;
        pt[2] = textpos[2];

        pnts.append(pt[0]);
        pnts.append(pt[1]);
        pnts.append(pt[2]);

        idx++;
      } else {
        idxs.append(-1); // pen-up, end of the line strip
      }
    }
    idxs.append(-1); // pen-up, end of the line strip
    textpos[0] += rm * textsize;
    str++;
  }

  fprintf(outfile, "<Shape>\n");
  fprintf(outfile, "  ");

  // 
  // Emit the line properties
  // 
  fprintf(outfile, "<Appearance><Material ");
  fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
  fprintf(outfile, "diffuseColor='0 0 0' "); 

  const float *rgb = matData[colorIndex];
  fprintf(outfile, "emissiveColor='%g %g %g' ",
          mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
  fprintf(outfile, "/>");

#if 0
  // XXX X3DOM v1.1 doesn't handle LineProperties nodes
  // emit a line thickness directive, if needed
  if (thickness < 0.99f || thickness > 1.01f) {
    fprintf(outfile, "  <LineProperties linewidthScaleFactor=\"%g\" "
            "containerField=\"lineProperties\"/>\n",
            (double) thickness);
  }
#endif
  fprintf(outfile, "</Appearance>\n");

  //
  // Emit the line set
  // 
  fprintf(outfile, "  <IndexedLineSet coordIndex='");
  int i, cnt;
  cnt = idxs.num();
  for (i=0; i<cnt; i++) {
    fprintf(outfile, "%d ", idxs[i]);
  }
  fprintf(outfile, "'>\n");

  fprintf(outfile, "    <Coordinate point='");
  cnt = pnts.num();
  for (i=0; i<cnt; i+=3) {
    fprintf(outfile, "%c%g %g %g", 
            (i==0) ? ' ' : ',',
            pnts[i], pnts[i+1], pnts[i+2]);
  }
  fprintf(outfile, "'/>\n");
  fprintf(outfile, "  </IndexedLineSet>\n");
  fprintf(outfile, "</Shape>\n");
}
// draw a 3-D field lines that follow the volume gradient
void
DrawMolItem::draw_volume_field_lines (int volid, float seedval, float minlen,
    float maxlen, float thickness)
{
  const VolumetricData * v = NULL;
  v = mol->get_volume_data (volid);
  int printdonemesg = 0;

  if (v == NULL)
  {
    msgInfo << "No volume data loaded at index " << volid << sendmsg;
    return;
  }

  int seedcount = 0;
  int pointcount = 0;
  int totalpointcount = 0;
  int usecolor;
  ResizeArray<float> seeds;

  append (DMATERIALOFF);
  usecolor = draw_volume_get_colorid ();
  cmdColorIndex.putdata (usecolor, cmdList);

  seedcount = calcseeds_gradient_magnitude (v, &seeds, seedval * 0.5f,
      seedval * 1.5f);

  // Integrate field lines starting with each of the seeds to simulate
  // particle advection.
  // Uses Euler's approximation for solving the initial value problem.
  // We could get a more accurate solution using a fourth order Runge-Kutta
  // method, but with more math per iteration.  We may want to implement 
  // the integrator as a user selected option.

  // The choice of integration step size is currently arbitrary,
  // but will become a user-defined parameter, since it affects speed
  // and accuracy.  A good default might be 0.25 times the smallest
  // grid cell spacing axis.
  float lx, ly, lz;
  v->cell_lengths (&lx, &ly, &lz);
  float mincelllen = lx;
  mincelllen = (mincelllen < ly) ? mincelllen : ly;
  mincelllen = (mincelllen < lz) ? mincelllen : lz;
  float delta = mincelllen * 0.25f; // delta per step (compensates gradient magnitude)

  // minimum gradient magnitude, before we consider that we've found
  // a critical point in the dataset.
  float mingmag = 0.0001f;

  // max gradient magnitude, before we consider it a source/sink
  float maxgmag = 5;

  ResizeArray<float> points;

  // For each seed point, integrate in both positive and
  // negative directions for a field line length up to
  // the maxlen criterion.
  msgtimer *msgt = msg_timer_create (1);
  int seed;
  for (seed = 0; seed < seedcount; seed++)
  {
    // emit UI messages as integrator runs, for long calculations...
    if (!(seed & 7) && msg_timer_timeout (msgt))
    {
      char tmpbuf[128];
      sprintf (tmpbuf, "%6.2f %% complete",
          (100.0f * seed) / (float) seedcount);
      msgInfo << "integrating " << seedcount << " field lines: " << tmpbuf
          << sendmsg;
      printdonemesg = 1;
    }

    int direction;
    for (direction = -1; direction != 1; direction = 1)
    {
      float pos[3], comsum[3];
      vec_copy (pos, &seeds[seed * 3]); // integration starting point is the seed

      // init the arrays
      points.clear ();

      // main integration loop
      pointcount = 0;
      totalpointcount++;
      float len = 0;
      int iterations = 0;
      float dir = (float) direction;

      vec_zero (comsum); // clear center of mass accumulator

      while ((len < maxlen) && (totalpointcount < 100000000))
      {
        float grad[3];

        // sample gradient at the current position
        v->voxel_gradient_interpolate_from_coord (pos, grad);

        // Early-exit if we run out of bounds (gradient returned will
        // be a vector of NANs), run into a critical point (zero gradient)
        // or a huge gradient at a source/sink point in the dataset.
        float gmag = norm (grad);
        if (gmag < mingmag || gmag > maxgmag)
          break;

        // Draw the current point only after the gradient value
        // has been checked, so we don't end up with out-of-bounds
        // vertices.
        // Only emit a fraction of integration points for display since
        // the integrator stepsize needs to be small for more numerical
        // accuracy, but the field lines themselves can be well 
        // represented with fewer sample points.
        if (!(iterations & 1))
        {
          // Add a vertex for this field line
          points.append (pos[0]);
          points.append (pos[1]);
          points.append (pos[2]);

          vec_incr (comsum, pos);

          pointcount++;
          totalpointcount++;
        }

        // adjust integration stepsize so we never move more than 
        // the distance specified by delta at each step, to compensate
        // for varying gradient magnitude
        vec_scaled_add (pos, dir * delta / gmag, grad); // integrate position
        len += delta; // accumulate distance

        iterations++;
      }

      int drawfieldline = 1;

      // only draw the field line for this seed if we have enough points.
      // If we haven't reached the minimum field line length, we'll
      // drop the whole field line.
      if (pointcount < 2 || len < minlen)
        drawfieldline = 0;

      // only draw if bounding sphere diameter exceeds minlen
      if (drawfieldline)
      {
        float com[3];
        vec_scale (com, 1.0f / (float) pointcount, comsum);
        float minlen2 = minlen * minlen;

        drawfieldline = 0;
        int p;
        for (p = 0; p < pointcount; p++)
        {
          if ((2.0f * distance2 (com, &points[p * 3])) > minlen2)
          {
            drawfieldline = 1;
            break;
          }
        }
      }

      // only draw the field line if it met all selection criteria
      if (drawfieldline)
      {
        cmdLineType.putdata (SOLIDLINE, cmdList);
        cmdLineWidth.putdata ((int) thickness, cmdList);
        cmdColorIndex.putdata (usecolor, cmdList);
        DispCmdPolyLineArray cmdPolyLineArray;
        cmdPolyLineArray.putdata (&points[0], pointcount, cmdList);
      }
    }
  }
  msg_timer_destroy (msgt);

  if (printdonemesg)
    msgInfo << "field line integration complete." << sendmsg;
}
Example #11
0
File: vmd.C Project: quolc/VMDLeap
// read in the startup script, execute it, and then execute any other commands
// which might be necessary (i.e. to load any molecules at start)
// This searches for the startup file in the following
// places (and in this order), reading only the FIRST one found:
//		1. Current directory
//		2. Home directory
//		3. 'Default' directory (here, /usr/local/vmd)
// If a name was given in the -startup switch, that file is checked for ONLY.
void VMDreadStartup(VMDApp *app) {
  char namebuf[512], *envtxt;
  int found = FALSE;
  FILE * tfp;
  char *DataPath; // path of last resort to find a .vmdrc file

  // These options were set by environment variables or command line options
  app->display_set_screen_height(displayHeight);
  app->display_set_screen_distance(displayDist);
  app->set_eofexit(eofexit);
  if (showTitle == TITLE_ON && which_display != DISPLAY_TEXT) {
    app->display_titlescreen();
  }

  if((envtxt = getenv("VMDDIR")) != NULL)
    DataPath = stringdup(envtxt);
  else
    DataPath = stringdup(DEF_VMDENVVAR);
  stripslashes(DataPath); // strip out ending '/' chars.

  // check if the file is available
  if(startupFileStr) {	// name specified by -startup
    if((tfp = fopen(startupFileStr, "rb")) != NULL) {
      found = TRUE;
      fclose(tfp);
      strcpy(namebuf, startupFileStr);
    }
  } else {	// search in different directories, for default file
    const char *def_startup = VMD_STARTUP;
    // first, look in current dir
    strcpy(namebuf, def_startup);
    if((tfp = fopen(namebuf, "rb")) != NULL) {
      found = TRUE;
      fclose(tfp);
    } else {
      // not found in current dir; look in home dir
      if((envtxt = getenv("HOME")) != NULL)
        strcpy(namebuf,envtxt);
      else
        strcpy(namebuf,".");
      strcat(namebuf,"/");
      strcat(namebuf,def_startup);
      if((tfp = fopen(namebuf, "rb")) != NULL) {
        found = TRUE;
        fclose(tfp);
      } else {
        // not found in home dir; look in default dir
	strcpy(namebuf, DataPath);
	strcat(namebuf,"/");
	strcat(namebuf, def_startup);
        if((tfp = fopen(namebuf, "rb")) != NULL) {
          found = TRUE;
          fclose(tfp);
	}
      }
    }
  }
  delete [] DataPath; DataPath = NULL;

  //
  // execute any commands needed at start
  //
  
  // read in molecules requested via command-line switches
  FileSpec spec;
  spec.waitfor = -1; // wait for all files to load before proceeding
  int molid = -1;    // set sentinel value to determine if files were loaded

  if (startNewMoleculeFlags.num() > 0) {
    msgInfo << "File loading in progress, please wait." << sendmsg;
  }

  for (int i=0; i<startNewMoleculeFlags.num(); i++) {
    const char *filename = initFilenames[i];
    const char *filetype = initFiletypes[i];
    if (!filetype) {
      filetype = app->guess_filetype(filename);
      if (!filetype) {
        // assume pdb 
        msgErr << "Unable to determine file type for file '"
          << filename << "'.  Assuming pdb." << sendmsg;
        filetype = "pdb";
      }
    }
    if (startNewMoleculeFlags[i]) {
      molid = app->molecule_load(-1, filename, filetype, &spec);
    } else {
      molid = app->molecule_load(molid, filename, filetype, &spec);
    }
    if (molid < 0) {
      msgErr  << "Loading of startup molecule files aborted." << sendmsg;
      break;
    }
  }

  // if the startup file was found, read in the commands there
  if(found) {
    app->logfile_read(namebuf);
  }

  // Load the extension packages here, _after_ reading the .vmdrc file,
  // so that the search path for extensions can be customized.
  app->commandQueue->runcommand(
    new TclEvalEvent("vmd_load_extension_packages"));   
  
  // Switch to Python if requested, before reading beginCmdFile
  if (cmdFileUsesPython) {
    if (!app->textinterp_change("python")) {
      // bail out since Python scripts won't be readable by Tcl.
      msgErr << "Skipping startup script because Python could not be started." 
             << sendmsg;
      return;
    }
  }
  // after reading in startup file and loading any molecule, the file
  // specified by the -e option is set up to be executed.  
  if(beginCmdFile) {
    app->logfile_read(beginCmdFile);
  } 
}
Example #12
0
File: vmd.C Project: quolc/VMDLeap
// look for all environment variables VMD can use, and initialize the
// proper variables.  If an env variable is not found, use a default value.
// ENVIRONMENT VARIABLES USED BY VMD (default values set in config.h):
//	VMDDIR		directory with VMD data files and utility programs
//	VMDTMPDIR	directory in which to put temporary files (def: /tmp)
static void VMDGetOptions(int argc, char **argv) {
  char *envtxt;

  //
  // VMDDISPLAYDEVICE: which display device to use by default
  // 
  if((envtxt = getenv("VMDDISPLAYDEVICE"))) {
    for(int i=0; i < NUM_DISPLAY_TYPES; i++) {
      if(!strupcmp(envtxt, displayTypeNames[i])) {
        which_display = i;
        break;
      }
    }
  }

  // 
  // VMDTITLE: whether to enable the title screen
  //  
  if((envtxt = getenv("VMDTITLE"))) {
    for(int i=0; i < NUM_TITLE_TYPES; i++) {
      if(!strupcmp(envtxt, titleTypeNames[i])) {
        showTitle = i;
        break;
      }
    }
  }

  //
  // VMDSCRHEIGHT: height of the screen
  //
  if((envtxt = getenv("VMDSCRHEIGHT")))
    displayHeight = (float) atof(envtxt);

  //
  // VMDSCRDIST: distance to the screen
  //
  if((envtxt = getenv("VMDSCRDIST")))
    displayDist = (float) atof(envtxt); 

  // 
  // VMDSCRPOS: graphics window location
  //
  if((envtxt = getenv("VMDSCRPOS"))) {
    char * dispStr = NULL;
    char * dispArgv[64];
    int dispArgc;

    if((dispStr = str_tokenize(envtxt, &dispArgc, dispArgv)) != NULL
                && dispArgc == 2) {
      displayLoc[0] = atoi(dispArgv[0]);
      displayLoc[1] = atoi(dispArgv[1]);
    } else {
      msgErr << "Illegal VMDSCRPOS environment variable setting '" 
             << envtxt << "'." << sendmsg;
    }
    if(dispStr)  delete [] dispStr;
  }

  // 
  // VMDSCRSIZE: graphics window size
  //
  if((envtxt = getenv("VMDSCRSIZE"))) {
    char * dispStr = NULL;
    char * dispArgv[64];
    int dispArgc;
    if((dispStr = str_tokenize(envtxt, &dispArgc, dispArgv)) != NULL
                && dispArgc == 2) {
      displaySize[0] = atoi(dispArgv[0]);
      displaySize[1] = atoi(dispArgv[1]);
 
      // force users to do something that makes sense
      if (displaySize[0] < 100) 
        displaySize[0] = 100; // minimum sane width
      if (displaySize[1] < 100) 
        displaySize[1] = 100; // minimum sane height

    } else {
      msgErr << "Illegal VMDSCRSIZE environment variable setting '" 
             << envtxt << "'." << sendmsg;
    }
    if(dispStr)  delete [] dispStr;
  }

  // initialize variables which indicate how VMD starts up, and
  // parse the command-line options

  // go through the arguments
  int ev = 1;
  while(ev < argc) {
    if(!strupcmp(argv[ev], "-dist")) {
      if(argc > (ev + 1)) {
        displayDist = (float) atof(argv[++ev]);
      } else
        msgErr << "-dist must also specify a distance." << sendmsg;

    } else if(!strupcmp(argv[ev], "-e")) {
      if(argc > (ev + 1)) {
        beginCmdFile = argv[++ev];
      } else
        msgErr << "-e must also specify a filename." << sendmsg;

    } else if(!strupcmp(argv[ev], "-height")) {
      if(argc > (ev + 1)) {
        displayHeight = (float) atof(argv[++ev]);
      } else
        msgErr << "-height must also specify a distance." << sendmsg;

    } else if(!strupcmp(argv[ev], "-pos")) {
      if(argc > (ev + 2) && *(argv[ev+1]) != '-' && *(argv[ev+2]) != '-') {
        displayLoc[0] = atoi(argv[++ev]);
        displayLoc[1] = atoi(argv[++ev]);
      } else
        msgErr << "-pos must also specify an X Y pair." << sendmsg;

    } else if(!strupcmp(argv[ev], "-size")) {
      if(argc > (ev + 2) && *(argv[ev+1]) != '-' && *(argv[ev+2]) != '-') {
        displaySize[0] = atoi(argv[++ev]);
        displaySize[1] = atoi(argv[++ev]);
      } else
        msgErr << "-size must also specify an X Y pair." << sendmsg;

    } else if(!strupcmp(argv[ev], "-startup")) {
      // use next argument as startup config file name
      if(argc > (ev + 1))
        startupFileStr = argv[++ev];
      else
        msgErr << "-startup must also have a new file name specified."
	       << sendmsg;

    } else if(!strupcmp(argv[ev], "-nt")) {
      // do not print out the program title
      showTitle = TITLE_OFF;

    } else if (!strupcmp(argv[ev], "-dispdev")) {  // startup Display
      ev++;
      if (argc > ev) {
        if (!strupcmp(argv[ev], "cave")) {  
          which_display = DISPLAY_CAVE;        // use the CAVE
        } else if (!strupcmp(argv[ev], "win")) {       
          which_display = DISPLAY_WIN;         // use OpenGL, the default
        } else if (!strupcmp(argv[ev], "opengl")) {  
          which_display = DISPLAY_WINOGL;      // use OpenGL if available
        } else if (!strupcmp(argv[ev], "text")) {
          which_display = DISPLAY_TEXT;        // use text console only 
        } else if (!strupcmp(argv[ev], "caveforms")) {
          which_display = DISPLAY_CAVEFORMS;   // use CAVE+Forms
        } else if (!strupcmp(argv[ev], "freevr")) {
          which_display = DISPLAY_FREEVR;      // use FreeVR
        } else if (!strupcmp(argv[ev], "freevrforms")) {
          which_display = DISPLAY_FREEVRFORMS; // use FreeVR+Forms
        } else if (!strupcmp(argv[ev], "none")) {      
          which_display = DISPLAY_TEXT;        // use text console only
        } else {
          msgErr << "-dispdev options are 'win' (default), 'cave', 'caveforms', 'freevr', 'freevrforms', or 'text | none'" << sendmsg;
        }
      } else {
        msgErr << "-dispdev options are 'win' (default), 'cave', 'caveforms', 'freevr', 'freevrforms', or 'text | none'" << sendmsg;
      }
    } else if (!strupcmp(argv[ev], "-h") || !strupcmp(argv[ev], "--help")) {
      // print out command-line option summary
      msgInfo << "Available command-line options:" << sendmsg;
      msgInfo << "\t-dispdev <win | cave | text | none> Specify display device";
      msgInfo << sendmsg;
      msgInfo << "\t-dist <d>           Distance from origin to screen";
      msgInfo << sendmsg;
      msgInfo << "\t-e <filename>       Execute commands in <filename>\n";
      msgInfo << "\t-python             Use Python for -e file and subsequent text input\n";
      msgInfo << "\t-eofexit            Exit when end-of-file occurs on input\n";
      msgInfo << "\t-h | --help         Display this command-line summary\n";
      msgInfo << "\t-height <h>         Height of display screen";
      msgInfo << sendmsg;
      msgInfo << "\t-pos <X> <Y>        Lower-left corner position of display";
      msgInfo << sendmsg;
      msgInfo << "\t-nt                 No title display at start" << sendmsg;
      msgInfo << "\t-size <X> <Y>       Size of display" << sendmsg;
      msgInfo << "\t-startup <filename> Specify startup script file" << sendmsg;
      msgInfo << "\t-m                  Load subsequent files as separate molecules\n";
      msgInfo << "\t-f                  Load subsequent files into the same molecule\n";
      msgInfo << "\t<filename>          Load file using best-guess file type\n";
      msgInfo << "\t-<type> <filename>  Load file using specified file type\n";
      msgInfo << "\t-args               Pass subsequent arguments to text interpreter\n";
      msgInfo << sendmsg;
      just_print_help = 1;
    } else if (!strupcmp(argv[ev], "-eofexit")) {  // exit on EOF
      eofexit = 1;
    } else if (!strupcmp(argv[ev], "-node")) { 
      // start VMD process on a cluster node, next parm is node ID..
      ev++; // skip node ID parm
    } else if (!strupcmp(argv[ev], "-webhelper")) { 
      // Unix startup script doesn't run VMD in the background, so that
      // web browsers won't delete files out from under us until it really
      // exits.  We don't do anything special inside VMD itself presently
      // however.
    } else if (!strupcmp(argv[ev], "-python")) {
      cmdFileUsesPython = 1;
    } else if (!strupcmp(argv[ev], "-args")) {
      // pass the rest of the command line arguments, and only those, 
      // to the embedded text interpreters.
      while (++ev < argc)
        customArgv.append(argv[ev]);

    } else if (!strupcmp(argv[ev], "-m")) {
      loadAsMolecules = 1;
      startNewMolecule = 1;
    } else if (!strupcmp(argv[ev], "-f")) {
      loadAsMolecules = 0;
      startNewMolecule = 1;
#ifdef VMDMPI
    } else if (!strupcmp(argv[ev], "-vmddir")) {
      ev++; // skip VMDDIR directory parm, since we already handled this
            // in MPI startup before we got to this loop...
#endif
    } else {
      // any other argument is treated either as a filename or as a 
      // filetype/filename pair of the form -filetype filename.
      const char *filename, *filetype;
      if (argv[ev][0] == '-') {
        // must be filetype/filename pair
        if (argc > ev+1) {
          filetype = argv[ev]+1;
          filename = argv[ev+1];
          ev++;
        } else {
          msgErr << "filetype argument '" << argv[ev] << "' needs a filename."
            << sendmsg;
          ev++;  // because we skip past the ev++ at the bottom of the loop.
          continue; 
        }
      } else {
        // Given just a filename.  The filetype will have to be guessed.
        filename = argv[ev];
        filetype = NULL;
      }
      initFilenames.append(filename);
      initFiletypes.append(filetype);
      startNewMoleculeFlags.append(startNewMolecule);
      if (!loadAsMolecules) startNewMolecule = 0;
    }
    ev++;
  }

  // command-line options have been parsed ... any init status variables that
  // have been given initial values will have flags saying so, and their
  // values will not be changed when the init file(s) is parsed.
}
Example #13
0
File: vmd.C Project: quolc/VMDLeap
int VMDinitialize(int *argc, char ***argv) {
  int i;

#if defined VMDMPI
  // hack to fix up env vars if necessary
  for (i=0; i<(*argc); i++) {
    if(!strupcmp((*argv)[i], "-vmddir")) {
      if((*argc) > (i + 1)) {
        setenv("VMDDIR", (*argv)[++i], 1);
      } else {
        msgErr << "-vmddir must specify a fully qualified path." << sendmsg;
      }
    }
  }

  vmd_mpi_init(argc, argv);  // initialize MPI, fix up env vars, etc.
#endif

#if defined(_MSC_VER) && !defined(VMDSEPARATESTARTUP)
  win32vmdstart(); // get registry info etc
#endif

#if !defined(VMDNOMACBUNDLE) && defined(__APPLE__)
  macosxvmdstart(*argc, *argv); // get env variables etc
#endif

  // Tell Tcl where the executable is located
  const char *argv0 = vmd_initialize_tcl((*argv)[0]);

#ifdef VMDTCL
  // register signal handler
  tclhandler = Tcl_AsyncCreate(VMDTclAsyncProc, (ClientData)NULL); 
  signal(SIGINT, (sighandler_t) VMDTclSigHandler);  
#endif

  // Let people know who we are.
  VMDtitle();

  // Tell the user what we think about the hardware we're running on.
  // If VMD is compiled for MPI, then we don't print any of the normal
  // standalone startup messages and instead we use the special MPI-specific
  // node scan startup messages only.
#if !defined(VMDMPI)
#if defined(VMDTHREADS) 
  int vmdnumcpus = wkf_thread_numprocessors();
  msgInfo << "Multithreading available, " << vmdnumcpus <<
             ((vmdnumcpus > 1) ? " CPUs" : " CPU") <<  " detected." 
          << sendmsg;
#endif

  long vmdcorefree = vmd_get_avail_physmem_mb();
  if (vmdcorefree >= 0) {
    long vmdcorepcnt = vmd_get_avail_physmem_percent();
    msgInfo << "Free system memory: " << vmdcorefree 
            << "MB (" << vmdcorepcnt << "%)" << sendmsg;
  }
#endif

  // Read environment variables and command line options.
  // Initialize customArgv with just argv0 to avoid problems with
  // Tcl extension.
  customArgv.append((char *)argv0);
  VMDGetOptions(*argc, *argv); 

#if (!defined(__APPLE__) && !defined(_MSC_VER)) && (defined(VMDOPENGL) || defined(VMDFLTK))
  // If we're using X-windows, we autodetect if the DISPLAY environment
  // variable is unset, and automatically switch back to text mode without
  // requiring the user to pass the "-dispdev text" command line parameters
  if ((which_display == DISPLAY_WIN) && (getenv("DISPLAY") == NULL)) {
    which_display = DISPLAY_TEXT;
  }
#endif

#if defined(VMDTKCON)
  vmdcon_init();
  msgInfo << "Using VMD Console redirection interface." << sendmsg;
  // we default to a widget mode console, unless text mode is requested.
  // we don't have an tcl interpreter registered yet, so it is set to NULL.
  // flushing pending messages to the screen, is only in text mode possible.
  if ((which_display == DISPLAY_TEXT) || just_print_help) {
    vmdcon_use_text(NULL);
    vmdcon_purge();
  } else {
    vmdcon_use_widget(NULL);
  }
#endif

#ifdef VMDFLTK
  // Do various special FLTK initialization stuff here
  if ((which_display != DISPLAY_TEXT)) {
    // Cause FLTK to to use 24-bit color for all windows if possible
    // This must be done before any FLTK windows are shown for the first time.
    if (!Fl::visual(FL_DOUBLE | FL_RGB8)) {
      if (!Fl::visual(FL_RGB8)) {
        Fl::visual(FL_RGB); 
      }
    }

    // Disable the use of the arrow keys for navigating buttons and other
    // non-text widgets, we'll try it out and see how it pans out
    Fl::visible_focus(0);

    // Disable Drag 'n Drop since the only text field in VMD is the
    // atomselection input and DND severely gets in the way there.
    Fl::dnd_text_ops(0);
  }
#endif

  // Quit now if the user just wanted a list of command line options.
  if (just_print_help) {
    vmd_sleep(10);  // This is here so that the user can see the message 
                    // before the terminal/shell exits...
    return 0;
  }

  // Set up default allocators; these may be overridden by cave or freevr. 
  vmd_alloc   = malloc;  // system malloc() in the default case
  vmd_dealloc = free;    // system free() in the default case
  vmd_realloc = realloc; // system realloc(), set to NULL when not available 

  // check for a CAVE display
  if (DISPLAY_USES_CAVE(which_display)) {
#ifdef VMDCAVE
    // allocate shared memory pool used to communicate with child renderers
    int megs = 2048;
    if (getenv("VMDCAVEMEM") != NULL) {
      megs = atoi(getenv("VMDCAVEMEM"));
    } 
    msgInfo << "Attempting to get " << megs << 
            "MB of CAVE Shared Memory" << sendmsg;
    grab_CAVE_memory(megs);

    CAVEConfigure(argc, *argv, NULL); // configure cave walls and memory use

    // point VMD shared memory allocators to CAVE routines
    vmd_alloc = malloc_from_CAVE_memory;
    vmd_dealloc = free_to_CAVE_memory;
    vmd_realloc = NULL; // no realloc() functionality is available presently
#else
    msgErr << "Not compiled with the CAVE options set." << sendmsg;
    which_display = DISPLAY_WIN;    
#endif
  }

  // check for a FreeVR display
  if (DISPLAY_USES_FREEVR(which_display)) {
#ifdef VMDFREEVR
    int megs = 2048;
    if (getenv("VMDFREEVRMEM") != NULL) {
      megs = atoi(getenv("VMDFREEVRMEM"));
    } 
    msgInfo << "Attempting to get " << megs << 
            "MB of FreeVR Shared Memory" << sendmsg;
    grab_FreeVR_memory(megs); // have to do this *before* vrConfigure() if
                              // we want more than the default shared mem.
    vrConfigure(NULL, NULL, NULL); // configure FreeVR walls

    // point shared memory allocators to FreeVR routines
    vmd_alloc = malloc_from_FreeVR_memory;
    vmd_dealloc = free_to_FreeVR_memory;
    vmd_realloc = NULL; // no realloc() functionality is available presently
#else
    msgErr << "Not compiled with the FREEVR options set." << sendmsg;
    which_display = DISPLAY_WIN;    
#endif
  }

  // return custom argc/argv
  *argc = customArgv.num();
  for (i=0; i<customArgv.num(); i++) {
    (*argv)[i] = customArgv[i];
  }
  return 1; // successful startup
}
Example #14
0
int text_cmd_mobile(ClientData cd, Tcl_Interp *interp, int argc,
                            const char *argv[]) {

  VMDApp *app = (VMDApp *)cd;

  if (argc < 3 || argc > 6) {
    // if here, something went wrong, so return an error message
    mobile_usage(interp);
    return TCL_ERROR;
  }

  if (!strupncmp(argv[1], "mode", CMDLEN)) {
    int m1 = Mobile::OFF;
    // see if these are string values
    if (!strupncmp(argv[2], "off", CMDLEN))          m1 = Mobile::OFF;
    else if (!strupncmp(argv[2], "move", CMDLEN))    m1 = Mobile::MOVE;
    else if (!strupncmp(argv[2], "animate", CMDLEN)) m1 = Mobile::ANIMATE;
    else if (!strupncmp(argv[2], "tracker", CMDLEN)) m1 = Mobile::TRACKER;
    else if (!strupncmp(argv[2], "user", CMDLEN))    m1 = Mobile::USER;
    else mobile_usage(interp); // error 

    if (!app->mobile_set_mode(m1)) {
      Tcl_AppendResult(interp, "Unable to set Mobile mode to ",
          argv[2], argc > 3 ? argv[3] : NULL, NULL);

      // if here, something went wrong, so return an error message
      mobile_usage(interp);
      return TCL_ERROR;
    }
  } else if(!strupncmp(argv[1], "port", CMDLEN)) {
    int port;
    if (sscanf(argv[2], "%d", &port) == 1) {
      if (!app->mobile_network_port(port)) {
        // if here, something went wrong, so return an error message
        mobile_usage(interp);
        return TCL_ERROR;
      }
    } else {
      // if here, something went wrong, so return an error message
      mobile_usage(interp);
      return TCL_ERROR;
    }
  } else if(!strupncmp(argv[1], "get", CMDLEN)) {
    if (!strupncmp(argv[2], "mode", CMDLEN))          
    {
       Tcl_AppendResult(interp, Mobile::get_mode_str((Mobile::MoveMode)app->mobile_get_mode()), NULL);
    } else if (!strupncmp(argv[2], "clientList", CMDLEN)) {
       ResizeArray <JString *>* ip;
       ResizeArray <JString *>* nick;
       ResizeArray <bool>* active;
       app->mobile_get_client_list( nick, ip, active);
       for (int i=0; i<nick->num(); i++)
       {
          Tcl_AppendResult(interp, " {", NULL);

          Tcl_AppendResult(interp, " {", NULL);
          // here's what we've got..
          //   (const char *)(*(*nick)[i])
          //      now to explain it....
          //   (const char *)               Tcl_AppendResult needs a char*
          //                 (*          )  We have a JString* in ResizeArray that we want to be a JString   
          //                   (*nick)      we have a ResizeArray ptr that we want to be a ResizeArray
          //                          [i]   specific array elem
          Tcl_AppendResult(interp, (const char *)(*(*nick)[i]), NULL);
          Tcl_AppendResult(interp, "}", NULL);

          Tcl_AppendResult(interp, " {", NULL);
          Tcl_AppendResult(interp, (const char *)(*(*ip)[i]), NULL);
          Tcl_AppendResult(interp, "}", NULL);

          Tcl_AppendResult(interp, " {", NULL);
          char tmp[10]; sprintf(tmp, "%d", (*active)[i]);
          Tcl_AppendResult(interp, tmp, NULL);
          Tcl_AppendResult(interp, "}", NULL);

          Tcl_AppendResult(interp, " }", NULL);
       }

    } else if (!strupncmp(argv[2], "port", CMDLEN)) {
       char tmpstr[20];
       sprintf(tmpstr, "%d", app->mobile_get_network_port());
       Tcl_AppendResult(interp, tmpstr, NULL);
    } else if (!strupncmp(argv[2], "APIsupported", CMDLEN)) {
       char tmpstr[20];
       sprintf(tmpstr, "%d", app->mobile_get_APIsupported());
       Tcl_AppendResult(interp, tmpstr, NULL);
    } else mobile_usage(interp); // error 

  } else if(!strupncmp(argv[1], "sendMsg", CMDLEN)) {
    if (argc >= 6)
    {
       if (!app->mobile_sendMsg(argv[2], argv[3], argv[4], argv[5])) {

            // if here, something went wrong, so return an error message
         mobile_usage(interp);
         return TCL_ERROR;
       }
    } else mobile_usage(interp); // error 

  } else if(!strupncmp(argv[1], "set", CMDLEN)) {
    if (!strupncmp(argv[2], "activeClient", CMDLEN))          
    {
       if (argc >= 5)
       {
          if (!app->mobile_set_activeClient(argv[3], argv[4])) {
//         Tcl_AppendResult(interp, "Unable to set activeClient to ",
//             argv[2], argc > 3 ? argv[3] : NULL, NULL);

            // if here, something went wrong, so return an error message
            mobile_usage(interp);
            return TCL_ERROR;
          }
       } else mobile_usage(interp); // error 

    } else mobile_usage(interp); // error 

  } else {
    // if here, something went wrong, so return an error message
    mobile_usage(interp);
    return TCL_ERROR;
  }
  
  // if here, everything worked out ok
  return TCL_OK;
}
Example #15
0
  int
  DisplayDevice::pick (int dim, const float *pos, const VMDDisplayList *cmdList,
      float &eyedist, int *unitcell, float window_size)
  {
    char *cmdptr = NULL;
    int tok;
    float newEyeDist, currEyeDist = eyedist;
    int tag = (-1), inRegion, currTag;
    int minX = 0, minY = 0, maxX = 0, maxY = 0;
    float fminX = 0.0f, fminY = 0.0f, fminZ = 0.0f, fmaxX = 0.0f, fmaxY = 0.0f,
        fmaxZ = 0.0f;
    float pntpos[3];
    long cpos[2];

    if (!cmdList)
      return (-1);

    // initialize picking: find screen region to look for object
    if (dim == 2)
    {
      fminX = pos[0] - window_size;
      fmaxX = pos[0] + window_size;
      fminY = pos[1] - window_size;
      fmaxY = pos[1] + window_size;
      abs_screen_pos (fminX, fminY);
      abs_screen_pos (fmaxX, fmaxY);
      minX = (int) fminX;
      maxX = (int) fmaxX;
      minY = (int) fminY;
      maxY = (int) fmaxY;
    }
    else
    {
      fminX = pos[0] - window_size;
      fmaxX = pos[0] + window_size;
      fminY = pos[1] - window_size;
      fmaxY = pos[1] + window_size;
      fminZ = pos[2] - window_size;
      fmaxZ = pos[2] + window_size;
    }

    // make sure we do not disturb the regular transformation matrix
    transMat.dup ();
    (transMat.top ()).multmatrix (cmdList->mat);

    // Transform the current pick point for each periodic image
    ResizeArray<Matrix4> pbcImages;
    ResizeArray<int> pbcCells;
    find_pbc_images (cmdList, pbcImages);
    find_pbc_cells (cmdList, pbcCells);
    int pbcimg;
    for (pbcimg = 0; pbcimg < pbcImages.num (); pbcimg++)
    {
      transMat.dup ();
      (transMat.top ()).multmatrix (pbcImages[pbcimg]);

      // scan through the list, getting each command and executing it, until
      // the end of commands token is found
      VMDDisplayList::VMDLinkIter cmditer;
      cmdList->first (&cmditer);
      float *dataBlock = NULL;
      while ((tok = cmdList->next (&cmditer, cmdptr)) != DLASTCOMMAND)
      {
        switch (tok)
        {
          case DDATABLOCK:
#ifdef VMDCAVE
            dataBlock = (float *)cmdptr;
#else
            dataBlock = ((DispCmdDataBlock *) cmdptr)->data;
#endif
            break;

          case DPICKPOINT:
          case DPICKPOINT_I:
            // calculate the transformed position of the point
            if (tok == DPICKPOINT)
            {
              DispCmdPickPoint *cmd = (DispCmdPickPoint *) cmdptr;
              (transMat.top ()).multpoint3d (cmd->postag, pntpos);
              currTag = cmd->tag;
            }
            else
            {
              DispCmdPickPointIndex *cmd = (DispCmdPickPointIndex *) cmdptr;
              (transMat.top ()).multpoint3d (dataBlock + cmd->pos, pntpos);
              currTag = cmd->tag;
            }

            // check if in picking region ... different for 2D and 3D
            if (dim == 2)
            {
              // convert the 3D world coordinate to 2D absolute screen coord
              abs_screen_loc_3D (pntpos, cpos);

              // check to see if the position falls in our picking region
              inRegion = (cpos[0] >= minX && cpos[0] <= maxX && cpos[1] >= minY
                  && cpos[1] <= maxY);
            }
            else
            {
              // just check to see if the position is in a box centered on our
              // pointer.  The pointer position should already be transformed.
              inRegion = (pntpos[0] >= fminX && pntpos[0] <= fmaxX
                  && pntpos[1] >= fminY && pntpos[1] <= fmaxY
                  && pntpos[2] >= fminZ && pntpos[2] <= fmaxZ);
            }

            // has a hit occurred?
            if (inRegion)
            {
              // yes, see if it is closer to the eye position than earlier objects
              if (dim == 2)
                newEyeDist = DTOEYE(pntpos[0], pntpos[1], pntpos[2]);
              else
                newEyeDist = DTOPOINT(pntpos[0],pntpos[1],pntpos[2]);

              if (currEyeDist < 0.0 || newEyeDist < currEyeDist)
              {
                currEyeDist = newEyeDist;
                tag = currTag;
                if (unitcell)
                {
                  unitcell[0] = pbcCells[3 * pbcimg];
                  unitcell[1] = pbcCells[3 * pbcimg + 1];
                  unitcell[2] = pbcCells[3 * pbcimg + 2];
                }
              }
            }
            break;

          case DPICKPOINT_IARRAY:
            // loop over all of the pick points in the pick point index array
            DispCmdPickPointIndexArray *cmd =
                (DispCmdPickPointIndexArray *) cmdptr;
            float *pickpos;
            int *indices;
            cmd->getpointers (indices);

            int i;
            for (i = 0; i < cmd->numpicks; i++)
            {
              if (cmd->allselected)
              {
                pickpos = dataBlock + i * 3;
                currTag = i;
              }
              else
              {
                pickpos = dataBlock + indices[i] * 3;
                currTag = indices[i];
              }

              (transMat.top ()).multpoint3d (pickpos, pntpos);

              // check if in picking region ... different for 2D and 3D
              if (dim == 2)
              {
                // convert the 3D world coordinate to 2D absolute screen coord
                abs_screen_loc_3D (pntpos, cpos);

                // check to see if the position falls in our picking region
                inRegion = (cpos[0] >= minX && cpos[0] <= maxX
                    && cpos[1] >= minY && cpos[1] <= maxY);
              }
              else
              {
                // just check to see if the position is in a box centered on our
                // pointer.  The pointer position should already be transformed.
                inRegion = (pntpos[0] >= fminX && pntpos[0] <= fmaxX
                    && pntpos[1] >= fminY && pntpos[1] <= fmaxY
                    && pntpos[2] >= fminZ && pntpos[2] <= fmaxZ);
              }

              // has a hit occurred?
              if (inRegion)
              {
                // yes, see if it is closer to the eye than earlier hits
                if (dim == 2)
                  newEyeDist = DTOEYE(pntpos[0], pntpos[1], pntpos[2]);
                else
                  newEyeDist = DTOPOINT(pntpos[0],pntpos[1],pntpos[2]);

                if (currEyeDist < 0.0 || newEyeDist < currEyeDist)
                {
                  currEyeDist = newEyeDist;
                  tag = currTag;
                  if (unitcell)
                  {
                    unitcell[0] = pbcCells[3 * pbcimg];
                    unitcell[1] = pbcCells[3 * pbcimg + 1];
                    unitcell[2] = pbcCells[3 * pbcimg + 2];
                  }
                }
              }
            }
            break;
        }
      }

      // Pop the PBC image transform
      transMat.pop ();
    } // end of loop over PBC images

    // make sure we do not disturb the regular transformation matrix
    transMat.pop ();

    // return result; if tag >= 0, we found something
    eyedist = currEyeDist;
    return tag;
  }
static PyObject *sasa(PyObject *self, PyObject *args, PyObject *keywds) {
  int molid = -1, frame = -1;
  float srad = 0;
  PyObject *selobj = NULL, *restrictobj = NULL;
  int samples = -1;
  const int *sampleptr = NULL;
  PyObject *pointsobj = NULL;

  static char *kwlist[] = {
    (char *)"srad", (char *)"molid", (char *)"frame", (char *)"selected",
    (char *)"samples", (char *)"points", (char *)"restrict"
  };
  if (!PyArg_ParseTupleAndKeywords(args, keywds, 
        (char *)"fiiO!|iO!O!:atomselection.sasa", kwlist, 
        &srad, &molid, &frame, &PyTuple_Type, &selobj, 
        &samples, &PyList_Type, &pointsobj, &PyTuple_Type, &restrictobj))
    return NULL;

  // validate srad
  if (srad < 0) {
    PyErr_SetString(PyExc_ValueError, (char *)"atomselect.sasa: srad must be non-negative.");
    return NULL;
  }

  // validate selection
  VMDApp *app = get_vmdapp();
  AtomSel *sel = sel_from_py(molid, frame, selobj, app);
  if (!sel) return NULL;

  // fetch the radii and coordinates
  const float *radii = 
    app->moleculeList->mol_from_id(sel->molid())->extraflt.data("radius");
  const float *coords = sel->coordinates(app->moleculeList);

  // if samples was given and is valid, use it
  if (samples > 1) sampleptr = &samples;

  // if restrict is given, validate it
  AtomSel *restrictsel = NULL;
  if (restrictobj) {
    if (!(restrictsel = sel_from_py(molid, frame, restrictobj, app))) {
      delete sel;
      return NULL;
    }
  }

  // if points are requested, fetch them
  ResizeArray<float> sasapts;
  ResizeArray<float> *sasaptsptr = pointsobj ? &sasapts : NULL;
 
  // go!
  float sasa = 0;
  int rc = measure_sasa(sel, coords, radii, srad, &sasa, 
        sasaptsptr, restrictsel, sampleptr);
  delete sel;
  delete restrictsel;
  if (rc) {
    PyErr_SetString(PyExc_ValueError, (char *)measure_error(rc));
    return NULL;
  }

  // append surface points to the provided list object.
  if (pointsobj) {
    for (int i=0; i<sasapts.num(); i++) {
      PyList_Append(pointsobj, PyFloat_FromDouble(sasapts[i]));
    }
  }

  // return the total SASA.
  return PyFloat_FromDouble(sasa);
}
Example #17
0
GromacsTopFile::GromacsTopFile(char *filename) {
  fudgeLJ = fudgeQQ = 1.0;
  /* open the file */
  FILE *f = fopen(filename,"r");
  char buf[LINESIZE];
  char modename[20];
  int mode;
  if(f==NULL) {
    sprintf(buf,"Error opening file '%s'",filename);
    NAMD_die(buf);
  }

  /* really bad parser XXX probably just works on the files we
     happen to have REWRITE THIS SOON.  It should allow for \- line
     continuations, check for errors in the file, etc. */
  while(fgets(buf,LINESIZE-1,f)) {
    char testchar;
    int i,j;

    /* defaults */
    int nbfunc, combrule;
    char genpairs[20];
    
    /* atom buffers */
    int num, resnum, chargegp, typenum;
    char type[NAMESIZE+1], restype[NAMESIZE+1], atomname[NAMESIZE+1];
    char particletype[NAMESIZE+1];
    float charge, mass, c6, c12, junkf;

    /* moltype buffers */
    int nrexcl;
    char molname[LONGNAMESIZE+1];

    /* molInst buffers */
    int copies;
    MolInst *moleculeinstance;

    /* general atomset buffers */
    int atomi, atomj, atomk, atoml;
    char typea[NAMESIZE+1],typeb[NAMESIZE+1],
      typec[NAMESIZE+1],typed[NAMESIZE+1];
    const char *tmptypea,*tmptypeb,*tmptypec,*tmptyped;
    int funct, index;
    float c0,c1;
    
    /* bonds */
    float b0,kB,th0,kth;

    /* dihedrals */
    float c[6];
    int mult=0;

    /* check for comments */
    if(sscanf(buf," %c",&testchar)==1) {
      if(testchar == ';') continue;
    }
    else { /* this is a blank line */
      continue;
    }

    /* check for a new mode */
    if(sscanf(buf," [ %19[^] ] ]",modename)==1) {
      /* switch the mode */
      if(0==strcmp(modename,"atoms"))              mode = ATOMS;
      else if(0==strcmp(modename,"atomtypes"))	   mode = ATOMTYPES;
      else if(0==strcmp(modename,"moleculetype"))  mode = MOLECULETYPE;
      else if(0==strcmp(modename,"molecules"))	   mode = MOLECULES;
      else if(0==strcmp(modename,"system"))	   mode = SYSTEM;
      else if(0==strcmp(modename,"bonds"))	   mode = BONDS;
      else if(0==strcmp(modename,"bondtypes"))	   mode = BONDTYPES;
      else if(0==strcmp(modename,"angles"))	   mode = ANGLES;
      else if(0==strcmp(modename,"angletypes"))	   mode = ANGLETYPES;
      else if(0==strcmp(modename,"dihedrals"))	   mode = DIHEDRALS;
      else if(0==strcmp(modename,"dihedraltypes")) mode = DIHEDRALTYPES;
      else if(0==strcmp(modename,"defaults"))      mode = DEFAULTS;
      else if(0==strcmp(modename,"nonbond_params")) mode = NONBOND;
      // JLai
      else if(0==strcmp(modename,"pairs")) mode = PAIRS;
      else if(0==strcmp(modename,"exclusions")) mode = EXCLUSIONS;
      else {	
	fprintf(stderr,"Warning: unknown mode %s\n",modename);
	mode = UNKNOWN;
      }

      continue;
    }

    /* now do the appropriate thing based on the current mode */
    switch(mode) {
    case SYSTEM:
      systemName = strdup(buf);
      break;

    case DEFAULTS:
      i = sscanf(buf," %d %d %20s %f %f",
		 &nbfunc,&combrule,genpairs,&fudgeLJ,&fudgeQQ);
      if(i < 3) { // didn't get enough parameters 
	fprintf(stderr,"syntax error in DEFAULTS\n");
	exit(1);
      }
      if(nbfunc != 1) { // I don't know how it works with nbfunc=2
	fprintf(stderr,"Non-bonded function != 1 unsupported in DEFAULTS\n");
	exit(1);
      }
      if(combrule != 1) { // same here
	fprintf(stderr,"Combination rule != 1 unsupported in DEFAULTS\n");
	exit(1);
      }
      if(0==strcmp(genpairs,"yes")) {
	genPairs=1;
	if(i!=5) {
	  fprintf(stderr,"syntax error in DEFAULTS\n");
	  exit(1);
	}
	// else fudgeLJ and fudgeQQ got written automatically
      }
      else genPairs=0;

      break;

    case NONBOND:
      if(5 != sscanf(buf," %5s %5s %d %f %f",
		     typea, typeb, &funct, &c6, &c12)) {
	fprintf(stderr,"Syntax error in NONBOND\n");
	exit(1);
      }
      // convert kJ/mol*nm6 to kcal/mol*A6 and ..12 ..12
      c6 =  c6/JOULES_PER_CALORIE*1E6;
      c12= c12/JOULES_PER_CALORIE*1E12;
      vdwTable.addType(typea,typeb,c6,c12);
      break;

    case BONDS:
      i = sscanf(buf," %d %d %d %f %f",
		 &atomi,&atomj,&funct,&c0,&c1);
      atomi--; // shift right away to a zero-indexing
      atomj--;
      if(i==3) {
       tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
       tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
	/* find the index and parameters */
	index = bondTable.getParams(tmptypea, tmptypeb, funct, &b0, &kB);
	if(index==-1) {
	  fprintf(stderr,"Required bondtype %s--%s (function %d) not found.\n",
		  tmptypea,tmptypeb,funct);
	  exit(1);
	}
      }
      else if(i==5) {
	/* first set the values of b0 and kB correctly */
	b0 = c0*ANGSTROMS_PER_NM; /* convert nm to A */
	if(funct==1) { /* harmonic potential */
	  /* convert kJ/nm2 to kcal/A2 and use E=kx2 instead of half that. */
	  kB = c1/JOULES_PER_CALORIE/100/2;
	}
	else if(funct==2) { /* special fourth-order potential */
	  /* convert to the normal harmonic constant and kJ/nm2 to kcal/A2 */
	  kB = 2*c1*c0*c0/JOULES_PER_CALORIE/100;
	  kB /= 2; /* use the NAMD system where E=kx2 */
	}
	else {
	  fprintf(stderr,"I don't know what funct=%d means in BONDS\n",funct);
	  exit(1);
	}
	/* look up the index */
	index = bondTable.getIndex(b0,kB,funct);
      }
      else {
	fprintf(stderr,"Syntax error in BONDS\n");
	exit(1);
      }

      genericMols[genericMols.size()-1]->addBond(atomi,atomj,index);
      break;
      
    case BONDTYPES:
      if(5 != sscanf(buf," %5s %5s %d %f %f",
		     typea,typeb,&funct,&c0,&c1)) {
	fprintf(stderr,"Syntax error in BONDTYPES\n");
	exit(1);
      }

      /* first set the values of b0 and kB correctly */
      b0 = c0*10; /* convert nm to A */
      if(funct==1) { /* harmonic potential */
	/* convert kJ/nm2 to kcal/A2 and use E=kx2 instead of half that. */
	kB = c1/JOULES_PER_CALORIE/100/2;
      }
      else if(funct==2) { /* special fourth-order potential */
	/* convert to the normal harmonic constant and kJ/nm2 to kcal/A2 */
	kB = 2*c1*c0*c0/JOULES_PER_CALORIE/100;
	kB /= 2; /* use the NAMD system where E=kx2 */
      }
      else {
 fprintf(stderr,"I don't know what funct=%d means in BONDTYPES\n",funct);
	exit(1);
      }

      bondTable.addType(typea,typeb,b0,kB,funct);
      break;

    case ANGLES:
      i = sscanf(buf," %d %d %d %d %f %f",
		     &atomi,&atomj,&atomk,&funct,&c0,&c1);
      atomi--; // shift right away to a zero-indexing
      atomj--;
      atomk--;
      if(i == 4) { /* we have to look up the last two parameters */
       tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
       tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
       tmptypec = genericMols[genericMols.size()-1]->getAtom(atomk)->getType();
	/* find the index and parameters */
	index = angleTable.getParams(tmptypea, tmptypeb, tmptypec,
					funct, &th0, &kth);
	if(index==-1) {
	  fprintf(stderr,
		  "Required angletype %s--%s--%s (function %d) not found.\n",
		  tmptypea,tmptypeb,tmptypec,funct);
	  exit(1);
	}
      }
      else if(i == 6) {
	/* first set the values of th0 and kth correctly */
	if(funct == 1) {
	  th0 = c0; /* both are in degrees */
	  kth = c1/JOULES_PER_CALORIE/2; /* convert kJ/rad2 to kcal/rad2 and use E=kx2 */
	}
	else if(funct == 2) {
	  th0 = c0; /* both are in degrees */
	  /* convert G96 kJ to kcal/rad2 and use E=kx2 */
	  kth = sin(th0*PI/180)*sin(th0*PI/180)*c1/JOULES_PER_CALORIE/2;
	}
	else {
	  fprintf(stderr,"I don't know what funct=%d means in ANGLES\n",funct);
	  exit(1);
	}
	/* add the angle type to our table */
	index = angleTable.getIndex(th0,kth,funct);
      }
      else {
	fprintf(stderr,"Syntax error (%d args) in ANGLES: %s\n",i,buf);
	exit(1);
      }

      /* add the angle to our table */
      genericMols[genericMols.size()-1]->addAngle(atomi,atomj,atomk,index);
      break;

    case ANGLETYPES:
      if(6 != sscanf(buf," %5s %5s %5s %d %f %f",
		     typea,typeb,typec,&funct,&c0,&c1)) {
	fprintf(stderr,"Syntax error in ANGLETYPES\n");
	exit(1);
      }
      /* first set the values of th0 and kth correctly */
      if(funct == 1) {
	th0 = c0; /* both are in degrees */
	kth = c1/JOULES_PER_CALORIE/2; /* convert kJ/rad2 to kcal/rad2 and use E=kx2 */
      }
      else if(funct == 2) {
	th0 = c0; /* both are in degrees */
	/* convert G96 kJ to kcal/rad2 and use E=kx2 */
	kth = sin(th0*PI/180)*sin(th0*PI/180)*c1/JOULES_PER_CALORIE/2;
      }
      else {
	fprintf(stderr,"I don't know what funct=%d means in ANGLETYPES\n",
		funct);
	exit(1);
      }
      angleTable.addType(typea,typeb,typec,th0,kth,funct);
      break;

    case DIHEDRALS:
      i = sscanf(buf," %d %d %d %d %d %f %f %f %f %f %f",
		 &atomi,&atomj,&atomk,&atoml,&funct,
		 &c[0],&c[1],&c[2],&c[3],&c[4],&c[5]);
      atomi--; // shift right away to a zero-indexing
      atomj--;
      atomk--;
      atoml--;
      if(i==5) { /* we have to look up the parameters */
       tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
       tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
       tmptypec = genericMols[genericMols.size()-1]->getAtom(atomk)->getType();
       tmptyped = genericMols[genericMols.size()-1]->getAtom(atoml)->getType();
	/* find the index and parameters */
	index = dihedralTable.getParams(tmptypea, tmptypeb, tmptypec,
					tmptyped, funct, c, &mult);
	if(index==-1) {
	  fprintf(stderr,
	     "Required dihedraltype %s--%s--%s--%s (function %d) not found.\n",
		  tmptypea,tmptypeb,tmptypec,tmptyped,funct);
	  exit(1);
	}
      }
      else if(i==7 || i==8 || i==11) { /* the parameters are given */
	if(funct==1 || funct==2) { /* we should have two parameters */
	  if(i!=7+(funct==1)) {    /* plus a multiplicity for funct==1 */
	    fprintf(stderr,"Must have 7 args for funct=1,2\n");
	    exit(1);
	  }
	  c[0] = c[0]; /* both in deg */
	  if(i==7) {
	      c[1] = c[1]/(2*JOULES_PER_CALORIE); /* convert kJ to kcal and still use E=kx2*/
	  } else if (i==8 || i==11) {
	      c[1] = c[1]/(1*JOULES_PER_CALORIE); /* convert kJ to kcal and still use E=kx2*/
	  } 
	  //c[1] = c[1]/(2*JOULES_PER_CALORIE); /* convert kJ to kcal and still use E=kx2*/
	  /* for funct==1 these are both divided by rad^2 */
	  if(funct==1) {
	    mult=(int)(c[2]+0.5); /* round to nearest integer :p */
	  }
	}
	else if(funct==3) {
	  if(i!=11){
	    fprintf(stderr,"Must have 11 args for funct=3\n");
	    exit(1);
	  }

	  for(j=0;j<6;j++) {
	    c[j] = c[j]/JOULES_PER_CALORIE; /* convert kJ to kcal and E=Cn cos^n */
	  }
	}
	else {
	  fprintf(stderr,
		  "I don't know what funct=%d means in DIHEDRALS\n",funct);
	  exit(1);
	}
	index = dihedralTable.getIndex(c,mult,funct);
      }
      else {
	fprintf(stderr,"Syntax error (%d args) in DIHEDRALS: %s\n",i,buf);
	exit(1);
      }

      /* add the dihedrals to our table */
      genericMols[genericMols.size()-1]->addDihedral(atomi,atomj,atomk,atoml,
						     index);
      break;
    case DIHEDRALTYPES:
      i = sscanf(buf," %5s %5s %d %f %f %f %f %f %f",
		 typea,typeb,&funct,&c[0],&c[1],&c[2],&c[3],&c[4],&c[5]);
      if(funct == 1 || funct == 2) {
	if(i!=5+(funct==1)) { /* 6 for f=2, 5 for f=1 */
	  fprintf(stderr,"Syntax error in DIHEDRALTYPES: %s\n",buf);
	  exit(1);
	}
	c[0] = c[0]; /* both in deg */
	c[1] = c[1]/JOULES_PER_CALORIE; /* convert kJ to kcal and still use E=kx2*/
	/* for funct==1 these are both divided by rad^2 */
	if(funct==1) {
	  mult=(int)(c[2]+0.5); /* round to nearest integer :p */
	}
      }
      else if(funct == 3) {
	if(i!=9) {
	  fprintf(stderr,"Syntax error in DIHEDRALTYPES\n");
	  exit(1);
	}
	for(j=0;j<6;j++) {
	  c[j] = c[j]/JOULES_PER_CALORIE; /* convert kJ to kcal and E=Cn cos^n */
	}
      }
      else {
	fprintf(stderr,"I don't know what funct=%d means in DIHEDRALTYPES\n",
		funct);
	exit(1);
      }
      dihedralTable.addType(typea,typeb,c,mult,funct);
      break;
      
    case ATOMS:
      i = sscanf(buf," %d %5s %d %5s %5s %d %f %f",
		   &num, type, &resnum, restype,
		 atomname, &chargegp, &charge, &mass);
      if(i==7) { /* XXX temporary - I should be able to get more
		    params */
        typenum = atomTable.getParams(type,&mass,&junkf,&junkf,&junkf);
	i=8;
      }
      else {
	if(i!=8) {
	  fprintf(stderr,"Syntax error in ATOMS\n");
	  exit(1);
	}
	// just get the type number
	typenum = atomTable.getParams(type,&junkf,&junkf,&junkf,&junkf);
      }
      genericMols[genericMols.size()-1]->addAtom(type,typenum,resnum,
						 restype,atomname,charge,mass);
      break;

    case ATOMTYPES:
      if(6 != sscanf(buf," %5s %f %f %5s %f %f",type,&mass,&charge,
		     particletype,&c6,&c12)) {
	fprintf(stderr,"Syntax error in ATOMTYPES: %s\n",buf);
	exit(1);
      }
      /* conversions:
	 c6  - kJ/mol nm6  -> kcal/mol A6
	 c12 - kJ/mol nm12 -> kcal/mol A12 */
      atomTable.addType(type,mass,charge,
			c6/(JOULES_PER_CALORIE)*1E6,
			c12/(JOULES_PER_CALORIE)*1E12);
      break;

    case MOLECULETYPE:
      if(2!=sscanf(buf," %20s %d",molname,&nrexcl)) {
	fprintf(stderr,"Syntax error in MOLECULETYPE: %s\n",buf);
	exit(1);
      }

      /* add another generic molecule holder */
      genericMols.add(new GenericMol(molname));
      break;

    case MOLECULES:
      if(2!=sscanf(buf," %20s %d",molname,&copies)) {
	fprintf(stderr,"Syntax error in MOLECULES: %s\n",buf);
	exit(1);
      }
      
      /* search for the specified molecule and make a molInst of it*/
      moleculeinstance = NULL;
      for(i=0;i<genericMols.size();i++) {
	if(0==strcmp(molname,genericMols[i]->getName())) {
	  moleculeinstance = new MolInst(genericMols[i],copies);
	  break;
	}
      }

      if(moleculeinstance==NULL) {
	fprintf(stderr,"Molecule %s undefined.\n",molname);
	exit(1);
      }
      
      /* put it at the end of the list */
      molInsts.add(moleculeinstance);

      break;
    case PAIRS:
      int indexA;
      int indexB;
      int pairFunction;
      Real fA;
      Real fB;
      Real fC;
      Real fD;
      Real fE;
      Real fF;
      
      int countVariables;
      countVariables = sscanf(buf," %d %d %d %f %f %f %f %f %f",&indexA,&indexB,&pairFunction,&fA,&fB,&fC,&fD,&fE,&fF);

      if ((countVariables >= 4 && countVariables >= 10)) {
	fprintf(stderr,"Syntax error in PAIRS: %s\n",buf);
	exit(1);
      }
      
      // Shift the atom indices to be zero-based
      indexA--;
      indexB--;

      // Make sure that the indexA is less than indexB
      /*if ( indexA > indexB ) {
	  int tmpIndex = indexA;
	  indexB = indexA;
	  indexA = tmpIndex;
	  }*/

      if (pairFunction == 1) {
	
	// LJ code
	fA = (fA/JOULES_PER_CALORIE)*1E6;
	fB= (fB/JOULES_PER_CALORIE)*1E12;
	pairTable.addPairLJType2(indexA,indexB,fA,fB);
      } else if (pairFunction == 5){
	
	// Bare Gaussian potential
	fA = (fA/JOULES_PER_CALORIE); //-->gaussA
	fB = (fB*ANGSTROMS_PER_NM); //-->gaussMu1
	if(fC == 0) {
	  char buff[100];
	  sprintf(buff,"GromacsTopFile.C::Attempting to load zero into gaussSigma.  Please check the pair: %s\n",buf);
	  NAMD_die(buff);
	}
	if(fC < 0 && !bool_negative_number_warning_flag) {
	  iout << iWARN << "Attempting to load a negative standard deviation into the gaussSigma.  Taking the absolute value of the standard deviation.";
	  bool_negative_number_warning_flag = true;
	}
	fC = (fC*ANGSTROMS_PER_NM); //-->gaussSigma1
	fC = 1.0/(2 * fC * fC); // Normalizes sigma
	pairTable.addPairGaussType2(indexA,indexB,fA,fB,fC);
      } else if (pairFunction == 6) {
	
	// Combined Gaussian + repulsive r^-12 potential
	fA = (fA/JOULES_PER_CALORIE); //-->gaussA
	fB = (fB*ANGSTROMS_PER_NM); //-->gaussMu1
	if(fC == 0) {
	  char buff[100];
	  sprintf(buff,"GromacsTopFile.C::Attempting to load zero into gaussSigma.  Please check the pair: %s\n",buf);
	  NAMD_die(buff);
	}
	if(fC < 0 && !bool_negative_number_warning_flag) {
	  iout << iWARN << "Attempting to load a negative standard deviation into the gaussSigma.  Taking the absolute value of the standard deviation.";
	  bool_negative_number_warning_flag = true;
	}
	fC = (fC*ANGSTROMS_PER_NM); //-->gaussSigma1
	fC = 1.0/(2 * fC * fC); // Normalizes sigma
	fD = (fD*ANGSTROMS_PER_NM); //-->gaussRepulsive
	pairTable.addPairGaussType2(indexA,indexB,fA,fB,fC,fD);
      } else if (pairFunction == 7) {
	
	// Double well Guassian function
	fA = (fA/JOULES_PER_CALORIE); //-->gaussA
	fB = (fB*ANGSTROMS_PER_NM); //-->gaussMu1
        if(fC == 0 || fE == 0) {
	  char buff[100];
	  sprintf(buff,"GromacsTopFile.C::Attempting to load zero into gaussSigma.  Please check the pair: %s\n",buf);
	  NAMD_die(buff);
	}
	if((fC < 0 || fE < 0)&& !bool_negative_number_warning_flag) {
	  iout << iWARN << "Attempting to load a negative standard deviation into the gaussSigma.  Taking the absolute value of the standard deviation.";
	  bool_negative_number_warning_flag = true;
	}
	fC = (fC*ANGSTROMS_PER_NM); //-->gaussSigma1
	fC = 1.0/(2 * fC * fC); // Normalizes sigma
        fD = (fD*ANGSTROMS_PER_NM); //-->gaussMu2
	fE = (fE*ANGSTROMS_PER_NM); //-->gaussSigma2
	fE = 1.0/(2 * fE * fE); // Normalizes sigma
	fF = (fE*ANGSTROMS_PER_NM); //-->gaussRepulsive
	pairTable.addPairGaussType2(indexA,indexB,fA,fB,fC,fD,fE,fF);
      } else {
	
	// Generic error statement
	fprintf(stderr,"Unknown pairFunction in GromacsTopFile.C under the PAIRS section: %d\n",pairFunction);
      }
      break;
    case EXCLUSIONS:
      /* Start of JLai modifications August 16th, 2012 */
      if(2 != sscanf(buf," %d %d ",&atomi,&atomj)) {
	fprintf(stderr,"Syntax error in EXCLUSIONS: %s\n",buf);
	exit(1);
      }
      
      // Shift the atom indices to be zero-based
      atomi--;
      atomj--;

      /*Load exclusion information into file*/
      exclusions_atom_i.add(atomi);
      exclusions_atom_j.add(atomj);
      numExclusion++;

      /* Reading in exclusions information from file and loading */
      break;
      // End of JLai modifications August 16th, 2012
    }
  }

  fclose(f);
}
Example #18
0
int DisplayDevice::pick(int dim, const float *pos, const VMDDisplayList *cmdList,
			float &eyedist, int *unitcell, float window_size) {
  char *cmdptr = NULL;
  int tok;
  float newEyeDist, currEyeDist = eyedist;
  int tag = (-1), inRegion, currTag;
  float minX=0.0f, minY=0.0f, maxX=0.0f, maxY=0.0f;
  float fminX=0.0f, fminY=0.0f, fminZ=0.0f, fmaxX=0.0f, fmaxY=0.0f, fmaxZ=0.0f;
  float wpntpos[3], pntpos[3], cpos[3];

  if(!cmdList)
    return (-1);

  // initialize picking: find screen region to look for object
  if (dim == 2) {
    fminX = pos[0] - window_size;
    fmaxX = pos[0] + window_size;
    fminY = pos[1] - window_size;
    fmaxY = pos[1] + window_size;
    abs_screen_pos(fminX, fminY);
    abs_screen_pos(fmaxX, fmaxY);
#if defined(_MSC_VER)
    // Win32 lacks the C99 round() routine
    // Add +/- 0.5 then then round towards zero.
#if 1
    minX = (int) ((float) (fminX + (fminX >= 0.0f ?  0.5f : -0.5f)));
    maxX = (int) ((float) (fmaxX + (fmaxX >= 0.0f ?  0.5f : -0.5f)));
    minY = (int) ((float) (fminY + (fminY >= 0.0f ?  0.5f : -0.5f)));
    maxY = (int) ((float) (fmaxY + (fmaxY >= 0.0f ?  0.5f : -0.5f)));
#else
    minX = truncf(fminX + (fminX >= 0.0f ?  0.5f : -0.5f));
    maxX = truncf(fmaxX + (fmaxX >= 0.0f ?  0.5f : -0.5f));
    minY = truncf(fminY + (fminY >= 0.0f ?  0.5f : -0.5f));
    maxY = truncf(fmaxY + (fmaxY >= 0.0f ?  0.5f : -0.5f));
//    minX = floor(fminX + 0.5);
//    maxX = floor(fmaxX + 0.5);
//    minY = floor(fminY + 0.5);
//    maxY = floor(fmaxY + 0.5);
#endif
#else
    minX = round(fminX);
    maxX = round(fmaxX);
    minY = round(fminY);
    maxY = round(fmaxY);
#endif

  } else {
    fminX = pos[0] - window_size;
    fmaxX = pos[0] + window_size;
    fminY = pos[1] - window_size;
    fmaxY = pos[1] + window_size;
    fminZ = pos[2] - window_size;
    fmaxZ = pos[2] + window_size;
  }

  // make sure we do not disturb the regular transformation matrix
  transMat.dup();
  (transMat.top()).multmatrix(cmdList->mat);

  // Transform the current pick point for each periodic image 
  ResizeArray<Matrix4> pbcImages;
  ResizeArray<int> pbcCells;
  find_pbc_images(cmdList, pbcImages);
  find_pbc_cells(cmdList, pbcCells);
  int pbcimg;
  for (pbcimg=0; pbcimg<pbcImages.num(); pbcimg++) {
    transMat.dup();
    (transMat.top()).multmatrix(pbcImages[pbcimg]);

    // scan through the list, getting each command and executing it, until
    // the end of commands token is found
    VMDDisplayList::VMDLinkIter cmditer;
    cmdList->first(&cmditer);
    while((tok = cmdList->next(&cmditer, cmdptr)) != DLASTCOMMAND) {
      switch (tok) {
        case DPICKPOINT:
          // calculate the transformed position of the point
          {
            DispCmdPickPoint *cmd = (DispCmdPickPoint *)cmdptr;
            vec_copy(wpntpos, cmd->postag);
            currTag = cmd->tag;
          }
          (transMat.top()).multpoint3d(wpntpos, pntpos);

          // check if in picking region ... different for 2D and 3D
          if (dim == 2) {
            // convert the 3D world coordinate to 2D (XY) absolute screen 
            // coordinate, and a normalized Z coordinate.
            abs_screen_loc_3D(pntpos, cpos);
      
            // check to see if the projected picking position falls within the 
            // view frustum, with the XY coords falling within the displayed 
            // window, and the Z coordinate falling within the view volume
            // between the front and rear clipping planes.
            inRegion = (cpos[0] >= minX && cpos[0] <= maxX &&
                        cpos[1] >= minY && cpos[1] <= maxY &&
                        cpos[2] >= 0.0  && cpos[2] <= 1.0);
          } else {
            // just check to see if the position is in a box centered on our
            // pointer.  The pointer position should already be transformed.
            inRegion = (pntpos[0] >= fminX && pntpos[0] <= fmaxX &&	
                        pntpos[1] >= fminY && pntpos[1] <= fmaxY &&
                        pntpos[2] >= fminZ && pntpos[2] <= fmaxZ);
          }

          // Clip still-viable pick points against all active clipping planes
          if (inRegion) {
            // We must perform a check against all of the active
            // user-defined clipping planes to ensure that only pick points
            // associated with visible geometry can be selected.
            int cp;
            for (cp=0; cp < VMD_MAX_CLIP_PLANE; cp++) {
              // The final result is the intersection of all of the
              // individual clipping plane tests...
              if (cmdList->clipplanes[cp].mode) {
                float cpdist[3];
                vec_sub(cpdist, wpntpos, cmdList->clipplanes[cp].center);
                inRegion &= (dot_prod(cpdist, 
                                      cmdList->clipplanes[cp].normal) > 0.0f);
              }
            }
          }
      
          // has a hit occurred?
          if (inRegion) {
            // yes, see if it is closer to the eye position than earlier objects
            if(dim==2) 
              newEyeDist = DTOEYE(pntpos[0], pntpos[1], pntpos[2]);
            else 
              newEyeDist = DTOPOINT(pntpos[0],pntpos[1],pntpos[2]);

            if(currEyeDist < 0.0 || newEyeDist < currEyeDist) {
              currEyeDist = newEyeDist;
              tag = currTag;
              if (unitcell) {
                unitcell[0] = pbcCells[3*pbcimg  ];
                unitcell[1] = pbcCells[3*pbcimg+1];
                unitcell[2] = pbcCells[3*pbcimg+2];
              }
            }
          }
          break;

        case DPICKPOINT_ARRAY:
          // loop over all of the pick points in the pick point index array
          DispCmdPickPointArray *cmd = (DispCmdPickPointArray *)cmdptr;
          float *pickpos=NULL;
          float *crds=NULL;
          int *indices=NULL;
          cmd->getpointers(crds, indices); 

          int i;
          for (i=0; i<cmd->numpicks; i++) {
            pickpos = crds + i*3;
            if (cmd->allselected) {
              currTag = i + cmd->firstindex;
            } else {
              currTag = indices[i];
            }
            vec_copy(wpntpos, pickpos);

            (transMat.top()).multpoint3d(pickpos, pntpos);

            // check if in picking region ... different for 2D and 3D
            if (dim == 2) {
              // convert the 3D world coordinate to 2D absolute screen coord
              abs_screen_loc_3D(pntpos, cpos);

              // check to see if the position falls in our picking region
              // including the clipping region (cpos[2])
              inRegion = (cpos[0] >= minX && cpos[0] <= maxX &&
                          cpos[1] >= minY && cpos[1] <= maxY &&
                          cpos[2] >= 0.0  && cpos[2] <= 1.0);
            } else {
              // just check to see if the position is in a box centered on our
              // pointer.  The pointer position should already be transformed.
              inRegion = (pntpos[0] >= fminX && pntpos[0] <= fmaxX &&
                          pntpos[1] >= fminY && pntpos[1] <= fmaxY &&
                          pntpos[2] >= fminZ && pntpos[2] <= fmaxZ);
            }

            // Clip still-viable pick points against all active clipping planes
            if (inRegion) {
              // We must perform a check against all of the active
              // user-defined clipping planes to ensure that only pick points
              // associated with visible geometry can be selected.
              int cp;
              for (cp=0; cp < VMD_MAX_CLIP_PLANE; cp++) {
                // The final result is the intersection of all of the
                // individual clipping plane tests...
                if (cmdList->clipplanes[cp].mode) {
                  float cpdist[3];
                  vec_sub(cpdist, wpntpos, cmdList->clipplanes[cp].center);
                  inRegion &= (dot_prod(cpdist, 
                                        cmdList->clipplanes[cp].normal) > 0.0f);
                }
              }
            }

            // has a hit occurred?
            if (inRegion) {
              // yes, see if it is closer to the eye than earlier hits
              if (dim==2)
                newEyeDist = DTOEYE(pntpos[0], pntpos[1], pntpos[2]);
              else
                newEyeDist = DTOPOINT(pntpos[0],pntpos[1],pntpos[2]);

              if (currEyeDist < 0.0 || newEyeDist < currEyeDist) {
                currEyeDist = newEyeDist;
                tag = currTag;
                if (unitcell) {
                  unitcell[0] = pbcCells[3*pbcimg  ];
                  unitcell[1] = pbcCells[3*pbcimg+1];
                  unitcell[2] = pbcCells[3*pbcimg+2];
                }
              }
            }
          }
          break;
      }
    }

    // Pop the PBC image transform
    transMat.pop();
  } // end of loop over PBC images

  // make sure we do not disturb the regular transformation matrix
  transMat.pop();

  // return result; if tag >= 0, we found something
  eyedist = currEyeDist;
  return tag;
}
void
DrawMolItem::draw_volume_isosurface_lit_points (const VolumetricData * v,
    float isovalue, int stepsize, int thickness)
{
  int x, y, z;
  float *addr;
  float pos[3];
  float xax[3], yax[3], zax[3];
  ResizeArray<float> centers;
  ResizeArray<float> normals;
  ResizeArray<float> colors;

  int i;
  float vorigin[3];
  for (i = 0; i < 3; i++)
  {
    vorigin[i] = float (v->origin[i]);
  }

  int pointcount = 0;
  int usecolor;
  append (DMATERIALON);
  usecolor = draw_volume_get_colorid ();
  const float *cp = scene->color_value (usecolor);
  cmdColorIndex.putdata (usecolor, cmdList);

  // calculate cell axes
  v->cell_axes (xax, yax, zax);

  for (z = 0; z < v->zsize; z += stepsize)
  {
    for (y = 0; y < v->ysize; y += stepsize)
    {
      addr = &(v->data[(z * (v->xsize * v->ysize)) + (y * v->xsize)]);

      // loop through xsize - 1 rather than the full range
      for (x = 0; x < (v->xsize - 1); x += stepsize)
      {
        float diff, isodiff;

        // draw a point if the isovalue falls between neighboring X samples
        diff = addr[x] - addr[x + 1];
        isodiff = addr[x] - isovalue;
        if ((fabs (diff) > fabs (isodiff)) && (MYSGN(diff) == MYSGN(isodiff)))
        {
          pos[0] = vorigin[0] + x * xax[0] + y * yax[0] + z * zax[0];
          pos[1] = vorigin[1] + x * xax[1] + y * yax[1] + z * zax[1];
          pos[2] = vorigin[2] + x * xax[2] + y * yax[2] + z * zax[2];

          float norm[3];
          vec_copy (norm,
              &v->gradient[(z * v->xsize * v->ysize + y * v->xsize + x) * 3]);

          // draw a point there.
          centers.append (pos[0]);
          centers.append (pos[1]);
          centers.append (pos[2]);
          normals.append (norm[0]);
          normals.append (norm[1]);
          normals.append (norm[2]);
          colors.append (cp[0]);
          colors.append (cp[1]);
          colors.append (cp[2]);

          pointcount++;
        }
      }
    }
  }

  if (pointcount > 0)
  {
    DispCmdLitPointArray cmdLitPointArray;
    cmdLitPointArray.putdata ((float *) &centers[0], (float *) &normals[0],
        (float *) &colors[0], (float) thickness, pointcount, cmdList);
  }
}