int
main(int argc, char *argv[]) {
    char         **av, fname[STRLEN], *out_fname, *subject_name, *cp ;
    int          ac, nargs, i, n, noint = 0, options ;
    int          msec, minutes, seconds, nsubjects, input ;
    struct timeb start ;
    GCA          *gca ;
    MRI          *mri_seg, *mri_tmp, *mri_inputs ;
    TRANSFORM    *transform ;
    LTA          *lta;
    GCA_BOUNDARY *gcab ;

    Progname = argv[0] ;

    ErrorInit(NULL, NULL, NULL) ;
    DiagInit(NULL, NULL, NULL) ;

    TimerStart(&start) ;

    parms.use_gradient = 0 ;
    spacing = 8 ;

    /* rkt: check for and handle version tag */
    nargs = handle_version_option
            (argc, argv,
             "$Id: mri_gcab_train.c,v 1.4 2011/03/16 20:23:33 fischl Exp $",
             "$Name:  $");
    if (nargs && argc - nargs == 1)
        exit (0);
    argc -= nargs;

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

    printf("reading gca from %s\n", argv[1]) ;
    gca = GCAread(argv[1]) ;
    if (!gca)
        exit(Gerror) ;

    if (!strlen(subjects_dir)) /* hasn't been set on command line */
    {
        cp = getenv("SUBJECTS_DIR") ;
        if (!cp)
            ErrorExit(ERROR_BADPARM, "%s: SUBJECTS_DIR not defined in environment",
                      Progname);
        strcpy(subjects_dir, cp) ;
        if (argc < 4)
            usage_exit(1) ;
    }

    // options parsed.   subjects and gca name remaining
    out_fname = argv[argc-1] ;
    nsubjects = argc-3 ;
    for (options = i = 0 ; i < nsubjects ; i++) {
        if (argv[i+1][0] == '-') {
            nsubjects-- ;
            options++ ;
        }
    }

    printf("training on %d subject and writing results to %s\n",
           nsubjects, out_fname) ;

    n = 0 ;

    gcab = GCABalloc(gca, 8, 0, 30, 10, target_label);
    strcpy(gcab->gca_fname, argv[1]) ;
    // going through the subject one at a time
    for (nargs = i = 0 ; i < nsubjects+options ; i++) {
        subject_name = argv[i+2] ;
        //////////////////////////////////////////////////////////////
        printf("***************************************"
               "************************************\n");
        printf("processing subject %s, %d of %d...\n", subject_name,i+1-nargs,
               nsubjects);

        if (stricmp(subject_name, "-NOINT") == 0) {
            printf("not using intensity information for subsequent subjects...\n");
            noint = 1 ;
            nargs++ ;
            continue ;
        } else if (stricmp(subject_name, "-INT") == 0) {
            printf("using intensity information for subsequent subjects...\n");
            noint = 0 ;
            nargs++ ;
            continue ;
        }
        // reading this subject segmentation
        sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, seg_dir) ;
        if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
            fprintf(stderr, "Reading segmentation from %s...\n", fname) ;
        mri_seg = MRIread(fname) ;
        if (!mri_seg)
            ErrorExit(ERROR_NOFILE, "%s: could not read segmentation file %s",
                      Progname, fname) ;
        if ((mri_seg->type != MRI_UCHAR) && (mri_seg->type != MRI_FLOAT)) {
            ErrorExit
            (ERROR_NOFILE,
             "%s: segmentation file %s is not type UCHAR or FLOAT",
             Progname, fname) ;
        }

        if (binarize) {
            int j ;
            for (j = 0 ; j < 256 ; j++) {
                if (j == binarize_in)
                    MRIreplaceValues(mri_seg, mri_seg, j, binarize_out) ;
                else
                    MRIreplaceValues(mri_seg, mri_seg, j, 0) ;
            }
        }
        if (insert_fname) {
            MRI *mri_insert ;

            sprintf(fname, "%s/%s/mri/%s",
                    subjects_dir, subject_name, insert_fname) ;
            mri_insert = MRIread(fname) ;
            if (mri_insert == NULL)
                ErrorExit(ERROR_NOFILE,
                          "%s: could not read volume from %s for insertion",
                          Progname, insert_fname) ;

            MRIbinarize(mri_insert, mri_insert, 1, 0, insert_label) ;
            MRIcopyLabel(mri_insert, mri_seg, insert_label) ;
            MRIfree(&mri_insert) ;
        }

        replaceLabels(mri_seg) ;
        MRIeraseBorderPlanes(mri_seg, 1) ;

        for (input = 0 ; input < gca->ninputs ; input++) {
            //////////// set the gca type //////////////////////////////
            // is this T1/PD training?
            // how can we allow flash data training ???????
            // currently checks the TE, TR, FA to be the same for all inputs
            // thus we cannot allow flash data training.
            ////////////////////////////////////////////////////////////

            sprintf(fname, "%s/%s/mri/%s",
                    subjects_dir, subject_name,input_names[input]);
            if (DIAG_VERBOSE_ON)
                printf("reading co-registered input from %s...\n", fname) ;
            fprintf(stderr, "   reading input %d: %s\n", input, fname);
            mri_tmp = MRIread(fname) ;
            if (!mri_tmp)
                ErrorExit
                (ERROR_NOFILE,
                 "%s: could not read image from file %s", Progname, fname) ;
            // input check 1
            if (getSliceDirection(mri_tmp) != MRI_CORONAL) {
                ErrorExit
                (ERROR_BADPARM,
                 "%s: must be in coronal direction, but it is not\n",
                 fname);
            }
            // input check 2
            if (mri_tmp->xsize != 1 || mri_tmp->ysize != 1 || mri_tmp->zsize != 1) {
                ErrorExit
                (ERROR_BADPARM,
                 "%s: must have 1mm voxel size, but have (%f, %f, %f)\n",
                 fname, mri_tmp->xsize, mri_tmp->ysize, mri_tmp->ysize);
            }
            // input check 3 is removed.  now we can handle c_(ras) != 0 case
            // input check 4
            if (i == 0) {
                TRs[input] = mri_tmp->tr ;
                FAs[input] = mri_tmp->flip_angle ;
                TEs[input] = mri_tmp->te ;
            } else if (!FEQUAL(TRs[input],mri_tmp->tr) ||
                       !FEQUAL(FAs[input],mri_tmp->flip_angle) ||
                       !FEQUAL(TEs[input], mri_tmp->te))
                ErrorExit
                (ERROR_BADPARM,
                 "%s: subject %s input volume %s: sequence parameters "
                 "(%2.1f, %2.1f, %2.1f)"
                 "don't match other inputs (%2.1f, %2.1f, %2.1f)",
                 Progname, subject_name, fname,
                 mri_tmp->tr, DEGREES(mri_tmp->flip_angle), mri_tmp->te,
                 TRs[input], DEGREES(FAs[input]), TEs[input]) ;
            // first time do the following
            if (input == 0) {
                int nframes = gca->ninputs ;

                ///////////////////////////////////////////////////////////
                mri_inputs =
                    MRIallocSequence(mri_tmp->width, mri_tmp->height, mri_tmp->depth,
                                     mri_tmp->type, nframes) ;
                if (!mri_inputs)
                    ErrorExit
                    (ERROR_NOMEMORY,
                     "%s: could not allocate input volume %dx%dx%dx%d",
                     mri_tmp->width, mri_tmp->height, mri_tmp->depth,nframes) ;
                MRIcopyHeader(mri_tmp, mri_inputs) ;
            }
            // -mask option ////////////////////////////////////////////
            if (mask_fname)
            {
                MRI *mri_mask ;

                sprintf(fname, "%s/%s/mri/%s",
                        subjects_dir, subject_name, mask_fname);
                printf("reading volume %s for masking...\n", fname) ;
                mri_mask = MRIread(fname) ;
                if (!mri_mask)
                    ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n",
                              Progname, fname) ;

                MRImask(mri_tmp, mri_mask, mri_tmp, 0, 0) ;
                MRIfree(&mri_mask) ;
            }
            MRIcopyFrame(mri_tmp, mri_inputs, 0, input) ;
            MRIfree(&mri_tmp) ;
        }// end of inputs per subject


        /////////////////////////////////////////////////////////
        // xform_name is given, then we can use the consistent c_(r,a,s) for gca
        /////////////////////////////////////////////////////////
        if (xform_name)
        {
            // we read talairach.xfm which is a RAS-to-RAS
            sprintf(fname, "%s/%s/mri/transforms/%s",
                    subjects_dir, subject_name, xform_name) ;
            if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
                printf("INFO: reading transform file %s...\n", fname);
            if (!FileExists(fname))
            {
                fprintf(stderr,"ERROR: cannot find transform file %s\n",fname);
                exit(1);
            }
            transform = TransformRead(fname);
            if (!transform)
                ErrorExit(ERROR_NOFILE, "%s: could not read transform from file %s",
                          Progname, fname);

            modify_transform(transform, mri_inputs, gca);
            // Here we do 2 things
            // 1. modify gca direction cosines to
            // that of the transform destination (both linear and non-linear)
            // 2. if ras-to-ras transform,
            // then change it to vox-to-vox transform (linear case)

            // modify transform to store inverse also
            TransformInvert(transform, mri_inputs) ;
            // verify inverse
            lta = (LTA *) transform->xform;
        }
        else
        {
            GCAreinit(mri_inputs, gca);
            // just use the input value, since dst = src volume
            transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ;
        }


        ////////////////////////////////////////////////////////////////////
        // train gca
        ////////////////////////////////////////////////////////////////////
        // segmentation is seg volume
        // inputs       is the volumes of all inputs
        // transform    is for this subject
        // noint        is whether to use intensity information or not
        GCABtrain(gcab, mri_inputs, mri_seg, transform, target_label) ;
        MRIfree(&mri_seg) ;
        MRIfree(&mri_inputs) ;
        TransformFree(&transform) ;
    }
    GCABcompleteTraining(gcab) ;

    if (smooth > 0) {
        printf("regularizing conditional densities with smooth=%2.2f\n", smooth) ;
        GCAregularizeConditionalDensities(gca, smooth) ;
    }
    if (navgs) {
        printf("applying mean filter %d times to conditional densities\n", navgs) ;
        GCAmeanFilterConditionalDensities(gca, navgs) ;
    }

    printf("writing trained GCAB to %s...\n", out_fname) ;
    if (GCABwrite(gcab, out_fname) != NO_ERROR)
        ErrorExit
        (ERROR_BADFILE, "%s: could not write gca to %s", Progname, out_fname) ;

    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
        MRI *mri ;

        mri = GCAbuildMostLikelyVolume(gca, NULL) ;
        MRIwrite(mri, "m.mgz") ;
        MRIfree(&mri) ;
    }

    if (histo_fname) {
        FILE *fp ;
        int   histo_counts[10000], xn, yn, zn, max_count ;
        GCA_NODE  *gcan ;

        memset(histo_counts, 0, sizeof(histo_counts)) ;
        fp = fopen(histo_fname, "w") ;
        if (!fp)
            ErrorExit(ERROR_BADFILE, "%s: could not open histo file %s",
                      Progname, histo_fname) ;

        max_count = 0 ;
        for (xn = 0 ; xn < gca->node_width;  xn++) {
            for (yn = 0 ; yn < gca->node_height ; yn++) {
                for (zn = 0 ; zn < gca->node_depth ; zn++) {
                    gcan = &gca->nodes[xn][yn][zn] ;
                    if (gcan->nlabels < 1)
                        continue ;
                    if (gcan->nlabels == 1 && IS_UNKNOWN(gcan->labels[0]))
                        continue ;
                    histo_counts[gcan->nlabels]++ ;
                    if (gcan->nlabels > max_count)
                        max_count = gcan->nlabels ;
                }
            }
        }
        max_count = 20 ;
        for (xn = 1 ; xn < max_count ;  xn++)
            fprintf(fp, "%d %d\n", xn, histo_counts[xn]) ;
        fclose(fp) ;
    }

    GCAfree(&gca) ;
    msec = TimerStop(&start) ;
    seconds = nint((float)msec/1000.0f) ;
    minutes = seconds / 60 ;
    seconds = seconds % 60 ;
    printf("classifier array training took %d minutes"
           " and %d seconds.\n", minutes, seconds) ;
    exit(0) ;
    return(0) ;
}
int
main(int argc, char *argv[])
{
  char         *gca_fname, *in_fname, *out_fname, **av, *xform_fname, fname[STRLEN] ;
  MRI          *mri_in, *mri_norm = NULL, *mri_tmp, *mri_ctrl = NULL ;
  GCA          *gca ;
  int          ac, nargs, nsamples, msec, minutes, seconds;
  int          i, struct_samples, norm_samples = 0, n, input, ninputs ;
  struct timeb start ;
  GCA_SAMPLE   *gcas, *gcas_norm = NULL, *gcas_struct ;
  TRANSFORM    *transform = NULL ;
  char         cmdline[CMD_LINE_LEN], line[STRLEN], *cp, subject[STRLEN], sdir[STRLEN], base_name[STRLEN] ;
  FILE         *fp ;

  make_cmd_version_string
    (argc, argv,
     "$Id: mri_cal_normalize.c,v 1.2.2.1 2011/08/31 00:32:41 nicks Exp $",
     "$Name: stable5 $", cmdline);

  /* rkt: check for and handle version tag */
  nargs = handle_version_option
    (argc, argv,
     "$Id: mri_cal_normalize.c,v 1.2.2.1 2011/08/31 00:32:41 nicks Exp $",
     "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

  setRandomSeed(-1L) ;
  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 < 6)
    ErrorExit
      (ERROR_BADPARM,
       "usage: %s [<options>] <longitudinal time point file> <in vol> <atlas> <transform file> <out vol> \n",
       Progname) ;
  in_fname = argv[2] ;
  gca_fname = argv[3] ;
  xform_fname = argv[4] ;
  out_fname = argv[5] ;

  transform = TransformRead(xform_fname) ;
  if (transform == NULL)
    ErrorExit(ERROR_NOFILE, "%s: could not read transform from %s", Progname, xform_fname) ;
  if (read_ctrl_point_fname)
  {
    mri_ctrl = MRIread(read_ctrl_point_fname) ;
    if (mri_ctrl == NULL)
      ErrorExit(ERROR_NOFILE, "%s: could not read precomputed control points from %s", 
                Progname, read_ctrl_point_fname) ;
  }
  TimerStart(&start) ;
  printf("reading atlas from '%s'...\n", gca_fname) ;
  fflush(stdout) ;

  gca = GCAread(gca_fname) ;
  if (gca == NULL)
    ErrorExit(ERROR_NOFILE, "%s: could not open GCA %s.\n",Progname, gca_fname) ;
  GCAregularizeConditionalDensities(gca, .5) ;

  FileNamePath(argv[1], sdir) ;
  cp = strrchr(sdir, '/') ; 
  if (cp)
  {
    strcpy(base_name, cp+1) ;
    *cp = 0 ;  // remove last component of path, which is base subject name
  }
  ninputs = 0 ;
  fp = fopen(argv[1], "r") ;
  if (fp == NULL)
    ErrorExit(ERROR_NOFILE, "%s: could not read time point file %s", argv[1]) ;

  do
  {
    cp = fgetl(line, STRLEN-1, fp) ;
    if (cp != NULL && strlen(cp) > 0)
    {
      subjects[ninputs] = (char *)calloc(strlen(cp)+1, sizeof(char)) ;
      strcpy(subjects[ninputs], cp) ;
      ninputs++ ;
    }
  } while (cp != NULL && strlen(cp) > 0) ;
  fclose(fp) ;
  printf("processing %d timepoints in SUBJECTS_DIR %s...\n", ninputs, sdir) ;
  for (input = 0 ; input < ninputs ; input++)
  {
    sprintf(subject, "%s.long.%s", subjects[input], base_name) ;
    printf("reading subject %s - %d of %d\n", subject, input+1, ninputs) ;
    sprintf(fname, "%s/%s/mri/%s", sdir, subject, in_fname) ;
    mri_tmp = MRIread(fname) ;
    if (!mri_tmp)
      ErrorExit(ERROR_NOFILE, "%s: could not read input MR volume from %s",
                Progname, fname) ;
    MRImakePositive(mri_tmp, mri_tmp) ;
    if (mri_tmp && ctrl_point_fname && !mri_ctrl)
    {
      mri_ctrl = MRIallocSequence(mri_tmp->width, mri_tmp->height, 
                                  mri_tmp->depth,MRI_FLOAT, nregions*2) ; // labels and means
      MRIcopyHeader(mri_tmp, mri_ctrl) ;
    }
    if (input == 0)
    {
      mri_in =
        MRIallocSequence(mri_tmp->width, mri_tmp->height, mri_tmp->depth,
                         mri_tmp->type, ninputs) ;
      if (!mri_in)
        ErrorExit(ERROR_NOMEMORY,
                  "%s: could not allocate input volume %dx%dx%dx%d",
                  mri_tmp->width,mri_tmp->height,mri_tmp->depth,ninputs) ;
      MRIcopyHeader(mri_tmp, mri_in) ;
    }

    if (mask_fname)
    {
      int i ;
      MRI *mri_mask ;

      mri_mask = MRIread(mask_fname) ;
      if (!mri_mask)
        ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n",
                  Progname, mask_fname) ;

      for (i = 1 ; i < WM_MIN_VAL ; i++)
        MRIreplaceValues(mri_mask, mri_mask, i, 0) ;
      MRImask(mri_tmp, mri_mask, mri_tmp, 0, 0) ;
      MRIfree(&mri_mask) ;
    }
    MRIcopyFrame(mri_tmp, mri_in, 0, input) ;
    MRIfree(&mri_tmp) ;
  }
  MRIaddCommandLine(mri_in, cmdline) ;

  GCAhistoScaleImageIntensitiesLongitudinal(gca, mri_in, 1) ;

  {
    int j ;

    gcas = GCAfindAllSamples(gca, &nsamples, NULL, 1) ;
    printf("using %d sample points...\n", nsamples) ;
    GCAcomputeSampleCoords(gca, mri_in, gcas, nsamples, transform) ;
    if (sample_fname)
      GCAtransformAndWriteSamples
        (gca, mri_in, gcas, nsamples, sample_fname, transform) ;

    for (j = 0 ; j < 1 ; j++)
    {
      for (n = 1 ; n <= nregions ; n++)
      {
        for (norm_samples = i = 0 ; i < NSTRUCTURES ; i++)
        {
          if (normalization_structures[i] == Gdiag_no)
            DiagBreak() ;
          printf("finding control points in %s....\n",
                 cma_label_to_name(normalization_structures[i])) ;
          gcas_struct = find_control_points(gca, gcas, nsamples, &struct_samples, n,
                                            normalization_structures[i], mri_in, transform, min_prior,
                                            ctl_point_pct) ;
          discard_unlikely_control_points(gca, gcas_struct, struct_samples, mri_in, transform,
                                          cma_label_to_name(normalization_structures[i])) ;
          if (mri_ctrl && ctrl_point_fname) // store the samples
            copy_ctrl_points_to_volume(gcas_struct, struct_samples, mri_ctrl, n-1) ;
          if (i)
          {
            GCA_SAMPLE *gcas_tmp ;
            gcas_tmp = gcas_concatenate(gcas_norm, gcas_struct, norm_samples, struct_samples) ;
            free(gcas_norm) ;
            norm_samples += struct_samples ;
            gcas_norm = gcas_tmp ;
          }
          else
          {
            gcas_norm = gcas_struct ; norm_samples = struct_samples ;
          }
        }
        
        printf("using %d total control points "
                 "for intensity normalization...\n", norm_samples) ;
        if (normalized_transformed_sample_fname)
          GCAtransformAndWriteSamples(gca, mri_in, gcas_norm, norm_samples,
                                      normalized_transformed_sample_fname,
                                      transform) ;
        mri_norm = GCAnormalizeSamplesAllChannels(mri_in, gca, gcas_norm, file_only ? 0 :norm_samples,
                                                  transform, ctl_point_fname, bias_sigma) ;
        if (Gdiag & DIAG_WRITE)
        {
          char fname[STRLEN] ;
          sprintf(fname, "norm%d.mgz", n) ;
          printf("writing normalized volume to %s...\n", fname) ;
          MRIwrite(mri_norm, fname) ;
          sprintf(fname, "norm_samples%d.mgz", n) ;
          GCAtransformAndWriteSamples(gca, mri_in, gcas_norm, norm_samples,
                                      fname, transform) ;
          
        }
        MRIcopy(mri_norm, mri_in) ;  /* for next pass through */
        MRIfree(&mri_norm) ;
      }
    }
  }

  // now do cross-time normalization to bring each timepoint closer to the mean at each location
  {
    MRI   *mri_frame1, *mri_frame2, *mri_tmp ;
    double rms_before, rms_after ;
    int    i ;

    mri_tmp = MRIcopy(mri_in, NULL) ;
    mri_frame1 = MRIcopyFrame(mri_in, NULL, 0, 0) ;
    mri_frame2 = MRIcopyFrame(mri_in, NULL, 1, 0) ;
    rms_before = MRIrmsDiff(mri_frame1, mri_frame2) ;
    printf("RMS before = %2.2f\n", rms_before) ;
    MRIfree(&mri_frame1) ; MRIfree(&mri_frame2) ;
    for (i = 50 ; i <= 50 ; i += 25)
    {
      MRIcopy(mri_tmp, mri_in) ;
      normalize_timepoints_with_samples(mri_in, gcas_norm, norm_samples, i) ;
      mri_frame1 = MRIcopyFrame(mri_in, NULL, 0, 0) ;
      mri_frame2 = MRIcopyFrame(mri_in, NULL, 1, 0) ;
      rms_after = MRIrmsDiff(mri_frame1, mri_frame2) ;
      MRIfree(&mri_frame1) ; MRIfree(&mri_frame2) ;
      printf("RMS after (%d) = %2.2f\n", i, rms_after) ;
    }
  }
  {
    MRI   *mri_frame1, *mri_frame2 ;
    double rms_after ;
    int    i ;

    mri_tmp = MRIcopy(mri_in, NULL) ;
    for (i = 10 ; i <= 10 ; i += 10)
    {
      MRIcopy(mri_tmp, mri_in) ;
      normalize_timepoints(mri_in, 2.0, i) ;
      mri_frame1 = MRIcopyFrame(mri_in, NULL, 0, 0) ;
      mri_frame2 = MRIcopyFrame(mri_in, NULL, 1, 0) ;
      rms_after = MRIrmsDiff(mri_frame1, mri_frame2) ;
      MRIfree(&mri_frame1) ; MRIfree(&mri_frame2) ;
      printf("RMS after intensity cohering = %2.2f\n", rms_after) ;
    }
  }

  for (input = 0 ; input < ninputs ; input++)
  {
    sprintf(fname, "%s/%s.long.%s/mri/%s", sdir, subjects[input], base_name, out_fname) ;
    printf("writing normalized volume to %s...\n", fname) ;
    if (MRIwriteFrame(mri_in, fname, input)  != NO_ERROR)
      ErrorExit(ERROR_BADFILE, "%s: could not write normalized volume to %s",Progname, fname);
  }

  if (ctrl_point_fname)
  {
    printf("writing control points to %s\n", ctrl_point_fname) ;
    MRIwrite(mri_ctrl, ctrl_point_fname) ;
    MRIfree(&mri_ctrl) ;
  }
  MRIfree(&mri_in) ;

  printf("freeing GCA...") ;
  if (gca)
    GCAfree(&gca) ;
  printf("done.\n") ;
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("normalization took %d minutes and %d seconds.\n",
         minutes, seconds) ;
  if (diag_fp)
    fclose(diag_fp) ;
  exit(0) ;
  return(0) ;
}