Example #1
0
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 */
}
Example #2
0
int
main(int argc, char *argv[])
{
  char        **av, *in_fname, *out_fname ;
  int         ac, nargs, i, label ;
  MRI         *mri_in, *mri_out, *mri_kernel, *mri_smoothed ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option
          (argc, argv,
           "$Id: mri_extract_label.c,v 1.13 2011/03/02 00:04:15 nicks 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() ;

  in_fname = argv[1] ;
  out_fname = argv[argc-1] ;

  printf("reading volume from %s...\n", in_fname) ;
  mri_in = MRIread(in_fname) ;
  if (!mri_in)
    ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume %s", Progname,
              in_fname) ;
  if (out_like_fname)
  {
    MRI *mri_tmp = MRIread(out_like_fname) ;
    if (!mri_tmp)
      ErrorExit
      (ERROR_NOFILE,
       "%s: could not read template volume from %s",
       out_like_fname) ;
    mri_out = MRIalloc(mri_tmp->width,
                       mri_tmp->height,
                       mri_tmp->depth,
                       mri_tmp->type) ;
    /*    MRIcopyHeader(mri_tmp, mri_out) ;*/
    MRIfree(&mri_tmp) ;
  }
  else
    mri_out = MRIclone(mri_in, NULL) ;

  for (i = 2 ; i < argc-1 ; i++)
  {
    label = atoi(argv[i]) ;
    printf("extracting label %d (%s)\n", label, cma_label_to_name(label)) ;
    extract_labeled_image(mri_in, transform, label, mri_out) ;
  }
  if (!FZERO(sigma))
  {
    printf("smoothing extracted volume...\n") ;
    mri_kernel = MRIgaussian1d(sigma, 10*sigma) ;
    mri_smoothed = MRIconvolveGaussian(mri_out, NULL, mri_kernel) ;
    MRIfree(&mri_out) ;
    mri_out = mri_smoothed ;
  }
  /* removed for gcc3.3
   * vsprintf(out_fname, out_fname, (va_list) &label) ;
   */
  if (dilate > 0)
  {
    int i ;
    printf("dilating output volume %d times...\n", dilate) ;
    for (i = 0 ; i < dilate ; i++)
      MRIdilate(mri_out, mri_out) ;
  }
  if (erode > 0)
  {
    int i ;
    printf("eroding output volume %d times...\n", erode) ;
    for (i = 0 ; i < erode ; i++)
      MRIerode(mri_out, mri_out) ;
  }
  printf("writing output to %s.\n", out_fname) ;
  MRIwrite(mri_out, out_fname) ;

  if (exit_none_found && (nvoxels == 0))
  {
    printf("No voxels with specified label were found!\n");
    exit(1);
  }

  exit(0) ;
  return(0) ;  /* for ansi */
}
static MRI *
MRIcomputeSurfaceDistanceProbabilities(MRI_SURFACE *mris,  MRI *mri_ribbon, MRI *mri, MRI *mri_aseg) 
{
  MRI          *mri_features, *mri_binary, *mri_white_dist, *mri_pial_dist, *mri_mask ;
  int          nwhite_bins, npial_bins, x, y, z, label, i ;
  HISTOGRAM2D *hw, *hp ; 
  float        pdist, wdist, val ;
  double       wval, pval ;

  mri_features = MRIallocSequence(mri->width, mri->height, mri->depth, MRI_FLOAT, 2) ;
  MRIcopyHeader(mri, mri_features) ;

  mri_binary = MRIcopy(mri_ribbon, NULL) ;
  mri_binary = MRIbinarize(mri_ribbon, NULL, 1, 0, 1) ;
  mri_pial_dist = MRIdistanceTransform(mri_binary, NULL, 1, max_pial_dist+1, DTRANS_MODE_SIGNED,NULL);
  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    MRIwrite(mri_pial_dist, "pd.mgz") ;

  MRIclear(mri_binary) ;
  MRIcopyLabel(mri_ribbon, mri_binary, Left_Cerebral_White_Matter) ;
  MRIcopyLabel(mri_ribbon, mri_binary, Right_Cerebral_White_Matter) ;
  MRIbinarize(mri_binary, mri_binary, 1, 0, 1) ;
  mri_white_dist = MRIdistanceTransform(mri_binary, NULL, 1, max_white_dist+1, DTRANS_MODE_SIGNED,NULL);
  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    MRIwrite(mri_white_dist, "wd.mgz") ;

  nwhite_bins = ceil((max_white_dist - min_white_dist) / white_bin_size)+1 ;
  npial_bins = ceil((max_pial_dist - min_pial_dist) / pial_bin_size)+1 ;
  hw = HISTO2Dalloc(NBINS, nwhite_bins) ;
  hp = HISTO2Dalloc(NBINS, npial_bins) ;

  HISTO2Dinit(hw, NBINS, nwhite_bins, 0, NBINS-1, min_white_dist, max_white_dist) ;
  HISTO2Dinit(hp, NBINS, npial_bins, 0, NBINS-1, min_pial_dist, max_pial_dist) ;

  for (x = 0 ; x < mri->width ; x++)
    for (y = 0 ; y < mri->height ; y++)
      for (z = 0 ; z < mri->depth ; z++)
      {
	label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ;
	if (IS_CEREBELLUM(label) || IS_VENTRICLE(label) || label == Brain_Stem || IS_CC(label))
	  continue ;
	pdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ;
	wdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ;
	val  = MRIgetVoxVal(mri, x, y, z, 0) ;
	if (pdist >= min_pial_dist && pdist <= max_pial_dist)
	  HISTO2DaddSample(hp, val, pdist, 0, 0, 0, 0) ;
	if (wdist >= min_white_dist && wdist <= max_white_dist)
	  HISTO2DaddSample(hw, val, wdist, 0, 0, 0, 0) ;
      }
  HISTO2DmakePDF(hp, hp) ;
  HISTO2DmakePDF(hw, hw) ;
  for (x = 0 ; x < mri->width ; x++)
    for (y = 0 ; y < mri->height ; y++)
      for (z = 0 ; z < mri->depth ; z++)
      {
	label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ;
	if (IS_CEREBELLUM(label) || IS_VENTRICLE(label) || label == Brain_Stem || IS_CC(label))
	  continue ;
	pdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ;
	wdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ;
	val  = MRIgetVoxVal(mri, x, y, z, 0) ;
	wval = HISTO2DgetCount(hw, val, wdist);
	if (DZERO(wval) == 0)
	  MRIsetVoxVal(mri_features, x, y, z, 1, -log10(wval)) ;
	pval = HISTO2DgetCount(hp, val, pdist);
	if (DZERO(pval) == 0)
	  MRIsetVoxVal(mri_features, x, y, z, 0, -log10(pval)) ;
      }

  MRIclear(mri_binary) ;
  MRIbinarize(mri_ribbon, mri_binary, 1, 0, 1) ;
  mri_mask = MRIcopy(mri_binary, NULL) ;
  for (i = 0 ; i < close_order ; i++)
  {
    MRIdilate(mri_binary, mri_mask) ;
    MRIcopy(mri_mask, mri_binary) ;
  }
  
  for (i = 0 ; i < close_order ; i++)
  {
    MRIerode(mri_binary, mri_mask) ;
    MRIcopy(mri_mask, mri_binary) ;
  }

  MRIwrite(mri_mask, "m.mgz") ;
  MRImask(mri_features, mri_mask, mri_features, 0, 0) ;
  HISTO2Dfree(&hw) ;
  HISTO2Dfree(&hp) ;
  MRIfree(&mri_white_dist) ; MRIfree(&mri_pial_dist) ; MRIfree(&mri_binary) ;
  return(mri_features) ;
}
static int
initialize_surface_position(MRI_SURFACE *mris, MRI *mri_masked, int outside, INTEGRATION_PARMS *parms) {
  MRI    *mri_dilated ;
  int    x, y, z, vno ;
  double x0, y0, z0, radius = 0, dist, num ;
  Real   xs, ys, zs ;
  VERTEX *v ;

  if (outside) {
    mri_dilated = MRIdilate(mri_masked, NULL) ;

    MRIsubtract(mri_dilated, mri_masked, mri_dilated) ;
    MRIwrite(mri_dilated, "outside.mgz") ;

    num = x0 = y0 = z0 = 0 ;
    for (x = 0 ; x < mri_dilated->width ; x++) {
      for (y = 0 ; y < mri_dilated->height ; y++) {
        for (z = 0 ; z < mri_dilated->depth ; z++) {
          if (MRIgetVoxVal(mri_dilated, x, y, z,0) > 0) {
            MRIvoxelToSurfaceRAS(mri_dilated, x, y, z, &xs, &ys, &zs) ;
            x0 += xs ;
            y0 += ys ;
            z0 += zs ;
            num++ ;
          }
        }
      }
    }
    x0 /= num ;
    y0 /= num ;
    z0 /= num ;
    printf("centroid at (%2.1f, %2.1f, %2.1f)\n", x0,  y0, z0) ;

    num = radius = 0 ;
    for (x = 0 ; x < mri_dilated->width ; x++) {
      for (y = 0 ; y < mri_dilated->height ; y++) {
        for (z = 0 ; z < mri_dilated->depth ; z++) {
          if (MRIgetVoxVal(mri_dilated, x, y, z,0) > 0) {
            MRIvoxelToSurfaceRAS(mri_dilated, x, y, z, &xs, &ys, &zs) ;
            dist = sqrt(SQR(xs-x0)+SQR(ys-y0)+SQR(zs-z0)) ;
            radius += dist ;
            num++ ;
          }
        }
      }
    }

    radius /= num ;
    printf("average radius = %2.3f\n", radius) ;


    MRIfree(&mri_dilated) ;
    MRISprojectOntoSphere(mris, mris, radius*1.25) ;
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      v->x += x0 ;
      v->y += y0 ;
      v->z += z0 ;
    }
    MRIScomputeMetricProperties(mris) ;
  }
  parms->target_radius = radius ;
  MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ;
  return(NO_ERROR) ;
}
Example #5
0
static RANDOM_FOREST *
train_rforest(MRI *mri_inputs[MAX_SUBJECTS][MAX_TIMEPOINTS], MRI *mri_segs[MAX_SUBJECTS][MAX_TIMEPOINTS], TRANSFORM *transforms[MAX_SUBJECTS][MAX_TIMEPOINTS], 
	      int nsubjects, GCA *gca, RFA_PARMS *parms, float wm_thresh,
	      int wmsa_whalf, int ntp) 
{
  RANDOM_FOREST  *rf ;
  int            nfeatures, x, y, z, ntraining, n, tvoxel_size, width, height, depth, xt, yt, zt ;
  double         xatlas, yatlas, zatlas ;
  MRI            *mri_in, *mri_seg, *mri_training_voxels, *mri_wmsa_possible ;
  TRANSFORM      *transform ;
  double         **training_data ;
  int            *training_classes, i, label, tlabel, nwmsa, nfuture, nnot, correct, label_time1, label_time2;

  nwmsa = nnot = nfuture = 0 ;

/*
  features are:
  t1 intensity (3 vols)
  3 priors
  # of unknown voxels in the nbhd
  # of neighboring wmsa voxels at t1
*/
  nfeatures = parms->wsize*parms->wsize*parms->wsize*parms->nvols + 5 ; 

  rf = RFalloc(parms->ntrees, nfeatures, NCLASSES, parms->max_depth, single_classifier_names, max_steps) ;
  if (rf == NULL)
    ErrorExit(ERROR_NOFILE, "%s: could not allocate random forest", Progname) ;
  rf->min_step_size = 1 ; 

  tvoxel_size=1 ;
  width = (int)ceil((float)mri_segs[0][0]->width/tvoxel_size) ;
  height = (int)ceil((float)mri_segs[0][0]->height/tvoxel_size) ;
  depth = (int)ceil((float)mri_segs[0][0]->depth/tvoxel_size) ;
  mri_wmsa_possible = MRIalloc(width, height, depth, MRI_UCHAR) ;
  GCAcopyDCToMRI(gca, mri_wmsa_possible) ;
  mri_in = mri_inputs[0][0] ;
  mri_training_voxels = MRIallocSequence(mri_in->width,mri_in->height, mri_in->depth,MRI_UCHAR,nsubjects) ;

#if 1
  // update time 1 segmentation based on labels at time1 and time2
  for (n = 0 ; n < nsubjects ; n++)
  {
    mri_seg = mri_segs[n][0] ;
    for (x = 0 ; x < mri_in->width ; x++)
      for (y = 0 ; y < mri_in->height ; y++)
	for (z = 0 ; z < mri_in->depth ; z++)
	{
	  label_time1 = MRIgetVoxVal(mri_segs[n][0], x, y, z, 0) ;
	  label_time2 = MRIgetVoxVal(mri_segs[n][1], x, y, z, 0) ;
	  if (IS_WMSA(label_time1))
	    MRIsetVoxVal(mri_segs[n][0], x, y, z, 0, label_time1) ;
	  else if (IS_WMSA(label_time2))
	    MRIsetVoxVal(mri_segs[n][0], x, y, z, 0, future_WMSA) ;
	}
  }
#endif

  // build map of spatial locations that WMSAs can possibly occur in
  for (n = 0 ; n < nsubjects ; n++)
  {
    mri_in = mri_inputs[n][1] ; transform = transforms[n][1] ; 
    for (x = 0 ; x < mri_in->width ; x++)
      for (y = 0 ; y < mri_in->height ; y++)
	for (z = 0 ; z < mri_in->depth ; z++)
	  if (is_possible_wmsa(gca, mri_in, transform, x, y, z, 0))
	  {
	    TransformSourceVoxelToAtlas(transform, mri_in, x, y, z, &xatlas, &yatlas, &zatlas) ;
	    xt = nint(xatlas/tvoxel_size) ;
	    yt = nint(yatlas/tvoxel_size) ;
	    zt = nint(zatlas/tvoxel_size) ;
	    if (xt == Gx && yt == Gy && zt == Gz)
	      DiagBreak() ;
	    MRIsetVoxVal(mri_wmsa_possible, xt, yt, zt, 0, 1) ;
	  }
  }
  for ( ; wmsa_whalf > 0 ; wmsa_whalf--)
    MRIdilate(mri_wmsa_possible, mri_wmsa_possible) ;

  // now build map of all voxels in training set
  for (nnot = nwmsa = nfuture = ntraining = n = 0 ; n < nsubjects ; n++)
  {
    mri_in = mri_inputs[n][0] ; mri_seg = mri_segs[n][0] ; transform = transforms[n][0] ;
    for (x = 0 ; x < mri_in->width ; x++)
      for (y = 0 ; y <  mri_in->height; y++)
	for (z = 0 ; z <  mri_in->depth; z++)
	{
	  label = MRIgetVoxVal(mri_seg, x, y, z, 0) ;
	  
	  TransformSourceVoxelToAtlas(transform, mri_in, x, y, z, &xatlas, &yatlas, &zatlas) ;
	  xt = nint(xatlas/tvoxel_size) ;
	  yt = nint(yatlas/tvoxel_size) ;
	  zt = nint(zatlas/tvoxel_size) ;
	  if (xt == Gx && yt == Gy && zt == Gz)
	    DiagBreak() ;
	  if ((IS_WMSA(label) == 0) &&
	      MRIgetVoxVal(mri_wmsa_possible,xt,yt, zt,0) == 0)
	    continue ;
	  if (NOT_TRAINING_LABEL(label))
	    continue ;
	  ntraining++ ;
	  
	  if (IS_FUTURE_WMSA(label))
	  {
	    label = FUTURE_WMSA;
	    nfuture++ ;
	  }
	  else if (IS_WMSA(label))
	  {
	    label = WMSA ;
	    nwmsa++ ;
	  }
	  else
	  {
	    label = NOT_WMSA ;
	    nnot++ ;
	  }
          // set label to one more than it will be for training so that 0 means this is not a training voxel
	  MRIsetVoxVal(mri_training_voxels, x, y, z, n, label+1) ;
	}
  }

  correct = MRIcountNonzero(mri_training_voxels) ;
  if (correct != ntraining)
    DiagBreak() ;
  printf("total training set size = %2.1fM\n", (float)ntraining/(1024.0f*1024.0f)) ;
  printf("initial training set found with %dK FUTURE WMSA labels, %dK WMSA labels, and %dK non (ratio=%2.1f:%2.1f)\n",
	 nfuture/1000, nwmsa/1000, nnot/1000, (float)nnot/(float)nfuture, (float)nnot/(float)nwmsa) ;

  MRIfree(&mri_wmsa_possible) ;

  if (max_wm_wmsa_ratio*(nfuture+nwmsa) < nnot)   // too many wm labels w.r.t. # of wmsas - remove some wm
  {
    int removed, total_to_remove =  nnot - (max_wm_wmsa_ratio*(nfuture+nwmsa)) ;
    double premove ;

    premove = (double)total_to_remove  / (double)nnot ;
    printf("removing %dK WM indices to reduce training set imbalance (p < %f)\n", total_to_remove/1000, premove) ;

    for (removed = n = 0 ; n < nsubjects ; n++)
      for (x = 0 ; x < mri_in->width ; x++)
	for (y = 0 ; y <  mri_in->height; y++)
	  for (z = 0 ; z <  mri_in->depth; z++)
	  {
	    label = MRIgetVoxVal(mri_training_voxels, x, y, z, n) ;
	    if (label == 1)   // a WM voxel
	    {
	      if (randomNumber(0,1) < premove)
	      {
		removed++ ;
		MRIsetVoxVal(mri_training_voxels, x, y, z, n, 0) ;  // remove it from training set
	      }
	    }
	  }
    ntraining -= removed ;
    printf("%d WM voxels removed, new training set size = %dM (ratio = %2.1f)\n",
	   removed, ntraining/(1024*1024), (double)(nnot-removed)/(double)(nwmsa+nfuture)) ;
  }

  correct = MRIcountNonzero(mri_training_voxels) ;
  if (correct != ntraining)
    DiagBreak() ;
//  if (Gx >= 0)
  {
    int whalf = (parms->wsize-1)/2 ;
    char buf[STRLEN] ;
    rf->feature_names = (char **)calloc(rf->nfeatures, sizeof(char *)) ;
    for (i = 0, x = -whalf ; x <= whalf ; x++)
      for (y = -whalf ; y <= whalf ; y++)
	for (z = -whalf ; z <= whalf ; z++)
	  for (n = 0 ; n < mri_in->nframes ; n++, i++)
	  {
	    switch (n)
	    {
	    default:
	    case 0: sprintf(buf, "T1(%d, %d, %d)", x, y, z) ; break ;
	    case 1: sprintf(buf, "T2(%d, %d, %d)", x, y, z) ; 
	      break ;
	    case 2: sprintf(buf, "FLAIR(%d, %d, %d)", x, y, z) ; 
	      if (x == 0 && y == 0 && z == 0)
		Gdiag_no = i ;
	      break ;
	    }
	    rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ;
	    strcpy(rf->feature_names[i], buf) ;
	  }
    printf("FLAIR(0,0,0) = %dth feature\n", Gdiag_no) ;

    sprintf(buf, "CSF voxels in nbhd") ;
    rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ;
    strcpy(rf->feature_names[i], buf) ;
    i++ ; sprintf(buf, "gm prior") ;
    rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ;
    strcpy(rf->feature_names[i], buf) ;
    i++ ; sprintf(buf, "wm prior") ;
    rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ;
    strcpy(rf->feature_names[i], buf) ;
    i++ ; sprintf(buf, "csf prior") ;
    rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ;
    strcpy(rf->feature_names[i], buf) ;
    i++ ; sprintf(buf, "WMSA in nbhd") ;
    rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ;
    strcpy(rf->feature_names[i], buf) ;

    if (Gdiag & DIAG_WRITE)
    {
      printf("writing training voxels to tv.mgz\n") ;
      MRIwrite(mri_training_voxels, "tv.mgz") ;
    }
  }

  // now build training features and classes
  training_classes = (int *)calloc(ntraining, sizeof(training_classes[0])) ;
  if (training_classes == NULL)
    ErrorExit(ERROR_NOFILE, "train_rforest: could not allocate %d-length training buffers",ntraining);
  training_data = (double **)calloc(ntraining, sizeof(training_data[0])) ;
  if (training_classes == NULL)
    ErrorExit(ERROR_NOFILE, "train_rforest: could not allocate %d-length training buffers",ntraining);
  for (i = n = 0 ; n < nsubjects ; n++)
  {
    mri_in = mri_inputs[n][0] ; mri_seg = mri_segs[n][0] ; transform = transforms[n][0] ;
    for (x = 0 ; x < mri_in->width ; x++)
      for (y = 0 ; y <  mri_in->height; y++)
	for (z = 0 ; z <  mri_in->depth; z++)
	{
	  if ((int)MRIgetVoxVal(mri_training_voxels, x, y, z, n) == 0)
	    continue ;
	  label = MRIgetVoxVal(mri_seg, x, y, z, 0) ;
	  TransformSourceVoxelToAtlas(transform, mri_in, x, y, z, &xatlas, &yatlas, &zatlas) ;
	  xt = nint(xatlas/tvoxel_size) ; yt = nint(yatlas/tvoxel_size) ; zt = nint(zatlas/tvoxel_size) ;
	  if (IS_FUTURE_WMSA(label))
	    tlabel = FUTURE_WMSA ;
	  else if (IS_WMSA(label))
	    tlabel = WMSA ;
	  else
	    tlabel= NOT_WMSA ;
	    
	  training_classes[i] =  tlabel ;
	  training_data[i] = (double *)calloc(nfeatures, sizeof(double)) ;
	  if (training_data[i] == NULL)
	    ErrorExit(ERROR_NOMEMORY, "train_rforest: could not allocate %d-len feature vector #%d",
		      nfeatures, i) ;
	  training_classes[i] = training_classes[i] ;
//	  extract_feature(mri_in, parms->wsize, x, y, z, training_data[i], xatlas, yatlas, zatlas) ;
	  extract_long_features(mri_in, mri_seg, transform, gca, parms->wsize, x, y, z, training_data[i]) ;
	  if (training_data[i][Gdiag_no] < 80 && training_classes[i] == 1)
	    DiagBreak() ;
	  i++ ;
	}
    MRIfree(&mri_in) ; MRIfree(&mri_seg) ; TransformFree(&transform) ;
  }

  if (i < ntraining)
  {
    printf("warning!!!! i (%d) < ntraining (%d)! Setting ntraining=i\n", i, ntraining) ;
    ntraining = i ;
  }
  printf("training random forest with %dK FUTURE WMSA labels, %dK WMSA labels, and %dK non (ratio=%2.1f:%2.1f)\n",
	 nfuture/1000, nwmsa/1000, nnot/1000, (float)nnot/(float)nfuture, (float)nnot/(float)nwmsa) ;
  RFtrain(rf, parms->feature_fraction, parms->training_fraction, training_classes, training_data, ntraining);
  correct = RFcomputeOutOfBagCorrect(rf, training_classes, training_data,ntraining);
  printf("out of bag accuracy: %d of %d = %2.2f%%\n", correct, ntraining,
	 100.0*correct/ntraining) ;
  if (log_file_name)
  {
      struct flock fl;
      int    fd;
      char   line[MAX_LINE_LEN] ;

      printf("writing results to train.log file %s\n", log_file_name) ;
      fd = open(log_file_name, O_WRONLY|O_APPEND|O_CREAT, S_IRWXU|S_IRWXG);
      if (fd < 0)
	ErrorExit(ERROR_NOFILE, "%s: could not open test log file %s", 
		  Progname, log_file_name);
      
      fcntl(fd, F_SETLKW, &fl);  /* F_GETLK, F_SETLK, F_SETLKW */
      sprintf(line, "%f %d %d %f\n", 
	      rf->training_fraction,
	      rf->max_depth,
	      rf->ntrees,
	       100.0*correct/ntraining) ;
      write(fd, line, (strlen(line))*sizeof(char)) ;
      fl.l_type   = F_UNLCK;  /* tell it to unlock the region */
      fcntl(fd, F_SETLK, &fl); /* set the region to unlocked */
      close(fd) ;
  }

  for (i = 0 ; i < ntraining ; i++)  // allow for augmenting with other wmsa examples
    free(training_data[i]) ;
  free(training_data) ;
  free(training_classes) ;
  MRIfree(&mri_training_voxels) ;
  return(rf) ;
}
int
main(int argc, char *argv[]) {
  char   **av, *cp ;
  int    ac, nargs, i, dof, no_transform, which, sno = 0, nsubjects = 0 ;
  MRI    *mri=0, *mri_mean = NULL, *mri_std=0, *mri_T1=0,*mri_binary=0,*mri_dof=NULL,
                             *mri_priors = NULL ;
  char   *subject_name, *out_fname, fname[STRLEN] ;
  /*  LTA    *lta;*/
  MRI *mri_tmp=0 ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mri_make_template.c,v 1.26 2011/03/02 00:04:22 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 (!strlen(subjects_dir)) {
    cp = getenv("SUBJECTS_DIR") ;
    if (!cp)
      ErrorExit(ERROR_BADPARM,"%s: SUBJECTS_DIR not defined in environment.\n",
                Progname) ;
    strcpy(subjects_dir, cp) ;
  }

  if (argc < 3)  usage_exit(1) ;

  out_fname = argv[argc-1] ;

  no_transform = first_transform ;
  if (binary_name)   /* generate binarized volume with priors and */
  {                  /* separate means and variances */
    for (which = BUILD_PRIORS ; which <= OFF_STATS ; which++) {
      /* for each subject specified on cmd line */
      for (dof = 0, i = 1 ; i < argc-1 ; i++) {
        if (*argv[i] == '-')   /* don't do transform for next subject */
        { no_transform = 1 ;
          continue ;
        }
        dof++ ;
        subject_name = argv[i] ;
        if (which != BUILD_PRIORS) {
          sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, T1_name);
          fprintf(stderr, "%d of %d: reading %s...\n", i, argc-2, fname) ;
          mri_T1 = MRIread(fname) ;
          if (!mri_T1)
            ErrorExit(ERROR_NOFILE,"%s: could not open volume %s",
                      Progname,fname);
        }

        sprintf(fname, "%s/%s/mri/%s",subjects_dir,subject_name,binary_name);
        fprintf(stderr, "%d of %d: reading %s...\n", i, argc-2, fname) ;
        mri_binary = MRIread(fname) ;
        if (!mri_binary)
          ErrorExit(ERROR_NOFILE,"%s: could not open volume %s",
                    Progname,fname);

        /* only count voxels which are mostly labeled */
        MRIbinarize(mri_binary, mri_binary, WM_MIN_VAL, 0, 100) ;
        if (transform_fname && no_transform-- <= 0) {
          sprintf(fname, "%s/%s/mri/transforms/%s",
                  subjects_dir, subject_name, transform_fname) ;

          fprintf(stderr, "reading transform %s...\n", fname) ;
          ////////////////////////////////////////////////////////
#if 1
          {
            TRANSFORM *transform ;
            transform = TransformRead(fname) ;
            if (transform == NULL)
              ErrorExit(ERROR_NOFILE, "%s: could not open transform file %s\n",Progname, fname) ;
            mri_tmp = TransformApply(transform, mri_T1, NULL) ;
            TransformFree(&transform) ;
          }
#else
          lta = LTAreadEx(fname);
          if (lta == NULL)
            ErrorExit(ERROR_NOFILE,
                      "%s: could not open transform file %s\n",
                      Progname, fname) ;
          /* LTAtransform() runs either MRIapplyRASlinearTransform()
          for RAS2RAS or MRIlinearTransform() for Vox2Vox. */
          /* MRIlinearTransform() calls MRIlinearTransformInterp() */
          mri_tmp = LTAtransform(mri_T1, NULL, lta);
          MRIfree(&mri_T1) ;
          mri_T1 = mri_tmp ;
          LTAfree(&lta);
          lta = NULL;
#endif
          if (DIAG_VERBOSE_ON)
            fprintf(stderr, "transform application complete.\n") ;
        }
        if (which == BUILD_PRIORS) {
          mri_priors =
            MRIupdatePriors(mri_binary, mri_priors) ;
        } else {
          if (!mri_mean) {
            mri_dof = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth,
                               MRI_UCHAR) ;
            mri_mean =
              MRIalloc(mri_T1->width, mri_T1->height,mri_T1->depth,MRI_FLOAT);
            mri_std =
              MRIalloc(mri_T1->width,mri_T1->height,mri_T1->depth,MRI_FLOAT);
            if (!mri_mean || !mri_std)
              ErrorExit(ERROR_NOMEMORY, "%s: could not allocate templates.\n",
                        Progname) ;
          }

          if (DIAG_VERBOSE_ON)
            fprintf(stderr, "updating mean and variance estimates...\n") ;
          if (which == ON_STATS) {
            MRIaccumulateMaskedMeansAndVariances(mri_T1, mri_binary, mri_dof,
                                                 90, 100, mri_mean, mri_std) ;
            fprintf(stderr, "T1 = %d, binary = %d, mean = %2.1f\n",
                    (int)MRIgetVoxVal(mri_T1, 141,100,127,0),
                    MRIvox(mri_binary, 141,100,127),
                    MRIFvox(mri_mean, 141,100,127)) ;
          } else  /* computing means and vars for off */
            MRIaccumulateMaskedMeansAndVariances(mri_T1, mri_binary, mri_dof,
                                                 0, WM_MIN_VAL-1,
                                                 mri_mean, mri_std) ;
          MRIfree(&mri_T1) ;
        }
        MRIfree(&mri_binary) ;
      }

      if (which == BUILD_PRIORS) {
        mri = MRIcomputePriors(mri_priors, dof, NULL) ;
        MRIfree(&mri_priors) ;
        fprintf(stderr, "writing priors to %s...\n", out_fname) ;
      } else {
        MRIcomputeMaskedMeansAndStds(mri_mean, mri_std, mri_dof) ;
        mri_mean->dof = dof ;

        fprintf(stderr, "writing T1 means with %d dof to %s...\n", mri_mean->dof,
                out_fname) ;
        if (!which)
          MRIwrite(mri_mean, out_fname) ;
        else
          MRIappend(mri_mean, out_fname) ;
        MRIfree(&mri_mean) ;
        fprintf(stderr, "writing T1 variances to %s...\n", out_fname);
        if (dof <= 1)
          MRIreplaceValues(mri_std, mri_std, 0, 1) ;
        mri = mri_std ;
      }

      if (!which)
        MRIwrite(mri, out_fname) ;
      else
        MRIappend(mri, out_fname) ;
      MRIfree(&mri) ;
    }
  }
  else {
    /* for each subject specified on cmd line */

    if (xform_mean_fname) {
      m_xform_mean = MatrixAlloc(4,4,MATRIX_REAL) ;
      /* m_xform_covariance = MatrixAlloc(12,12,MATRIX_REAL) ;*/
    }

    dof = 0;
    for (i = 1 ; i < argc-1 ; i++) {

      if (*argv[i] == '-') {
        /* don't do transform for next subject */
        no_transform = 1 ;
        continue ;
      }
      dof++ ;

      subject_name = argv[i] ;
      sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, T1_name);
      fprintf(stderr, "%d of %d: reading %s...\n", i, argc-2, fname) ;
      mri_T1 = MRIread(fname) ;
      if (!mri_T1)
        ErrorExit(ERROR_NOFILE,"%s: could not open volume %s",Progname,fname);
      check_mri(mri_T1) ;

      if (binarize)
        MRIbinarize(mri_T1, mri_T1, binarize, 0, 1) ;
      if (erode) {
        int i ;
        printf("eroding input %d times\n", erode) ;
        for (i = 0 ; i < erode ; i++)
          MRIerode(mri_T1, mri_T1) ;
      }
      if (open) {
        int i ;
        printf("opening input %d times\n", open) ;
        for (i = 0 ; i < open ; i++)
          MRIerode(mri_T1, mri_T1) ;
        for (i = 0 ; i < open ; i++)
          MRIdilate(mri_T1, mri_T1) ;
      }

      check_mri(mri_T1) ;
      if (transform_fname) {

        sprintf(fname, "%s/%s/mri/transforms/%s",
                subjects_dir, subject_name, transform_fname) ;

        fprintf(stderr, "reading transform %s...\n", fname) ;
        ////////////////////////////////////////////////////////
#if 1
        {
          TRANSFORM *transform ;
          transform = TransformRead(fname) ;
          if (transform == NULL)
            ErrorExit(ERROR_NOFILE, "%s: could not open transform file %s\n",Progname, fname) ;
          mri_tmp = TransformApply(transform, mri_T1, NULL) ;
          if (DIAG_VERBOSE_ON)
            MRIwrite(mri_tmp, "t1.mgz") ;
          TransformFree(&transform) ;
        }
#else
        lta = LTAreadEx(fname);
        if (lta == NULL)
          ErrorExit(ERROR_NOFILE,
                    "%s: could not open transform file %s\n",
                    Progname, fname) ;
        printf("transform matrix -----------------------\n");
        MatrixPrint(stdout,lta->xforms[0].m_L);
        /* LTAtransform() runs either MRIapplyRASlinearTransform()
        for RAS2RAS or MRIlinearTransform() for Vox2Vox. */
        /* MRIlinearTransform() calls MRIlinearTransformInterp() */
        mri_tmp = LTAtransform(mri_T1, NULL, lta);
        printf("----- -----------------------\n");
        LTAfree(&lta);
#endif
        MRIfree(&mri_T1);
        mri_T1 = mri_tmp ; // reassign pointers
        if (DIAG_VERBOSE_ON)
          fprintf(stderr, "transform application complete.\n") ;
      }

      if (!mri_mean) {
        mri_mean =
          MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_FLOAT) ;
        mri_std =
          MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_FLOAT) ;
        if (!mri_mean || !mri_std)
          ErrorExit(ERROR_NOMEMORY, "%s: could not allocate templates.\n",
                    Progname) ;
        // if(transform_fname == NULL){
        if (DIAG_VERBOSE_ON)
          printf("Copying geometry\n");
        MRIcopyHeader(mri_T1,mri_mean);
        MRIcopyHeader(mri_T1,mri_std);
        // }
      }

      check_mri(mri_mean) ;
      if (!stats_only) {
        if (DIAG_VERBOSE_ON)
          fprintf(stderr, "updating mean and variance estimates...\n") ;
        MRIaccumulateMeansAndVariances(mri_T1, mri_mean, mri_std) ;
      }

      check_mri(mri_mean) ;
      if (DIAG_VERBOSE_ON)
        MRIwrite(mri_mean, "t2.mgz") ;
      MRIfree(&mri_T1) ;
      no_transform = 0;
    } /* end loop over subjects */

    if (xform_mean_fname) {
      FILE   *fp ;
      VECTOR *v = NULL, *vT = NULL ;
      MATRIX *m_vvT = NULL ;
      int    rows, cols ;

      nsubjects = sno ;

      fp = fopen(xform_covariance_fname, "w") ;
      if (!fp)
        ErrorExit(ERROR_NOFILE, "%s: could not open covariance file %s",
                  Progname, xform_covariance_fname) ;
      fprintf(fp, "nsubjects=%d\n", nsubjects) ;

      MatrixScalarMul(m_xform_mean, 1.0/(double)nsubjects, m_xform_mean) ;
      printf("means:\n") ;
      MatrixPrint(stdout, m_xform_mean) ;
      MatrixAsciiWrite(xform_mean_fname, m_xform_mean) ;

      /* subtract the mean from each transform */
      rows = m_xform_mean->rows ;
      cols = m_xform_mean->cols ;
      for (sno = 0 ; sno < nsubjects ; sno++) {
        MatrixSubtract(m_xforms[sno], m_xform_mean, m_xforms[sno]) ;
        v = MatrixReshape(m_xforms[sno], v, rows*cols, 1) ;
        vT = MatrixTranspose(v, vT) ;
        m_vvT = MatrixMultiply(v, vT, m_vvT) ;
        if (!m_xform_covariance)
          m_xform_covariance =
            MatrixAlloc(m_vvT->rows, m_vvT->cols,MATRIX_REAL) ;
        MatrixAdd(m_vvT, m_xform_covariance, m_xform_covariance) ;
        MatrixAsciiWriteInto(fp, m_xforms[sno]) ;
      }

      MatrixScalarMul(m_xform_covariance, 1.0/(double)nsubjects,
                      m_xform_covariance) ;
      printf("covariance:\n") ;
      MatrixPrint(stdout, m_xform_covariance) ;
      MatrixAsciiWriteInto(fp, m_xform_covariance) ;
      fclose(fp) ;
      if (stats_only)
        exit(0) ;
    }

    MRIcomputeMeansAndStds(mri_mean, mri_std, dof) ;
    check_mri(mri_mean) ;
    check_mri(mri_std) ;

    mri_mean->dof = dof ;

    if (smooth) {
      MRI *mri_kernel, *mri_smooth ;

      printf("applying smoothing kernel\n") ;
      mri_kernel = MRIgaussian1d(smooth, 100) ;
      mri_smooth = MRIconvolveGaussian(mri_mean, NULL, mri_kernel) ;
      MRIfree(&mri_kernel) ;
      MRIfree(&mri_mean) ;
      mri_mean = mri_smooth ;
    }
    fprintf(stderr, "\nwriting T1 means with %d dof to %s...\n", mri_mean->dof,
            out_fname) ;
    MRIwrite(mri_mean, out_fname) ;
    MRIfree(&mri_mean) ;
    if (dof <= 1) /* can't calculate variances - set them to reasonable val */
    {
      //               src      dst
      MRIreplaceValues(mri_std, mri_std, 0, 1) ;
    }
    if (!novar) {
      // mri_std contains the variance here  (does it?? I don't think so -- BRF)
      if (!var_fname) {
        fprintf(stderr, "\nwriting T1 standard deviations to %s...\n", out_fname);
        MRIappend(mri_std, out_fname) ;
      } else {
        fprintf(stderr, "\nwriting T1 standard deviations to %s...\n", var_fname);
        MRIwrite(mri_std, var_fname) ;
      }
    }
    MRIfree(&mri_std) ;
    if (mri)
      MRIfree(&mri);
  } /* end if binarize */
  return(0) ;
}