int
main(int argc, char *argv[])
{
  char          **av, *output_fname ;
  int           ac, nargs, msec, mode=-1 ;
  LABEL         *area = NULL ;
  MRI_SURFACE   *mris ;
  struct timeb  then ;
  MRI           *mri_dist ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option 
    (argc, argv, 
     "$Id: mris_distance_transform.c,v 1.5 2013/04/12 20:59:17 fischl Exp $", 
     "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

  Gdiag |= DIAG_SHOW ;
  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() ;

  TimerStart(&then) ;
  mris = MRISread(argv[1]) ;
  if (mris == NULL)
    ErrorExit(ERROR_NOFILE, "%s: could not read surface %s",
              Progname, argv[1]) ;

  if (vol)
  {
/*
    mri_template = MRIread(argv[2]) ;
    if (!mri_template)
      ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume from %s\n", Progname, argv[2]) ;
*/
  }
  else
  {
    area = LabelRead(NULL, argv[2]) ;
    if (area == NULL)
      ErrorExit(ERROR_NOFILE, "%s: could not read label %s",
		Progname, argv[2]) ;
    
    if (anterior_dist > 0)
      LabelCropAnterior(area, anterior_dist) ;
    if (posterior_dist > 0)
      LabelCropPosterior(area, posterior_dist) ;
  }
  
  if (stricmp(argv[3], "signed") == 0)
    mode = DTRANS_MODE_SIGNED ;
  else if (stricmp(argv[3], "unsigned") == 0)
    mode = DTRANS_MODE_UNSIGNED ;
  else if (stricmp(argv[3], "outside") == 0)
    mode = DTRANS_MODE_OUTSIDE ;
  else
  {
    print_usage() ;
    ErrorExit(ERROR_BADPARM, "unrecognized mode choice %s\n", argv[3]) ;
  }
  output_fname = argv[4] ;

  MRIScomputeMetricProperties(mris) ;
  if (vol)
  {
    mri_dist = MRIScomputeDistanceToSurface(mris, NULL, 0.25) ;
    MRIwrite(mri_dist, argv[4]) ;
  }
  else
  {
    MRIScomputeSecondFundamentalForm(mris) ;
    if (normalize > 0)
    {
      normalize = sqrt(mris->total_area) ;
      printf("normalizing surface distances by sqrt(%2.1f) = %2.1f\n", mris->total_area,normalize) ;
    }
    if (divide > 1)
    {
      int  i ;
      char fname[STRLEN], ext[STRLEN], base_name[STRLEN] ;
      LABEL *area_division ;
      
      FileNameExtension(output_fname, ext) ;
      FileNameRemoveExtension(output_fname, base_name) ;
      LabelMark(area, mris) ;
      MRIScopyMarksToAnnotation(mris) ;
      MRISsaveVertexPositions(mris, TMP_VERTICES) ;
      if (MRISreadVertexPositions(mris, divide_surf_name) != NO_ERROR)
	ErrorExit(ERROR_BADPARM, "%s: could not read vertex coords from %s", Progname, divide_surf_name) ;
      MRIScomputeSecondFundamentalForm(mris) ;
      MRISdivideAnnotationUnit(mris, 1, divide) ;
      MRISrestoreVertexPositions(mris, TMP_VERTICES) ;
      MRIScomputeSecondFundamentalForm(mris) ;
      
      
      // MRISdivideAnnotationUnit sets the marked to be in [0,divide-1], make it [1,divide]
      // make sure they are oriented along original a/p direction
#define MAX_UNITS 100    
      {
	double cx[MAX_UNITS], cy[MAX_UNITS], cz[MAX_UNITS], min_a ;
	int    index, num[MAX_UNITS], new_index[MAX_UNITS], j, min_i ;
	VERTEX *v ;
	
	memset(num, 0, sizeof(num[0])*divide) ;
	memset(cx, 0, sizeof(cx[0])*divide) ;
	memset(cy, 0, sizeof(cy[0])*divide) ;
	memset(cz, 0, sizeof(cz[0])*divide) ;
	for (i = 0 ; i < area->n_points ; i++)
	{
	  if (area->lv[i].vno < 0 || area->lv[i].deleted > 0)
	    continue ;
	  v = &mris->vertices[area->lv[i].vno] ;
	  v->marked++ ;
	  index = v->marked ;
	  cx[index] += v->x ;
	  cy[index] += v->y ;
	  cz[index] += v->z ;
	  num[index]++ ;
	}
	memset(new_index, 0, sizeof(new_index[0])*divide) ;
	for (i = 1 ; i <= divide ; i++)
	  cy[i] /= num[i] ;
	
	// order them from posterior to anterior
	for (j = 1 ; j <= divide ; j++)
	{
	  min_a = 1e10 ; min_i = 0 ;
	  for (i = 1 ; i <= divide ; i++)
	  {
	    if (cy[i] < min_a)
	    {
	      min_a = cy[i] ;
	      min_i = i ;
	    }
	  }
	  cy[min_i] = 1e10 ;  // make it biggest so it won't be considered again
	  new_index[j] = min_i ;
	}
	for (i = 0 ; i < area->n_points ; i++)
	{
	  if (area->lv[i].vno < 0 || area->lv[i].deleted > 0)
	    continue ;
	  v = &mris->vertices[area->lv[i].vno] ;
	  v->marked = new_index[v->marked] ;
	}
      }
      for (i = 1 ; i <= divide ; i++)
      {
	area_division = LabelFromMarkValue(mris, i) ;
	
	printf("performing distance transform on division %d with %d vertices\n", 
	       i, area_division->n_points) ;
	if (output_label)
	{
	  sprintf(fname, "%s%d.label", base_name, i) ;
	  printf("writing %dth subdivision to %s\n", i, fname) ;
	  LabelWrite(area_division, fname);
	}
	MRISdistanceTransform(mris, area_division, mode) ;
	sprintf(fname, "%s%d.%s", base_name, i, ext) ;
	if (normalize > 0)
	  MRISmulVal(mris, 1.0/normalize) ;
	MRISwriteValues(mris, fname) ;
      }
    }
    else
    {
      MRISdistanceTransform(mris, area, mode) ;
      if (normalize > 0)
	MRISmulVal(mris, 1.0/normalize) ;
      MRISwriteValues(mris, output_fname) ;
    }
  }

  msec = TimerStop(&then) ;
  fprintf(stderr,"distance transform took %2.1f minutes\n", (float)msec/(60*1000.0f));

  exit(0) ;
  return(0) ;  /* for ansi */
}
Esempio n. 2
0
int
main(int argc, char *argv[])
{
  char         **av, *source_fname, *target_fname, *out_fname, fname[STRLEN] ;
  int          ac, nargs, new_transform = 0, pad ;
  MRI          *mri_target, *mri_source, *mri_orig_source ;
  MRI_REGION   box ;
  struct timeb start ;
  int          msec, minutes, seconds ;
  GCA_MORPH    *gcam ;
  MATRIX       *m_L/*, *m_I*/ ;
  LTA          *lta ;


  /* initialize the morph params */
  memset(&mp, 0, sizeof(GCA_MORPH_PARMS));
  /* for nonlinear morph */
  mp.l_jacobian = 1 ;
  mp.min_sigma = 0.4 ;
  mp.l_distance = 0 ;
  mp.l_log_likelihood = .025 ;
  mp.dt = 0.005 ;
  mp.noneg = True ;
  mp.exp_k = 20 ;
  mp.diag_write_snapshots = 1 ;
  mp.momentum = 0.9 ;
  if (FZERO(mp.l_smoothness))
    mp.l_smoothness = 2 ;
  mp.sigma = 8 ;
  mp.relabel_avgs = -1 ;
  mp.navgs = 256 ;
  mp.levels = 6 ;
  mp.integration_type = GCAM_INTEGRATE_BOTH ;
  mp.nsmall = 1 ;
  mp.reset_avgs = -1 ;
  mp.npasses = 3 ;
  mp.regrid = regrid? True : False ;
  mp.tol = 0.1 ;
  mp.niterations = 1000 ;
	
  TimerStart(&start) ;
  setRandomSeed(-1L) ;
  DiagInit(NULL, NULL, NULL) ;
  ErrorInit(NULL, NULL, NULL) ;

  Progname = argv[0] ;
  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(1) ;

  source_fname = argv[1] ;
  target_fname = argv[2] ;
  out_fname = argv[3] ;
  FileNameOnly(out_fname, fname) ;
  FileNameRemoveExtension(fname, fname) ;
  strcpy(mp.base_name, fname) ;
  mri_source = MRIread(source_fname) ;
  if (!mri_source)
    ErrorExit(ERROR_NOFILE, "%s: could not read source label volume %s",
	      Progname, source_fname) ;

  if (mri_source->type == MRI_INT)
    {
      MRI *mri_tmp = MRIchangeType(mri_source, MRI_FLOAT, 0, 1, 1) ;
      MRIfree(&mri_source); mri_source = mri_tmp ;
    }
  mri_target = MRIread(target_fname) ;
  if (!mri_target)
    ErrorExit(ERROR_NOFILE, "%s: could not read target label volume %s",
	      Progname, target_fname) ;
  if (mri_target->type == MRI_INT)
    {
      MRI *mri_tmp = MRIchangeType(mri_target, MRI_FLOAT, 0, 1, 1) ;
      MRIfree(&mri_target); mri_target = mri_tmp ;
    }
  if (erosions > 0)
    {
      int n ;
      for (n = 0 ; n < erosions ; n++)
	{
	  MRIerodeZero(mri_target, mri_target) ;
	  MRIerodeZero(mri_source, mri_source) ;
	}
    }
  if (scale_values > 0)
    {
      MRIscalarMul(mri_source, mri_source, scale_values) ;
      MRIscalarMul(mri_target, mri_target, scale_values) ;
    }
  if (transform && transform->type == MORPH_3D_TYPE)
    TransformRas2Vox(transform, mri_source,NULL) ;
  if (use_aseg == 0)
    {
      if (match_peak_intensity_ratio)
	MRImatchIntensityRatio(mri_source, mri_target, mri_source, .8, 1.2, 
			       100, 125) ;
      else if (match_mean_intensity)
	MRImatchMeanIntensity(mri_source, mri_target, mri_source) ;
      MRIboundingBox(mri_source, 0, &box) ;
      pad = (int)ceil(PADVOX * 
		      MAX(mri_target->xsize,MAX(mri_target->ysize,mri_target->zsize)) / 
		      MIN(mri_source->xsize,MIN(mri_source->ysize,mri_source->zsize))); 
#if 0
      { MRI *mri_tmp ;
	if (pad < 1)
	  pad = 1 ;
	printf("padding source with %d voxels...\n", pad) ;
	mri_tmp = MRIextractRegionAndPad(mri_source, NULL, &box, pad) ;
	if ((Gdiag & DIAG_WRITE) && DIAG_VERBOSE_ON)
	  MRIwrite(mri_tmp, "t.mgz") ;
	MRIfree(&mri_source) ;
	mri_source = mri_tmp ;
      }
#endif
    }
  mri_orig_source = MRIcopy(mri_source, NULL) ;

  mp.max_grad = 0.3*mri_source->xsize ;

  if (transform == NULL)
    transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ;

  if (transform->type != MORPH_3D_TYPE)  // initializing m3d from a linear transform
    {
      new_transform = 1 ;
      lta = ((LTA *)(transform->xform)) ;
      if (lta->type != LINEAR_VOX_TO_VOX)
	{
	  printf("converting ras xform to voxel xform\n") ;
	  m_L = MRIrasXformToVoxelXform(mri_source, mri_target, lta->xforms[0].m_L, NULL) ;
	  MatrixFree(&lta->xforms[0].m_L) ;
	  lta->type = LINEAR_VOX_TO_VOX ;
	}
      else
	{
	  printf("using voxel xform\n") ;
	  m_L = lta->xforms[0].m_L ;
	}
#if 0
      if (Gsx >= 0)   // update debugging coords
	{
	  VECTOR *v1, *v2 ;

	  v1 = VectorAlloc(4, MATRIX_REAL) ;
	  Gsx -= (box.x-pad) ;
	  Gsy -= (box.y-pad) ;
	  Gsz -= (box.z-pad) ;
	  V3_X(v1) = Gsx ; V3_Y(v1) = Gsy ; V3_Z(v1) = Gsz ;
	  VECTOR_ELT(v1,4) = 1.0 ;
	  v2 = MatrixMultiply(m_L, v1, NULL) ;
      
	  Gsx = nint(V3_X(v2)) ; Gsy = nint(V3_Y(v2)) ; Gsz = nint(V3_Z(v2)) ;
	  MatrixFree(&v2) ; MatrixFree(&v1) ;
	  printf("mapping by transform (%d, %d, %d) --> (%d, %d, %d) for rgb writing\n",
		 Gx, Gy, Gz, Gsx, Gsy, Gsz) ;
	}
#endif
      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
	write_snapshot(mri_target, mri_source, m_L, &mp, 0, 1, "linear_init");

      lta->xforms[0].m_L = m_L ;
      printf("initializing GCAM with vox->vox matrix:\n") ;
      MatrixPrint(stdout, m_L) ;
      gcam = GCAMcreateFromIntensityImage(mri_source, mri_target, transform) ;
#if 0
      gcam->gca = gcaAllocMax(1, 1, 1, 
			      mri_target->width, mri_target->height, 
			      mri_target->depth,
			      0, 0) ;
#endif
      GCAMinitVolGeom(gcam, mri_source, mri_target) ;
      if (use_aseg)
	{
	  if (ribbon_name)
	    {
	      char fname[STRLEN], path[STRLEN], *str, *hemi ;
	      int  h, s, label ;
	      MRI_SURFACE *mris_white, *mris_pial ;
	      MRI         *mri ;

	      for (s = 0 ; s <= 1 ; s++) // source and target
		{
		  if (s == 0)
		    {
		      str = source_surf ;
		      mri = mri_source ;
		      FileNamePath(mri->fname, path) ;
		      strcat(path, "/../surf") ;
		    }
		  else
		    {
		      mri = mri_target ;
		      FileNamePath(mri->fname, path) ;
		      strcat(path, "/../elastic") ;
		      str = target_surf ;
		    }
		  // sorry - these values come from FreeSurferColorLUT.txt
		  MRIreplaceValueRange(mri, mri, 1000, 1034, Left_Cerebral_Cortex) ;
		  MRIreplaceValueRange(mri, mri, 1100, 1180, Left_Cerebral_Cortex) ;
		  MRIreplaceValueRange(mri, mri, 2000, 2034, Right_Cerebral_Cortex) ;
		  MRIreplaceValueRange(mri, mri, 2100, 2180, Right_Cerebral_Cortex) ;
		  for (h = LEFT_HEMISPHERE ; h <= RIGHT_HEMISPHERE ; h++)  
		    {
		      if (h == LEFT_HEMISPHERE)
			{
			  hemi = "lh" ;
			  label = Left_Cerebral_Cortex ;
			}
		      else
			{
			  label = Right_Cerebral_Cortex ;
			  hemi = "rh" ;
			}
		      sprintf(fname, "%s/%s%s.white", path, hemi, str) ;
		      mris_white = MRISread(fname) ;
		      if (mris_white == NULL)
			ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ;
		      MRISsaveVertexPositions(mris_white, WHITE_VERTICES) ;
		      sprintf(fname, "%s/%s%s.pial", path, hemi, str) ;
		      mris_pial = MRISread(fname) ;
		      if (mris_pial == NULL)
			ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ;
		      MRISsaveVertexPositions(mris_pial, PIAL_VERTICES) ;
		      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
			{
			  sprintf(fname, "sb.mgz") ;
			  MRIwrite(mri_source, fname) ; 
			  sprintf(fname, "tb.mgz") ;
			  MRIwrite(mri_target, fname) ;
			}

		      insert_ribbon_into_aseg(mri, mri, mris_white, mris_pial, h) ;
		      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
			{
			  sprintf(fname, "sa.mgz") ;
			  MRIwrite(mri_source, fname) ; 
			  sprintf(fname, "ta.mgz") ;
			  MRIwrite(mri_target, fname) ;
			}
		      MRISfree(&mris_white) ; MRISfree(&mris_pial) ;
		    }
		}
	      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
		{
		  sprintf(fname, "s.mgz") ;
		  MRIwrite(mri_source, fname) ; 
		  sprintf(fname, "t.mgz") ;
		  MRIwrite(mri_target, fname) ;
		}
	    }
	  GCAMinitLabels(gcam, mri_target) ;
	  GCAMsetVariances(gcam, 1.0) ;
	  mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ;
	}
    }
  else  /* use a previously create morph and integrate it some more */
    {
      printf("using previously create gcam...\n") ;
      gcam = (GCA_MORPH *)(transform->xform) ;
      GCAMrasToVox(gcam, mri_source) ;
      if (use_aseg)
	{
	  GCAMinitLabels(gcam, mri_target) ;
	  GCAMsetVariances(gcam, 1.0) ;
	  mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ;
	}
      else
	GCAMaddIntensitiesFromImage(gcam, mri_target) ;
    }
  if (gcam->width != mri_source->width ||
      gcam->height != mri_source->height ||
      gcam->depth != mri_source->depth)
    ErrorExit(ERROR_BADPARM, "%s: warning gcam (%d, %d, %d), doesn't match source vol (%d, %d, %d)",
	      Progname, gcam->width, gcam->height, gcam->depth,
	      mri_source->width, mri_source->height, mri_source->depth) ;
	
  mp.mri_diag = mri_source ;
  mp.diag_morph_from_atlas = 0 ;
  mp.diag_write_snapshots = 1 ;
  mp.diag_sample_type = use_aseg ? SAMPLE_NEAREST : SAMPLE_TRILINEAR ;
  mp.diag_volume = use_aseg ? GCAM_LABEL : GCAM_MEANS ;

  if (renormalize)
    GCAMnormalizeIntensities(gcam, mri_target) ;
  if (mp.write_iterations != 0)
    {
      char fname[STRLEN] ;
      MRI  *mri_gca ;
		
      if (getenv("DONT_COMPRESS"))
        sprintf(fname, "%s_target.mgh", mp.base_name) ;
      else
        sprintf(fname, "%s_target.mgz", mp.base_name) ;
      if (mp.diag_morph_from_atlas == 0)
      {
        printf("writing target volume to %s...\n", fname) ;
        MRIwrite(mri_target, fname) ;
        sprintf(fname, "%s_target", mp.base_name) ;
        MRIwriteImageViews(mri_target, fname, IMAGE_SIZE) ;
      }
      else
      {
        if (use_aseg)
          mri_gca = GCAMwriteMRI(gcam, NULL, GCAM_LABEL) ;
        else
        {
          mri_gca = MRIclone(mri_source, NULL) ;
          GCAMbuildMostLikelyVolume(gcam, mri_gca) ;
        }
	  printf("writing target volume to %s...\n", fname) ;
	  MRIwrite(mri_gca, fname) ;
	  sprintf(fname, "%s_target", mp.base_name) ;
	  MRIwriteImageViews(mri_gca, fname, IMAGE_SIZE) ;
	  MRIfree(&mri_gca) ;
	}
    }

  if (nozero)
    {
      printf("disabling zero nodes\n") ;
      GCAMignoreZero(gcam, mri_target) ;
    }
  mp.mri = mri_target ;
  if (mp.regrid == True && new_transform == 0)
    GCAMregrid(gcam, mri_target, PAD, &mp, &mri_source) ;

  mp.write_fname = out_fname ;
  GCAMregister(gcam, mri_source, &mp) ; // atlas is target, morph target into register with it
  if (apply_transform)
    {
      MRI *mri_aligned ;
      char   fname[STRLEN] ;
		
      FileNameRemoveExtension(out_fname, fname) ;
      strcat(fname, ".mgz") ;
      mri_aligned = GCAMmorphToAtlas(mp.mri, gcam, NULL, -1, mp.diag_sample_type) ;
      printf("writing transformed output volume to %s...\n", fname) ;
      MRIwrite(mri_aligned, fname) ;
      MRIfree(&mri_aligned) ;
    }
  printf("writing warp vector field to %s\n", out_fname) ;
  GCAMvoxToRas(gcam) ;
  GCAMwrite(gcam, out_fname) ;
  GCAMrasToVox(gcam, mri_source) ;

  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("registration took %d minutes and %d seconds.\n", 
	 minutes, seconds) ;
  exit(0) ;
  return(0) ;
}
int
main(int argc, char *argv[]) {
  char          **av, *surf_fname, *profile_fname, *seg_fname ;
  int           ac, nargs ;
  MRI_SURFACE   *mris, *mris_ico = NULL ;
  // LABEL         *label = NULL ;
  MRI           *mri_profiles ;
  CLUSTER       *ct ;

  setRandomSeed(10L) ;

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

  profile_fname = argv[1] ;
  surf_fname = argv[2] ;
  seg_fname = argv[3] ;
  mris = MRISread(surf_fname) ;
  if (!mris)
    ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s",
              Progname, surf_fname) ;
  MRISsetNeighborhoodSize(mris, 2) ;

  if (MRISreadAnnotation(mris, "ad_aparc") != NO_ERROR) {
    if (MRISreadAnnotation(mris, "aparc") != NO_ERROR)
      ErrorExit(ERROR_NOFILE, "%s: could not read annotation file ad_aparc", Progname) ;
  }

  printf("reading intensity profile volume from %s...\n", profile_fname) ;
  mri_profiles = MRIread(profile_fname) ;
  if (!mri_profiles)
    ErrorExit(ERROR_NOFILE, "%s: could not read intensity volume %s",
              Progname, profile_fname) ;
  rip_vertices_out_of_fov(mris, mri_profiles) ;
  rip_bad_vertices(mris, mri_profiles) ;
  MRISclearAnnotations(mris) ;

#if 0
  if (nlabels > 0) {
    int l ;
    char label_name[STRLEN] ;
    LABEL *ltotal = NULL ;

    for (l = 0 ; l < nlabels ; l++) {
      sprintf(label_name, "%s/%s/label/%s.%s.label", sdir, sname, hemi,label_names[l]) ;

      label = LabelRead(NULL, label_name) ;
      if (!label)
        ErrorExit(ERROR_NOFILE, "%s: could not read label file %s...\n", Progname,
                  label_name) ;
      if (num_erode > 0) {
        printf("eroding label %d times, npoints went from %d ", num_erode,label->n_points) ;
        LabelErode(label, mris, num_erode) ;
        printf("to %d ", label->n_points) ;
      }
      ltotal = LabelCombine(label, ltotal) ;
    }
    if (nlabels == 0)
      ltotal = LabelInFOV(mris, mri, MIN_BORDER_DIST) ;

    LabelRipRestOfSurfaceWithThreshold(ltotal, mris, thresh) ;
  }
#endif

  if (navgs > 0) {
    printf("smoothing profiles %d times\n", navgs) ;
    MRISsmoothFrames(mris, mri_profiles, navgs) ;
  }
  if (ico_fname) {
    mris_ico = MRISread(ico_fname) ;
    if (mris_ico == NULL)
      ErrorExit(ERROR_BADPARM, "%s: could not read icosahedron from %s...\n", Progname, ico_fname) ;
  }
  ct = MRIScluster(mris, mri_profiles, cluster_type, k, start_fname, mris_ico) ;
  printf("writing cortical intensity clusters to %s...\n", seg_fname) ;
  MRISwriteAnnotation(mris, seg_fname) ;
  {
    int    vno ;
    VERTEX *v ;
    int    c, i ;
    char   fname[STRLEN], ext[STRLEN] ;

    // write average profiles into mri_profiles and write it out
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->ripflag)
        continue ;
      c = v->curv ;
      if (c < 0)
        continue ;
      for (i = 0 ; i < mri_profiles->nframes ; i++)
        MRIsetVoxVal(mri_profiles, vno, 0, 0, i, VECTOR_ELT(ct[c].v_mean,i+1)) ;
    }
    FileNameExtension(seg_fname, ext) ;
    FileNameRemoveExtension(seg_fname, fname) ;
    strcat(fname, "_cluster_avg.mgz") ;
    printf("writing average cluster profiles to %s...\n", fname) ;
    MRIwrite(mri_profiles, fname) ;
  }

  MRIfree(&mri_profiles) ;

  exit(0) ;
  return(0) ;  /* for ansi */
}
int
main(int argc, char *argv[]) {
  char   **av, fname[STRLEN] ;
  int    ac, nargs, i ;
  MRI    *mri_flash[MAX_IMAGES], *mri_T1, *mri_PD ;
  char   *in_fname, *out_PD_fname, *out_T1_fname ;
  int          msec, minutes, seconds, nvolumes ;
  struct timeb start ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mri_estimate_tissue_parms.c,v 1.9 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) ;

  TimerStart(&start) ;
  parms.dt = 1e-6 ;
  parms.tol = 1e-5 ;
  parms.momentum = 0.0 ;
  parms.niterations = 20 ;

  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(1) ;

  out_T1_fname = argv[argc-2] ;
  out_PD_fname = argv[argc-1] ;
  FileNameOnly(out_T1_fname, fname) ;
  FileNameRemoveExtension(fname, fname) ;
  strcpy(parms.base_name, fname) ;

  nvolumes = 0 ;
  for (i = 1 ; i < argc-2 ; i++) {
    if (argv[i][0] == '-') {
      if (!stricmp(argv[i]+1, "te"))
        te = atof(argv[i+1]) ;
      else if (!stricmp(argv[i]+1, "tr"))
        tr = atof(argv[i+1]) ;
      else if (!stricmp(argv[i]+1, "fa"))
        fa = RADIANS(atof(argv[i+1])) ;
      else
        ErrorExit(ERROR_BADPARM, "%s: unsupported MR parameter %s",
                  Progname, argv[i]+1) ;
      i++ ;  /* skip parameter */
      continue ;
    }

    in_fname = argv[i] ;
    printf("reading %s...", in_fname) ;

    mri_flash[nvolumes] = MRIread(in_fname) ;
    if (!mri_flash[nvolumes])
      ErrorExit(Gerror, "%s: MRIread(%s) failed", Progname, in_fname) ;
    if (tr > 0) {
      mri_flash[nvolumes]->tr = tr ;
      tr = 0 ;
    }
    if (te > 0) {
      mri_flash[nvolumes]->te = te ;
      te = 0 ;
    }
    if (fa > 0) {
      mri_flash[nvolumes]->flip_angle = fa ;
      fa = 0 ;
    }
    printf("TE = %2.2f, TR = %2.2f, alpha = %2.2f\n", mri_flash[nvolumes]->te,
           mri_flash[nvolumes]->tr, DEGREES(mri_flash[nvolumes]->flip_angle)) ;
    mri_flash[nvolumes]->flip_angle = mri_flash[nvolumes]->flip_angle;
    if (conform) {
      MRI *mri_tmp ;

      printf("embedding and interpolating volume\n") ;
      mri_tmp = MRIconform(mri_flash[nvolumes]) ;
      /*      MRIfree(&mri_src) ;*/
      mri_flash[nvolumes] = mri_tmp ;
    }
    if (FZERO(mri_flash[nvolumes]->tr) ||
        FZERO(mri_flash[nvolumes]->flip_angle))
      ErrorExit(ERROR_BADPARM, "%s: invalid TR or FA for image %d:%s",
                Progname, nvolumes, in_fname) ;
    nvolumes++ ;
  }
  printf("using %d FLASH volumes to estimate tissue parameters.\n", nvolumes) ;
  mri_T1 = MRIclone(mri_flash[0], NULL) ;
  mri_PD = MRIclone(mri_flash[0], NULL) ;


  {
    double   sse, last_T1, last_PD, total_rms, avg_rms ;
    int      x, y, z, width, height, depth, total_vox, ignored, nvox ;
    struct timeb first_slice ;

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

    TimerStart(&first_slice) ;

    last_T1 = last_PD = 1000 ;
    sse = 0.0 ;
    width = mri_T1->width ;
    height = mri_T1->height ;
    depth = mri_T1->depth ;
    total_vox = width*depth*height ;
#if 0
    estimateVoxelParameters(mri_flash, nvolumes, width/2, height/2, depth/2,
                            mri_T1, mri_PD, last_T1, last_PD) ;
#endif
    if (Gdiag_no == 999) {
      x = 130 ;
      y = 124 ;
      z = 74 ; /* CSF */
      computeErrorSurface("error_surf_csf.dat",mri_flash,nvolumes,x,y,z,500,3000,500,3000);
      x = 161 ;
      y = 157 ;
      z = 63 ;  /* wm */
      computeErrorSurface("error_surf_wm.dat",mri_flash,nvolumes,x,y,z,250,3000,250,3000);
      x = 166 ;
      y = 153 ;
      z = 63 ;  /* gm */
      computeErrorSurface("error_surf_gm.dat",mri_flash,nvolumes,x,y,z,250,3000,250,3000);
    }
    avg_rms = 0 ;
    for (ignored = z = 0 ; z < depth ; z++) {
      if (z > 0)
        printf("z = %d, avg rms=%2.1f, T1=%2.0f, PD=%2.0f...\n",
               z, avg_rms, last_T1, last_PD) ;
#if 0
      if (z > 0 && z*width*height - ignored > 0) {
        int processed = z*width*height - ignored, hours ;

        msec = TimerStop(&first_slice) ;
        seconds = nint((float)msec/1000.0f) ;
        minutes = seconds / 60 ;
        seconds = seconds % 60 ;
        hours = minutes / 60 ;
        minutes = minutes % 60 ;
        printf("%02d:%02d:%02d total processing time ... ",
               hours,minutes,seconds);
        msec = (int)((float)(total_vox-ignored)*msec/(float)processed) ;
        seconds = nint((float)msec/1000.0f) ;
        minutes = seconds / 60 ;
        seconds = seconds % 60 ;
        hours = minutes / 60 ;
        minutes = minutes % 60 ;
        printf("estimate %02d:%02d:%02d remaining.\n", hours,minutes, seconds);
      }
#endif
      if (write_iterations > 0 && z > 0 && !(z%write_iterations)) {
        printf("writing T1 esimates to %s...\n", out_T1_fname) ;
        printf("writing PD estimates to %s...\n", out_PD_fname) ;
        MRIwrite(mri_T1, out_T1_fname) ;
        MRIwrite(mri_PD, out_PD_fname) ;
        printf("writing residuals to %s...\n", residual_name) ;
        if (residual_name) {
          MRI *mri_res, *mri_res_total = NULL ;
          for (i = 0 ; i < nvolumes ; i++) {

            mri_res = compute_residuals(mri_flash[i], mri_T1, mri_PD) ;
            sprintf(fname, "%s%d.mgh", residual_name, i) ;
#if 0
            MRIwrite(mri_res, fname) ;
#endif
            if (!mri_res_total) {
              mri_res_total = MRIcopy(mri_res, NULL) ;
            } else {
              MRIsadd(mri_res, mri_res_total, mri_res_total) ;
            }

            MRIfree(&mri_res) ;
          }
          MRIsscalarMul(mri_res_total, mri_res_total, 1.0/(float)nvolumes) ;
          MRIssqrt(mri_res_total, mri_res_total) ;
          sprintf(fname, "%s.mgh", residual_name) ;
          MRIwrite(mri_res_total, fname) ;
        }
      }

      nvox = 0 ;
      total_rms = 0 ;
      for (y = 0 ; y < height ; y++) {
#if 0
        if (y%32 == 0 && nvox > 0)
          printf("z = %d, y = %d, avg rms=%2.1f, T1=%2.0f, PD=%2.0f...\n",
                 z, y, total_rms/(double)nvox, last_T1, last_PD) ;
#endif
        for (x = 0 ; x < width ; x++) {
#if 0
          for (i = 0 ; i < nvolumes ; i++)
            if (MRISvox(mri_flash[i],x,y,z) > thresh)
              break ;
          if (i >= nvolumes)
#else
          if (no_valid_data(mri_flash, nvolumes, x, y, z, thresh))
#endif
          {
            ignored++ ;
            MRISvox(mri_T1, x, y, z) = MRISvox(mri_PD, x, y, z) = 0 ;
            /*            last_T1 = last_PD = 1000 ;*/
            continue ;
          }
#if 0
          sse = findInitialParameters(mri_flash, nvolumes, x, y, z,
                                      last_PD-1000, last_PD+1000,
                                      last_T1-1000, last_T1+1000,
                                      &last_PD, &last_T1, 10) ;
#endif
#if 0
          sse = findInitialParameters(mri_flash, nvolumes, x, y, z,
                                      last_PD-100, last_PD+100,
                                      last_T1-100, last_T1+100,
                                      &last_PD, &last_T1, 10) ;
          if (last_T1 <= MIN_T1 || last_PD <= 0) {
            ignored++ ;
            MRISvox(mri_T1, x, y, z) = MRISvox(mri_PD, x, y, z) = 0 ;
            /*            last_T1 = last_PD = 1000 ;*/
            continue ;
          }
#endif
          sse = estimateVoxelParameters(mri_flash, nvolumes, x, y, z,
                                        mri_T1, mri_PD, nsteps) ;
          nvox++ ;
          last_T1 = MRISvox(mri_T1, x, y, z) ;
          last_PD = MRISvox(mri_PD, x, y, z) ;
          total_rms += sqrt(sse/nvolumes) ;
          if (!finite(total_rms))
            DiagBreak() ;
        }
      }
      avg_rms = total_rms / nvox ;
      if (!finite(avg_rms))
        DiagBreak() ;
    }
  }


  printf("writing T1 esimates to %s...\n", out_T1_fname) ;
  printf("writing PD estimates to %s...\n", out_PD_fname) ;
  MRIwrite(mri_T1, out_T1_fname) ;
  MRIwrite(mri_PD, out_PD_fname) ;
  if (residual_name) {
    MRI *mri_res_total = NULL ;

    for (i = 0 ; i < nvolumes ; i++) {
      MRI *mri_res ;

      mri_res = compute_residuals(mri_flash[i], mri_T1, mri_PD) ;
#if 0
      sprintf(fname, "%s%d.mgh", residual_name, i) ;
      MRIwrite(mri_res, fname) ;
#endif
      if (!mri_res_total) {
        mri_res_total = MRIcopy(mri_res, NULL) ;
      } else {
        MRIsadd(mri_res, mri_res_total, mri_res_total) ;
      }
      MRIfree(&mri_res) ;
    }
    MRIsscalarMul(mri_res_total, mri_res_total, 1.0/(float)nvolumes) ;
    MRIssqrt(mri_res_total, mri_res_total) ;
    sprintf(fname, "%s.mgh", residual_name) ;
    MRIwrite(mri_res_total, fname) ;
  }
  MRIfree(&mri_T1) ;
  MRIfree(&mri_PD) ;
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("parameter estimation took %d minutes and %d seconds.\n",
         minutes, seconds) ;
  exit(0) ;
  return(0) ;
}
Esempio n. 5
0
int
main(int argc, char *argv[])
{
  char         **av, in_surf_fname[STRLEN], *in_patch_fname, *out_patch_fname,
  fname[STRLEN], path[STRLEN], *cp, hemi[10] ;
  int          ac, nargs ;
  MRI_SURFACE  *mris ;
  MRI          *mri_vertices ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option
          (argc, argv,
           "$Id: mris_flatten.c,v 1.42 2016/12/10 22:57:46 fischl Exp $",
           "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

  Gdiag |= DIAG_SHOW ;
  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;
  Gdiag |= (DIAG_SHOW | DIAG_WRITE) ;
  memset(&parms, 0, sizeof(parms)) ;
  parms.dt = .1 ;
  parms.projection = PROJECT_PLANE ;
  parms.tol = 0.2 ;
  parms.n_averages = 1024 ;
  parms.l_dist = 1.0 ;
  parms.l_nlarea = 1.0 ;
  parms.niterations = 40 ;
  parms.area_coef_scale = 1.0 ;
  parms.dt_increase = 1.01 /* DT_INCREASE */;
  parms.dt_decrease = 0.98 /* 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.nbhd_size = 7 ;    /* out to 7-connected neighbors */
  parms.max_nbrs = 12 ;    /* 12 at each distance */
  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() ;

  parms.base_dt = base_dt_scale * parms.dt ;
  in_patch_fname = argv[1] ;
  out_patch_fname = argv[2] ;
  FileNamePath(in_patch_fname, path) ;
  cp = strrchr(in_patch_fname, '/') ;
  if (!cp)
    cp = in_patch_fname ;
  cp = strchr(cp, '.') ;
  if (cp)
  {
    strncpy(hemi, cp-2, 2) ;
    hemi[2] = 0 ;
  }
  else
    strcpy(hemi, "lh") ;
  if (one_surf_flag)
    sprintf(in_surf_fname, "%s", in_patch_fname) ;
  else
    sprintf(in_surf_fname, "%s/%s.%s", path, hemi, original_surf_name) ;

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

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

  if (sphere_flag)
  {
    MRIScenter(mris, mris) ;
    mris->radius = MRISaverageRadius(mris) ;
    MRISstoreMetricProperties(mris) ;
    MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ;
  }

  if (Gdiag_no >= 0)
  {
    int n ;
    printf("vertex %d has %d nbrs before patch:\n",
           Gdiag_no, mris->vertices[Gdiag_no].vnum) ;
    for (n = 0 ; n < mris->vertices[Gdiag_no].vnum ; n++)
      printf("\t%d\n", mris->vertices[Gdiag_no].v[n]) ;
  }
  if (one_surf_flag)  /* only have the 1 surface - no patch file */
  {
    mris->patch = 1 ;
    mris->status = MRIS_PATCH ;
    if (!FEQUAL(rescale,1))
    {
      MRISscaleBrain(mris, mris, rescale) ;
      MRIScomputeMetricProperties(mris) ;
    }
    MRISstoreMetricProperties(mris) ;
    MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ;

  } 
  else
  {
    MRISresetNeighborhoodSize(mris, mris->vertices[0].nsize) ; // set back to max
    if (label_fname) // read in a label instead of a patch
    {
      LABEL *area ;
      area = LabelRead(NULL, label_fname) ;
      if (area == NULL)
        ErrorExit(ERROR_BADPARM, "%s: could not read label file %s",
                  Progname, label_fname) ;

      LabelDilate(area, mris, dilate_label, CURRENT_VERTICES) ;
      MRISclearMarks(mris) ;
      LabelMark(area, mris) ;
      MRISripUnmarked(mris) ;
      MRISripFaces(mris);
      mris->patch = 1 ;
      mris->status = MRIS_CUT ;
      LabelFree(&area) ;
      printf("%d valid vertices (%2.1f %% of total)\n",
             MRISvalidVertices(mris), 
             100.0*MRISvalidVertices(mris)/mris->nvertices) ;
    }
    else
    {
      if (MRISreadPatch(mris, in_patch_fname) != NO_ERROR)
        ErrorExit(ERROR_BADPARM, "%s: could not read patch file %s",
                  Progname, in_patch_fname) ;
      if (dilate)
      {
        printf("dilating patch %d times\n", dilate) ;
        MRISdilateRipped(mris, dilate) ;
        printf("%d valid vertices (%2.1f %% of total)\n",
               MRISvalidVertices(mris), 100.0*MRISvalidVertices(mris)/mris->nvertices) ;
      }
    }
    MRISremoveRipped(mris) ;
    MRISupdateSurface(mris) ;
#if 0
    mris->nsize = 1 ; // before recalculation of 2 and 3-nbrs
    {
      int vno ;
      VERTEX *v ;
      for (vno= 0 ; vno < mris->nvertices ; vno++)
      {
        v = &mris->vertices[vno] ;
        v->vtotal = v->vnum ;
        v->nsize = 1 ;
      }
    }
    MRISsetNeighborhoodSize(mris, nbrs) ;
#endif
  }

  if (Gdiag_no >= 0)
    printf("vno %d is %sin patch\n", Gdiag_no,
           mris->vertices[Gdiag_no].ripflag ? "NOT " : "") ;

  if (Gdiag_no >= 0 && mris->vertices[Gdiag_no].ripflag == 0)
  {
    int n ;
    printf("vertex %d has %d nbrs after patch:\n",
           Gdiag_no, mris->vertices[Gdiag_no].vnum) ;
    for (n = 0 ; n < mris->vertices[Gdiag_no].vnum ; n++)
      printf("\t%d\n", mris->vertices[Gdiag_no].v[n]) ;
  }
  fprintf(stderr, "reading original vertex positions...\n") ;
  if (!FZERO(disturb))
    mrisDisturbVertices(mris, disturb) ;
  if (parms.niterations > 0)
  {
    MRISresetNeighborhoodSize(mris, nbrs) ;

    if (!FZERO(parms.l_unfold) || !FZERO(parms.l_expand))
    {
      static INTEGRATION_PARMS p2 ;
      sprintf(in_surf_fname, "%s/%s.%s", path, hemi, original_surf_name) ;
      if (stricmp(original_unfold_surf_name,"none") == 0)
      {
        printf("using current position of patch as initial position\n") ;
        MRISstoreMetricProperties(mris) ;  /* use current positions */
      }
      else if (!sphere_flag && !one_surf_flag)
        MRISreadOriginalProperties(mris, original_unfold_surf_name) ;
      *(&p2) = *(&parms) ;
      p2.l_dist = 0 ;
      p2.niterations = 100 ;
      p2.nbhd_size = p2.max_nbrs = 1 ;
      p2.n_averages = 0 ;
      p2.write_iterations = parms.write_iterations > 0 ? 25 : 0 ;
      p2.tol = -1 ;
      p2.dt = 0.5 ;
      p2.l_area = 0.0 ;
      p2.l_spring = 0.9 ;
      p2.l_convex = 0.9 ;
      p2.momentum = 0 ;
      p2.integration_type = INTEGRATE_MOMENTUM ;
      MRISrestoreVertexPositions(mris, ORIGINAL_VERTICES) ;
#if 0
      p2.flags |= IPFLAG_NO_SELF_INT_TEST ;
      printf("expanding surface....\n") ;
      MRISexpandSurface(mris, 4.0, &p2) ;  // push it away from fissure
#endif
      p2.niterations = 100 ;
      MRISunfold(mris, &p2, 1) ;
      p2.niterations = 300 ;
      p2.l_unfold *= 0.25 ;
      MRISunfold(mris, &p2, 1) ;
      p2.l_unfold *= 0.25 ;
      MRISunfold(mris, &p2, 1) ;
#if 0
      printf("smoothing unfolded surface..\n");
      p2.niterations = 200 ;
      p2.l_unfold = 0 ;  // just smooth it
      MRISunfold(mris, &p2, max_passes) ;
#endif
      parms.start_t = p2.start_t ;
      parms.l_unfold = parms.l_convex = parms.l_boundary = parms.l_expand=0 ;
      MRIfree(&parms.mri_dist) ;
    }

    sprintf(in_surf_fname, "%s/%s.%s", path, hemi, original_surf_name) ;
    if (!sphere_flag && !one_surf_flag)
      MRISreadOriginalProperties(mris, original_surf_name) ;
    if (randomly_flatten)
      MRISflattenPatchRandomly(mris) ;
    else
      MRISflattenPatch(mris) ;

    /* optimize metric properties of flat map */
    fprintf(stderr,"minimizing metric distortion induced by projection...\n");
    MRISscaleBrain(mris, mris, scale) ;
    MRIScomputeMetricProperties(mris) ;
    MRISunfold(mris, &parms, max_passes) ;
    MRIScenter(mris, mris) ;
    fprintf(stderr, "writing flattened patch to %s\n", out_patch_fname) ;
    MRISwritePatch(mris, out_patch_fname) ;
  }

  if (plane_flag || sphere_flag)
  {
    char fname[STRLEN] ;
    FILE *fp ;

#if 0
    sprintf(fname, "%s.%s.out",
            mris->hemisphere == RIGHT_HEMISPHERE ? "rh" : "lh",
            parms.base_name);
#else
    sprintf(fname, "flatten.log") ;
#endif
    fp = fopen(fname, "a") ;

    if (plane_flag)
      MRIScomputeAnalyticDistanceError(mris, MRIS_PLANE, fp) ;
    else if (sphere_flag)
      MRIScomputeAnalyticDistanceError(mris, MRIS_SPHERE, fp) ;
    fclose(fp) ;
  }

  if (mri_overlay)
  {
    MRI  *mri_flattened ;
    char fname[STRLEN] ;

    // if it is NxNx1x1 reshape it to be Nx1x1xN
    if ( mri_overlay->width == mri_overlay->height &&
       mri_overlay->depth == 1 &&
       mri_overlay->nframes == 1)
    {
      MRI *mri_tmp ;
      printf("reshaping to move 2nd dimension to time\n") ;
      mri_tmp = mri_reshape( mri_overlay, mri_overlay->width, 1, 1, mri_overlay->height);
      MRIfree( &mri_overlay );
      mri_overlay = mri_tmp;
    }

    // put in some special code that knows about icosahedra
    if (mris->nvertices == 163842 ||  // ic7
        mris->nvertices == 40962 ||  // ic6
        mris->nvertices == 10242 ||  // ic5
        mris->nvertices == 2562)  // ic4
    {
      int nvals, start_index, end_index ;
      MRI *mri_tmp ;
      
      printf("cross-hemispheric correlation matrix detected, reshaping...\n") ;
      nvals = mri_overlay->width * mri_overlay->height * mri_overlay->depth ;
      if (nvals == 2*mris->nvertices)   // it's a corr matrix for both hemis
      {
        if (mris->hemisphere == LEFT_HEMISPHERE || mris->hemisphere == RIGHT_HEMISPHERE)
        {
          if (mris->hemisphere == LEFT_HEMISPHERE)
          {
            start_index = 0 ; 
            end_index = mris->nvertices-1 ;
          }
          else
          {
            start_index = mris->nvertices ; 
            end_index = 2*mris->nvertices-1 ;
          }
          mri_tmp = MRIextract(mri_overlay, NULL, start_index, 0, 0, mris->nvertices, 1, 1) ;
          MRIfree(&mri_overlay) ;
          mri_overlay = mri_tmp;
        }
        else // both hemis
        {
        }
      }
    }
    
    printf("resampling overlay (%d x %d x %d x %d) into flattened coordinates..\n",
           mri_overlay->width, mri_overlay->height, mri_overlay->depth, mri_overlay->nframes) ;
    if (synth_name)
    {
      LABEL *area_lh, *area_rh ;
      char  fname[STRLEN], path[STRLEN], fname_no_path[STRLEN] ;
      int   vno, n, vno2, n2 ;

      MRIsetValues(mri_overlay, 0) ;
      FileNameOnly(synth_name, fname_no_path) ;
      FileNamePath(synth_name, path) ;
      sprintf(fname, "%s/lh.%s", path, fname_no_path) ;
      area_lh = LabelRead(NULL, fname) ;
      if (area_lh == NULL)
        ErrorExit(ERROR_NOFILE, "%s: could not read label from %s",
                  Progname,fname) ;
      sprintf(fname, "%s/rh.%s", path, fname_no_path) ;
      area_rh = LabelRead(NULL, fname) ;
      if (area_rh == NULL)
        ErrorExit(ERROR_NOFILE, "%s: could not read label from %s",
                  Progname,fname) ;
#if 0
      for (n = 0 ; n < area_lh->n_points ; n++)
      {
        vno = area_lh->lv[n].vno ;
        MRIsetVoxVal(mri_overlay, vno, 0, 0, vno, 1) ;
	printf("synthesizing map with vno %d: (%2.1f, %2.1f)\n", vno, mris->vertices[vno].x, mris->vertices[vno].y) ;
        break ;
      }
#else
      for (n = 0 ; n < area_lh->n_points ; n++)
      {
        vno = area_lh->lv[n].vno ;
        if (vno >= 0)
        {
          for (n2 = 0 ; n2 < area_lh->n_points ; n2++)
          {
            vno2 = area_lh->lv[n2].vno ;
            if (vno2 >= 0)
              MRIsetVoxVal(mri_overlay, vno, 0, 0, vno2, 1) ;
          }
          for (n2 = 0 ; n2 < area_rh->n_points ; n2++)
          {
            vno2 = area_rh->lv[n2].vno ;
            if (vno2 >= 0)
              MRIsetVoxVal(mri_overlay, vno, 0, 0, mris->nvertices+vno2, 1) ;
          }
        }
      }
#endif
    }

    mri_flattened = MRIflattenOverlay(mris, mri_overlay, NULL, 1.0, label_overlay, &mri_vertices) ;
    printf("writing flattened overlay to %s\n", out_patch_fname) ;
    MRIwrite(mri_flattened, out_patch_fname) ;
    MRIfree(&mri_flattened) ;

    FileNameRemoveExtension(out_patch_fname, fname) ;
    strcat(fname, ".vnos.mgz") ;
    printf("writing flattened vertex #s to %s\n", fname) ;
    MRIwrite(mri_vertices, fname) ;
    MRIfree(&mri_vertices) ;
  }
#if 0
  sprintf(fname, "%s.area_error", out_fname) ;
  printf("writing area errors to %s\n", fname) ;
  MRISwriteAreaError(mris, fname) ;
  sprintf(fname, "%s.angle_error", out_fname) ;
  printf("writing angle errors to %s\n", fname) ;
  MRISwriteAngleError(mris, fname) ;
  MRISfree(&mris) ;
#endif

  exit(0) ;
  return(0) ;  /* for ansi */
}
Esempio n. 6
0
int
main(int argc, char *argv[])
{
  char      **av, *out_fname ;
  int       ac, nargs ;
  GCA_MORPH *gcam ;
  int       msec, minutes, seconds ;
  struct timeb start ;
  MRI       *mri, *mri_jacobian, *mri_area, *mri_orig_area ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mri_jacobian.c,v 1.11 2011/12/10 22:47:57 fischl Exp $", "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

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

  TimerStart(&start) ;

  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(1) ;

  out_fname = argv[argc-1] ;
  gcam = GCAMread(argv[1]) ;
  
  if (gcam == NULL)
    ErrorExit(ERROR_BADPARM, "%s: could not read input morph %s\n", Progname,argv[1]);
  if (Gx >= 0 && atlas == 0)
    find_debug_node(gcam, Gx, Gy, Gz) ;

  mri = MRIread(argv[2]) ;
  if (gcam == NULL)
    ErrorExit(ERROR_BADPARM, "%s: could not read template volume %s\n", Progname,argv[2]);

  GCAMrasToVox(gcam, mri) ;
  if (init || tm3dfile)
    init_gcam_areas(gcam) ;
  if (atlas)
    {
      mri_area = GCAMwriteMRI(gcam, NULL, GCAM_AREA);
      mri_orig_area = GCAMwriteMRI(gcam, NULL, GCAM_ORIG_AREA);
    }
  else
    {
      mri_area = GCAMmorphFieldFromAtlas(gcam, mri, GCAM_AREA, 0, 0);
      mri_orig_area = GCAMmorphFieldFromAtlas(gcam, mri, GCAM_ORIG_AREA, 0, 0);
    }

  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
      MRIwrite(mri_orig_area, "o.mgz") ;
      MRIwrite(mri_area, "a.mgz") ;
    }
  if (Gx > 0)
    printf("area = %2.3f, orig = %2.3f\n", 
	   MRIgetVoxVal(mri_area, Gx, Gy, Gz,0),MRIgetVoxVal(mri_orig_area,Gx,Gy,Gz,0)) ;
  if (lta)
    {
      double det ;
      if  (lta->type == LINEAR_RAS_TO_RAS)
	LTArasToVoxelXform(lta, mri, mri) ;
      det = MatrixDeterminant(lta->xforms[0].m_L) ;
      printf("correcting transform with det=%2.3f\n", det) ;
      MRIscalarMul(mri_orig_area, mri_orig_area, 1/det) ;
    }
  
  if (! FZERO(sigma))
    {
      MRI *mri_kernel, *mri_smooth ;
      mri_kernel = MRIgaussian1d(sigma, 100) ;
      mri_smooth = MRIconvolveGaussian(mri_area, NULL, mri_kernel) ;
      MRIfree(&mri_area) ; mri_area = mri_smooth ;
      mri_smooth = MRIconvolveGaussian(mri_orig_area, NULL, mri_kernel) ;
      MRIfree(&mri_orig_area) ; mri_orig_area = mri_smooth ;

      MRIfree(&mri_kernel) ; 
    }
  if (Gx > 0)
    printf("after smoothing area = %2.3f, orig = %2.3f\n", 
	   MRIgetVoxVal(mri_area, Gx, Gy, Gz,0),MRIgetVoxVal(mri_orig_area,Gx,Gy,Gz,0)) ;
  mri_jacobian = MRIdivide(mri_area, mri_orig_area, NULL) ;
  if (Gx > 0)
    printf("jacobian = %2.3f\n", MRIgetVoxVal(mri_jacobian, Gx, Gy, Gz,0)) ;
  if (atlas)
    mask_invalid(gcam, mri_jacobian) ;
  if (use_log)
    {
      MRIlog10(mri_jacobian, NULL, mri_jacobian, 0) ;
      if (zero_mean)
	MRIzeroMean(mri_jacobian, mri_jacobian) ;
      if (Gx > 0)
	printf("log jacobian = %2.3f\n", MRIgetVoxVal(mri_jacobian, Gx, Gy, Gz,0)) ;
    }
  fprintf(stderr, "writing to %s...\n", out_fname) ;
  MRIwrite(mri_jacobian, out_fname) ;
  MRIfree(&mri_jacobian) ;
  if (write_areas)
    {
      char fname[STRLEN] ;
      sprintf(fname, "%s_area.mgz", out_fname) ;
      printf("writing area to %s\n", fname) ;
      MRIwrite(mri_area, fname) ;
      sprintf(fname, "%s_orig_area.mgz", out_fname) ;
      printf("writing orig area to %s\n", fname) ;
      MRIwrite(mri_orig_area, fname) ;
    }
  if (atlas && DIAG_WRITE && DIAG_VERBOSE_ON)
    {
      char fname[STRLEN] ;
      FileNameRemoveExtension(out_fname, out_fname) ;
      mri_area = GCAMwriteMRI(gcam, mri_area, GCAM_MEANS);
      sprintf(fname, "%s_means.mgz", out_fname) ;
      printf("writing means to %s\n", fname) ;
      MRIwrite(mri_area, fname) ;
      sprintf(fname, "%s_labels.mgz", out_fname) ;
      mri_area = GCAMwriteMRI(gcam, mri_area, GCAM_LABEL);
      printf("writing labels to %s\n", fname) ;
      MRIwrite(mri_area, fname) ;
    }
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ;seconds = seconds % 60 ;
  fprintf(stderr, "jacobian calculation took %d minutes and %d seconds.\n", minutes, seconds) ;
  exit(0) ;
  return(0) ;
}
int
main(int argc, char *argv[]) {
  char         *ref_fname, *in_fname, *out_fname, fname[STRLEN], **av ;
  MRI          *mri_ref, *mri_in, *mri_orig, *mri_in_red, *mri_ref_red,
  *mri_in_tmp, *mri_ref_tmp, *mri_ref_orig, *mri_in_orig ;
  int          ac, nargs, i, msec, minutes, seconds ;
  struct timeb start ;
  MATRIX       *m_L ;

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

  parms.mri_crop = NULL ;
  parms.l_intensity = 1.0f ;
  parms.niterations = 100 ;
  parms.levels = -1 ;   /* use default */
  parms.dt = 1e-6 ;  /* was 5e-6 */
  parms.tol = INTEGRATION_TOL*5 ;

  parms.dt = 5e-6 ;  /* was 5e-6 */
  parms.tol = 1e-3 ;
  parms.momentum = 0.8 ;
  parms.max_levels = MAX_LEVELS ;
  parms.factor = 1.0 ;
  parms.niterations = 25 ;
  Progname = argv[0] ;


  DiagInit(NULL, NULL, NULL) ;
  ErrorInit(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)
    ErrorExit(ERROR_BADPARM,
              "usage: %s <in brain> <template> <output file name>\n",
              Progname) ;

  in_fname = argv[1] ;
  ref_fname = argv[2] ;
  if (xform_mean_fname) {
    int   sno, nsubjects ;
    FILE  *fp ;

    parms.m_xform_mean = MatrixAsciiRead(xform_mean_fname, NULL) ;
    if (!parms.m_xform_mean)
      ErrorExit(Gerror, "%s: could not read parameter means from %s",
                Progname, xform_mean_fname) ;

    fp = fopen(xform_covariance_fname, "r") ;
    if (!fp)
      ErrorExit(ERROR_NOFILE, "%s: could not read covariances from %s",
                Progname, xform_covariance_fname) ;

    fscanf(fp, "nsubjects=%d", &nsubjects) ;
    printf("reading %d transforms...\n", nsubjects) ;

    parms.m_xforms = (MATRIX **)calloc(nsubjects, sizeof(MATRIX *)) ;
    if (!parms.m_xforms)
      ErrorExit(ERROR_NOMEMORY, "%s: could not allocate array of %d xforms",
                Progname, nsubjects) ;
    for (sno = 0 ; sno < nsubjects ; sno++) {
      parms.m_xforms[sno] = MatrixAsciiReadFrom(fp, NULL) ;
      if (!parms.m_xforms[sno])
        ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %dth xform",
                  Progname, sno) ;

    }
    parms.m_xform_covariance = MatrixAsciiReadFrom(fp, NULL) ;
    if (!parms.m_xform_covariance)
      ErrorExit(Gerror, "%s: could not read parameter covariance from %s",
                Progname, xform_covariance_fname) ;
    fclose(fp) ;
    parms.l_priors = l_priors ;
    parms.nxforms = nsubjects ;
  }
  out_fname = argv[3] ;
  FileNameOnly(out_fname, fname) ;
  FileNameRemoveExtension(fname, fname) ;
  strcpy(parms.base_name, fname) ;
  fprintf(stderr, "logging results to %s.log\n", parms.base_name) ;

  TimerStart(&start) ;
  fprintf(stderr, "reading '%s'...\n", ref_fname) ;
  fflush(stderr) ;
  mri_ref = MRIread(ref_fname) ;
  if (!mri_ref)
    ErrorExit(ERROR_NOFILE, "%s: could not open reference volume %s.\n",
              Progname, ref_fname) ;
  if (mri_ref->type != MRI_UCHAR) {
    MRI *mri_tmp ;

    mri_tmp = MRIchangeType(mri_ref, MRI_UCHAR, 0.0, 0.999, FALSE) ;
    MRIfree(&mri_ref) ;
    mri_ref = mri_tmp ;
  }

  if (var_fname)  /* read in a volume of standard deviations */
  {
    MRI *mri_var, *mri_tmp ;

    fprintf(stderr, "reading '%s'...\n", var_fname) ;
    mri_var = MRIread(var_fname) ;
    if (!mri_var)
      ErrorExit(ERROR_NOFILE, "%s: could not open variance volume %s.\n",
                Progname, var_fname) ;
    mri_tmp = MRIconcatenateFrames(mri_ref, mri_var, NULL) ;
    MRIfree(&mri_var) ;
    MRIfree(&mri_ref) ;
    mri_ref = mri_tmp ;
  }
  fprintf(stderr, "reading '%s'...\n", in_fname) ;
  fflush(stderr) ;
  mri_orig = mri_in = MRIread(in_fname) ;
  if (!mri_in)
    ErrorExit(ERROR_NOFILE, "%s: could not open input volume %s.\n",
              Progname, in_fname) ;
  if (mri_in->type != MRI_UCHAR) {
    MRI *mri_tmp ;

    mri_orig = mri_tmp = MRIchangeType(mri_in, MRI_UCHAR, 0.0, 0.999, FALSE) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }

  /* make sure they are the same size */
  if (mri_in->width  != mri_ref->width ||
      mri_in->height != mri_ref->height  ||
      mri_in->depth  != mri_ref->depth) {
    int  width, height, depth ;
    MRI  *mri_tmp ;

    width = MAX(mri_in->width, mri_ref->width) ;
    height = MAX(mri_in->height, mri_ref->height) ;
    depth = MAX(mri_in->depth, mri_ref->depth) ;
    mri_tmp = MRIalloc(width, height, depth, MRI_UCHAR) ;
    MRIextractInto(mri_in, mri_tmp, 0, 0, 0,
                   mri_in->width, mri_in->height, mri_in->depth, 0, 0, 0) ;
#if 0
    MRIfree(&mri_in) ;
#else
    parms.mri_in = mri_in ;
#endif
    mri_in = mri_orig = mri_tmp ;

    mri_tmp = MRIallocSequence(width, height,depth,MRI_UCHAR,mri_ref->nframes);
    MRIextractInto(mri_ref, mri_tmp, 0, 0, 0,
                   mri_ref->width, mri_ref->height, mri_ref->depth, 0, 0, 0) ;
#if 0
    MRIfree(&mri_ref) ;
#else
    parms.mri_in = mri_in ;
#endif
    mri_ref = mri_tmp ;
  }


  if (!FZERO(tx) || !FZERO(ty) || !FZERO(tz)) {
    MRI *mri_tmp ;

    fprintf(stderr, "translating second volume by (%2.1f, %2.1f, %2.1f)\n",
            tx, ty, tz) ;
    mri_tmp = MRItranslate(mri_in, NULL, tx, ty, tz) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }

  if (!FZERO(rzrot)) {
    MRI *mri_tmp ;

    fprintf(stderr,
            "rotating second volume by %2.1f degrees around Z axis\n",
            (float)DEGREES(rzrot)) ;
    mri_tmp = MRIrotateZ_I(mri_in, NULL, rzrot) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }
  if (!FZERO(rxrot)) {
    MRI *mri_tmp ;

    fprintf(stderr,
            "rotating second volume by %2.1f degrees around X axis\n",
            (float)DEGREES(rxrot)) ;
    mri_tmp = MRIrotateX_I(mri_in, NULL, rxrot) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }
  if (!FZERO(ryrot)) {
    MRI *mri_tmp ;

    fprintf(stderr,
            "rotating second volume by %2.1f degrees around Y axis\n",
            (float)DEGREES(ryrot)) ;
    mri_tmp = MRIrotateY_I(mri_in, NULL, ryrot) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }

  if (!transform_loaded)   /* wasn't preloaded */
    parms.lta = LTAalloc(1, mri_in) ;

  if (!FZERO(blur_sigma)) {
    MRI *mri_kernel, *mri_tmp ;

    mri_kernel = MRIgaussian1d(blur_sigma, 100) ;
    mri_tmp = MRIconvolveGaussian(mri_in, NULL, mri_kernel) ;
    mri_in = mri_tmp ;
    MRIfree(&mri_kernel) ;
  }
  MRIscaleMeanIntensities(mri_in, mri_ref, mri_in);

  mri_ref_orig = mri_ref ;
  mri_in_orig = mri_in ;
  if (nreductions > 0) {
    mri_in_red = mri_in_tmp = MRIcopy(mri_in, NULL) ;
    mri_ref_red = mri_ref_tmp = MRIcopy(mri_ref, NULL) ;
    for (i = 0 ; i < nreductions ; i++) {
      mri_in_red = MRIreduceByte(mri_in_tmp, NULL) ;
      mri_ref_red = MRIreduceMeanAndStdByte(mri_ref_tmp,NULL);
      MRIfree(&mri_in_tmp);
      MRIfree(&mri_ref_tmp) ;
      mri_in_tmp = mri_in_red ;
      mri_ref_tmp = mri_ref_red ;
    }
    mri_in = mri_in_red ;
    mri_ref = mri_ref_red ;
  }
  /* for diagnostics */
  if (full_res) {
    parms.mri_ref = mri_ref ;
    parms.mri_in = mri_in ;
  } else {
    parms.mri_ref = mri_ref_orig ;
    parms.mri_in = mri_in_orig ;
  }

  m_L = initialize_transform(mri_in, mri_ref, &parms) ;

  if (use_gradient) {
    MRI  *mri_in_mag, *mri_ref_mag, *mri_grad, *mri_mag ;

    printf("computing gradient magnitude of input image...\n") ;
    mri_mag = MRIalloc(mri_in->width, mri_in->height, mri_in->depth,MRI_FLOAT);
    MRIcopyHeader(mri_in, mri_mag) ;
    mri_grad = MRIsobel(mri_in, NULL, mri_mag) ;
    MRIfree(&mri_grad) ;

    /* convert it to ubytes */
    MRIvalScale(mri_mag, mri_mag, 0.0f, 255.0f) ;
    mri_in_mag = MRIclone(mri_in, NULL) ;
    MRIcopy(mri_mag, mri_in_mag) ;
    MRIfree(&mri_mag) ;

    /* now compute gradient of ref image */
    printf("computing gradient magnitude of reference image...\n") ;
    mri_mag = MRIalloc(mri_ref->width, mri_ref->height, mri_ref->depth,MRI_FLOAT);
    MRIcopyHeader(mri_ref, mri_mag) ;
    mri_grad = MRIsobel(mri_ref, NULL, mri_mag) ;
    MRIfree(&mri_grad) ;

    /* convert it to ubytes */
    MRIvalScale(mri_mag, mri_mag, 0.0f, 255.0f) ;
    mri_ref_mag = MRIclone(mri_ref, NULL) ;
    MRIcopy(mri_mag, mri_ref_mag) ;
    MRIfree(&mri_mag) ;

    register_mri(mri_in_mag, mri_ref_mag, &parms, m_L) ;
    MRIfree(&mri_in_mag) ;
    MRIfree(&mri_ref_mag) ;
  }
  register_mri(mri_in, mri_ref, &parms, m_L) ;
  if (check_crop_flag)  /* not working yet! */
  {
    printf("searching for cropped regions in the input image...\n") ;
    parms.mri_crop = find_cropping(mri_orig, mri_ref, &parms) ;
    MRIwrite(parms.mri_crop, "crop.mgh") ;
    register_mri(mri_in, mri_ref, &parms, m_L) ;
  }

  if (voxel_coords) {
    printf("transforming xform to voxel coordinates...\n") ;
    MRIrasXformToVoxelXform(mri_in_orig, mri_ref_orig,
                            parms.lta->xforms[0].m_L,
                            parms.lta->xforms[0].m_L);
    if (Gdiag & DIAG_WRITE) {
      MRI *mri_tmp ;

      mri_tmp = MRIlinearTransform(mri_in_orig, NULL,parms.lta->xforms[0].m_L);
      MRIwriteImageViews(mri_tmp, "morphed", IMAGE_SIZE) ;
      MRIfree(&mri_tmp) ;
    }
  }
  // save src and target info in lta
  getVolGeom(mri_in_orig, &parms.lta->xforms[0].src);
  getVolGeom(mri_ref_orig, &parms.lta->xforms[0].dst);
  fprintf(stderr, "writing output transformation to %s...\n", out_fname) ;
  if (invert_flag) {
    MATRIX *m_tmp ;

    m_tmp = MatrixInverse(parms.lta->xforms[0].m_L, NULL) ;
    MatrixFree(&parms.lta->xforms[0].m_L) ;
    // change src and dst
    getVolGeom(mri_in_orig, &parms.lta->xforms[0].dst);
    getVolGeom(mri_ref_orig, &parms.lta->xforms[0].src);
    parms.lta->xforms[0].m_L = m_tmp ;
  }
  //
  LTAwriteEx(parms.lta, out_fname) ;
  //
  if (mri_ref)
    MRIfree(&mri_ref) ;
  if (mri_in)
    MRIfree(&mri_in) ;
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  fprintf(stderr, "registration took %d minutes and %d seconds.\n",
          minutes, seconds) ;
  exit(0) ;
  return(0) ;
}