static PyObject *minmax(PyObject *self, PyObject *args) {
  int molid, frame;
  PyObject *selected;

  if (!PyArg_ParseTuple(args, (char *)"iiO!", 
                        &molid, &frame, &PyTuple_Type, &selected))
    return NULL;  // bad args

  VMDApp *app = get_vmdapp();
  AtomSel *sel = sel_from_py(molid, frame, selected, app);
  if (!sel) return NULL;
  const Timestep *ts = app->moleculeList->mol_from_id(molid)->get_frame(frame); 
  if (!ts) {
    PyErr_SetString(PyExc_ValueError, "No coordinates in selection");
    delete sel;
    return NULL;
  }
  float min[3], max[3];
  int rc = measure_minmax(sel->num_atoms, sel->on, ts->pos, NULL, min, max);
  delete sel;
  if (rc < 0) {
    PyErr_SetString(PyExc_ValueError, measure_error(rc));
    return NULL;
  }
  PyObject *mintuple, *maxtuple, *result;
  mintuple = PyTuple_New(3);
  maxtuple = PyTuple_New(3);
  result = PyTuple_New(2);
  for (int i=0; i<3; i++) {
    PyTuple_SET_ITEM(mintuple, i, PyFloat_FromDouble(min[i]));
    PyTuple_SET_ITEM(maxtuple, i, PyFloat_FromDouble(max[i]));
  }
  PyTuple_SET_ITEM(result, 0, mintuple);
  PyTuple_SET_ITEM(result, 1, maxtuple);
  return result;
}
int measure_surface(AtomSel *sel, MoleculeList *mlist,
                   const float *framepos,
                   const double gridsz, 
                   const double radius,
                   const double depth,
                   int **surface, int *n_surf ) {
   int i;
   
   if (!sel)                     return MEASURE_ERR_NOSEL;
   if (sel->num_atoms == 0)      return MEASURE_ERR_NOATOMS;
   
   // compute the axis aligned aligned bounding box for the selected atoms
   int sel_count = 0;
   for(i=0; i < sel->num_atoms; i++) {
      if (sel->on[i]) {
         sel_count++;
      }
   }
   int *sel_ind = new int[sel_count];
   float *coords = new float[sel_count*3];
   int j=0;
   int k=0;
   int ind=0;
   for(i=0; i < sel->num_atoms; i++) {
      if (sel->on[i]) {
         sel_ind[j++] = i;
         coords[k++] = framepos[ind];
         coords[k++] = framepos[ind+1];
         coords[k++] = framepos[ind+2];
      }
      ind += 3;
   }
   
   Timestep *ts = sel->timestep(mlist);
   double a = ts->a_length;
   double b = ts->b_length;
   double c = ts->c_length;
   double alpha = ts->alpha;
   double beta = ts->beta;
   double gamma = ts->gamma;
   bool periodic = true;
   if (a == 0 || b == 0 || c == 0 
       || alpha == 0 || beta == 0 || gamma == 0) {
     periodic = false;
     float min_coord[3];
     float max_coord[3];
     measure_minmax(sel->num_atoms, sel->on, framepos, NULL, min_coord, max_coord);
     a = max_coord[0] - min_coord[0];
     b = max_coord[1] - min_coord[1];
     c = max_coord[2] - min_coord[2];
     alpha = beta = gamma = 90;
   }
         
   printf("Periodic: %f %f %f %f %f %f\n",a,b,c,alpha,beta,gamma);
   
   measure_surface_int(gridsz, radius, depth, periodic,
                       a,b,c,alpha,beta,gamma,
                       sel_ind,coords,sel_count,
                       surface, n_surf);
   
   printf("Done!\n");
   
   return MEASURE_NOERR;
}