Exemple #1
0
int
main(int argc, char *argv[])
{
  char         **av, *in_surf_fname, *out_fname, fname[STRLEN], *cp ;
  int          ac, nargs, msec, err ;
  MRI_SURFACE  *mris ;
  struct timeb then ;
  float        max_dim ;

  char cmdline[CMD_LINE_LEN] ;

  make_cmd_version_string
  (argc, argv,
   "$Id: mris_sphere.c,v 1.57 2011/03/02 00:04:34 nicks Exp $",
   "$Name: stable5 $", cmdline);

  /* rkt: check for and handle version tag */
  nargs = handle_version_option
          (argc, argv,
           "$Id: mris_sphere.c,v 1.57 2011/03/02 00:04:34 nicks Exp $",
           "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs;

#ifdef FS_CUDA
  /* print GPU device info */
  MRISCdeviceInfo();
#endif // FS_CUDA

  TimerStart(&then) ;
  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  memset(&parms, 0, sizeof(parms)) ;
  parms.dt = .05 ;
  parms.projection = PROJECT_ELLIPSOID ;
  parms.tol = .5 /*1e-1*/ ;
  parms.n_averages = 1024 ;
  parms.min_averages = 0 ;
  parms.l_angle = 0.0 /* L_ANGLE */ ;
  parms.l_area = 0.0 /* L_AREA */ ;
  parms.l_neg = 0.0 ;
  parms.l_dist = 1.0 ;
  parms.l_spring = 0.0 ;
  parms.l_area = 1.0 ;
  parms.l_boundary = 0.0 ;
  parms.l_curv = 0.0 ;
  parms.niterations = 25 ;
  parms.write_iterations = 1000 ;
  parms.a = parms.b = parms.c = 0.0f ;  /* ellipsoid parameters */
  parms.dt_increase = 1.01 /* DT_INCREASE */;
  parms.dt_decrease = 0.99 /* DT_DECREASE*/ ;
  parms.error_ratio = 1.03 /*ERROR_RATIO */;
  parms.integration_type = INTEGRATE_LINE_MINIMIZE ;
  parms.momentum = 0.9 ;
  parms.desired_rms_height = -1.0 ;
  parms.base_name[0] = 0 ;
  parms.Hdesired = 0.0 ;   /* a flat surface */
  parms.nbhd_size = 7 ;
  parms.max_nbrs = 8 ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  parms.scale = scale ;

  if (argc != 3) // catches args beyond the expected two
  {
    usage_exit() ;
  }

  parms.base_dt = base_dt_scale * parms.dt ;
  in_surf_fname = argv[1] ;
  out_fname = argv[2] ;

  printf("%s\n",vcid);
  printf("  %s\n",MRISurfSrcVersion());
  fflush(stdout);

  if (parms.base_name[0] == 0)
  {
    FileNameOnly(out_fname, fname) ;
    cp = strchr(fname, '.') ;
    if (cp)
    {
      strcpy(parms.base_name, cp+1) ;
    }
    else
    {
      strcpy(parms.base_name, "sphere") ;
    }
  }

  mris = MRISread(in_surf_fname) ;
  if (!mris)
    ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s",
              Progname, in_surf_fname) ;

  MRISaddCommandLine(mris, cmdline) ;

  fprintf(stderr, "reading original vertex positions...\n") ;
  if (!FZERO(disturb))
  {
    mrisDisturbVertices(mris, disturb) ;
  }
  if (quick == 0)
  {
    // don't need original properties unless preserving metric
    err = MRISreadOriginalProperties(mris, orig_name) ;
    if(err)
    {
      exit(1);
    }
  }
  if (smooth_avgs > 0)
  {
    MRISsaveVertexPositions(mris, TMP_VERTICES) ;
    MRISrestoreVertexPositions(mris, ORIGINAL_VERTICES) ;
    MRISaverageVertexPositions(mris, smooth_avgs) ;
    MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ;
    MRISrestoreVertexPositions(mris, TMP_VERTICES) ;
  }

  if (!FZERO(ralpha) || !FZERO(rbeta) || !FZERO(rgamma))
  {
    MRISrotate(mris,mris,RADIANS(ralpha),RADIANS(rbeta),RADIANS(rgamma)) ;
    //                if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    MRISwrite(mris, "rot") ;
  }
  fprintf(stderr, "unfolding cortex into spherical form...\n");
  if (talairach)
  {
    MRIStalairachTransform(mris, mris) ;
    MRISwrite(mris, "tal") ;
  }

  if (xform_fname)
  {
    LTA *lta ;
    MRI *mri ;
    TRANSFORM transform ;

    lta = LTAread(xform_fname) ;
    if (lta == NULL)
    {
      ErrorExit(ERROR_NOFILE, "%s: could not load %s", xform_fname) ;
    }
    mri = MRIread(vol_fname) ;
    if (mri == NULL)
    {
      ErrorExit(ERROR_NOFILE, "%s: could not load %s", vol_fname) ;
    }
    transform.type = lta->type ;
    transform.xform = (void *)lta ;
    MRIStransform(mris, mri, &transform, mri) ;
    MRIfree(&mri) ;
    LTAfree(&lta) ;
    MRISwrite(mris, "xfm") ;
  }
#if 0
  max_dim = MAX(abs(mris->xlo), abs(mris->xhi)) ;
  max_dim = MAX(abs(max_dim), abs(mris->ylo)) ;
  max_dim = MAX(abs(max_dim), abs(mris->yhi)) ;
  max_dim = MAX(abs(max_dim), abs(mris->zlo)) ;
  max_dim = MAX(abs(max_dim), abs(mris->zhi)) ;
#else
  max_dim = MAX(abs(mris->xhi-mris->xlo), abs(mris->yhi-mris->ylo)) ;
  max_dim = MAX(max_dim,abs(mris->zhi-mris->zlo)) ;
#endif
  if (max_dim > .75*DEFAULT_RADIUS)
  {
    float ratio = .75*DEFAULT_RADIUS / (max_dim) ;
    printf("scaling brain by %2.3f...\n", ratio) ;
    MRISscaleBrain(mris, mris, ratio) ;
  }

  if (target_radius < 0)
  {
    target_radius = sqrt(mris->total_area / (4*M_PI)) ;
    printf("setting target radius to be %2.3f to match surface areas\n",
           target_radius) ;
  }
  //  MRISsampleAtEachDistance(mris, parms.nbhd_size, parms.max_nbrs) ;
  if (!load && inflate)
  {
    INTEGRATION_PARMS inflation_parms ;

    MRIScenter(mris, mris) ;
    memset(&inflation_parms, 0, sizeof(INTEGRATION_PARMS)) ;
    strcpy(inflation_parms.base_name, parms.base_name) ;
    inflation_parms.write_iterations = parms.write_iterations ;
    inflation_parms.niterations = inflate_iterations ;
    inflation_parms.l_spring_norm = l_spring_norm ;
    inflation_parms.l_spring = inflate_spring ;
    inflation_parms.l_nlarea = inflate_nlarea ;
    inflation_parms.l_area = inflate_area ;
    inflation_parms.n_averages = inflate_avgs ;
    inflation_parms.l_expand = l_expand ;
    inflation_parms.l_tspring = inflate_tspring ;
    inflation_parms.l_sphere = l_sphere ;
    inflation_parms.l_convex = l_convex ;
#define SCALE_UP 2
    inflation_parms.a = SCALE_UP*DEFAULT_RADIUS ;
    inflation_parms.tol = inflate_tol ;
    inflation_parms.integration_type = INTEGRATE_MOMENTUM ;
    inflation_parms.momentum = 0.9 ;
    inflation_parms.dt = inflate_dt ;

    /* store the inflated positions in the v->c? field so that they can
      be used in the repulsive term.
    */
    /*    inflation_parms.l_repulse_ratio = .1 ;*/
    MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ;
    if (l_expand > 0)
    {
      MRISexpandSurface(mris, target_radius/2, &inflation_parms, 0, 1) ;
      l_expand = parms.l_expand = 0 ;
    }
    MRIScenter(mris, mris) ;
    mris->x0 = mris->xctr ;
    mris->y0 = mris->yctr ;
    mris->z0 = mris->zctr ;
    MRISinflateToSphere(mris, &inflation_parms) ;
    if (inflation_parms.l_expand > 0)
    {
      inflation_parms.l_expand = 0 ;
      inflation_parms.niterations += (inflate_iterations*.1) ;
      MRISinflateToSphere(mris, &inflation_parms) ;
    }
    MRISscaleBrain(mris, mris, target_radius/(DEFAULT_RADIUS*SCALE_UP)) ;
    parms.start_t = inflation_parms.start_t ;
    MRISresetNeighborhoodSize(mris, nbrs) ;
  }

  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
  {
    MRISwrite(mris, "before") ;
  }
  MRISprojectOntoSphere(mris, mris, target_radius) ;
  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
  {
    MRISwrite(mris, "after") ;
  }
  fprintf(stderr,"surface projected - minimizing metric distortion...\n");
  MRISsetNeighborhoodSize(mris, nbrs) ;
  if (quick)
  {
    if (!load)
    {
#if 0
      parms.n_averages = 32 ;
      parms.tol = .1 ;
      parms.l_parea = parms.l_dist = 0.0 ;
      parms.l_nlarea = 1 ;
#endif
      MRISprintTessellationStats(mris, stderr) ;
      MRISquickSphere(mris, &parms, max_passes) ;
    }
  }
  else
  {
    MRISunfold(mris, &parms, max_passes) ;
  }
  if (remove_negative)
  {
    parms.niterations = 1000 ;
    MRISremoveOverlapWithSmoothing(mris,&parms) ;
  }
  if (!load)
  {
    fprintf(stderr, "writing spherical brain to %s\n", out_fname) ;
    MRISwrite(mris, out_fname) ;
  }

  msec = TimerStop(&then) ;
  fprintf(stderr, "spherical transformation took %2.2f hours\n",
          (float)msec/(1000.0f*60.0f*60.0f));
  exit(0) ;
  return(0) ;  /* for ansi */
}
int
main(int argc, char *argv[]) {
  char          **av, *hemi, *subject_name, *cp, fname[STRLEN];
  char          *parc_name, *annot_name ;
  int           ac, nargs, vno, i ;
  MRI_SURFACE   *mris ;
  MRI           *mri_parc ;
  VERTEX        *v ;
  double        d ;
  Real          x, y, z, xw, yw, zw ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv,
                                 "$Id: mris_sample_parc.c,v 1.31 2016/12/11 14:33:38 fischl Exp $", "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc < 4)
    usage_exit() ;

  subject_name = argv[1] ;
  hemi = argv[2] ;
  parc_name = argv[3] ;
  annot_name = argv[4] ;

  if (strlen(sdir) == 0)  /* if not specified explicitly as option */
  {
    cp = getenv("SUBJECTS_DIR") ;
    if (!cp)
      ErrorExit(ERROR_BADPARM,
                "%s: SUBJECTS_DIR not defined in environment.\n", Progname) ;
    strcpy(sdir, cp) ;
  }

  if (parc_name[0] == '/')  // full path specified
    strcpy(fname, parc_name) ;
  else
    sprintf(fname, "%s/%s/mri/%s", sdir, subject_name, parc_name) ;
  printf("reading parcellation volume from %s...\n", fname) ;
  mri_parc = MRIread(fname) ;
  if (!mri_parc)
    ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s",
              Progname, fname) ;

  if (mask_fname) {
    MRI *mri_mask, *mri_tmp ;

    mri_tmp = MRIread(mask_fname) ;
    if (mri_tmp == NULL)
      ErrorExit(ERROR_BADPARM, "%s: could not load mask volume %s", Progname, mask_fname) ;
    mri_mask = MRIclone(mri_tmp, NULL) ;
    MRIcopyLabel(mri_tmp, mri_mask, mask_val) ;
    MRIdilate(mri_mask, mri_mask) ;
    MRIdilate(mri_mask, mri_mask) ;
    MRIdilate(mri_mask, mri_mask) ;
    MRIdilate(mri_mask, mri_mask) ;
    MRIfree(&mri_tmp) ;
    mri_tmp = MRIclone(mri_parc, NULL) ;
    MRIcopyLabeledVoxels(mri_parc, mri_mask, mri_tmp, mask_val) ;
    MRIfree(&mri_parc) ;
    mri_parc = mri_tmp ;
    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
      MRIwrite(mri_parc, "p.mgz") ;
    MRIfree(&mri_mask) ;
  }

  for (i = 0 ; i < ntrans ; i++) {
    MRIreplaceValues(mri_parc, mri_parc, trans_in[i], trans_out[i]) ;
  }
  sprintf(fname, "%s/%s/surf/%s.%s", sdir, subject_name, hemi, surf_name) ;
  printf("reading input surface %s...\n", fname) ;
  mris = MRISread(fname) ;
  if (!mris)
    ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s",
              Progname, fname) ;
  MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ;
  MRIScomputeMetricProperties(mris) ;
  if (avgs > 0)
    MRISaverageVertexPositions(mris, avgs) ;

  if (FZERO(proj_mm)) {
    if (MRISreadCurvatureFile(mris, thickness_name) != NO_ERROR)
      ErrorExit(ERROR_NOFILE, "%s: could not read thickness file %s",
                Progname, thickness_name) ;
  }

  if (color_table_fname) {
    mris->ct = CTABreadASCII(color_table_fname) ;
    if (mris->ct == NULL)
      ErrorExit(ERROR_NOFILE, "%s: could not read color file %s",
                Progname, color_table_fname) ;
  }

  if (sample_from_vol_to_surf) // sample from volume to surface */
  {
    MRIsampleParcellationToSurface(mris, mri_parc) ;
  } else  /* sample from surface to volume */
  {
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->ripflag)
        continue ;
      if (vno == Gdiag_no)
        DiagBreak() ;

      if (!FZERO(proj_mm))
        d = proj_mm ;
      else
        d = v->curv*proj_frac ;  /* halfway out */
      x = v->x+d*v->nx ;
      y = v->y+d*v->ny ;
      z = v->z+d*v->nz ;
      MRIsurfaceRASToVoxel(mri_parc, x, y, z, &xw, &yw, &zw) ;
      v->annotation = v->val =
                        MRIfindNearestNonzero(mri_parc, wsize, xw, yw, zw, ((float)wsize-1)/2) ;
      if (v->val == 0xffffffff)
        DiagBreak() ;
    }
  }
  if (replace_label)
    replace_vertices_with_label(mris, mri_parc, replace_label, proj_mm);
  if (unknown_label >= 0) {
    LABEL **labels, *label ;
    int   nlabels, i, biggest_label, most_vertices, nzero ;

#define TMP_LABEL 1000
    for (nzero = vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->annotation == 0) {
        v->annotation = TMP_LABEL;
        nzero++ ;
      }
    }
    printf("%d unknown vertices found\n", nzero) ;
    MRISsegmentAnnotated(mris, &labels, &nlabels, 10) ;
    most_vertices = 0 ;
    biggest_label = -1 ;
    for (i = 0 ; i < nlabels ; i++) {
      label = labels[i] ;
      if (mris->vertices[label->lv[0].vno].annotation == TMP_LABEL) {
        if (label->n_points > most_vertices) {
          biggest_label = i ;
          most_vertices = label->n_points ;
        }
      }
    }
    if (biggest_label >= 0) {
      label = labels[biggest_label] ;
      printf("replacing label # %d with %d vertices "
             "(vno=%d) with label %d\n",
             biggest_label,
             label->n_points,
             label->lv[0].vno,
             unknown_label) ;
      for (i = 0 ; i < label->n_points ; i++) {
        v = &mris->vertices[label->lv[i].vno] ;
        v->annotation = v->val = unknown_label ;
      }
    }
    for (nzero = vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->annotation == TMP_LABEL) {
        v->annotation = 0;
        nzero++ ;
      }
    }
    printf("after replacement, %d unknown vertices found\n", nzero) ;
    MRISmodeFilterZeroVals(mris) ;  /* get rid of the rest
                                    of the unknowns by mode filtering */
    for (i = 0 ; i < nlabels ; i++)
      LabelFree(&labels[i]) ;
    free(labels) ;
  }

  MRIScopyValsToAnnotations(mris) ;
  if (fix_topology != 0)
    fix_label_topology(mris, fix_topology) ;

  if (mode_filter) {
    printf("mode filtering sample labels...\n") ;
#if 0
    MRISmodeFilterZeroVals(mris) ;
#else
    MRISmodeFilterVals(mris, mode_filter) ;
#endif
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->ripflag)
        continue ;
      v->annotation = v->val ;
    }
  }

  /* this will fill in the v->annotation field from the v->val ones */
  translate_indices_to_annotations(mris, translation_fname) ;

  if (label_index >= 0)
  {
    int index ;
    LABEL *area ;

    printf("writing label to %s...\n", annot_name) ;
    MRISclearMarks(mris) ;
    for (vno = 0 ; vno < mris->nvertices ; vno++)
    {
      if (vno == Gdiag_no)
        DiagBreak() ;
      v = &mris->vertices[vno] ;
      if (v->annotation > 0)
        DiagBreak() ;
      CTABfindAnnotation(mris->ct, v->annotation, &index);
      if (index == label_index)
        v->marked = 1 ;
    }
    area = LabelFromMarkedSurface(mris) ;
    if (nclose > 0)
    {
      LabelDilate(area, mris, nclose, CURRENT_VERTICES) ;
      LabelErode(area, mris, nclose) ;
    }
    LabelWrite(area, annot_name) ;
  }
  else
  {
    printf("writing annotation to %s...\n", annot_name) ;
    MRISwriteAnnotation(mris, annot_name) ;
  }
  /*  MRISreadAnnotation(mris, fname) ;*/
  exit(0) ;

  return(0) ;  /* for ansi */
}
Exemple #3
0
int
main(int argc, char *argv[])
{
  char               **av, *in_fname, *out_fname, fname[STRLEN], path[STRLEN] ;
  int                ac, nargs, start_t, pass ;
  MRI_SURFACE        *mris ;

  char cmdline[CMD_LINE_LEN] ;

  make_cmd_version_string
  (argc, argv,
   "$Id: mris_smooth.c,v 1.28 2011/03/02 00:04:34 nicks Exp $",
   "$Name: stable5 $", cmdline);

  /* rkt: check for and handle version tag */
  nargs = handle_version_option
          (argc, argv,
           "$Id: mris_smooth.c,v 1.28 2011/03/02 00:04:34 nicks Exp $",
           "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs;

  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc < 3)
  {
    print_help() ;
  }

  in_fname = argv[1] ;
  out_fname = argv[2] ;
  FileNamePath(out_fname, path) ;

  mris = MRISfastRead(in_fname) ;
  if (!mris)
    ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s",
              Progname, in_fname) ;

  MRISaddCommandLine(mris, cmdline) ;
  MRISremoveTriangleLinks(mris) ;
  fprintf(stderr, "smoothing surface tessellation for %d iterations...\n",
          niterations);

  MRIScomputeMetricProperties(mris) ;
  MRISstoreMetricProperties(mris) ;
  MRISsetNeighborhoodSize(mris, nbrs) ;
#define DT 0.5
  if (gaussian_norm > 0)
  {
    int i, done, start_avgs = gaussian_avgs, j ;

    done = 0;
    start_t = 0 ;
    pass = 0 ;
    do
    {
      for (i = start_t ; i < niterations+start_t ; i++)
      {
        MRIScomputeMetricProperties(mris) ;
        MRISsaveVertexPositions(mris, TMP_VERTICES) ;
        for (j = 0 ; j < 5 ; j++)
        {
          MRISaverageVertexPositions(mris, 2) ; // turn flat spikes into tubular ones
          MRIScomputeMetricProperties(mris) ;
          MRIScomputeSecondFundamentalForm(mris) ;
          MRIShistoThresholdGaussianCurvatureToMarked(mris, (float)(mris->nvertices-20)/mris->nvertices) ;
        }
        MRISrestoreVertexPositions(mris, TMP_VERTICES) ;
        MRIScomputeMetricProperties(mris) ;
        MRISsmoothSurfaceNormals(mris, gaussian_avgs) ;
        MRISclearMarks(mris) ;
        MRISthresholdGaussianCurvatureToMarked(mris, 10, 50);
        MRIScomputeSecondFundamentalForm(mris) ;
        MRIShistoThresholdGaussianCurvatureToMarked(mris, (float)(mris->nvertices-20)/mris->nvertices) ;
        MRISthresholdGaussianCurvatureToMarked(mris, 10, 50);
        if ((write_iterations > 0) && ((i % write_iterations) == 0))
        {
          char fname[STRLEN] ;

          sprintf(fname, "%s%04d", out_fname, i) ;
          printf("writing snapshot to %s...\n", fname) ;
          MRISwrite(mris, fname) ;
          if (Gdiag & DIAG_WRITE)
          {
            MRISuseGaussianCurvature(mris) ;
            sprintf(fname, "%s_K%04d", out_fname, i) ;
            printf("writing curvature to %s...\n", fname) ;
            MRISwriteCurvature(mris, fname) ;
            sprintf(fname, "%s_marked%04d", out_fname, i) ;
            printf("writing marks to %s...\n", fname) ;
            MRISwriteMarked(mris, fname) ;
          }
        }
        for (j = 0 ; j <= 5*nint(1/DT) ; j++)
        {
          MRISmarkedSpringTerm(mris, l_spring) ;
          MRISaverageGradients(mris, gaussian_avgs) ;
          MRISmomentumTimeStep(mris, momentum, DT, 1, gaussian_avgs) ;
          MRISclearGradient(mris) ;
          MRIScomputeMetricProperties(mris) ;
          MRISsmoothSurfaceNormals(mris, gaussian_avgs) ;
          {
            int vno ;
            VERTEX *v ;

            for (vno = 0 ; vno < mris->nvertices ; vno++)
            {
              v = &mris->vertices[vno] ;
              if (v->marked > 0)
              {
                v->K = 1.0/(v->marked) ;
              }
              else
              {
                v->K = 0 ;
              }
            }
          }
        }
      }
      MRISclearGradient(mris) ;
      if (gaussian_avgs == 2)
      {
        if (pass++ > 4)
        {
          done = 1 ;
        }
        else
        {
          int num = count_big_curvatures(mris, 2) ;
          printf("------------------------------------------------------\n") ;
          printf("------------------------------------------------------\n") ;
          printf("------------------ pass %d (num=%d) ------------------\n",
                 pass, num) ;
          printf("------------------------------------------------------\n") ;
          printf("------------------------------------------------------\n") ;
          gaussian_avgs = start_avgs ;
        }
      }
      else
      {
        gaussian_avgs /= 2 ;
        if (done ==0)
        {
          printf("----------------- setting avgs to %d -----------------\n", gaussian_avgs) ;
        }
      }
      start_t = i ;
    }
    while (!done) ;

#if 0
    // more smoothing with principal curvatures
    gaussian_avgs = start_avgs ;
    printf("--------------------------------------------------------------------------\n") ;
    printf("--------------------------------------------------------------------------\n") ;
    printf("---------------------- starting threshold smoothing ----------------------\n") ;
    printf("--------------------------------------------------------------------------\n") ;
    printf("--------------------------------------------------------------------------\n") ;
    do
    {
      for (i = start_t ; i < niterations+start_t ; i++)
      {
        MRIScomputeMetricProperties(mris) ;
        MRIScomputeSecondFundamentalForm(mris) ;
        MRISsmoothSurfaceNormals(mris, 16) ;
#define KTHRESH 1.5  // everything with kmin less than this will not move
        MRISthresholdPrincipalCurvatures(mris, KTHRESH) ;
        MRISspringTermWithGaussianCurvature(mris, gaussian_norm, l_spring) ;
        MRISaverageGradients(mris, gaussian_avgs) ;
        MRISmomentumTimeStep(mris, 0, 0.1, 1, gaussian_avgs) ;
        MRISclearGradient(mris) ;
        if ((write_iterations > 0) && (((i+1) % write_iterations) == 0))
        {
          char fname[STRLEN] ;

          sprintf(fname, "%s%04d", out_fname, i+1) ;
          printf("writing snapshot to %s...\n", fname) ;
          MRISwrite(mris, fname) ;
          if (Gdiag & DIAG_WRITE/* && DIAG_VERBOSE_ON*/)
          {
            MRISuseGaussianCurvature(mris) ;
            sprintf(fname, "%s_K%04d", out_fname, i+1) ;
            printf("writing curvature to %s...\n", fname) ;
            MRISwriteCurvature(mris, fname) ;
          }
        }
      }
      MRISclearGradient(mris) ;
      done = (gaussian_avgs == 2) ;
      gaussian_avgs /= 2 ;
      if (done ==0)
      {
        printf("---------------------- setting avgs to %d ----------------------\n", gaussian_avgs) ;
      }
      start_t = i ;
    }
    while (!done) ;
#endif
  }
  else
  {
    MRISaverageVertexPositions(mris, niterations) ;
  }

  fprintf(stderr, "smoothing complete - recomputing first and second "
          "fundamental forms...\n") ;
  MRIScomputeMetricProperties(mris) ;

  if (rescale)
  {
    MRISscaleBrainArea(mris) ;
  }
  MRIScomputeSecondFundamentalForm(mris) ;
  MRISuseMeanCurvature(mris) ;
  MRISaverageCurvatures(mris, navgs) ;
  if (normalize_flag)
  {
    MRISnormalizeCurvature(mris, which_norm) ;
  }
  sprintf(fname, "%s.%s", mris->hemisphere == LEFT_HEMISPHERE?"lh":"rh",
          curvature_fname);
  if (no_write == 0)
  {
    fprintf(stderr, "writing smoothed curvature to %s/%s\n", path,fname) ;
    MRISwriteCurvature(mris, fname) ;
    sprintf(fname, "%s.%s", mris->hemisphere == LEFT_HEMISPHERE?"lh":"rh",
            area_fname);
    fprintf(stderr, "writing smoothed area to %s/%s\n", path, fname) ;
    MRISwriteArea(mris, fname) ;
  }

  if (Gdiag & DIAG_SHOW)
  {
    fprintf(stderr, "writing smoothed surface to %s\n", out_fname) ;
  }
  MRISwrite(mris, out_fname) ;
  exit(0) ;
  return(0) ;  /* for ansi */
}