Attachment 'gca.c'

Download

   1 /**
   2  * @file  gca.c
   3  * @brief Core routines implementing the Gaussian Classifier Atlas mechanism
   4  *
   5  * Routines implementing the mechanism of encoding voxel label information
   6  * based on probabilistic information estimated from a training set.
   7  *
   8  * Reference:
   9  * "Whole Brain Segmentation: Automated Labeling of Neuroanatomical
  10  * Structures in the Human Brain", Fischl et al.
  11  * (2002) Neuron, 33:341-355.
  12  */
  13 /*
  14  * Original Author: Bruce Fischl
  15  * CVS Revision Info:
  16  *    $Author: fischl $
  17  *    $Date: 2007/05/11 20:20:05 $
  18  *    $Revision: 1.230 $
  19  *
  20  * Copyright (C) 2002-2007,
  21  * The General Hospital Corporation (Boston, MA). 
  22  * All rights reserved.
  23  *
  24  * Distribution, usage and copying of this software is covered under the
  25  * terms found in the License Agreement file named 'COPYING' found in the
  26  * FreeSurfer source code root directory, and duplicated here:
  27  * https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferOpenSourceLicense
  28  *
  29  * General inquiries: freesurfer@nmr.mgh.harvard.edu
  30  * Bug reports: analysis-bugs@nmr.mgh.harvard.edu
  31  *
  32  */
  33 
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <math.h>
  37 #include <errno.h>
  38 
  39 #include "mri.h"
  40 #include "error.h"
  41 #include "diag.h"
  42 #include "utils.h"
  43 #include "gca.h"
  44 #include "proto.h"
  45 #include "fio.h"
  46 #include "transform.h"
  47 #include "macros.h"
  48 #include "utils.h"
  49 #include "cma.h"
  50 #include "flash.h"
  51 #include "talairachex.h"
  52 #include "mrimorph.h"
  53 #include "intensity_eig.h"
  54 #include "numerics.h"
  55 #include "mrisegment.h"
  56 
  57 #if WITH_DMALLOC
  58 #include <dmalloc.h>
  59 #endif
  60 
  61 int Ggca_label = -1 ;
  62 int Ggca_nbr_label = -1 ;
  63 int Ggca_x = -1 ;
  64 int Ggca_y = -1 ;
  65 int Ggca_z = -1 ;
  66 int Gxp = -1;
  67 int Gyp = -1;
  68 int Gzp = -1;
  69 int Gxn = -1; // 32;
  70 int Gyn = -1; // 21;
  71 int Gzn = -1; // 32;
  72 char *G_write_probs = NULL ;
  73 
  74 /* this is the hack section */
  75 double PRIOR_FACTOR = 0.1 ;
  76 #define LABEL_UNDETERMINED   255
  77 
  78 static int total_pruned = 0 ;
  79 
  80 #define MIN_DET 1e-7
  81 /* less than this, and the covariance matrix is poorly conditioned */
  82 
  83 #define MAX_LABELS_PER_GCAN         25
  84 #define MAX_DIFFERENT_LABELS        500
  85 #define MIN_VAR                     (5*5)   /* should make this configurable */
  86 #define BIG_AND_NEGATIVE            -10000000.0
  87 #define VERY_UNLIKELY               1e-10
  88 #define UNKNOWN_DIST                4  /* within 4 mm of some known label */
  89 #define GCA_OLD_VERSION             2.0
  90 #define GCA_UCHAR_VERSION           4.0  // labels were uchars in file
  91 #define GCA_INT_VERSION             5.0  // labels are ints in file
  92 #define DEFAULT_MAX_LABELS_PER_GCAN 4
  93 
  94 //static int gcapBrainIsPossible(GCA_PRIOR *gcap) ;
  95 #if 0
  96 static HISTOGRAM *gcaComputeHistogramNormalization(GCA *gca,
  97     HISTOGRAM *h_mri,
  98     int label) ;
  99 static float gcaFindCerebellarScaleFactor(GCA *gca,
 100     HISTOGRAM *h_mri,
 101     int label,
 102     FILE *logfp);
 103 static double GCAcomputeScaledMeanEntropy(GCA *gca, 
 104                                           MRI *mri, 
 105                                           TRANSFORM *transform,
 106     int *labels, float *scales, int nlabels) ;
 107 #endif
 108 static int gcaScale(GCA *gca, int *labels, int *contra_labels, 
 109                     float *scales, int nlabels, int dir);
 110 #if 0
 111 static int gcaMaxPriorLabel(GCA *gca, 
 112                             MRI *mri, 
 113                             TRANSFORM *transform, 
 114                             int x, int y, int z) ;
 115 #endif
 116 static HISTOGRAM *gcaGetLabelHistogram(GCA *gca, int label, int frame) ;
 117 int GCAmaxLabel(GCA *gca) ;
 118 static int gcaRelabelSegment(GCA *gca,
 119                              TRANSFORM *transform,
 120                              MRI *mri_inputs,
 121                              MRI *mri_dst,
 122                              MRI_SEGMENT *mseg) ;
 123 
 124 #define INTERP_PRIOR 0
 125 #if INTERP_PRIOR
 126 static float gcaComputePrior(GCA *gca, MRI *mri, TRANSFORM *transform,
 127                              int x, int y, int z, int label) ;
 128 #endif
 129 
 130 static int gcapGetMaxPriorLabel(GCA_PRIOR *gcap, double *p_prior) ;
 131 double compute_partial_volume_log_posterior(GCA *gca,
 132     GCA_NODE *gcan,
 133     GCA_PRIOR *gcap,
 134     float *vals, int l1, int l2) ;
 135 static double gcaComputeSampleConditionalLogDensity(GCA_SAMPLE *gcas,
 136     float *vals,
 137     int ninputs,
 138     int label) ;
 139 static VECTOR *load_sample_mean_vector(GCA_SAMPLE *gcas,
 140                                        VECTOR *v_means,
 141                                        int ninputs) ;
 142 static MATRIX *load_sample_covariance_matrix(GCA_SAMPLE *gcas,
 143     MATRIX *m_cov,
 144     int ninputs) ;
 145 static double sample_covariance_determinant(GCA_SAMPLE *gcas, int ninputs) ;
 146 static GC1D *findClosestValidGC(GCA *gca,
 147                                 int x, int y, int z,
 148                                 int label, int check_var) ;
 149 static GC1D *findGCInWindow(GCA *gca,
 150                             int x, int y, int z,
 151                             int label, int wsize) ;
 152 
 153 static int    MRIorderIndices(MRI *mri, short *x_indices, short *y_indices,
 154                               short *z_indices) ;
 155 static int gcaCheck(GCA *gca) ;
 156 static double gcaVoxelLogLikelihood(GCA *gca,
 157                                     MRI *mri_labels,
 158                                     MRI *mri_inputs,
 159                                     int x, int y, int z,
 160                                     TRANSFORM *transform);
 161 static double gcaVoxelGibbsLogLikelihood(GCA *gca,
 162     MRI *mri_labels,
 163     MRI *mri_inputs,
 164     int x, int y, int z,
 165     TRANSFORM *transform,
 166     double gibbs_coef) ;
 167 static double gcaNbhdGibbsLogLikelihood(GCA *gca,
 168                                         MRI *mri_labels,
 169                                         MRI *mri_inputs,
 170                                         int x, int y, int z,
 171                                         TRANSFORM *transform,
 172                                         double gibbs_coef) ;
 173 static double gcaGibbsImpossibleConfiguration(GCA *gca,
 174     MRI *mri_labels,
 175     int x, int y, int z,
 176     TRANSFORM *transform) ;
 177 static GCA_SAMPLE *gcaExtractLabelAsSamples(GCA *gca,
 178     MRI *mri_labeled,
 179     TRANSFORM *transform,
 180     int *pnsamples, int label) ;
 181 #if 0
 182 static GCA_SAMPLE *gcaExtractRegionLabelAsSamples(GCA *gca, MRI *mri_labeled,
 183     TRANSFORM *transform,
 184     int *pnsamples, int label,
 185     int xn, int yn, int zn,
 186     int wsize) ;
 187 #endif
 188 static GCA_SAMPLE *gcaExtractThresholdedRegionLabelAsSamples
 189 (GCA *gca,
 190  MRI *mri_labeled,
 191  TRANSFORM *transform,
 192  int *pnsamples,
 193  int label,
 194  int xn,
 195  int yn,
 196  int zn,
 197  int wsize,
 198  float pthresh);
 199 /*static double gcaComputeSampleConditionalDensity(GCA_SAMPLE *gcas,
 200   float *vals, int ninputs, int label) ;*/
 201 static double gcaComputeLogDensity(GC1D *gc, float *vals, \
 202                                    int ninputs, float prior, int label) ;
 203 static double gcaComputeSampleLogDensity(GCA_SAMPLE *gcas,
 204     float *vals, int ninputs) ;
 205 int MRIcomputeVoxelPermutation(MRI *mri, short *x_indices, short *y_indices,
 206                                short *z_indices);
 207 GCA *gcaAllocMax(int ninputs, float prior_spacing, float node_spacing, \
 208                  int width, int height, int depth,
 209                  int max_labels, int flags) ;
 210 static int GCAupdateNode(GCA *gca, MRI *mri, int xn, int yn, int zn,
 211                          float *vals,int label, GCA *gca_prune, int noint);
 212 static int GCAupdateNodeCovariance(GCA *gca, MRI *mri, int xn, int yn, int zn,
 213                                    float *vals,int label);
 214 static int GCAupdatePrior(GCA *gca,
 215                           MRI *mri,
 216                           int xn, int yn, int zn,
 217                           int label);
 218 static int GCAupdateNodeGibbsPriors(GCA *gca,MRI*mri,int xn,int yn,int zn,
 219                                     int x, int y, int z, int label);
 220 #if 0
 221 static int different_nbr_labels(GCA *gca, int x, int y, int z, int wsize,
 222                                 int label, float pthresh) ;
 223 #endif
 224 static int different_nbr_max_labels(GCA *gca, int x, int y, int z, int wsize,
 225                                     int label) ;
 226 static int gcaRegionStats(GCA *gca, int x0, int y0, int z0, int wsize,
 227                           float *priors, float *vars, \
 228                           float means[MAX_DIFFERENT_LABELS][MAX_GCA_INPUTS]) ;
 229 static int gcaFindBestSample(GCA *gca, int x, int y, int z, int best_label,
 230                              int wsize, GCA_SAMPLE *gcas);
 231 #if 0
 232 static int gcaFindClosestMeanSample(GCA *gca, float *means, float min_prior,
 233                                     int x, int y, int z,
 234                                     int label, int wsize, GCA_SAMPLE *gcas);
 235 static GC1D *gcaFindHighestPriorGC(GCA *gca, int x, int y, int z,int label,
 236                                    int wsize) ;
 237 #endif
 238 static double gcaGibbsImageLogLikelihood(GCA *gca,
 239     MRI *mri_labels,
 240     MRI *mri_inputs,
 241     TRANSFORM *transform) ;
 242 
 243 static int mriFillRegion(MRI *mri, int x,int y,int z,int fill_val,int whalf);
 244 static int gcaFindMaxPriors(GCA *gca, float *max_priors) ;
 245 static int gcaFindIntensityBounds(GCA *gca, float *pmin, float *pmax) ;
 246 static int dump_gcan(GCA *gca,
 247                      GCA_NODE *gcan,
 248                      FILE *fp,
 249                      int verbose,
 250                      GCA_PRIOR *gcap) ;
 251 static GCA_NODE *findSourceGCAN(GCA *gca,
 252                                 MRI *mri_src,
 253                                 TRANSFORM *transform,
 254                                 int x,int y,int z);
 255 #if 0
 256 static int getLabelMean(GCA_NODE *gcan, int label, \
 257                         float *pvar, float *means, int ninputs) ;
 258 #endif
 259 static int   borderVoxel(MRI *mri, int x, int y, int z) ;
 260 static int   GCAmaxLikelihoodBorderLabel(GCA *gca, MRI *mri_inputs,
 261     MRI *mri_labels, TRANSFORM *transform,
 262     int x, int y, int z, float min_ratio);
 263 
 264 
 265 float getPrior(GCA_PRIOR *gcap, int label) ;
 266 GCA_PRIOR *getGCAP(GCA *gca,
 267                    MRI *mri,
 268                    TRANSFORM *transform,
 269                    int xv, int yv, int zv) ;
 270 GCA_PRIOR *getGCAPfloat(GCA *gca,
 271                         MRI *mri,
 272                         TRANSFORM *transform,
 273                         float xv, float yv, float zv) ;
 274 GCA_NODE *getGCAN(GCA *gca,
 275                   MRI *mri,
 276                   TRANSFORM *transform,
 277                   int xv, int yv, int zv) ;
 278 static int gcaNodeToPrior(GCA *gca,
 279                           int xn, int yn, int zn,
 280                           int *pxp, int *pyp, int *pzp) ;
 281 static HISTOGRAM *gcaHistogramSamples(GCA *gca, GCA_SAMPLE *gcas, MRI *mri,
 282                                       TRANSFORM *transform, int nsamples,
 283                                       HISTOGRAM *histo, int frame) ;
 284 int GCApriorToNode(GCA *gca,
 285                    int xp, int yp, int zp,
 286                    int *pxn, int *pyn, int *pzn) ;
 287 
 288 /* arrays for indexing 6-connected neighbors */
 289 static int xnbr_offset[] =
 290   {
 291     1, -1, 0, 0,  0,  0
 292   } ;
 293 static int ynbr_offset[] =
 294   {
 295     0, 0,  1, -1, 0,  0
 296   } ;
 297 static int znbr_offset[] =
 298   {
 299     0, 0,  0, 0,  1, -1
 300   } ;
 301 int check_finite(char *where, double what) ;
 302 static int boundsCheck(int *pix, int *piy, int *piz, MRI *mri);
 303 
 304 static void  set_equilavent_classes(int *equivalent_classes);
 305 
 306 static int initialize_ventricle_alignment(MRI *mri_seg, 
 307                                           MRI *mri, 
 308                                           MATRIX *m_L, 
 309                                           char *base_name) ;
 310 
 311 
 312 void GCAsetVolGeom(GCA *gca, VOL_GEOM *vg)
 313 {
 314   vg->width = gca->width;
 315   vg->height = gca->height;
 316   vg->depth = gca->depth;
 317   vg->xsize = gca->xsize;
 318   vg->ysize = gca->ysize;
 319   vg->zsize = gca->zsize;
 320   vg->x_r = gca->x_r;
 321   vg->y_r = gca->y_r;
 322   vg->z_r = gca->z_r;
 323   vg->x_a = gca->x_a;
 324   vg->y_a = gca->y_a;
 325   vg->z_a = gca->z_a;
 326   vg->x_s = gca->x_s;
 327   vg->y_s = gca->y_s;
 328   vg->z_s = gca->z_s;
 329   vg->c_r = gca->c_r;
 330   vg->c_a = gca->c_a;
 331   vg->c_s = gca->c_s;
 332   vg->valid = 1;
 333 }
 334 
 335 void GCAcopyDCToMRI(GCA *gca, MRI *mri)
 336 {
 337   mri->x_r = gca->x_r;
 338   mri->y_r = gca->y_r;
 339   mri->z_r = gca->z_r;
 340   mri->x_a = gca->x_a;
 341   mri->y_a = gca->y_a;
 342   mri->z_a = gca->z_a;
 343   mri->x_s = gca->x_s;
 344   mri->y_s = gca->y_s;
 345   mri->z_s = gca->z_s;
 346   mri->c_r = gca->c_r;
 347   mri->c_a = gca->c_a;
 348   mri->c_s = gca->c_s;
 349   mri->ras_good_flag = 1;
 350     MRIreInitCache(mri) ;
 351   mri->i_to_r__ = extract_i_to_r(mri);
 352   mri->r_to_i__ = extract_r_to_i(mri);
 353 }
 354 void GCAcopyDCToGCA(GCA *gca, GCA *gca_dst)
 355 {
 356   gca_dst->x_r = gca->x_r;
 357   gca_dst->y_r = gca->y_r;
 358   gca_dst->z_r = gca->z_r;
 359   gca_dst->x_a = gca->x_a;
 360   gca_dst->y_a = gca->y_a;
 361   gca_dst->z_a = gca->z_a;
 362   gca_dst->x_s = gca->x_s;
 363   gca_dst->y_s = gca->y_s;
 364   gca_dst->z_s = gca->z_s;
 365   gca_dst->c_r = gca->c_r;
 366   gca_dst->c_a = gca->c_a;
 367   gca_dst->c_s = gca->c_s;
 368   //
 369   gca_dst->node_i_to_r__ =
 370     MatrixCopy(gca->node_i_to_r__, gca_dst->node_i_to_r__);
 371   gca_dst->node_r_to_i__ =
 372     MatrixCopy(gca->node_r_to_i__, gca_dst->node_r_to_i__);
 373   gca_dst->prior_i_to_r__ =
 374     MatrixCopy(gca->prior_i_to_r__, gca_dst->prior_i_to_r__);
 375   gca_dst->prior_r_to_i__ =
 376     MatrixCopy(gca->prior_r_to_i__, gca_dst->prior_r_to_i__);
 377   gca_dst->tal_i_to_r__ = MatrixCopy(gca->tal_i_to_r__, gca_dst->tal_i_to_r__);
 378   gca_dst->tal_r_to_i__ = MatrixCopy(gca->tal_r_to_i__, gca_dst->tal_r_to_i__);
 379   //
 380   gca_dst->mri_prior__ = MRIcopy(gca->mri_prior__, gca_dst->mri_prior__);
 381   gca_dst->mri_node__ = MRIcopy(gca->mri_node__, gca_dst->mri_node__);
 382   gca_dst->mri_tal__ = MRIcopy(gca->mri_tal__, gca_dst->mri_tal__);
 383 }
 384 
 385 void GCAcleanup(GCA *gca)
 386 {
 387   if (gca->mri_node__)
 388   {
 389     MRIfree(&gca->mri_node__);
 390     gca->mri_node__= 0;
 391   }
 392   if (gca->mri_prior__)
 393   {
 394     MRIfree(&gca->mri_prior__);
 395     gca->mri_prior__ = 0;
 396   }
 397   if (gca->mri_tal__)
 398   {
 399     MRIfree(&gca->mri_tal__);
 400     gca->mri_tal__ = 0;
 401   }
 402   if (gca->node_i_to_r__)
 403   {
 404     MatrixFree(&(gca->node_i_to_r__));
 405     gca->node_i_to_r__ = 0;
 406   }
 407   if (gca->node_r_to_i__)
 408   {
 409     MatrixFree(&(gca->node_r_to_i__));
 410     gca->node_r_to_i__ = 0;
 411   }
 412   if (gca->prior_i_to_r__)
 413   {
 414     MatrixFree(&(gca->prior_i_to_r__));
 415     gca->prior_i_to_r__ = 0;
 416   }
 417   if (gca->prior_r_to_i__)
 418   {
 419     MatrixFree(&(gca->prior_r_to_i__));
 420     gca->prior_r_to_i__ = 0;
 421   }
 422   if (gca->tal_i_to_r__)
 423   {
 424     MatrixFree(&(gca->tal_i_to_r__));
 425     gca->tal_i_to_r__ = 0;
 426   }
 427   if (gca->tal_r_to_i__)
 428   {
 429     MatrixFree(&(gca->tal_r_to_i__));
 430     gca->tal_r_to_i__ = 0;
 431   }
 432   if (gca->tmp__)
 433   {
 434     MatrixFree(&gca->tmp__);
 435     gca->tmp__ = 0;
 436   }
 437 }
 438 
 439 // set up mri's used in GCA
 440 void GCAsetup(GCA *gca)
 441 {
 442   // set up node part /////////////////////
 443   if (gca->mri_node__)
 444   {
 445     MRIfree(&gca->mri_node__);
 446     gca->mri_node__ = 0;
 447   }
 448   gca->mri_node__ = \
 449                     MRIallocHeader(gca->node_width,
 450                                    gca->node_height,
 451                                    gca->node_depth,
 452                                    MRI_UCHAR);
 453   /* Copy the voxel resolutions.  Set the defaults */
 454   gca->mri_node__->xsize = gca->xsize * gca->node_spacing;
 455   gca->mri_node__->ysize = gca->ysize * gca->node_spacing;
 456   gca->mri_node__->zsize = gca->zsize * gca->node_spacing;
 457 
 458   // this will recalculate i_to_r__ etc and
 459   // thus xsize etc must be set correctly
 460   GCAcopyDCToMRI(gca, gca->mri_node__);
 461 
 462   // fprintf(stdout, "node voxelToRAS\n");
 463   // MATRIX *mnode = extract_i_to_r(gca->mri_node__);
 464   // MatrixPrint(stdout, mnode);
 465   // MatrixFree(&mnode);
 466 
 467   // setup prior part //////////////////////////////////////
 468   if (gca->mri_prior__)
 469   {
 470     MRIfree(&gca->mri_prior__);
 471     gca->mri_prior__ = 0;
 472   }
 473   gca->mri_prior__ =
 474     MRIallocHeader(gca->prior_width,
 475                    gca->prior_height,
 476                    gca->prior_depth,
 477                    MRI_UCHAR);
 478 
 479   /* Copy the voxel resolutions.  Set the defaults */
 480   gca->mri_prior__->xsize = gca->xsize * gca->prior_spacing;
 481   gca->mri_prior__->ysize = gca->ysize * gca->prior_spacing;
 482   gca->mri_prior__->zsize = gca->zsize * gca->prior_spacing;
 483 
 484   GCAcopyDCToMRI(gca, gca->mri_prior__);
 485 
 486   // fprintf(stdout, "prior voxelToRAS\n");
 487   // MATRIX *mprior = extract_i_to_r(gca->mri_prior__);
 488   // MatrixPrint(stdout, mprior);
 489   // MatrixFree(&mprior);
 490 
 491   // set up the default talairach volume ////////////////
 492   if (gca->mri_tal__)
 493   {
 494     MRIfree(&gca->mri_tal__);
 495     gca->mri_tal__ = 0;
 496   }
 497   gca->mri_tal__ = 
 498     MRIallocHeader(gca->width, gca->height, gca->depth, MRI_UCHAR);
 499 
 500   /* Copy the voxel resolutions.  Set the defaults */
 501   gca->mri_tal__->xsize = gca->xsize;
 502   gca->mri_tal__->ysize = gca->ysize;
 503   gca->mri_tal__->zsize = gca->zsize;
 504 
 505   GCAcopyDCToMRI(gca, gca->mri_tal__);
 506 
 507   //fprintf(stdout, "tal voxelToRAS\n");
 508   //mtal = extract_i_to_r(gca->mri_tal__);
 509   // MatrixPrint(stdout, mtal);
 510   // MatrixFree(&mtal);
 511   if (gca->node_i_to_r__)
 512   {
 513     MatrixFree(&(gca->node_i_to_r__));
 514     gca->node_i_to_r__ = 0;
 515   }
 516   if (gca->node_r_to_i__)
 517   {
 518     MatrixFree(&(gca->node_r_to_i__));
 519     gca->node_r_to_i__ = 0;
 520   }
 521   if (gca->prior_i_to_r__)
 522   {
 523     MatrixFree(&(gca->prior_i_to_r__));
 524     gca->prior_i_to_r__ = 0;
 525   }
 526   if (gca->prior_r_to_i__)
 527   {
 528     MatrixFree(&(gca->prior_r_to_i__));
 529     gca->prior_r_to_i__ = 0;
 530   }
 531   if (gca->tal_i_to_r__)
 532   {
 533     MatrixFree(&(gca->tal_i_to_r__));
 534     gca->tal_i_to_r__ = 0;
 535   }
 536   if (gca->tal_r_to_i__)
 537   {
 538     MatrixFree(&(gca->tal_r_to_i__));
 539     gca->tal_r_to_i__ = 0;
 540   }
 541   if (gca->tmp__)
 542   {
 543     MatrixFree(&(gca->tmp__));
 544     gca->tmp__ = 0;
 545   }
 546   gca->node_i_to_r__ = extract_i_to_r(gca->mri_node__);
 547   gca->node_r_to_i__ = extract_r_to_i(gca->mri_node__);
 548   gca->prior_i_to_r__ = extract_i_to_r(gca->mri_prior__);
 549   gca->prior_r_to_i__ = extract_r_to_i(gca->mri_prior__);
 550   gca->tal_i_to_r__ = extract_i_to_r(gca->mri_tal__);
 551   gca->tal_r_to_i__ = extract_r_to_i(gca->mri_tal__);
 552   gca->tmp__ = MatrixAlloc(4,4, MATRIX_REAL);
 553 }
 554 
 555 // using the values of mri, modify gca
 556 // now we can keep track of voxelToRAS info even for non-standard type
 557 // This has the potential of changing direction cosines
 558 void GCAreinit(MRI *mri, GCA *gca)
 559 {
 560   // Keep the direction cosine the same to avoid used by
 561   // different mri
 562   // modify direction cosines etc.
 563   gca->x_r = mri->x_r; gca->y_r = mri->y_r; gca->z_r = mri->z_r;
 564   gca->x_a = mri->x_a; gca->y_a = mri->y_a; gca->z_a = mri->z_a;
 565   gca->x_s = mri->x_s; gca->y_s = mri->y_s; gca->z_s = mri->z_s;
 566   gca->c_r = mri->c_r; gca->c_a = mri->c_a; gca->c_s = mri->c_s;
 567 
 568   if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
 569     printf("gca reinit c_(ras) = (%.2f, %.2f, %.2f)\n",
 570            gca->c_r, gca->c_a, gca->c_s);
 571 
 572   // modify width height depth
 573   if (gca->width != mri->width)
 574     fprintf(stdout, "gca width modified from %d to %d\n",
 575             gca->width, mri->width);
 576   if (gca->height != mri->height)
 577     fprintf(stdout, "gca height modified from %d to %d\n",
 578             gca->height, mri->height);
 579   if (gca->depth != mri->depth)
 580     fprintf(stdout, "gca depth modified from %d to %d\n",
 581             gca->depth, mri->depth);
 582   gca->width = mri->width;
 583   gca->height = mri->height;
 584   gca->depth = mri->depth;
 585 
 586   if (gca->xsize != mri->xsize)
 587     fprintf(stdout, "gca xsize modified from %.3f to %.3f\n",
 588             gca->xsize, mri->xsize);
 589   if (gca->ysize != mri->ysize)
 590     fprintf(stdout, "gca ysize modified from %.3f to %.3f\n",
 591             gca->ysize, mri->ysize);
 592   if (gca->zsize != mri->zsize)
 593     fprintf(stdout, "gca zsize modified from %.3f to %.3f\n",
 594             gca->zsize, mri->zsize);
 595   gca->xsize = mri->xsize;
 596   gca->ysize = mri->ysize;
 597   gca->zsize = mri->zsize;
 598 #if 0
 599     // can't do this without reallocating!!
 600   // then must modify node width etc.
 601   gca->node_width = (int)(((float)gca->width/gca->node_spacing)+.99) ;
 602   gca->node_height = (int)((float)gca->height/gca->node_spacing+.99) ;
 603   gca->node_depth = (int)(((float)gca->depth/gca->node_spacing)+.99) ;
 604   gca->prior_width = (int)(((float)gca->width/gca->prior_spacing)+.99) ;
 605   gca->prior_height = (int)((float)gca->height/gca->prior_spacing+.99) ;
 606   gca->prior_depth = (int)(((float)gca->depth/gca->prior_spacing)+.99) ;
 607 #endif
 608   //
 609   GCAsetup(gca);
 610   fflush(stdout) ;
 611 }
 612 
 613 GCA_PRIOR *
 614 getGCAP(GCA *gca, MRI *mri, TRANSFORM *transform, int xv, int yv, int zv)
 615 {
 616   int       xp, yp, zp ;
 617   GCA_PRIOR *gcap=NULL;
 618 
 619   if (!GCAsourceVoxelToPrior(gca, mri, transform, xv, yv, zv, &xp, &yp, &zp))
 620     gcap = &gca->priors[xp][yp][zp] ;
 621 
 622   return(gcap) ;
 623 }
 624 
 625 GCA_PRIOR *
 626 getGCAPfloat(GCA *gca, MRI *mri, TRANSFORM *transform, float xv, float yv, float zv)
 627 {
 628   int       xp, yp, zp ;
 629   GCA_PRIOR *gcap=NULL;
 630 
 631   if (!GCAsourceFloatVoxelToPrior(gca, mri, transform, xv, yv, zv, &xp, &yp, &zp))
 632     gcap = &gca->priors[xp][yp][zp] ;
 633 
 634   return(gcap) ;
 635 }
 636 
 637 GCA_NODE *
 638 getGCAN(GCA *gca, MRI *mri, TRANSFORM *transform, int xv, int yv, int zv)
 639 {
 640   int       xn, yn, zn ;
 641   GCA_NODE *gcan=NULL;
 642 
 643   if (!GCAsourceVoxelToNode(gca, mri, transform, xv, yv, zv, &xn, &yn, &zn))
 644     gcan = &gca->nodes[xn][yn][zn] ;
 645 
 646   return(gcan) ;
 647 }
 648 
 649 float
 650 getPrior(GCA_PRIOR *gcap, int label)
 651 {
 652   int n ;
 653 
 654   if (gcap==NULL)
 655     return (VERY_UNLIKELY);
 656 
 657   // find the label
 658   for (n = 0 ; n < gcap->nlabels ; n++)
 659     if (gcap->labels[n] == label)
 660       break ;
 661   // cannot find it
 662   if (n >= gcap->nlabels)
 663   {
 664     if (gcap->total_training > 0)
 665       return(0.1f/(float)gcap->total_training) ; /* make it unlikely */
 666     else
 667       return(VERY_UNLIKELY) ;
 668   }
 669   // return found one
 670   return(gcap->priors[n]) ;
 671 }
 672 
 673 int
 674 GCAisPossible(GCA *gca, MRI *mri, int label,
 675               TRANSFORM *transform, int x, int y, int z,
 676               int use_mrf)
 677 {
 678   int       n, i, found, nbr_label, xnbr, ynbr, znbr, xn, yn, zn ;
 679   GCA_PRIOR *gcap = NULL;
 680   GC1D      *gc ;
 681 
 682   gcap = getGCAP(gca, mri, transform, x, y, z) ;
 683   if (gcap==NULL)
 684     return(0) ;
 685   // if label found
 686   for (found = n = 0 ; n < gcap->nlabels ; n++)
 687     if (gcap->labels[n] == label)
 688     {
 689       found = 1 ;
 690       break ;
 691     }
 692   if (found == 0)
 693     return(0) ;
 694   if (use_mrf == 0)
 695     return(1) ;
 696 
 697   if (GCAsourceVoxelToNode(gca, mri, transform, x, y, z, &xn, &yn, &zn)
 698       != NO_ERROR)
 699     return(1) ;
 700   gc = GCAfindGC(gca, xn, yn, zn, label) ;
 701   for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
 702   {
 703     found = 0 ;
 704     xnbr = mri->xi[x+xnbr_offset[i]] ;// xnbr_offset 1, -1, 0,  0, 0,  0
 705     ynbr = mri->yi[y+ynbr_offset[i]] ;// ynbr_offset 0,  0, 1, -1, 0,  0
 706     znbr = mri->zi[z+znbr_offset[i]] ;// znbr_offset 0,  0, 0,  0, 1, -1
 707     nbr_label = nint(MRIgetVoxVal(mri, xnbr, ynbr, znbr, 0)) ;
 708     for (n = 0 ; n < gc->nlabels[i] ; n++)
 709       if (gc->labels[i][n] == nbr_label)
 710       {
 711         found = 1 ;
 712         break ;
 713       }
 714     if (found == 0)  // this pair never occurred here
 715       return(0) ;
 716   }
 717   return(1) ;
 718 }
 719 
 720 #if 0
 721 static float get_voxel_prior(GCA *gca, MRI *mri, TRANSFORM *transform,
 722                              int xv, int yv, int zv, int label);
 723 static float
 724 get_voxel_prior(GCA *gca, MRI *mri, TRANSFORM *transform,
 725                 int xv, int yv, int zv, int label)
 726 {
 727   int       xn, yn, zn ;
 728   GCA_PRIOR *gcap ;
 729 
 730   gcap = getGCAP(gca, mri, transform, xv, yv, zv) ;
 731   // this could return NULL
 732   if (gcap==NULL)
 733     return (VERY_UNLIKELY)
 734 
 735            return(getPrior(gcap, label)) ;
 736 }
 737 #endif
 738 
 739 static float
 740 get_node_prior(GCA *gca, int label, int xn, int yn, int zn)
 741 {
 742   int       xp, yp, zp ;
 743   GCA_PRIOR *gcap ;
 744 
 745   if (gcaNodeToPrior(gca, xn, yn, zn, &xp, &yp, &zp)==NO_ERROR)
 746   {
 747     gcap = &gca->priors[xp][yp][zp] ;
 748     if (gcap == NULL)
 749       return (VERY_UNLIKELY);
 750     return(getPrior(gcap, label)) ;
 751   }
 752   else
 753     return (VERY_UNLIKELY);
 754 }
 755 
 756 // use the same function for bounds checking
 757 // if (ix, iy, iz) is within mri volume, returns NO_ERROR
 758 //                                       otherwise ERROR_BADPARAM
 759 static int boundsCheck(int *pix, int *piy, int *piz, MRI *mri)
 760 {
 761   int ix = *pix;
 762   int iy = *piy;
 763   int iz = *piz;
 764   int errCode = NO_ERROR; // initialize
 765 
 766   if (ix < 0)
 767     errCode = ERROR_BADPARM;
 768   else if (iy < 0)
 769     errCode = ERROR_BADPARM;
 770   else if (iz < 0)
 771     errCode = ERROR_BADPARM;
 772   else if (ix > mri->width-1)
 773     errCode = ERROR_BADPARM;
 774   else if (iy > mri->height-1)
 775     errCode = ERROR_BADPARM;
 776   else if (iz > mri->depth-1)
 777     errCode = ERROR_BADPARM;
 778 
 779 #if 0
 780   // give up returning error
 781   if (ix < 0)
 782     *pix = 0;
 783   if (iy < 0)
 784     *piy = 0;
 785   if (iz < 0)
 786     *piz = 0;
 787   if (ix > mri->width -1)
 788     *pix = mri->width -1;
 789   if (iy > mri->height-1)
 790     *piy = mri->height -1;
 791   if (iz > mri->depth-1)
 792     *piz = mri->depth -1;
 793 #endif
 794 
 795   return errCode;
 796 }
 797 
 798 static int
 799 gcaNodeToPrior(GCA *gca, int xn, int yn, int zn, int *pxp, int *pyp, int *pzp)
 800 {
 801   // initialize errCode
 802   int errCode = NO_ERROR;
 803 
 804   // see GCApriorToNode comment
 805   // node_spacing > prior_spacing
 806   // integer operation is floor
 807   *pxp = xn*gca->node_spacing/gca->prior_spacing;
 808   *pyp = yn*gca->node_spacing/gca->prior_spacing;
 809   *pzp = zn*gca->node_spacing/gca->prior_spacing;
 810   // no error should occur
 811   return errCode ;
 812 }
 813 
 814 int
 815 GCApriorToNode(GCA *gca, int xp, int yp, int zp, int *pxn, int *pyn, int *pzn)
 816 {
 817   int errCode = NO_ERROR;
 818   /////////////////////////////////////////////////////////////////////
 819   // Note that prior and node share the common direction cosines/translation
 820   //
 821   //      prior has voxelToRAS = [ R | T ][prior_size | 0] = X [prior_size | 0]
 822   //                             [ 0 | 1 ][    0      | 1]     [    0      | 1]
 823   //      node  has voxelToRAS = [ R | T ][ node_size | 0] = X [ node_size | 0]
 824   //                             [ 0 | 1 ][    0      | 1]     [    0      | 1]
 825   //
 826   //        prior   --->  RAS
 827   //          |            |
 828   //          |            | identity
 829   //          V            V
 830   //         node    ---> RAS
 831   //                                  -1   -1
 832   //    priorToNode = [ node_size | 0]  * X   * X * [ prior_size | 0]
 833   //                  [     0     | 1]              [     0      | 1]
 834   //
 835   //                = [         -1             |     ]
 836   //                  [ node_size * prior_size |  0  ]
 837   //                  [           0            |  1  ]
 838   //
 839   // Note that node_spacing > prior_spacing and thus the following will do
 840   // .5 becomes 0.
 841   // but this is OK, since the correspondence is
 842   //               |  0  |   1  |   prior
 843   //               |     0      |   node
 844   // i.e. 1 becomes 0
 845   *pxn = xp*gca->prior_spacing/gca->node_spacing;
 846   *pyn = yp*gca->prior_spacing/gca->node_spacing;
 847   *pzn = zp*gca->prior_spacing/gca->node_spacing;
 848   // no error should occur
 849   return errCode;
 850 }
 851 
 852 static int
 853 dump_gcan(GCA *gca, GCA_NODE *gcan, FILE *fp, int verbose, GCA_PRIOR *gcap)
 854 {
 855   int       n, i, j, n1 ;
 856   GC1D      *gc ;
 857   float     prior ;
 858   VECTOR    *v_means = NULL ;
 859   MATRIX    *m_cov = NULL ;
 860 
 861   if (gcap==NULL)
 862     return -1;
 863   // print out gcan labels
 864   fprintf(fp,
 865           "node labels at this point -----"
 866           "---------------------------------\n");
 867   for (n = 0 ; n < gcan->nlabels ; n++)
 868   {
 869     // find the same label in gcap
 870     for (n1 = 0 ; n1 < gcap->nlabels ; n1++)
 871       if (gcap->labels[n1] == gcan->labels[n])
 872         break ;
 873     // the following won't happen
 874     if (n1 >= gcap->nlabels)
 875       continue ;
 876     prior = getPrior(gcap, gcan->labels[n]) ;
 877     if (FZERO(prior))
 878       continue ;
 879     // get gc for this label
 880     gc = &gcan->gcs[n] ;
 881     v_means = load_mean_vector(gc, v_means, gca->ninputs) ;
 882     m_cov = load_covariance_matrix(gc, m_cov, gca->ninputs) ;
 883     fprintf(fp, "%d: label %s (%d), prior %2.3f, ntr %d, means " ,
 884             n, cma_label_to_name(gcan->labels[n]),
 885             gcan->labels[n], prior, gc->ntraining) ;
 886     for (i = 0 ; i < gca->ninputs ; i++)
 887       fprintf(fp, "%2.1f ", VECTOR_ELT(v_means,i+1)) ;
 888     fprintf(fp, ", cov:\n") ;
 889     MatrixPrint(fp, m_cov) ;
 890 
 891     if (verbose)
 892     {
 893       for (i = 0 ; i < gca->ninputs ; i++)
 894       {
 895         for (j = 0 ; j < gca->ninputs ; j++)
 896         {
 897           fprintf(fp, "%2.1f\t", *MATRIX_RELT(m_cov,i+1,j+1)) ;
 898         }
 899         fprintf(fp, "\n") ;
 900       }
 901       // 6 neighbors
 902       for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
 903       {
 904         fprintf(fp, "\tnbr %d (%d,%d,%d): %d labels\n",
 905                 i, xnbr_offset[i], ynbr_offset[i], znbr_offset[i],
 906                 gc->nlabels[i]) ;
 907         fflush(fp);
 908         for (j = 0 ; j < gc->nlabels[i] ; j++)
 909         {
 910           fprintf(fp, "\t\tlabel %s, prior %2.3f\n",
 911                   cma_label_to_name(gc->labels[i][j]),
 912                   gc->label_priors[i][j]) ;
 913           fflush(fp);
 914         }
 915       }
 916     }
 917   }
 918   fprintf(fp, "--------------------------------"
 919           "--------------------------------\n");
 920   MatrixFree(&m_cov) ;
 921   VectorFree(&v_means);
 922   return(NO_ERROR) ;
 923 }
 924 
 925 ////////////////////////////////////////////////////////////////
 926 // transform from template -> node
 927 ////////////////////////////////////////////////////////////////
 928 int GCAvoxelToNodeReal(GCA *gca, MRI *mri, Real xv, Real yv, Real zv,
 929                        Real *pxn, Real *pyn, Real *pzn)
 930 {
 931   //               i_to_r
 932   //        mri    ----->    RAS
 933   //         |                |
 934   //         | we need        | identity
 935   //         V                V
 936   //        node   <-----    RAS
 937   //               r_to_i
 938   MATRIX *rasFromVoxel = mri->i_to_r__; // extract_i_to_r(mri);
 939   MATRIX *nodeFromRAS = gca->node_r_to_i__; // extract_r_to_i(gca->mri_node__);
 940   MATRIX *voxelToNode = gca->tmp__;
 941   MatrixMultiply(nodeFromRAS, rasFromVoxel, gca->tmp__);
 942 
 943   TransformWithMatrix(voxelToNode, xv, yv, zv, pxn, pyn, pzn);
 944 
 945   // MatrixFree(&rasFromVoxel);
 946   // MatrixFree(&nodeFromRAS);
 947   // MatrixFree(&voxelToNode);
 948 
 949   return NO_ERROR;
 950 }
 951 
 952 int
 953 GCAvoxelToNode(GCA *gca, MRI *mri, int xv, int yv, int zv, int *pxn,
 954                int *pyn, int *pzn)
 955 {
 956   Real xn, yn, zn;
 957   int   ixn, iyn, izn;
 958   int errCode = NO_ERROR;
 959 
 960   GCAvoxelToNodeReal(gca, mri, xv, yv, zv, &xn, &yn, &zn);
 961 
 962   // xn, yn, zn are double.  we use voxel center as integer
 963   ixn = (int) floor(xn);
 964   iyn = (int) floor(yn);
 965   izn = (int) floor(zn);
 966   // if outofbounds, tell it
 967   errCode = boundsCheck(&ixn, &iyn, &izn, gca->mri_node__);
 968   //
 969   *pxn = ixn;
 970   *pyn = iyn;
 971   *pzn = izn;
 972 
 973   return errCode;
 974 }
 975 
 976 ////////////////////////////////////////////////////////////////////
 977 // transform from template -> prior
 978 ////////////////////////////////////////////////////////////////////
 979 int GCAvoxelToPriorReal(GCA *gca, MRI *mri, Real xv, Real yv, Real zv,
 980                         Real *pxp, Real *pyp, Real *pzp)
 981 {
 982   MATRIX *rasFromVoxel = mri->i_to_r__; //extract_i_to_r(mri);
 983   MATRIX *priorFromRAS = gca->prior_r_to_i__;
 984   //extract_r_to_i(gca->mri_prior__);
 985   MATRIX *voxelToPrior = gca->tmp__;
 986   MatrixMultiply(priorFromRAS, rasFromVoxel, gca->tmp__);
 987 
 988   TransformWithMatrix(voxelToPrior, xv, yv, zv, pxp, pyp, pzp);
 989 
 990   // MatrixFree(&rasFromVoxel);
 991   // MatrixFree(&priorFromRAS);
 992   // MatrixFree(&voxelToPrior);
 993 
 994   return NO_ERROR;
 995 }
 996 
 997 int
 998 GCAvoxelToPrior(GCA *gca, MRI *mri, int xv, int yv, int zv,
 999                 int *pxp, int *pyp, int *pzp)
1000 {
1001   Real xp, yp, zp;
1002   int ixp, iyp, izp;
1003   int errCode = NO_ERROR;
1004 
1005   GCAvoxelToPriorReal(gca, mri, xv, yv, zv, &xp, &yp, &zp);
1006 
1007   ixp = (int) floor(xp);
1008   iyp = (int) floor(yp);
1009   izp = (int) floor(zp);
1010   // bound check
1011   // if outofbounds, tell it
1012   errCode = boundsCheck(&ixp, &iyp, &izp, gca->mri_prior__);
1013   //
1014   *pxp = ixp;
1015   *pyp = iyp;
1016   *pzp = izp;
1017 
1018   return errCode;
1019 }
1020 
1021 /////////////////////////////////////////////////////////////////////
1022 // transform node->template
1023 /////////////////////////////////////////////////////////////////////
1024 int GCAnodeToVoxelReal(GCA *gca, MRI *mri, Real xn, Real yn, Real zn,
1025                        Real *pxv, Real *pyv, Real *pzv)
1026 {
1027   //               r_to_i
1028   //        mri    <-----    RAS
1029   //         ^                ^
1030   //         | we need        | identity
1031   //         |                |
1032   //        node   ----->    RAS
1033   //               i_to_r
1034   MATRIX *rasFromNode = gca->node_i_to_r__;
1035   //  extract_i_to_r(gca->mri_node__);
1036   MATRIX *voxelFromRAS = mri->r_to_i__; //  extract_r_to_i(mri);
1037   MATRIX *nodeToVoxel = gca->tmp__;
1038   MatrixMultiply(voxelFromRAS, rasFromNode, gca->tmp__);
1039 
1040   TransformWithMatrix(nodeToVoxel, xn, yn, zn, pxv, pyv, pzv);
1041 
1042   // MatrixFree(&rasFromNode);
1043   // MatrixFree(&voxelFromRAS);
1044   // MatrixFree(&nodeToVoxel);
1045 
1046   return NO_ERROR;
1047 }
1048 
1049 int
1050 GCAnodeToVoxel(GCA *gca, MRI *mri, int xn, int yn, int zn,
1051                int *pxv, int *pyv, int *pzv)
1052 {
1053   Real xv, yv, zv;
1054   int ixv, iyv, izv;
1055   int errCode = NO_ERROR;
1056 
1057   GCAnodeToVoxelReal(gca, mri, xn, yn, zn, &xv, &yv, &zv);
1058 
1059   // addition makes overall error smaller
1060   //             0 picks  1 out of 0, 1, 2, 3 possible choices
1061   // without it, 0 pickes 0 out of 0, 1, 2, 3 possible choices
1062   // if you used float, then 0 picks 1.5.
1063   ixv = (int) floor(xv + gca->node_spacing/2.);
1064   iyv = (int) floor(yv + gca->node_spacing/2.);
1065   izv = (int) floor(zv + gca->node_spacing/2.);
1066 
1067   // bound check
1068   // if outofbounds, tell it
1069   errCode = boundsCheck(&ixv, &iyv, &izv, mri);
1070   //
1071 
1072   *pxv = ixv;
1073   *pyv = iyv;
1074   *pzv = izv;
1075   return errCode;
1076 }
1077 
1078 //////////////////////////////////////////////////////////////////////
1079 // transform from prior-> template
1080 //////////////////////////////////////////////////////////////////////
1081 int GCApriorToVoxelReal(GCA *gca, MRI *mri, Real xp, Real yp, Real zp,
1082                         Real *pxv, Real *pyv, Real *pzv)
1083 {
1084   MATRIX *rasFromPrior = gca->prior_i_to_r__;
1085   // extract_i_to_r(gca->mri_prior__);
1086   MATRIX *voxelFromRAS = mri->r_to_i__; // extract_r_to_i(mri);
1087   MATRIX *priorToVoxel = gca->tmp__;
1088   MatrixMultiply(voxelFromRAS, rasFromPrior, gca->tmp__);
1089 
1090   // TransformWithMatrix(priorToVoxel, xp, yp, zp, pxv, pyv, pzv);
1091   TransformWithMatrix(priorToVoxel, xp, yp, zp, pxv, pyv, pzv);
1092 
1093   // MatrixFree(&rasFromPrior);
1094   // MatrixFree(&voxelFromRAS);
1095   // MatrixFree(&priorToVoxel);
1096 
1097   return NO_ERROR;
1098 }
1099 
1100 int
1101 GCApriorToVoxel(GCA *gca, MRI *mri, int xp, int yp, int zp,
1102                 int *pxv, int *pyv, int *pzv)
1103 {
1104   Real xv, yv, zv;
1105   int ixv, iyv, izv;
1106   int errCode = NO_ERROR;
1107 
1108   GCApriorToVoxelReal(gca, mri, xp, yp, zp, &xv, &yv, &zv);
1109   // addition makes overall error smaller
1110   // without it, 0 pickes 0 out of 0, 1 possible choices
1111   ixv = (int) floor(xv + gca->prior_spacing/2.);
1112   iyv = (int) floor(yv + gca->prior_spacing/2.);
1113   izv = (int) floor(zv + gca->prior_spacing/2.);
1114   // bound check
1115   // if outofbounds, tell it
1116   errCode = boundsCheck(&ixv, &iyv, &izv, mri);
1117   //
1118   *pxv = ixv;
1119   *pyv = iyv;
1120   *pzv = izv;
1121 
1122   errCode = NO_ERROR;
1123 
1124   return errCode;
1125 }
1126 
1127 ///////////////////////////////////////////////////////////////////////
1128 // transform from source -> template space -> prior
1129 //////////////////////////////////////////////////////////////////////
1130 int
1131 GCAsourceVoxelToPrior(GCA *gca, MRI *mri, TRANSFORM *transform,
1132                       int xv, int yv, int zv, int *pxp, int *pyp, int *pzp)
1133 {
1134   float   xt, yt, zt ;
1135   Real    xrt, yrt, zrt, xrp, yrp, zrp;
1136 
1137   LTA *lta;
1138   if (transform->type != MORPH_3D_TYPE)
1139   {
1140     if (transform->type == LINEAR_VOX_TO_VOX)
1141     {
1142       lta = (LTA *) transform->xform;
1143       // transform point to talairach volume point
1144       TransformWithMatrix(lta->xforms[0].m_L,
1145                           xv, yv, zv, &xrt, &yrt, &zrt);
1146       xt = xrt;
1147       yt = yrt;
1148       zt = zrt;
1149       // TransformSample(transform, xv, yv, zv, &xt, &yt, &zt) ;
1150     }
1151     else
1152       ErrorExit(ERROR_BADPARM, \
1153                 "GCAsourceVoxelToPrior: needs vox-to-vox transform") ;
1154   }
1155   else // morph 3d type can go directly from source to template
1156   {
1157     TransformSample(transform, xv, yv, zv, &xt, &yt, &zt);
1158   }
1159   // get the position in gca from talairach volume
1160   GCAvoxelToPriorReal(gca, gca->mri_tal__, xt, yt, zt, &xrp, &yrp, &zrp) ;
1161   *pxp = nint(xrp) ;
1162   *pyp = nint(yrp) ;
1163   *pzp = nint(zrp) ;
1164   if (*pxp < 0 || *pyp < 0 || *pzp < 0 ||
1165       *pxp >= gca->prior_width ||
1166       *pyp >= gca->prior_height ||
1167       *pzp >= gca->prior_depth)
1168     return(ERROR_BADPARM) ;
1169   return (NO_ERROR) ;
1170 }
1171 
1172 int
1173 GCAsourceFloatVoxelToPrior(GCA *gca, MRI *mri, TRANSFORM *transform,
1174                            float xv, float yv, float zv, int *pxp, int *pyp, int *pzp)
1175 {
1176   float   xt, yt, zt ;
1177   Real    xrt, yrt, zrt, xrp, yrp, zrp;
1178 
1179   LTA *lta;
1180   if (transform->type != MORPH_3D_TYPE)
1181   {
1182     if (transform->type == LINEAR_VOX_TO_VOX)
1183     {
1184       lta = (LTA *) transform->xform;
1185       // transform point to talairach volume point
1186       TransformWithMatrix(lta->xforms[0].m_L,
1187                           xv, yv, zv, &xrt, &yrt, &zrt);
1188       xt = xrt;
1189       yt = yrt;
1190       zt = zrt;
1191       // TransformSample(transform, xv, yv, zv, &xt, &yt, &zt) ;
1192     }
1193     else
1194       ErrorExit(ERROR_BADPARM, \
1195                 "GCAsourceVoxelToPrior: needs vox-to-vox transform") ;
1196   }
1197   else // morph 3d type can go directly from source to template
1198   {
1199     TransformSample(transform, xv, yv, zv, &xt, &yt, &zt);
1200   }
1201   // get the position in gca from talairach volume
1202   GCAvoxelToPriorReal(gca, gca->mri_tal__, xt, yt, zt, &xrp, &yrp, &zrp) ;
1203   *pxp = nint(xrp) ;
1204   *pyp = nint(yrp) ;
1205   *pzp = nint(zrp) ;
1206   if (*pxp < 0 || *pyp < 0 || *pzp < 0 ||
1207       *pxp >= gca->prior_width ||
1208       *pyp >= gca->prior_height ||
1209       *pzp >= gca->prior_depth)
1210     return(ERROR_BADPARM) ;
1211   return (NO_ERROR) ;
1212 }
1213 
1214 /////////////////////////////////////////////////////////////////////
1215 // transform from source -> template space -> prior
1216 /////////////////////////////////////////////////////////////////////
1217 int
1218 GCAsourceVoxelToNode(GCA *gca, MRI *mri, TRANSFORM *transform,
1219                      int xv, int yv, int zv,
1220                      int *pxn, int *pyn, int *pzn)
1221 {
1222   float xt, yt, zt;
1223   Real  xrt, yrt, zrt ;
1224   LTA *lta;
1225 
1226   if (transform->type != MORPH_3D_TYPE)
1227   {
1228     if (transform->type == LINEAR_VOX_TO_VOX) // from src to talairach volume
1229     {
1230       lta = (LTA *) transform->xform;
1231       // get the talairach position
1232       TransformWithMatrix(lta->xforms[0].m_L,
1233                           xv, yv, zv, &xrt, &yrt, &zrt);
1234       // TransformSample(transform, xv, yv, zv, &xt, &yt, &zt) ;
1235       xt = xrt;
1236       yt = yrt;
1237       zt = zrt;
1238     }
1239     else
1240       ErrorExit(ERROR_BADPARM,
1241                 "GCAsourceVoxelToNode: needs vox-to-vox transform") ;
1242   }
1243   else
1244   {
1245     TransformSample(transform, xv, yv, zv, &xt, &yt, &zt);
1246   }
1247   if (Ggca_x == xv && Ggca_y == yv && Ggca_z == zv && DIAG_VERBOSE_ON)
1248     fprintf(stdout, "source (%d, %d, %d) to talposition (%.2f, %.2f, %.2f)\n",
1249             xv, yv, zv, xt, yt, zt);
1250   fflush(stdout) ;
1251 
1252   // get the position in node from the talairach position
1253   return GCAvoxelToNode(gca, gca->mri_tal__, xt, yt, zt, pxn, pyn, pzn) ;
1254 }
1255 
1256 //////////////////////////////////////////////////////////////////////
1257 // transform from node->template->source
1258 ////////////////////////////////////////////////////////////////////
1259 int
1260 GCApriorToSourceVoxelFloat(GCA *gca, MRI *mri, TRANSFORM *transform,
1261                            int xp, int yp, int zp,
1262                            float *pxv, float *pyv, float *pzv)
1263 {
1264   int   width, height, depth;
1265   Real  xt, yt, zt ;
1266   float  xv, yv, zv ;
1267   Real  xc, yc, zc;
1268   int errCode = NO_ERROR;
1269   LTA *lta;
1270   width = mri->width ;
1271   height = mri->height ;
1272   depth = mri->depth ;
1273   // go to the template voxel position
1274   GCApriorToVoxelReal(gca, gca->mri_tal__, xp, yp, zp, &xt, &yt, &zt);
1275   // got the point in gca->mri_tal__ position
1276   if (transform->type != MORPH_3D_TYPE)
1277   {
1278     if (transform->type == LINEAR_VOX_TO_VOX) // from src to talairach volume
1279     {
1280       lta = (LTA *) transform->xform;
1281       // get the talairach to orig
1282       TransformWithMatrix(lta->inv_xforms[0].m_L,
1283                           xt, yt, zt, &xc, &yc, &zc);
1284       // TransformSampleInverse(transform, xt, yt, zt, &xc, &yc, &zc);
1285       if (xc < 0)
1286         errCode = ERROR_BADPARM;
1287       else if (yc < 0)
1288         errCode = ERROR_BADPARM;
1289       else if (zc < 0)
1290         errCode = ERROR_BADPARM;
1291       else if (xc > (width-1))
1292         errCode = ERROR_BADPARM;
1293       else if (yc > (height-1))
1294         errCode = ERROR_BADPARM;
1295       else if (zc > (depth-1))
1296         errCode = ERROR_BADPARM;
1297       xv = xc;
1298       yv = yc;
1299       zv = zc;
1300     }
1301     else
1302       ErrorExit(ERROR_BADPARM,
1303                 "GCApriorToSourceVoxelFloat: needs vox-to-vox transform") ;
1304   }
1305   else // go directly from template to source
1306   {
1307     TransformSampleInverse(transform, xt, yt, zt, &xv, &yv, &zv);
1308   }
1309   *pxv = xv ;
1310   *pyv = yv ;
1311   *pzv = zv ;
1312   return errCode ;
1313 }
1314 
1315 int
1316 GCAnodeToSourceVoxelFloat(GCA *gca, MRI *mri, TRANSFORM *transform,
1317                           int xn, int yn, int zn,
1318                           float *pxv, float *pyv, float *pzv)
1319 {
1320   int   width, height, depth;
1321   Real  xt, yt, zt ;
1322   float  xv, yv, zv ;
1323   Real  xc, yc, zc ;
1324   int errCode = NO_ERROR;
1325   LTA *lta;
1326   width = mri->width ;
1327   height = mri->height ;
1328   depth = mri->depth ;
1329   // get template voxel position
1330   GCAnodeToVoxelReal(gca, gca->mri_tal__, xn, yn, zn, &xt, &yt, &zt) ;
1331   if (transform->type != MORPH_3D_TYPE)
1332   {
1333     lta = (LTA *) transform->xform;
1334     // get the talairach to orig
1335     TransformWithMatrix(lta->inv_xforms[0].m_L, xt, yt, zt, &xc, &yc, &zc);
1336     // TransformSampleInverse(transform, xt, yt, zt, &xc, &yc, &zc);
1337     if (xc < 0)
1338       errCode = ERROR_BADPARM;
1339     else if (yc < 0)
1340       errCode = ERROR_BADPARM;
1341     else if (zc < 0)
1342       errCode = ERROR_BADPARM;
1343     else if (xc > (width-1))
1344       errCode = ERROR_BADPARM;
1345     else if (yc > (height-1))
1346       errCode = ERROR_BADPARM;
1347     else if (zc > (depth-1))
1348       errCode = ERROR_BADPARM;
1349     xv = xc;
1350     yv = yc;
1351     zv = zc;
1352   }
1353   else  // template to source
1354   {
1355     TransformSampleInverse(transform, xt, yt, zt, &xv, &yv, &zv);
1356   }
1357   *pxv = xv ;
1358   *pyv = yv ;
1359   *pzv = zv ;
1360   return errCode;
1361 }
1362 
1363 int
1364 GCAnodeToSourceVoxel(GCA *gca, MRI *mri, TRANSFORM *transform,
1365                      int xn, int yn, int zn,
1366                      int *pxv, int *pyv, int *pzv)
1367 {
1368   float  xf, yf, zf ;
1369   int errCode = NO_ERROR;
1370   errCode = GCAnodeToSourceVoxelFloat(gca, mri, transform,
1371                                       xn, yn, zn, &xf, &yf, &zf) ;
1372   if (xf < 0)
1373     errCode = ERROR_BADPARM;
1374   else if (yf <0)
1375     errCode = ERROR_BADPARM;
1376   else if (zf < 0)
1377     errCode = ERROR_BADPARM;
1378   else if (xf > (mri->width-1))
1379     errCode = ERROR_BADPARM;
1380   else if (yf > (mri->height-1))
1381     errCode = ERROR_BADPARM;
1382   else if (zf > (mri->depth-1))
1383     errCode = ERROR_BADPARM;
1384 
1385   *pxv = nint(xf) ;
1386   *pyv = nint(yf) ;
1387   *pzv = nint(zf) ;
1388   return errCode;
1389 }
1390 
1391 int
1392 GCApriorToSourceVoxel(GCA *gca, MRI *mri, TRANSFORM *transform,
1393                       int xp, int yp, int zp,
1394                       int *pxv, int *pyv, int *pzv)
1395 {
1396   float  xf, yf, zf ;
1397   int errCode = NO_ERROR;
1398 
1399   errCode = GCApriorToSourceVoxelFloat(gca, mri, transform,
1400                                        xp, yp, zp, &xf, &yf, &zf) ;
1401   if (xf < 0)
1402     errCode = ERROR_BADPARM;
1403   else if (yf < 0)
1404     errCode = ERROR_BADPARM;
1405   else if (zf < 0)
1406     errCode = ERROR_BADPARM;
1407   else if (xf > (mri->width-1))
1408     errCode = ERROR_BADPARM;
1409   else if (yf > (mri->height-1))
1410     errCode = ERROR_BADPARM;
1411   else if (zf > (mri->depth-1))
1412     errCode = ERROR_BADPARM;
1413 
1414   *pxv = nint(xf) ;
1415   *pyv = nint(yf) ;
1416   *pzv = nint(zf) ;
1417   return errCode;
1418 }
1419 
1420 GCA  *
1421 GCAalloc(int ninputs,
1422          float prior_spacing, float node_spacing,
1423          int width, int height, int depth, int flags)
1424 {
1425   int max_labels ;
1426 
1427   if (flags & GCA_NO_GCS)
1428     max_labels = 0 ;
1429   else
1430     max_labels = DEFAULT_MAX_LABELS_PER_GCAN ;
1431   return(gcaAllocMax(ninputs, prior_spacing, node_spacing, width,height,depth,
1432                      max_labels, flags));
1433 }
1434 
1435 GCA *
1436 gcaAllocMax(int ninputs,
1437             float prior_spacing, float node_spacing,
1438             int width, int height, int depth,
1439             int max_labels, int flags)
1440 {
1441   GCA       *gca ;
1442   GCA_NODE  *gcan ;
1443   GCA_PRIOR *gcap ;
1444   int       x, y, z ;
1445 
1446   gca = calloc(1, sizeof(GCA)) ;
1447   if (!gca)
1448     ErrorExit(ERROR_NOMEMORY, "GCAalloc: could not allocate struct") ;
1449 
1450   gca->ninputs = ninputs ;
1451   gca->prior_spacing = prior_spacing ;
1452   gca->node_spacing = node_spacing ;
1453   gca->type = GCA_UNKNOWN; // mark it as unknown
1454 
1455   // setup default direction cosines
1456   gca->x_r = -1;
1457   gca->y_r =  0;
1458   gca->z_r = 0;
1459   gca->c_r = 0;
1460   gca->x_a =  0;
1461   gca->y_a =  0;
1462   gca->z_a = 1;
1463   gca->c_a = 0;
1464   gca->x_s =  0;
1465   gca->y_s = -1;
1466   gca->z_s = 0;
1467   gca->c_s = 0;
1468   gca->xsize = 1;
1469   gca->ysize = 1;
1470   gca->zsize = 1;
1471   //
1472   gca->width = width;
1473   gca->height = height;
1474   gca->depth = depth;
1475 
1476   /* ceil gives crazy results, I don't know why */
1477   gca->node_width = (int)(((float)width/node_spacing)+.99) ;
1478   gca->node_height = (int)((float)height/node_spacing+.99) ;
1479   gca->node_depth = (int)(((float)depth/node_spacing)+.99) ;
1480   gca->prior_width = (int)(((float)width/prior_spacing)+.99) ;
1481   gca->prior_height = (int)((float)height/prior_spacing+.99) ;
1482   gca->prior_depth = (int)(((float)depth/prior_spacing)+.99) ;
1483   gca->flags = flags ;
1484 
1485   gca->nodes = (GCA_NODE ***)calloc(gca->node_width, sizeof(GCA_NODE **)) ;
1486   if (!gca->nodes)
1487     ErrorExit(ERROR_NOMEMORY, "GCAalloc: could not allocate nodes") ;
1488 
1489   // setting vlaues gca->nodes volume
1490   for (x = 0 ; x < gca->node_width ; x++)
1491   {
1492     gca->nodes[x] =
1493       (GCA_NODE **)calloc(gca->node_height, sizeof(GCA_NODE *)) ;
1494     if (!gca->nodes[x])
1495       ErrorExit(ERROR_NOMEMORY, "GCAalloc: could not allocate %dth **",x) ;
1496 
1497     for (y = 0 ; y < gca->node_height ; y++)
1498     {
1499       gca->nodes[x][y] =
1500         (GCA_NODE *)calloc(gca->node_depth, sizeof(GCA_NODE)) ;
1501       if (!gca->nodes[x][y])
1502         ErrorExit(ERROR_NOMEMORY,
1503                   "GCAalloc: could not allocate %d,%dth *",x,y);
1504       for (z = 0 ; z < gca->node_depth ; z++)
1505       {
1506         gcan = &gca->nodes[x][y][z] ;
1507         // set max_labels
1508         gcan->max_labels = max_labels ;
1509 
1510         if (max_labels > 0)
1511         {
1512           /* allocate new ones */
1513           gcan->gcs =
1514             alloc_gcs(gcan->max_labels, flags, gca->ninputs) ;
1515           if (!gcan->gcs)
1516             ErrorExit(ERROR_NOMEMORY,
1517                       "GCANalloc: couldn't allocate gcs to %d",
1518                       gcan->max_labels) ;
1519           // allocate label storage up to max_labels
1520           gcan->labels =
1521             (unsigned short *)calloc(gcan->max_labels,
1522                                     sizeof(unsigned short)) ;
1523           if (!gcan->labels)
1524             ErrorExit(ERROR_NOMEMORY,
1525                       "GCANalloc: couldn't allocate labels to %d",
1526                       gcan->max_labels) ;
1527         }
1528       }
1529     }
1530   }
1531 
1532   gca->priors = (GCA_PRIOR ***)calloc(gca->prior_width, sizeof(GCA_PRIOR **)) ;
1533   if (!gca->priors)
1534     ErrorExit(ERROR_NOMEMORY, "GCAalloc: could not allocate priors") ;
1535   // setting values to gca->prior volume
1536   for (x = 0 ; x < gca->prior_width ; x++)
1537   {
1538     gca->priors[x] =
1539       (GCA_PRIOR **)calloc(gca->prior_height, sizeof(GCA_PRIOR *)) ;
1540     if (!gca->priors[x])
1541       ErrorExit(ERROR_NOMEMORY, "GCAalloc: could not allocate %dth **",x) ;
1542 
1543     for (y = 0 ; y < gca->prior_height ; y++)
1544     {
1545       gca->priors[x][y] =
1546         (GCA_PRIOR *)calloc(gca->prior_depth, sizeof(GCA_PRIOR)) ;
1547       if (!gca->priors[x][y])
1548         ErrorExit(ERROR_NOMEMORY,
1549                   "GCAalloc: could not allocate %d,%dth *",x,y);
1550       for (z = 0 ; z < gca->prior_depth ; z++)
1551       {
1552         gcap = &gca->priors[x][y][z] ;
1553         if (gcap==NULL)
1554           continue;
1555         gcap->max_labels = max_labels ;
1556 
1557         if (max_labels > 0)
1558         {
1559           /* allocate new ones */
1560           // allocate label space
1561           gcap->labels =
1562             (unsigned short *)calloc(max_labels,
1563                                     sizeof(unsigned short)) ;
1564           if (!gcap->labels)
1565             ErrorExit(ERROR_NOMEMORY, \
1566                       "GCANalloc: couldn't allocate labels to %d",
1567                       gcap->max_labels) ;
1568           // create prior space
1569           gcap->priors = (float *)calloc(max_labels, sizeof(float)) ;
1570           if (!gcap->priors)
1571             ErrorExit(ERROR_NOMEMORY,
1572                       "GCANalloc: couldn't allocate priors to %d",
1573                       max_labels) ;
1574         }
1575       }
1576     }
1577   }
1578   // setup
1579   gca->mri_node__ = 0;
1580   gca->mri_prior__ = 0;
1581   gca->mri_tal__ = 0;
1582   // initialize
1583   gca->node_i_to_r__ = gca->node_r_to_i__ = 0;
1584   gca->prior_i_to_r__ = gca->prior_r_to_i__ = 0;
1585   gca->tal_i_to_r__ = gca->tal_r_to_i__ = 0;
1586 
1587   GCAsetup(gca);
1588 
1589   return(gca) ;
1590 }
1591 
1592 int
1593 GCAfree(GCA **pgca)
1594 {
1595   GCA  *gca ;
1596   int  x, y, z ;
1597 
1598   gca = *pgca ;
1599   *pgca = NULL ;
1600 
1601   for (x = 0 ; x < gca->node_width ; x++)
1602   {
1603     for (y = 0 ; y < gca->node_height ; y++)
1604     {
1605       for (z = 0 ; z < gca->node_depth ; z++)
1606       {
1607         GCANfree(&gca->nodes[x][y][z], gca->ninputs) ;
1608       }
1609       free(gca->nodes[x][y]) ;
1610     }
1611     free(gca->nodes[x]) ;
1612   }
1613   free(gca->nodes) ;
1614 
1615   for (x = 0 ; x < gca->prior_width ; x++)
1616   {
1617     for (y = 0 ; y < gca->prior_height ; y++)
1618     {
1619       for (z = 0 ; z < gca->prior_depth ; z++)
1620       {
1621         free(gca->priors[x][y][z].labels) ;
1622         free(gca->priors[x][y][z].priors) ;
1623       }
1624       free(gca->priors[x][y]) ;
1625     }
1626     free(gca->priors[x]) ;
1627   }
1628 
1629   free(gca->priors) ;
1630   GCAcleanup(gca);
1631 
1632   free(gca) ;
1633 
1634   return(NO_ERROR) ;
1635 }
1636 
1637 int
1638 GCANfree(GCA_NODE *gcan, int ninputs)
1639 {
1640   if (gcan->nlabels)
1641   {
1642     free(gcan->labels) ;
1643     free_gcs(gcan->gcs, gcan->nlabels, ninputs) ;
1644   }
1645   return(NO_ERROR) ;
1646 }
1647 
1648 void PrintInfoOnLabels(GCA *gca, int label, int xn, int yn, int zn,
1649                        int xp, int yp, int zp,
1650                        int x, int y, int z)
1651 {
1652   GCA_NODE  *gcan ;
1653   GCA_PRIOR *gcap ;
1654   GC1D *gc ;
1655   int  i ;
1656   // using node to find the label
1657   gc = GCAfindGC(gca, xn, yn, zn, label) ;
1658   if (gc)
1659   {
1660     gcan = &gca->nodes[xn][yn][zn];
1661     fprintf(stdout,
1662             "\n Node (%3d, %3d, %3d) pos (%3d, %3d, %3d) label=%d, labels:",
1663             xn, yn, zn, x, y, z, label);
1664     for (i=0; i < gcan->nlabels; ++i)
1665       fprintf(stdout, "%4d ", gcan->labels[i]);
1666     fprintf(stdout, "\n");
1667     gcap = &gca->priors[xp][yp][zp];
1668     if (gcap==NULL)
1669       return;
1670     fprintf(stdout,
1671             "Prior (%3d, %3d, %3d) pos (%3d, %3d, %3d) label=%d\n",
1672             xp, yp, zp, x, y, z, label);
1673     fprintf(stdout, "prior label histogram  (label):");
1674     for (i=0; i < gcap->nlabels; ++i)
1675       fprintf(stdout, "%4d ", gcap->labels[i]);
1676     fprintf(stdout, "\n");
1677     fprintf(stdout, "                     :(counts):");
1678     for (i=0; i < gcap->nlabels; ++i)
1679       fprintf(stdout, "%4.f ", gcap->priors[i]);
1680     fprintf(stdout, "\n");
1681     fprintf(stdout, "mean: ");
1682     for (i = 0 ; i < gca->ninputs ; i++)
1683       fprintf(stdout, "%2.1f ", gc->means[i] / gc->ntraining) ;
1684     fprintf(stdout, "\n");
1685   }
1686   fflush(stdout) ;
1687 }
1688 
1689 int
1690 GCAtrainCovariances(GCA *gca,
1691                     MRI *mri_inputs,
1692                     MRI *mri_labels,
1693                     TRANSFORM *transform)
1694 {
1695   int    x, y, z, width, height, depth, label, xn, yn, zn ;
1696   float  vals[MAX_GCA_INPUTS] ;
1697   int xp, yp, zp;
1698 
1699   /* convert transform to voxel coordinates */
1700 
1701   /* go through each voxel in the input volume and find the canonical
1702      voxel (and hence the classifier) to which it maps. Then update the
1703      classifiers statistics based on this voxel's intensity and label.
1704   */
1705   width = mri_labels->width ;
1706   height = mri_labels->height;
1707   depth = mri_labels->depth ;
1708   for (x = 0 ; x < width ; x++)
1709   {
1710     for (y = 0 ; y < height ; y++)
1711     {
1712       for (z = 0 ; z < depth ; z++)
1713       {
1714         if (x == Gx && y == Gy && z == Gz)
1715           DiagBreak() ;
1716         // get the segmented value
1717         label = nint(MRIgetVoxVal(mri_labels, x, y, z,0)) ;
1718 
1719 #if 0
1720         if (!label)
1721           continue ;
1722 #endif
1723         // get all input volume values at this point
1724         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
1725 
1726         // src -> talairach -> node
1727         if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
1728                                   x, y, z, &xn, &yn, &zn))
1729         {
1730           if (!GCAsourceVoxelToPrior(gca, mri_inputs,
1731                                      transform, x, y, z,
1732                                      &xp, &yp, &zp))
1733           {
1734             ///////////////// debug code ////////////////////////////
1735             if ((xp == Gxp && yp == Gyp && zp == Gzp) &&
1736                 (Ggca_label < 0 || Ggca_label == label))
1737             {
1738               printf("src (%d, %d, %d), "
1739                      "prior (%d, %d, %d), "
1740                      "node (%d, %d, %d), label = %d\n",
1741                      x,y,z, xp, yp, zp, xn, yn, zn, label);
1742             }
1743             ////////////////////////////////////////////////////////
1744             // update the value
1745             GCAupdateNodeCovariance(gca, mri_inputs,
1746                                     xn, yn, zn, vals, label) ;
1747 
1748             //////////////debug code ////////////////////////////
1749             if (xn == Gxn && yn == Gyn && zn == Gzn)
1750             {
1751               fprintf(stdout, "Train Covariance\n");
1752               PrintInfoOnLabels(gca, label,
1753                                 xn,yn,zn,
1754                                 xp,yp,zp,
1755                                 x,y,z);
1756             }
1757             if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z &&
1758                 (label == Ggca_label || Ggca_label < 0))
1759             {
1760               GC1D *gc ;
1761               int  i, nsamples ;
1762               MATRIX *m ;
1763               gc = GCAfindGC(gca, xn, yn, zn, label) ;
1764               if (gc)
1765               {
1766                 nsamples = gc->ntraining - gc->n_just_priors ;
1767                 /* for no-intensity training */
1768                 if (nsamples < 1)
1769                   nsamples = 1  ;
1770                 printf("voxel(%d,%d,%d) = ", x, y, z) ;
1771                 for (i = 0 ; i < gca->ninputs ; i++)
1772                   printf("%d ", nint(vals[i])) ;
1773 
1774                 printf(" --> node(%d,%d,%d), "
1775                        "label %s (%d), mean ",
1776                        xn, yn, zn,
1777                        cma_label_to_name(label),label) ;
1778                 for (i = 0 ; i < gca->ninputs ; i++)
1779                   printf("%2.1f ", gc->means[i]) ;
1780                 printf("\ncovariances (det=%f):\n",
1781                        covariance_determinant
1782                        (gc,gca->ninputs)/pow
1783                        ((double)nsamples,
1784                         (double)gca->ninputs)) ;
1785                 m =
1786                   load_covariance_matrix(gc,
1787                                          NULL,
1788                                          gca->ninputs) ;
1789                 MatrixScalarMul(m, 1.0/(nsamples), m) ;
1790                 MatrixPrint(stdout, m) ;
1791                 MatrixFree(&m) ;
1792               }
1793             }
1794             /////////////////////////////////////////////////
1795           }
1796         } // if (!GCA...)
1797       }
1798     }
1799   }
1800 
1801   fflush(stdout) ;
1802   return(NO_ERROR) ;
1803 }
1804 #include <unistd.h>
1805 
1806 int
1807 GCAtrain(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
1808          TRANSFORM *transform, GCA *gca_prune,
1809          int noint)
1810 {
1811   int    x, y, z, width, height, depth, label, xn, yn, zn,holes_filled,
1812   /*i, xnbr, ynbr, znbr, xn_nbr, yn_nbr, zn_nbr,*/ xp, yp, zp ;
1813   float  vals[MAX_GCA_INPUTS] ;
1814   static int first_time = 1 ;
1815   FILE *logfp = NULL ;
1816   static int logging = 0 ;
1817   GCA_PRIOR *gcap ;
1818   GCA_NODE  *gcan ;
1819   MRI       *mri_mapped ;
1820 
1821     gca->total_training++ ;
1822   mri_mapped = MRIalloc(gca->prior_width, gca->prior_height, gca->prior_depth,
1823                         MRI_UCHAR) ;
1824   if (first_time)
1825   {
1826     first_time = 0 ;
1827     logging = getenv("GCA_LOG") != NULL ;
1828     if (logging)
1829     {
1830       printf("logging image intensities to GCA log file 'gca*.log'\n") ;
1831       for (label = 0 ; label <= MAX_CMA_LABEL ; label++)
1832       {
1833         char fname[STRLEN] ;
1834         sprintf(fname, "gca%d.log", label) ;
1835         if (FileExists(fname))
1836           unlink(fname) ;
1837       }
1838     }
1839   }
1840 
1841 
1842   /* convert transform to voxel coordinates */
1843 
1844   /* go through each voxel in the input volume and find the canonical
1845      voxel (and hence the classifier) to which it maps. Then update the
1846      classifiers statistics based on this voxel's intensity and label.
1847   */
1848   // segmented volume
1849   width = mri_labels->width ;
1850   height = mri_labels->height;
1851   depth = mri_labels->depth ;
1852   for (x = 0 ; x < width ; x++)
1853   {
1854     for (y = 0 ; y < height ; y++)
1855     {
1856       for (z = 0 ; z < depth ; z++)
1857       {
1858         /// debugging /////////////////////////////////////
1859         if (x == Gx && y == Gy && z == Gz)
1860           DiagBreak() ;
1861         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
1862           DiagBreak() ;
1863 
1864         ///////////////////////////////////////////////////
1865 
1866         // get the segmented voxel label
1867         label = nint(MRIgetVoxVal(mri_labels, x, y, z,0)) ;
1868 #if 0
1869         if (!label)
1870           continue ;
1871 #endif
1872         // get all the values to vals[] in inputs at this point
1873         // mri_inputs are T1, PD etc.
1874         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
1875         // segmented volume->talairach volume->node
1876         if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
1877                                   x, y, z, &xn, &yn, &zn))
1878           if (!GCAsourceVoxelToPrior(gca, mri_inputs, transform,
1879                                      x, y, z, &xp, &yp, &zp))
1880           {
1881             // got node point (xn, yn. zn) and
1882             // prior point (xp, yp, zp) for
1883             // this label volume point (x, y, z)
1884             // update the value at this prior point
1885             if (xp == Gxp && yp == Gyp && zp == Gzp)
1886             {
1887               DiagBreak() ;
1888               if (Ggca_label < 0 || Ggca_label == label)
1889               {
1890                 printf("src (%d, %d, %d), "
1891                        "prior (%d, %d, %d), "
1892                        "node (%d, %d, %d), label = %d\n",
1893                        x,y,z, xp, yp, zp, xn, yn, zn, label);
1894               }
1895             }
1896             MRIvox(mri_mapped, xp, yp, zp) = 1 ;
1897             GCAupdatePrior(gca, mri_inputs, xp, yp, zp, label) ;
1898             if ((GCAupdateNode(gca, mri_inputs, xn, yn, zn,
1899                                vals,label,gca_prune, noint) ==
1900                  NO_ERROR) &&
1901                 !(gca->flags & GCA_NO_MRF))
1902               //                 node        label point
1903               GCAupdateNodeGibbsPriors(gca, mri_labels,
1904                                        xn, yn, zn, x, y,z, label);
1905 
1906             /// debugging code //////////////////////////////////////
1907             if (xn == Gxn && yn == Gyn && zn == Gzn)
1908             {
1909               PrintInfoOnLabels(gca, label,
1910                                 xn,yn,zn,
1911                                 xp,yp,zp,
1912                                 x,y,z);
1913             }
1914             if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z &&
1915                 (label == Ggca_label || (Ggca_label < 0))
1916                 && (Ggca_nbr_label < 0))
1917             {
1918               GC1D *gc ;
1919               int  i ;
1920               gc = GCAfindGC(gca, xn, yn, zn, label) ;
1921               if (gc)
1922               {
1923                 if (logging)
1924                 {
1925                   char fname[STRLEN] ;
1926                   sprintf(fname, "gca%d.log", label) ;
1927                   logfp = fopen(fname, "a") ;
1928                 }
1929                 printf("voxel(%d,%d,%d) = ", x, y, z) ;
1930                 for (i = 0 ; i < gca->ninputs ; i++)
1931                 {
1932                   printf("%2.1f ", (vals[i])) ;
1933                   if (logging)
1934                     fprintf(logfp, "%2.1f ", (vals[i])) ;
1935                 }
1936 
1937                 printf(" --> node(%d,%d,%d), "
1938                        "label %s (%d), mean ",
1939                        xn, yn, zn,
1940                        cma_label_to_name(label),label) ;
1941                 for (i = 0 ; i < gca->ninputs ; i++)
1942                   printf("%2.1f ", gc->means[i] / gc->ntraining) ;
1943                 printf("\n") ;
1944                 gcan = &gca->nodes[xn][yn][zn];
1945                 printf("   node labels:");
1946                 for (i=0; i < gcan->nlabels; ++i)
1947                   printf("%d ", gcan->labels[i]);
1948                 printf("\n");
1949                 printf(" --> prior (%d,%d,%d)\n", xp, yp, zp);
1950                 gcap = &gca->priors[xp][yp][zp];
1951                 if (gcap==NULL)
1952                   continue;
1953                 printf("   prior labels:");
1954                 for (i=0; i < gcap->nlabels; ++i)
1955                   printf("%d ", gcap->labels[i]);
1956                 printf("\n");
1957                 if (logging)
1958                 {
1959                   fprintf(logfp, "\n") ;
1960                   fclose(logfp) ;
1961                 }
1962               }
1963               ///////////////////////////////////////////
1964             }
1965           }
1966       }
1967       if (gca->flags & GCA_NO_MRF)
1968         continue ;
1969 #if 0
1970       for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
1971       {
1972         xnbr = x+xnbr_offset[i] ;
1973         ynbr = y+ynbr_offset[i] ;
1974         znbr = z+znbr_offset[i] ;
1975         if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
1976                                   xnbr, ynbr, znbr,
1977                                   &xn_nbr,&yn_nbr,&zn_nbr))
1978         {
1979           if (xn_nbr == xn && yn_nbr == yn && zn_nbr == zn)
1980             continue ;  /* only update if it is a different node */
1981 
1982           if (GCAupdateNode(gca, mri_inputs, xn_nbr, yn_nbr, zn_nbr,
1983                             vals,label,gca_prune,noint) == NO_ERROR)
1984             GCAupdateNodeGibbsPriors(gca, mri_labels,
1985                                      xn_nbr, yn_nbr, zn_nbr,
1986                                      x, y,z, label);
1987         }
1988       }
1989 #endif
1990     }
1991   }
1992 
1993   for (holes_filled = xp = 0 ; xp < gca->prior_width; xp++)
1994   {
1995     for (yp = 0 ; yp < gca->prior_height; yp++)
1996     {
1997       for (zp = 0 ; zp < gca->prior_depth; zp++)
1998       {
1999         if (MRIvox(mri_mapped, xp, yp, zp) > 0)
2000           continue ;
2001         if (!GCApriorToSourceVoxel(gca, mri_inputs, transform,
2002                                    xp, yp, zp, &x, &y, &z))
2003         {
2004           GC1D *gc ;
2005           label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
2006           GCAupdatePrior(gca, mri_inputs, xp, yp, zp, label) ;
2007           GCApriorToNode(gca, xp, yp, zp, &xn, &yn, &zn) ;
2008           gc = GCAfindGC(gca, xn, yn, zn, label) ;
2009           if (gc == NULL)  // label doesn't exist at this position
2010           {
2011             load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
2012             if ((GCAupdateNode(gca, mri_inputs, xn, yn, zn,
2013                                vals,label,gca_prune, noint) ==
2014                  NO_ERROR) && !(gca->flags & GCA_NO_MRF))
2015               GCAupdateNodeGibbsPriors(gca, mri_labels,
2016                                        xn, yn, zn, x, y,z, label);
2017 
2018           }
2019           holes_filled++ ;
2020         }
2021       }
2022     }
2023   }
2024   if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
2025     MRIwrite(mri_mapped, "m.mgz") ;
2026   if (holes_filled > 0)
2027     printf("%d prior holes filled\n", holes_filled) ;
2028   MRIfree(&mri_mapped) ;
2029   return(NO_ERROR) ;
2030 }
2031 
2032 // declare function pointer
2033 static int (*myclose)(FILE *stream);
2034 
2035 int
2036 GCAwrite(GCA *gca, char *fname)
2037 {
2038   FILE      *fp ;
2039   int       x, y, z, n, i, j ;
2040   GCA_NODE  *gcan ;
2041   GCA_PRIOR *gcap ;
2042   GC1D      *gc ;
2043 
2044   if (strstr(fname, ".gcz"))
2045   {
2046     char command[STRLEN];
2047     myclose = pclose;
2048     strcpy(command, "gzip -f -c > ");
2049     strcat(command, fname);
2050     fp = popen(command, "w");
2051     if (errno)
2052     {
2053       pclose(fp);
2054       errno = 0;
2055       ErrorReturn(ERROR_BADPARM,
2056                   (ERROR_BADPARM,
2057                    "GCAwrite(%s): gzip encountered error",
2058                    fname)) ;
2059     }
2060   }
2061   else
2062   {
2063     myclose = fclose;
2064     fp  = fopen(fname, "wb") ;
2065   }
2066   if (!fp)
2067     ErrorReturn(ERROR_NOFILE,
2068                 (ERROR_NOFILE,
2069                  "GCAwrite: could not open GCA %s for writing",fname)) ;
2070 
2071   fwriteFloat(GCA_INT_VERSION, fp) ;
2072   fwriteFloat(gca->prior_spacing, fp) ;
2073   fwriteFloat(gca->node_spacing, fp) ;
2074   fwriteInt(gca->prior_width,fp);
2075   fwriteInt(gca->prior_height,fp);
2076   fwriteInt(gca->prior_depth,fp);
2077   fwriteInt(gca->node_width,fp);
2078   fwriteInt(gca->node_height,fp);
2079   fwriteInt(gca->node_depth,fp);
2080   fwriteInt(gca->ninputs,fp) ;
2081   fwriteInt(gca->flags, fp) ;
2082 
2083   for (x = 0 ; x < gca->node_width ; x++)
2084   {
2085     for (y = 0 ; y < gca->node_height ; y++)
2086     {
2087       for (z = 0 ; z < gca->node_depth ; z++)
2088       {
2089         if (x == 139 && y == 103 && z == 139)
2090           /* wm should be pallidum */
2091           DiagBreak() ;
2092         gcan = &gca->nodes[x][y][z] ;
2093         fwriteInt(gcan->nlabels, fp) ;
2094         fwriteInt(gcan->total_training, fp) ;
2095         for (n = 0 ; n < gcan->nlabels ; n++)
2096         {
2097           int  r, c ;
2098           gc = &gcan->gcs[n] ;
2099                     fwriteInt(gcan->labels[n], fp) ;
2100           for (r = 0 ; r < gca->ninputs ; r++)
2101             fwriteFloat(gc->means[r], fp) ;
2102           for (r = i = 0 ; r < gca->ninputs ; r++)
2103             for (c = r ;  c < gca->ninputs ; c++, i++)
2104               fwriteFloat(gc->covars[i], fp) ;
2105 
2106           if (gca->flags & GCA_NO_MRF)
2107             continue ;
2108           for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
2109           {
2110             fwriteInt(gc->nlabels[i], fp) ;
2111             for (j = 0 ; j < gc->nlabels[i] ; j++)
2112             {
2113               fwriteInt((int)gc->labels[i][j], fp) ;
2114               fwriteFloat(gc->label_priors[i][j], fp) ;
2115             }
2116           }
2117         }
2118       }
2119     }
2120   }
2121 
2122   for (x = 0 ; x < gca->prior_width ; x++)
2123   {
2124     for (y = 0 ; y < gca->prior_height ; y++)
2125     {
2126       for (z = 0 ; z < gca->prior_depth ; z++)
2127       {
2128         if (x == 139 && y == 103 && z == 139)
2129           /* wm should be pallidum */
2130           DiagBreak() ;
2131         gcap = &gca->priors[x][y][z] ;
2132         if (gcap==NULL)
2133           continue;
2134         fwriteInt(gcap->nlabels, fp) ;
2135         fwriteInt(gcap->total_training, fp) ;
2136         for (n = 0 ; n < gcap->nlabels ; n++)
2137         {
2138                     fwriteInt((int)gcap->labels[n], fp) ;
2139           fwriteFloat(gcap->priors[n], fp) ;
2140         }
2141       }
2142     }
2143   }
2144 
2145   // if (gca->type == GCA_FLASH || gca->type == GCA_PARAM)
2146   // always write gca->type
2147   {
2148     int  n ;
2149 
2150     fwriteInt(FILE_TAG, fp) ;  /* beginning of tagged section */
2151 
2152     /* all tags are format: <int: tag> <int: num> <parm> <parm> .... */
2153     fwriteInt(TAG_GCA_TYPE, fp) ;
2154     fwriteInt(1, fp) ;
2155     fwriteInt(gca->type, fp) ;
2156 
2157     if (gca->type == GCA_FLASH)
2158     {
2159       fwriteInt(TAG_PARAMETERS, fp) ;
2160       fwriteInt(3, fp) ;   /* currently only storing 3 parameters */
2161       for (n = 0 ; n < gca->ninputs ; n++)
2162       {
2163         fwriteFloat(gca->TRs[n], fp) ;
2164         fwriteFloat(gca->FAs[n], fp) ;
2165         fwriteFloat(gca->TEs[n], fp) ;
2166       }
2167     }
2168   }
2169 
2170   // write direction cosine information
2171   fwriteInt(TAG_GCA_DIRCOS, fp);
2172   fwriteFloat(gca->x_r, fp);
2173   fwriteFloat(gca->x_a, fp);
2174   fwriteFloat(gca->x_s, fp);
2175   fwriteFloat(gca->y_r, fp);
2176   fwriteFloat(gca->y_a, fp);
2177   fwriteFloat(gca->y_s, fp);
2178   fwriteFloat(gca->z_r, fp);
2179   fwriteFloat(gca->z_a, fp);
2180   fwriteFloat(gca->z_s, fp);
2181   fwriteFloat(gca->c_r, fp);
2182   fwriteFloat(gca->c_a, fp);
2183   fwriteFloat(gca->c_s, fp);
2184   fwriteInt(gca->width, fp);
2185   fwriteInt(gca->height, fp);
2186   fwriteInt(gca->depth, fp);
2187   fwriteFloat(gca->xsize, fp);
2188   fwriteFloat(gca->ysize, fp);
2189   fwriteFloat(gca->zsize, fp);
2190 
2191   // fclose(fp) ;
2192   myclose(fp);
2193 
2194   return(NO_ERROR) ;
2195 }
2196 
2197 GCA *
2198 GCAread(char *fname)
2199 {
2200   FILE      *fp ;
2201   int       x, y, z, n, i, j ;
2202   GCA       *gca ;
2203   GCA_NODE  *gcan ;
2204   GCA_PRIOR *gcap ;
2205   GC1D      *gc ;
2206   float     version, node_spacing, prior_spacing ;
2207   int       node_width, node_height, node_depth,
2208   prior_width, prior_height, prior_depth,
2209   ninputs, flags ;
2210   int       tag;
2211 
2212   if (strstr(fname, ".gcz"))
2213   {
2214     char command[STRLEN];
2215     myclose = pclose;
2216 #if defined(Darwin) || defined(SunOS)
2217     // zcat on Max OS always appends and assumes a .Z extention,
2218     // whereas we want .gcz
2219     strcpy(command, "gunzip -c ");
2220 #else
2221     strcpy(command, "zcat ");
2222 #endif
2223     strcat(command, fname);
2224     errno = 0;
2225     fp = popen(command, "r");
2226     if (errno)
2227     {
2228       pclose(fp);
2229       errno = 0;
2230       ErrorReturn(NULL, (ERROR_BADPARM,
2231                          "GCAread: encountered error executing: '%s'",
2232                          command)) ;
2233     }
2234   }
2235   else
2236   {
2237     myclose = fclose;
2238     fp  = fopen(fname, "rb") ;
2239   }
2240   if (!fp)
2241     ErrorReturn(NULL,
2242                 (ERROR_NOFILE,
2243                  "GCAread: could not open GCA %s for reading",fname)) ;
2244 
2245   if (!freadFloatEx(&version, fp))
2246     ErrorReturn(NULL, (ERROR_BADPARM,"GCAread(%s): could not read file",
2247                        fname)) ;
2248 
2249   if (version < GCA_UCHAR_VERSION)
2250   {
2251     node_spacing = freadFloat(fp) ;
2252     node_width = freadInt(fp);
2253     node_height = freadInt(fp);
2254     node_depth = freadInt(fp);
2255     ninputs = freadInt(fp) ;
2256     if (version == 3.0)
2257       flags = freadInt(fp) ;
2258     else
2259       flags = 0 ;
2260 
2261     gca = gcaAllocMax(ninputs, node_spacing, \
2262                       node_spacing, node_spacing*node_width,
2263                       node_spacing*node_height, \
2264                       node_spacing*node_depth, 0, flags) ;
2265     if (!gca)
2266       ErrorReturn(NULL, (Gerror, NULL)) ;
2267 
2268     for (x = 0 ; x < gca->node_width ; x++)
2269     {
2270       for (y = 0 ; y < gca->node_height ; y++)
2271       {
2272         for (z = 0 ; z < gca->node_depth ; z++)
2273         {
2274           if (x == 28 && y == 39 && z == 39)
2275             DiagBreak() ;
2276           gcan = &gca->nodes[x][y][z] ;
2277           gcan->nlabels = freadInt(fp) ;
2278           gcan->total_training = freadInt(fp) ;
2279           if (gcan->nlabels)
2280           {
2281             gcan->labels = \
2282                            (unsigned short *)calloc(gcan->nlabels,
2283                                                    sizeof(unsigned short)) ;
2284             if (!gcan->labels)
2285               ErrorExit(ERROR_NOMEMORY,
2286                         "GCAread(%s): could not allocate %d "
2287                         "labels @ (%d,%d,%d)",
2288                         fname, gcan->nlabels, x, y, z) ;
2289             gcan->gcs = alloc_gcs(gcan->nlabels,
2290                                   flags, gca->ninputs) ;
2291             if (!gcan->gcs)
2292               ErrorExit(ERROR_NOMEMORY,
2293                         "GCAread(%s); could not allocated %d gcs "
2294                         "@ (%d,%d,%d)",
2295                         fname, gcan->nlabels, x, y, z) ;
2296           }
2297           else // no labels assigned to this node
2298           {
2299             gcan->labels = 0;
2300             gcan->gcs = 0;
2301           }
2302           for (n = 0 ; n < gcan->nlabels ; n++)
2303           {
2304             int r, c;
2305             gc = &gcan->gcs[n] ;
2306             gcan->labels[n] = (unsigned short)fgetc(fp) ;
2307             for (r = 0 ; r < gca->ninputs ; r++)
2308               gc->means[r] = freadFloat(fp) ;
2309             for (i = r = 0 ; r < gca->ninputs ; r++)
2310               for (c = r ; c < gca->ninputs ; c++, i++)
2311                 gc->covars[i] = freadFloat(fp) ;
2312             if (gca->flags & GCA_NO_MRF)
2313               continue ;
2314             for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
2315             {
2316               gc->nlabels[i] = freadInt(fp) ;
2317 
2318 #if 1
2319               /* allocate new ones */
2320               gc->label_priors[i] =
2321                 (float *)calloc(gc->nlabels[i],sizeof(float));
2322               if (!gc->label_priors[i])
2323                 ErrorExit(ERROR_NOMEMORY, "GCAread(%s): "
2324                           "couldn't expand gcs to %d",
2325                           fname,gc->nlabels) ;
2326               gc->labels[i] =
2327                 (unsigned short *)calloc(gc->nlabels[i], \
2328                                         sizeof(unsigned short)) ;
2329               if (!gc->labels)
2330                 ErrorExit(ERROR_NOMEMORY,
2331                           "GCAread(%s): couldn't expand "
2332                           "labels to %d",
2333                           fname, gc->nlabels[i]) ;
2334 #endif
2335               for (j = 0 ; j < gc->nlabels[i] ; j++)
2336               {
2337                 gc->labels[i][j] = (unsigned short)freadInt(fp) ;
2338                 gc->label_priors[i][j] = freadFloat(fp) ;
2339               }
2340             }
2341           }
2342         }
2343       }
2344     }
2345   }
2346   else   /* current version - stores priors at different
2347                             resolution than densities */
2348   {
2349     if (!FEQUAL(version, GCA_UCHAR_VERSION) &&
2350                 !FEQUAL(version, GCA_INT_VERSION))
2351     {
2352       // fclose(fp) ;
2353       myclose(fp);
2354       ErrorReturn(NULL, (ERROR_BADFILE,
2355                          "GCAread(%s), version #%2.1f found, "
2356                          "%2.1f expected",
2357                          fname, version, GCA_INT_VERSION)) ;
2358     }
2359     prior_spacing = freadFloat(fp) ;
2360     node_spacing = freadFloat(fp) ;
2361     prior_width = freadInt(fp);
2362     prior_height = freadInt(fp);
2363     prior_depth = freadInt(fp);
2364     node_width = freadInt(fp);
2365     node_height = freadInt(fp);
2366     node_depth = freadInt(fp);
2367     ninputs = freadInt(fp) ;
2368     flags = freadInt(fp) ;
2369 
2370     gca = gcaAllocMax(ninputs, prior_spacing, node_spacing,
2371                       node_spacing*node_width,
2372                       node_spacing*node_height,
2373                       node_spacing*node_depth, 0, flags) ;
2374     if (!gca)
2375       ErrorReturn(NULL, (Gdiag, NULL)) ;
2376 
2377     for (x = 0 ; x < gca->node_width ; x++)
2378     {
2379       for (y = 0 ; y < gca->node_height ; y++)
2380       {
2381         for (z = 0 ; z < gca->node_depth ; z++)
2382         {
2383           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
2384             DiagBreak() ;
2385           gcan = &gca->nodes[x][y][z] ;
2386           gcan->nlabels = freadInt(fp) ;
2387           gcan->total_training = freadInt(fp) ;
2388           if (gcan->nlabels)
2389           {
2390             gcan->labels =
2391               (unsigned short *)calloc(gcan->nlabels,
2392                                       sizeof(unsigned short)) ;
2393             if (!gcan->labels)
2394               ErrorExit(ERROR_NOMEMORY, "GCAread(%s): could not "
2395                         "allocate %d "
2396                         "labels @ (%d,%d,%d)",
2397                         fname, gcan->nlabels, x, y, z) ;
2398             gcan->gcs = alloc_gcs(gcan->nlabels,
2399                                   flags,
2400                                   gca->ninputs) ;
2401             if (!gcan->gcs)
2402               ErrorExit(ERROR_NOMEMORY,
2403                         "GCAread(%s); could not allocated %d gcs "
2404                         "@ (%d,%d,%d)",
2405                         fname, gcan->nlabels, x, y, z) ;
2406           }
2407           else // no labels at this node
2408           {
2409             gcan->labels = 0;
2410             gcan->gcs = 0;
2411           }
2412           for (n = 0 ; n < gcan->nlabels ; n++)
2413           {
2414             int  r, c ;
2415 
2416             gc = &gcan->gcs[n] ;
2417 
2418                         if (version == GCA_UCHAR_VERSION)
2419                             gcan->labels[n] = (unsigned short)fgetc(fp) ;
2420                         else
2421                             gcan->labels[n] = (unsigned short)freadInt(fp) ;
2422 
2423             for (r = 0 ; r < gca->ninputs ; r++)
2424               gc->means[r] = freadFloat(fp) ;
2425             for (i = r = 0 ; r < gca->ninputs ; r++)
2426               for (c = r ; c < gca->ninputs ; c++, i++)
2427                 gc->covars[i] = freadFloat(fp) ;
2428             if (gca->flags & GCA_NO_MRF)
2429               continue ;
2430             for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
2431             {
2432               gc->nlabels[i] = freadInt(fp) ;
2433 
2434               /* allocate new ones */
2435               gc->label_priors[i] =
2436                 (float *)calloc(gc->nlabels[i],sizeof(float));
2437               if (!gc->label_priors[i])
2438                 ErrorExit(ERROR_NOMEMORY, "GCAread(%s): "
2439                           "couldn't expand gcs to %d",
2440                           fname,gc->nlabels) ;
2441               gc->labels[i] =
2442                 (unsigned short *)calloc(gc->nlabels[i], \
2443                                         sizeof(unsigned short)) ;
2444               if (!gc->labels)
2445                 ErrorExit(ERROR_NOMEMORY,
2446                           "GCAread(%s): couldn't expand "
2447                           "labels to %d",
2448                           fname, gc->nlabels[i]) ;
2449               for (j = 0 ; j < gc->nlabels[i] ; j++)
2450               {
2451                 gc->labels[i][j] = (unsigned short)freadInt(fp) ;
2452                 gc->label_priors[i][j] = freadFloat(fp) ;
2453               }
2454             }
2455           }
2456         }
2457       }
2458     }
2459 
2460     for (x = 0 ; x < gca->prior_width ; x++)
2461     {
2462       for (y = 0 ; y < gca->prior_height ; y++)
2463       {
2464         for (z = 0 ; z < gca->prior_depth ; z++)
2465         {
2466           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
2467             DiagBreak() ;
2468           gcap = &gca->priors[x][y][z] ;
2469           if (gcap==NULL)
2470             continue;
2471           gcap->nlabels = freadInt(fp) ;
2472           gcap->total_training = freadInt(fp) ;
2473           if (gcap->nlabels)
2474           {
2475             gcap->labels =
2476               (unsigned short *)calloc(gcap->nlabels, \
2477                                       sizeof(unsigned short)) ;
2478             if (!gcap->labels)
2479               ErrorExit(ERROR_NOMEMORY, "GCAread(%s): could not "
2480                         "allocate %d "
2481                         "labels @ (%d,%d,%d)",
2482                         fname, gcap->nlabels, x, y, z) ;
2483             gcap->priors = (float *)calloc(gcap->nlabels,
2484                                            sizeof(float)) ;
2485             if (!gcap->priors)
2486               ErrorExit(ERROR_NOMEMORY, "GCAread(%s): could "
2487                         "not allocate %d "
2488                         "priors @ (%d,%d,%d)",
2489                         fname, gcap->nlabels, x, y, z) ;
2490           }
2491           else // no labels assigned to this priors
2492           {
2493             gcap->labels = 0;
2494             gcap->priors = 0;
2495           }
2496           for (n = 0 ; n < gcap->nlabels ; n++)
2497           {
2498                         if (version == GCA_UCHAR_VERSION)
2499                             gcap->labels[n] = (unsigned short)fgetc(fp) ;
2500                         else
2501                             gcap->labels[n] = (unsigned short)freadInt(fp) ;
2502             gcap->priors[n] = freadFloat(fp) ;
2503           }
2504         }
2505       }
2506     }
2507   }
2508 
2509   for (x = 0 ; x < gca->node_width ; x++)
2510   {
2511     for (y = 0 ; y < gca->node_height ; y++)
2512     {
2513       for (z = 0 ; z < gca->node_depth ; z++)
2514       {
2515         int xp, yp, zp ;
2516 
2517         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
2518           DiagBreak() ;
2519         gcan = &gca->nodes[x][y][z] ;
2520         if (gcaNodeToPrior(gca, x, y, z, &xp, &yp, &zp)==NO_ERROR)
2521         {
2522           gcap = &gca->priors[xp][yp][zp] ;
2523           if (gcap==NULL)
2524             continue;
2525           for (n = 0 ; n < gcan->nlabels ; n++)
2526           {
2527             gc = &gcan->gcs[n] ;
2528             gc->ntraining =
2529               gcan->total_training * getPrior(gcap,gcan->labels[n]) ;
2530           }
2531         }
2532       }
2533     }
2534   }
2535 
2536   // if (!feof(fp))  // this does not work ;-)
2537   // feof(fp) check does not work, since feof is not signaled until you read
2538   while (freadIntEx(&tag, fp))
2539   {
2540     int  n, nparms ;
2541 
2542     // tag = freadInt(fp) ;
2543     if (tag == FILE_TAG) /* beginning of tagged section */
2544     {
2545       // while (!feof(fp))
2546       while (freadIntEx(&tag, fp))
2547       {
2548         /* all tags are format:
2549            <int: tag> <int: num> <parm> <parm> .... */
2550         // tag = freadInt(fp) ;
2551         switch (tag)
2552         {
2553         case TAG_GCA_TYPE:
2554           freadInt(fp) ;   /* skip num=1 */
2555           gca->type = freadInt(fp) ;
2556           if (DIAG_VERBOSE_ON) switch (gca->type)
2557             {
2558             case GCA_NORMAL:
2559               printf("setting gca type = Normal gca type\n");
2560               break;
2561             case GCA_PARAM:
2562               printf("setting gca type = T1/PD gca type\n");
2563               break;
2564             case GCA_FLASH:
2565               printf("setting gca type = FLASH gca type\n");
2566               break;
2567             default:
2568               printf("setting gca type = Unknown\n");
2569               gca->type=GCA_UNKNOWN;
2570               break;
2571             }
2572           break ;
2573         case TAG_PARAMETERS:
2574           nparms = freadInt(fp) ;
2575           /* how many MR parameters are stored */
2576           printf("reading %d MR parameters out of GCA header...\n",
2577                  nparms) ;
2578           for (n = 0 ; n < gca->ninputs ; n++)
2579           {
2580             gca->TRs[n] = freadFloat(fp) ;
2581             gca->FAs[n] = freadFloat(fp) ;
2582             gca->TEs[n] = freadFloat(fp) ;
2583             printf("input %d: TR=%2.1f msec, FA=%2.1f deg, "
2584                    "TE=%2.1f msec\n",
2585                    n,
2586                    gca->TRs[n],
2587                    DEGREES(gca->FAs[n]), gca->TEs[n]) ;
2588           }
2589           break ;
2590         case TAG_GCA_DIRCOS:
2591           gca->x_r = freadFloat(fp);
2592           gca->x_a = freadFloat(fp);
2593           gca->x_s = freadFloat(fp);
2594           gca->y_r = freadFloat(fp);
2595           gca->y_a = freadFloat(fp);
2596           gca->y_s = freadFloat(fp);
2597           gca->z_r = freadFloat(fp);
2598           gca->z_a = freadFloat(fp);
2599           gca->z_s = freadFloat(fp);
2600           gca->c_r = freadFloat(fp);
2601           gca->c_a = freadFloat(fp);
2602           gca->c_s = freadFloat(fp);
2603           gca->width = freadInt(fp);
2604           gca->height = freadInt(fp);
2605           gca->depth = freadInt(fp);
2606           gca->xsize = freadFloat(fp);
2607           gca->ysize = freadFloat(fp);
2608           gca->zsize = freadFloat(fp);
2609 
2610           if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
2611           {
2612             printf("Direction cosines read:\n");
2613             printf(" x_r = % .4f, y_r = % .4f, z_r = % .4f\n",
2614                    gca->x_r, gca->y_r, gca->z_r);
2615             printf(" x_a = % .4f, y_a = % .4f, z_a = % .4f\n",
2616                    gca->x_a, gca->y_a, gca->z_a);
2617             printf(" x_s = % .4f, y_s = % .4f, z_s = % .4f\n",
2618                    gca->x_s, gca->y_s, gca->z_s);
2619             printf(" c_r = % .4f, c_a = % .4f, c_s = % .4f\n",
2620                    gca->c_r, gca->c_a, gca->c_s);
2621           }
2622           break;
2623         default:
2624           ErrorPrintf(ERROR_BADFILE,
2625                       "GCAread(%s): unknown tag %x\n", fname, tag) ;
2626           break ;
2627         }
2628       }
2629     }
2630   }
2631 
2632   GCAsetup(gca);
2633 
2634   // fclose(fp) ;
2635   myclose(fp);
2636 
2637   return(gca) ;
2638 }
2639 
2640 static int
2641 GCAupdatePrior(GCA *gca, MRI *mri, int xn, int yn, int zn, int label)
2642 {
2643   int       n ;
2644   GCA_PRIOR *gcap ;
2645 
2646   if (label >= MAX_CMA_LABEL)
2647     ErrorReturn(ERROR_BADPARM,
2648                 (ERROR_BADPARM,
2649                  "GCAupdatePrior(%d, %d, %d, %d): label out of range",
2650                  xn, yn, zn, label)) ;
2651 
2652   if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
2653     DiagBreak() ;
2654 
2655   gcap = &gca->priors[xn][yn][zn] ;
2656   if (gcap==NULL)
2657     return -1;
2658   // find the label histogram index n
2659   for (n = 0 ; n < gcap->nlabels ; n++)
2660   {
2661     if (gcap->labels[n] == label)
2662       break ;
2663   }
2664   // if index is beyond what we have, then
2665   if (n >= gcap->nlabels)  /* have to allocate a new classifier */
2666   {
2667 
2668     if (n >= gcap->max_labels)
2669     {
2670       int  old_max_labels ;
2671       unsigned short *old_labels ;
2672       float *old_priors ;
2673 
2674       old_max_labels = gcap->max_labels ;
2675       gcap->max_labels += 2 ;
2676       old_labels = gcap->labels ;
2677       old_priors = gcap->priors ;
2678 
2679       /* allocate new ones */
2680       gcap->priors = (float *)calloc(gcap->max_labels, sizeof(float)) ;
2681 
2682       if (!gcap->priors)
2683         ErrorExit(ERROR_NOMEMORY,
2684                   "GCANupdatePriors: couldn't expand priors to %d",
2685                   gcap->max_labels) ;
2686       gcap->labels =
2687         (unsigned short *)calloc(gcap->max_labels, sizeof(unsigned short)) ;
2688       if (!gcap->labels)
2689         ErrorExit(ERROR_NOMEMORY,
2690                   "GCANupdatePriors: couldn't expand labels to %d",
2691                   gcap->max_labels) ;
2692 
2693       /* copy the old ones over */
2694       memmove(gcap->priors, old_priors, old_max_labels*sizeof(float)) ;
2695       memmove(gcap->labels, old_labels,
2696               old_max_labels*sizeof(unsigned short)) ;
2697 
2698       /* free the old ones */
2699       free(old_priors) ;
2700       free(old_labels) ;
2701     }
2702     // add one
2703     gcap->nlabels++ ;
2704   }
2705 
2706   /* these will be updated when training is complete */
2707   // give the value at n
2708   gcap->priors[n] += 1.0f ; // increment counter
2709   gcap->total_training++ ;  // increment training counter
2710   gcap->labels[n] = label ; // save the label value
2711 
2712   return(NO_ERROR) ;
2713 }
2714 
2715 static int
2716 GCAupdateNodeCovariance(GCA *gca, MRI *mri,
2717                         int xn, int yn, int zn, float *vals,int label)
2718 {
2719   int      n, r, c, v ;
2720   GCA_NODE *gcan ;
2721   GC1D     *gc ;
2722 
2723 
2724   if (label >= MAX_CMA_LABEL)
2725     ErrorReturn(ERROR_BADPARM,
2726                 (ERROR_BADPARM,
2727                  "GCAupdateNodeCovariance(%d, %d, %d, %d): label out of range",
2728                  xn, yn, zn, label)) ;
2729 
2730   ///////////// debug ////////////////////////////////
2731   if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z && label == Ggca_label)
2732     DiagBreak() ;
2733   if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
2734     DiagBreak() ;
2735   ////////////////////////////////////////////////////
2736 
2737   gcan = &gca->nodes[xn][yn][zn] ;
2738 
2739   for (n = 0 ; n < gcan->nlabels ; n++)
2740   {
2741     if (gcan->labels[n] == label)
2742       break ;
2743   }
2744   if (n >= gcan->nlabels)
2745     ErrorExit(ERROR_BADPARM,
2746               "GCAupdateNodeCovariance(%d, %d, %d, %d): could not find label",
2747               xn, yn, zn, label) ;
2748 
2749   gc = &gcan->gcs[n] ;
2750 
2751   /* remove means from vals */
2752   for (r = 0 ; r < gca->ninputs ; r++)
2753     vals[r] -= gc->means[r] ;
2754 
2755   /* these will be normalized when training is complete */
2756   for (v = r = 0 ; r < gca->ninputs ; r++)
2757   {
2758     for (c = r ; c < gca->ninputs ; c++, v++)
2759       gc->covars[v] += vals[r]*vals[c] ;
2760   }
2761 
2762   /* put means back in vals so caller isn't confused */
2763   for (r = 0 ; r < gca->ninputs ; r++)
2764     vals[r] += gc->means[r] ;
2765 
2766   return(NO_ERROR) ;
2767 }
2768 
2769 static int
2770 GCAupdateNode(GCA *gca, MRI *mri,
2771               int xn, int yn, int zn, float *vals, int label,
2772               GCA *gca_prune, int noint)
2773 {
2774   int      n, i ;
2775   GCA_NODE *gcan ;
2776   GC1D     *gc ;
2777 
2778 
2779   if (label >= MAX_CMA_LABEL)
2780     ErrorReturn(ERROR_BADPARM,
2781                 (ERROR_BADPARM,
2782                  "GCAupdateNode(%d, %d, %d, %d): label out of range",
2783                  xn, yn, zn, label)) ;
2784 
2785   if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z && label == Ggca_label)
2786     DiagBreak() ;
2787   if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
2788     DiagBreak() ;
2789 
2790   // if non-zero label and gca_prune is there
2791   if (label > 0 && gca_prune != NULL && !noint)
2792   {
2793     GCA_NODE *gcan_prune ;
2794     GC1D     *gc_prune ;
2795     int      nprune ;
2796 
2797     gcan_prune = &gca_prune->nodes[xn][yn][zn] ;
2798 
2799     for (nprune = 0 ; nprune < gcan_prune->nlabels ; nprune++)
2800     {
2801       if (gcan_prune->labels[nprune] == label)
2802         break ;
2803     }
2804     if (nprune >= gcan_prune->nlabels)
2805       ErrorPrintf(ERROR_BADPARM,
2806                   "WARNING: pruning GCA at (%d,%d,%d) doesn't "
2807                   "contain label %d", xn, yn, zn, label) ;
2808     gc_prune = &gcan_prune->gcs[nprune] ;
2809 
2810     if (sqrt(GCAmahDist(gc_prune, vals, gca->ninputs)) > 2)
2811       /* more than 2 stds from mean */
2812     {
2813 #if 0
2814       if (xn == 23 && yn == 30 && zn == 32)
2815       {
2816         printf(
2817           "pruning val %2.0f, label %d @ "
2818           "(%d,%d,%d),u=%2.1f, std=%2.1f\n"
2819           ,val, label, xn,yn,zn,mean, std) ;
2820         DiagBreak() ;
2821       }
2822 #endif
2823       total_pruned++ ;
2824       return(ERROR_BAD_PARM) ;
2825     }
2826   }
2827 
2828   // get one at this point
2829   gcan = &gca->nodes[xn][yn][zn] ;
2830 
2831   // look for this label in the array
2832   for (n = 0 ; n < gcan->nlabels ; n++)
2833   {
2834     if (gcan->labels[n] == label)
2835       break ;
2836   }
2837   // if not found
2838   if (n >= gcan->nlabels)  /* have to allocate a new classifier */
2839   {
2840 
2841     if (n >= gcan->max_labels)
2842     {
2843       int  old_max_labels ;
2844       unsigned short *old_labels ;
2845       GC1D *old_gcs ;
2846 
2847       old_max_labels = gcan->max_labels ;
2848       gcan->max_labels += 2 ;
2849       old_labels = gcan->labels ;
2850       old_gcs = gcan->gcs ;
2851 
2852       /* allocate new ones */
2853 #if 0
2854       gcan->gcs = (GC1D *)calloc(gcan->max_labels, sizeof(GC1D)) ;
2855 #else
2856       gcan->gcs = alloc_gcs(gcan->max_labels, gca->flags, gca->ninputs) ;
2857 #endif
2858 
2859       if (!gcan->gcs)
2860         ErrorExit(ERROR_NOMEMORY,
2861                   "GCANupdateNode: couldn't expand gcs to %d",
2862                   gcan->max_labels) ;
2863       gcan->labels =
2864         (unsigned short *)calloc(gcan->max_labels, sizeof(unsigned short)) ;
2865       if (!gcan->labels)
2866         ErrorExit(ERROR_NOMEMORY,
2867                   "GCANupdateNode: couldn't expand labels to %d",
2868                   gcan->max_labels) ;
2869 
2870       /* copy the old ones over */
2871 #if 0
2872       memmove(gcan->gcs, old_gcs, old_max_labels*sizeof(GC1D)) ;
2873 #else
2874       copy_gcs(old_max_labels, old_gcs, gcan->gcs, gca->ninputs) ;
2875 #endif
2876       memmove(gcan->labels, old_labels,
2877               old_max_labels*sizeof(unsigned short)) ;
2878 
2879       /* free the old ones */
2880       free(old_gcs) ;
2881       free(old_labels) ;
2882     }
2883     gcan->nlabels++ ;
2884   }
2885 
2886   gc = &gcan->gcs[n] ;
2887 
2888   /* these will be updated when training is complete */
2889   if (noint)
2890     gc->n_just_priors++ ;
2891   else
2892   {
2893     // vals[] array is the values of inputs at this point
2894     for (i = 0 ; i < gca->ninputs ; i++)
2895       gc->means[i] += vals[i] ;
2896     // get the mean valu (note it is not divided by ninputs!)
2897     /*gc->var += val*val ; */
2898   }
2899   if (gc->n_just_priors >= gc->ntraining)
2900     DiagBreak() ;
2901   gcan->total_training++ ;
2902 
2903   gcan->labels[n] = label ;
2904   gc->ntraining++ ;
2905 
2906   return(NO_ERROR) ;
2907 }
2908 int
2909 GCAcompleteMeanTraining(GCA *gca)
2910 {
2911   int       x, y, z, n, total_nodes, \
2912   total_gcs, i, j, holes_filled, total_brain_gcs,\
2913   total_brain_nodes, r ;
2914   float     nsamples ;
2915   GCA_NODE  *gcan ;
2916   GCA_PRIOR *gcap ;
2917   GC1D      *gc ;
2918 
2919   total_nodes = gca->node_width*gca->node_height*gca->node_depth ;
2920   total_brain_nodes = total_gcs = total_brain_gcs = 0 ;
2921   for (x = 0 ; x < gca->node_width ; x++)
2922   {
2923     for (y = 0 ; y < gca->node_height ; y++)
2924     {
2925       for (z = 0 ; z < gca->node_depth ; z++)
2926       {
2927         gcan = &gca->nodes[x][y][z] ;
2928         total_gcs += gcan->nlabels ;
2929         if (gcan->nlabels > 1 || !IS_UNKNOWN(gcan->labels[0]))
2930         {
2931           total_brain_gcs += gcan->nlabels ;
2932           total_brain_nodes++ ;
2933         }
2934 
2935         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
2936           DiagBreak() ;
2937         for (n = 0 ; n < gcan->nlabels ; n++)
2938         {
2939           gc = &gcan->gcs[n] ;
2940           nsamples = gc->ntraining ;
2941           if ((gca->flags & GCA_NO_MRF) == 0)
2942           {
2943             for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
2944             {
2945               for (j = 0 ; j < gc->nlabels[i] ; j++)
2946               {
2947                 gc->label_priors[i][j] /= (float)nsamples ;
2948                 check_finite(
2949                   "GCAcompleteMeanTraining: "
2950                   "label_priors",
2951                   gc->label_priors[i][j]) ;
2952               }
2953             }
2954           }
2955 
2956           nsamples -= gc->n_just_priors ;
2957           /* for no-intensity training */
2958           if (nsamples > 0)
2959           {
2960             for (r = 0 ; r < gca->ninputs ; r++)
2961             {
2962               gc->means[r] /= nsamples ;
2963               check_finite("GCAcompleteMeanTraining: mean",
2964                            gc->means[r]) ;
2965             }
2966           }
2967           else
2968           {
2969             int r ;
2970             for (r = 0 ; r < gca->ninputs ; r++)
2971               gc->means[r] = -1 ;  /* mark it for later processing */
2972           }
2973         }
2974       }
2975     }
2976   }
2977 
2978   for (x = 0 ; x < gca->prior_width ; x++)
2979   {
2980     for (y = 0 ; y < gca->prior_height ; y++)
2981     {
2982       for (z = 0 ; z < gca->prior_depth ; z++)
2983       {
2984         gcap = &gca->priors[x][y][z] ;
2985         if (gcap==NULL)
2986           continue;
2987         for (n = 0 ; n < gcap->nlabels ; n++)
2988         {
2989           gcap->priors[n] /= (float)gcap->total_training ;
2990           check_finite("GCAcompleteMeanTraining: priors",
2991                        gcap->priors[n]) ;
2992         }
2993 
2994       }
2995     }
2996   }
2997   printf("filling holes in the GCA...\n") ;
2998   for (holes_filled = x = 0 ; x < gca->node_width ; x++)
2999   {
3000     for (y = 0 ; y < gca->node_height ; y++)
3001     {
3002       for (z = 0 ; z < gca->node_depth ; z++)
3003       {
3004         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3005           DiagBreak() ;
3006         gcan = &gca->nodes[x][y][z] ;
3007         for (n = 0 ; n < gcan->nlabels ; n++)
3008         {
3009           gc = &gcan->gcs[n] ;
3010           nsamples = gc->ntraining - gc->n_just_priors ;
3011           if (nsamples <= 0)
3012           {
3013             GC1D *gc_nbr ;
3014             int  r, i ;
3015 
3016             gc_nbr = findClosestValidGC(gca, x, y, z,
3017                                         gcan->labels[n], 0) ;
3018             if (!gc_nbr)
3019             {
3020               ErrorPrintf(ERROR_BADPARM,
3021                           "gca(%d,%d,%d,%d) - could not "
3022                           "find valid nbr label "
3023                           "%s (%d)", x,  y, z, n,
3024                           cma_label_to_name(gcan->labels[n]),
3025                           gcan->labels[n]) ;
3026               continue ;
3027             }
3028             holes_filled++ ;
3029             for (i = r = 0 ; r < gca->ninputs ; r++)
3030             {
3031               gc->means[r] = gc_nbr->means[r] ;
3032             }
3033             if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3034               printf("filling hole @ (%d, %d, %d)\n", x, y, z) ;
3035           }
3036         }
3037       }
3038     }
3039   }
3040 
3041   printf("%d classifiers: %2.1f per node, %2.2f in brain (%d holes filled)\n",
3042          total_gcs, (float)total_gcs/(float)total_nodes,
3043          (float)total_brain_gcs/(float)total_brain_nodes,holes_filled) ;
3044   if (total_pruned > 0)
3045   {
3046     printf("%d samples pruned during training\n", total_pruned) ;
3047     total_pruned = 0 ;
3048   }
3049   return(NO_ERROR) ;
3050 }
3051 
3052 int
3053 GCAcompleteCovarianceTraining(GCA *gca)
3054 {
3055   int       x, y, z, n, holes_filled, r, c,v, nregs = 0, nsamples ;
3056   GCA_NODE  *gcan ;
3057   GC1D      *gc ;
3058 
3059   for (x = 0 ; x < gca->node_width ; x++)
3060   {
3061     for (y = 0 ; y < gca->node_height ; y++)
3062     {
3063       for (z = 0 ; z < gca->node_depth ; z++)
3064       {
3065         gcan = &gca->nodes[x][y][z] ;
3066 
3067         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3068           DiagBreak() ;
3069         for (n = 0 ; n < gcan->nlabels ; n++)
3070         {
3071           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
3072               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
3073             DiagBreak() ;
3074           gc = &gcan->gcs[n] ;
3075           nsamples = gc->ntraining - gc->n_just_priors ;
3076           /* for no-intensity training */
3077           if (nsamples > 0)
3078           {
3079             for (r = v = 0 ; r < gca->ninputs ; r++)
3080             {
3081               check_finite("GCAcompleteCovarianceTraining: mean",
3082                            gc->means[r]) ;
3083               if (nsamples > 1)
3084               {
3085                 for (c = r ; c < gca->ninputs ; c++, v++)
3086                 {
3087                   gc->covars[v] /= (float)(nsamples-1) ;
3088                   check_finite("GCAcompleteCovarianceTraining:"
3089                                " covar",
3090                                gc->covars[v]) ;
3091                   if (r == c)
3092                     /* diagonal should be positive definite */
3093                   {
3094                     if (gc->covars[v] < -0.1)
3095                       DiagBreak() ;
3096                   }
3097                 }
3098               }
3099             }
3100           }
3101           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
3102               (gcan->labels[n] == Ggca_label || Ggca_label < 0))
3103           {
3104             MATRIX *m ;
3105             double det ;
3106 
3107             det = covariance_determinant(gc, gca->ninputs) ;
3108             printf("final covariance matrix for %s "
3109                    "(nsamples=%d, det=%f):\n",
3110                    cma_label_to_name(gcan->labels[n]),
3111                    nsamples, det) ;
3112             m = load_covariance_matrix(gc, NULL, gca->ninputs) ;
3113             MatrixPrint(stdout, m) ;
3114             MatrixFree(&m) ;
3115             fflush(stdout) ;
3116           }
3117         }
3118       }
3119     }
3120   }
3121 
3122   holes_filled = 0 ;
3123 #if 0
3124   printf("filling holes in the GCA...\n") ;
3125   for (holes_filled = x = 0 ; x < gca->node_width ; x++)
3126   {
3127     for (y = 0 ; y < gca->node_height ; y++)
3128     {
3129       for (z = 0 ; z < gca->node_depth ; z++)
3130       {
3131         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3132           DiagBreak() ;
3133         gcan = &gca->nodes[x][y][z] ;
3134         for (n = 0 ; n < gcan->nlabels ; n++)
3135         {
3136           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
3137               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
3138             DiagBreak() ;
3139           gc = &gcan->gcs[n] ;
3140           nsamples = gc->ntraining - gc->n_just_priors ;
3141           /* for no-intensity training */
3142 #define MIN_GC_SAMPLES(gca) ((gca->ninputs*(gca->ninputs+1))/2)
3143           if (gc->means[0] < 0 || nsamples < MIN_GC_SAMPLES(gca))
3144           {
3145             GC1D *gc_nbr ;
3146             int  r, c, i ;
3147 
3148             gc_nbr = findClosestValidGC(gca, x, y, z,
3149                                         gcan->labels[n], 1) ;
3150             if (!gc_nbr)
3151             {
3152               ErrorPrintf(ERROR_BADPARM,
3153                           "gca(%d,%d,%d,%d) - could not "
3154                           "find valid nbr label "
3155                           "%s (%d)", x,  y, z, n,
3156                           cma_label_to_name(gcan->labels[n]),
3157                           gcan->labels[n]) ;
3158               continue ;
3159             }
3160             holes_filled++ ;
3161             for (i = r = 0 ; r < gca->ninputs ; r++)
3162             {
3163               gc->means[r] = gc_nbr->means[r] ;
3164               for (c = r ; c < gca->ninputs ; c++, i++)
3165                 gc->covars[i] = gc_nbr->covars[i] ;
3166             }
3167             if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
3168                 (Ggca_label == gcan->labels[n] || Ggca_label < 0))
3169               printf("filling hole @ (%d, %d, %d)\n", x, y, z) ;
3170           }
3171         }
3172       }
3173     }
3174   }
3175 #endif
3176 
3177   GCAfixSingularCovarianceMatrices(gca) ;
3178   /* shouldn't need the code that follows, but haven't made sure yet */
3179 
3180   /* find and fix singular covariance matrices */
3181   for (x = 0 ; x < gca->node_width ; x++)
3182   {
3183     for (y = 0 ; y < gca->node_height ; y++)
3184     {
3185       for (z = 0 ; z < gca->node_depth ; z++)
3186       {
3187         gcan = &gca->nodes[x][y][z] ;
3188         for (n = 0 ; n < gcan->nlabels ; n++)
3189         {
3190           MATRIX *m_cov, *m_cov_inv ;
3191           double det ;
3192 
3193           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
3194               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
3195             DiagBreak() ;
3196           gc = &gcan->gcs[n] ;
3197           m_cov = load_covariance_matrix(gc, NULL, gca->ninputs) ;
3198           m_cov_inv = MatrixInverse(m_cov, NULL) ;
3199           det = covariance_determinant(gc, gca->ninputs) ;
3200           if (det <= 0 )
3201           {
3202             MatrixFree(&m_cov_inv) ;
3203             m_cov_inv = NULL ;
3204           }
3205           if (m_cov_inv == NULL)  /* singular */
3206           {
3207             MATRIX *m_I ;
3208             m_I = MatrixIdentity(gca->ninputs, NULL) ;
3209             MatrixScalarMul(m_I, MIN_VAR, m_I) ;
3210             MatrixAdd(m_cov, m_I, m_cov) ;
3211             m_cov_inv = MatrixInverse(m_cov, NULL) ;
3212             if (m_cov_inv == NULL)
3213               ErrorExit(ERROR_BADPARM,
3214                         "GCAcompleteCovarianceTraining: cannot "
3215                         "regularize singular covariance matrix at "
3216                         "(%d,%d,%d):%d",
3217                         x, y, z, n) ;
3218             det = covariance_determinant(gc, gca->ninputs) ;
3219             if (det < 0)
3220               DiagBreak() ;
3221             for (v = r = 0 ; r < gca->ninputs ; r++)
3222               for (c = r ; c < gca->ninputs ; c++, v++)
3223                 gc->covars[v] = *MATRIX_RELT(m_cov, r+1, c+1) ;
3224             MatrixFree(&m_I) ;
3225             nregs++ ;
3226           }
3227 
3228           MatrixFree(&m_cov_inv) ;
3229           MatrixFree(&m_cov) ;
3230         }
3231       }
3232     }
3233   }
3234   gcaCheck(gca) ;
3235 
3236   if (total_pruned > 0)
3237   {
3238     printf("%d samples pruned during training\n", total_pruned) ;
3239     total_pruned = 0 ;
3240   }
3241   return(NO_ERROR) ;
3242 }
3243 
3244 MRI  *
3245 GCAlabel(MRI *mri_inputs, GCA *gca, MRI *mri_dst, TRANSFORM *transform)
3246 {
3247   int       x, y, z, width, height, depth, label, xn, yn, zn, n, num_pv,
3248   use_partial_volume_stuff ;
3249   GCA_NODE  *gcan ;
3250   GCA_PRIOR *gcap ;
3251   GC1D      *gc ;
3252   float    /*dist,*/ max_p, p, vals[MAX_GCA_INPUTS] ;
3253 #if INTERP_PRIOR
3254   float     prior ;
3255 #endif
3256 
3257   use_partial_volume_stuff = (getenv("USE_PARTIAL_VOLUME_STUFF") != NULL);
3258   if (use_partial_volume_stuff)
3259     printf("using partial volume calculations in labeling...\n") ;
3260 
3261   // labeled volume has the same property of the inputs
3262   if (!mri_dst)
3263   {
3264     mri_dst = MRIalloc(mri_inputs->width,
3265                        mri_inputs->height,
3266                        mri_inputs->depth,
3267                        MRI_UCHAR) ;
3268     if (!mri_dst)
3269       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
3270     MRIcopyHeader(mri_inputs, mri_dst) ;
3271   }
3272 
3273 
3274   /* go through each voxel in the input volume and find the canonical
3275      voxel (and hence the classifier) to which it maps. Then update the
3276      classifiers statistics based on this voxel's intensity and label.
3277   */
3278   width = mri_inputs->width ;
3279   height = mri_inputs->height;
3280   depth = mri_inputs->depth ;
3281   for (x = 0 ; x < width ; x++)
3282   {
3283     for (y = 0 ; y < height ; y++)
3284     {
3285       for (z = 0 ; z < depth ; z++)
3286       {
3287         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3288           DiagBreak() ;
3289 
3290         if (x == width/2 && y == height/2 && z == depth/2)
3291           DiagBreak() ;
3292 
3293         if (!GCAsourceVoxelToNode(gca, mri_inputs,
3294                                   transform, x, y, z, &xn, &yn, &zn))
3295         {
3296           load_vals(mri_inputs, x, y, z, vals, gca->ninputs);
3297 
3298 #if 0
3299           if (x == 153 && y == 119 && z == 117)
3300             /* wm should be hippo (1484) */
3301           {
3302             Gx = xn ;
3303             Gy = yn ;
3304             Gz = zn ;
3305             DiagBreak() ;
3306           }
3307 #endif
3308 
3309           gcan = &gca->nodes[xn][yn][zn] ;
3310           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
3311           if (gcap==NULL)
3312             continue;
3313           label = 0 ;
3314           max_p = 2*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE ;
3315           // going through gcap labels
3316           for (n = 0 ; n < gcap->nlabels ; n++)
3317           {
3318 #if 0
3319             p = GCAcomputePosteriorDensity(gcap, gcan, n, vals,
3320                                            gca->ninputs) ;
3321 #else
3322             gc = GCAfindGC(gca, xn, yn, zn, gcap->labels[n]) ;
3323             if (gc == NULL)
3324             {
3325               MRIsetVoxVal(mri_dst, x, y, z,0,0); // unknown
3326               continue ;
3327             }
3328 #if INTERP_PRIOR
3329             prior = gcaComputePrior(gca,
3330                                     mri_inputs,
3331                                     transform,
3332                                     x, y, z,
3333                                     gcap->labels[n]) ;
3334             p = gcaComputeLogDensity(gc, vals,
3335                                      gca->ninputs,
3336                                      prior,
3337                                      gcap->labels[n]) ;
3338 #else
3339             p = gcaComputeLogDensity(gc, vals,
3340                                      gca->ninputs,
3341                                      gcap->priors[n],
3342                                      gcap->labels[n]) ;
3343 #endif
3344 #endif
3345             // look for largest p
3346             if (p > max_p)
3347             {
3348               max_p = p ;
3349               label = gcap->labels[n] ;
3350             }
3351           }
3352           if (use_partial_volume_stuff)
3353             //////////// start of partial volume stuff
3354           {
3355             int n1, l1, l2, max_l1, max_l2, max_n1, max_n2 ;
3356             double max_p_pv ;
3357 
3358             max_p_pv = -10000  ;
3359             if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3360               DiagBreak() ;
3361             max_l1 = label ;
3362             max_l2 = max_n1 = max_n2 = 0 ;
3363             for (n = 0 ; n < gcap->nlabels ; n++)
3364               for (n1 = n+1 ; n1 < gcap->nlabels ; n1++)
3365               {
3366                 l1 = gcap->labels[n] ;
3367                 l2 = gcap->labels[n1] ;
3368                 p = compute_partial_volume_log_posterior
3369                     (gca, gcan, gcap, vals, l1, l2) ;
3370                 if (p > max_p_pv)
3371                 {
3372                   max_l1 = l1 ;
3373                   max_l2 = l2 ;
3374                   max_p_pv = p ;
3375                   max_n1 = n ;
3376                   max_n2 = n1 ;
3377                 }
3378                 if (p > max_p && l1 != label && l2 != label)
3379                   DiagBreak() ;
3380               }
3381 
3382             /* not the label picked before - change it */
3383             if (max_p_pv > max_p &&
3384                 max_l1 != label &&
3385                 max_l2 != label)
3386             {
3387               double p1, p2 ;
3388 
3389               gc = GCAfindGC(gca, xn, yn, zn, max_l1) ;
3390               p1 =
3391                 gcaComputeLogDensity(gc, vals, gca->ninputs,
3392                                      gcap->priors[max_n1],max_l1) ;
3393               gc = GCAfindGC(gca, xn, yn, zn, max_l2) ;
3394               p2 =
3395                 gcaComputeLogDensity(gc, vals, gca->ninputs,
3396                                      gcap->priors[max_n2],max_l2) ;
3397               num_pv++ ;
3398               if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3399                 printf("label @ %d, %d, %d: partial volume "
3400                        "from %s to %s\n",
3401                        x, y, z, cma_label_to_name(label),
3402                        cma_label_to_name
3403                        (p1 > p2 ? max_l1 : max_l2)) ;
3404               label = p1 > p2 ? max_l1 : max_l2 ;
3405               DiagBreak() ;
3406             }
3407           }
3408           //////////// end of partial volume stuff
3409 
3410           // found the label
3411           ///////////////////////// debug code /////////////////////
3412           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
3413           {
3414             int i ;
3415             printf("(%d, %d, %d): inputs=", x, y, z) ;
3416             for (i = 0 ; i < gca->ninputs ; i++)
3417               printf("%2.1f ", vals[i]) ;
3418 
3419             printf("\nprior label %s (%d), log(p)=%2.2e, "
3420                    "node (%d, %d, %d)\n",
3421                    cma_label_to_name(label), label, max_p,
3422                    xn, yn, zn) ;
3423             dump_gcan(gca, gcan, stdout, 1, gcap) ;
3424           }
3425           /////////////////////////////////////////////
3426           // set the value
3427           MRIsetVoxVal(mri_dst, x, y, z, 0, label) ;
3428         }
3429         else
3430           MRIsetVoxVal(mri_dst, x, y, z, 0, 0) ; // unknown
3431       } // z loop
3432     } // y loop
3433   } // x loop
3434 
3435   return(mri_dst) ;
3436 }
3437 
3438 MRI  *
3439 GCAlabelProbabilities(MRI *mri_inputs,
3440                       GCA *gca,
3441                       MRI *mri_dst,
3442                       TRANSFORM *transform)
3443 {
3444   int       x, y, z, width, height, depth, label,
3445   xn, yn, zn, n ;
3446   GCA_NODE  *gcan ;
3447   GCA_PRIOR *gcap ;
3448   GC1D      *gc ;
3449   double    max_p, p, total_p ;
3450   float     vals[MAX_GCA_INPUTS] ;
3451 
3452   width = mri_inputs->width ;
3453   height = mri_inputs->height;
3454   depth = mri_inputs->depth ;
3455   if (!mri_dst)
3456   {
3457     mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
3458     if (!mri_dst)
3459       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
3460     MRIcopyHeader(mri_inputs, mri_dst) ;
3461   }
3462 
3463   /* go through each voxel in the input volume and find the canonical
3464      voxel (and hence the classifier) to which it maps. Then update the
3465      classifiers statistics based on this voxel's intensity and label.
3466   */
3467   for (x = 0 ; x < width ; x++)
3468   {
3469     for (y = 0 ; y < height ; y++)
3470     {
3471       for (z = 0 ; z < depth ; z++)
3472       {
3473         /// debug code /////////////////////////
3474         if (x == 152 && y == 126 && z == 127)
3475           DiagBreak() ;
3476         if (x == 63 && y == 107 && z == 120)
3477           DiagBreak() ;
3478         ///////////////////////////////////////
3479 
3480         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
3481         if (!GCAsourceVoxelToNode(gca, mri_inputs,
3482                                   transform, x, y, z, &xn, &yn, &zn))
3483         {
3484           gcan = &gca->nodes[xn][yn][zn] ;
3485           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
3486           if (gcap == NULL || gcap->nlabels <= 0)
3487             continue;
3488           label = 0 ;
3489           max_p = 2*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE ;
3490           // go through labels and find the one with max probability
3491           for (total_p = 0.0, n = 0 ; n < gcan->nlabels ; n++)
3492           {
3493             gc = &gcan->gcs[n] ;
3494 
3495             /* compute 1-d Mahalanobis distance */
3496             p = GCAcomputePosteriorDensity(gcap, gcan, n, vals,
3497                                            gca->ninputs) ;
3498             if (p > max_p)
3499             {
3500               max_p = p ;
3501               label = gcan->labels[n] ;
3502             }
3503             total_p += p ;
3504           }
3505           max_p = 255.0* max_p / total_p ;
3506           if (max_p > 255) max_p = 255 ;
3507           MRIsetVoxVal(mri_dst, x, y, z, 0, (BUFTYPE)max_p) ;
3508         }
3509         else
3510           MRIsetVoxVal(mri_dst, x, y, z, 0,255); // 0;
3511       }
3512     }
3513   }
3514 
3515   return(mri_dst) ;
3516 }
3517 
3518 MRI  *
3519 GCAcomputeProbabilities(MRI *mri_inputs, GCA *gca, MRI *mri_labels,
3520                         MRI *mri_dst, TRANSFORM *transform)
3521 {
3522   int       x, y, z, width, height, depth, label,
3523   xn, yn, zn, n ;
3524   GCA_NODE  *gcan ;
3525   GCA_PRIOR *gcap ;
3526   GC1D      *gc ;
3527   double    label_p, p, total_p ;
3528   float     vals[MAX_GCA_INPUTS] ;
3529 
3530   width = mri_inputs->width ;
3531   height = mri_inputs->height;
3532   depth = mri_inputs->depth ;
3533   if (!mri_dst)
3534   {
3535     mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
3536     if (!mri_dst)
3537       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
3538     MRIcopyHeader(mri_inputs, mri_dst) ;
3539   }
3540 
3541 
3542   /* go through each voxel in the input volume and find the canonical
3543      voxel (and hence the classifier) to which it maps. Then update the
3544      classifiers statistics based on this voxel's intensity and label.
3545   */
3546   for (x = 0 ; x < width ; x++)
3547   {
3548     for (y = 0 ; y < height ; y++)
3549     {
3550       for (z = 0 ; z < depth ; z++)
3551       {
3552 #if 0
3553         if (x == 152 && y == 126 && z == 127)
3554           DiagBreak() ;
3555         if (x == 63 && y == 107 && z == 120)
3556           DiagBreak() ;
3557 #endif
3558         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
3559         if (!GCAsourceVoxelToNode(gca, mri_inputs,
3560                                   transform, x, y, z, &xn, &yn, &zn))
3561         {
3562           label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
3563 
3564           gcan = &gca->nodes[xn][yn][zn] ;
3565           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
3566           if (gcap==NULL)
3567             continue;
3568           for (label_p = total_p = 0.0, n = 0 ;
3569                n < gcan->nlabels ;
3570                n++)
3571           {
3572             gc = &gcan->gcs[n] ;
3573 
3574             p = GCAcomputePosteriorDensity(gcap, gcan, n, vals,
3575                                            gca->ninputs) ;
3576             if (label == gcan->labels[n])
3577             {
3578               label_p = p ;
3579             }
3580             total_p += p ;
3581           }
3582           label_p = 255.0* label_p / total_p ;
3583           if (label_p > 255) label_p = 255 ;
3584           MRIsetVoxVal(mri_dst, x, y, z,0,(BUFTYPE)label_p) ;
3585         }
3586       }
3587     }
3588   }
3589 
3590   return(mri_dst) ;
3591 }
3592 
3593 #define STARTING_T   500
3594 
3595 MRI  *
3596 GCAannealUnlikelyVoxels(MRI *mri_inputs,
3597                         GCA *gca,
3598                         MRI *mri_dst,
3599                         TRANSFORM *transform,
3600                         int max_iter,
3601                         MRI  *mri_fixed)
3602 {
3603   int       x, y, z, width, depth, height, *x_indices, *y_indices, *z_indices,
3604   nindices, index, iter, nchanged, xn, yn, zn, n, nbad,
3605   old_label  ;
3606   double    log_likelihood, T, delta_E, p, rn, new_ll, old_ll,
3607   total_likelihood ;
3608   GCA_NODE  *gcan ;
3609   MRI       *mri_bad ;
3610 
3611   width = mri_inputs->width ;
3612   height = mri_inputs->height ;
3613   depth = mri_inputs->depth ;
3614   mri_bad = MRIalloc(width, height, depth, MRI_UCHAR) ;
3615   MRIcopyHeader(mri_inputs, mri_bad);
3616 
3617   for (nindices = x = 0 ; x < width ; x++)
3618   {
3619     for (y = 0 ; y < height ; y++)
3620     {
3621       for (z = 0 ; z < depth ; z++)
3622       {
3623         if (mri_fixed && MRIvox(mri_fixed, x, y, z) > 0)
3624           continue ;
3625 
3626         if (!GCAsourceVoxelToNode(gca, mri_inputs,
3627                                   transform, x, y, z, &xn, &yn, &zn))
3628         {
3629           log_likelihood =
3630             gcaVoxelGibbsLogLikelihood(gca, mri_dst,
3631                                        mri_inputs, x, y, z,transform,
3632                                        PRIOR_FACTOR);
3633           gcan = &gca->nodes[xn][yn][zn] ;
3634           if (log_likelihood < log(1.0f/(float)gcan->total_training))
3635           {
3636             MRIvox(mri_bad, x, y, z) = 1 ;
3637             nindices++ ;
3638           }
3639         }
3640       }
3641     }
3642   }
3643 
3644   printf("annealing %d voxels...\n", nindices) ;
3645   x_indices = (int *)calloc(nindices, sizeof(int)) ;
3646   y_indices = (int *)calloc(nindices, sizeof(int)) ;
3647   z_indices = (int *)calloc(nindices, sizeof(int)) ;
3648   for (index = x = 0 ; x < width ; x++)
3649   {
3650     for (y = 0 ; y < height ; y++)
3651     {
3652       for (z = 0 ; z < depth ; z++)
3653       {
3654         if (MRIvox(mri_bad, x, y, z) > 0)
3655         {
3656           x_indices[index] = x ;
3657           y_indices[index] = y ;
3658           z_indices[index] = z ;
3659           index++ ;
3660         }
3661       }
3662     }
3663   }
3664 
3665   MRIfree(&mri_bad) ;
3666   T = STARTING_T ;
3667   iter = 0 ;
3668   do
3669   {
3670     total_likelihood = 0.0 ;
3671     for (nbad = nchanged = index = 0 ; index < nindices ; index++)
3672     {
3673       x = x_indices[index] ;
3674       y = y_indices[index] ;
3675       z = z_indices[index] ;
3676       if (x == 155 && y == 126 && z == 128)
3677         DiagBreak() ;
3678 
3679       /* find the node associated with this coordinate and classify */
3680       if (!GCAsourceVoxelToNode(gca, mri_inputs, transform, x, y, z,
3681                                 &xn, &yn, &zn))
3682       {
3683         gcan = &gca->nodes[xn][yn][zn] ;
3684 
3685         if (gcan->nlabels == 1)
3686           continue ;
3687         n = (int)randomNumber(0.0, (double)gcan->nlabels-0.0001) ;
3688         if (gcan->labels[n] == nint(MRIgetVoxVal(mri_dst, x, y, z,0)))
3689           continue ;
3690         old_ll =
3691           gcaNbhdGibbsLogLikelihood(gca, mri_dst, mri_inputs,
3692                                     x, y, z, transform,
3693                                     PRIOR_FACTOR) ;
3694         old_label = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
3695         MRIsetVoxVal(mri_dst, x, y, z, 0, gcan->labels[n]) ;
3696         new_ll =
3697           gcaNbhdGibbsLogLikelihood(gca, mri_dst, mri_inputs,
3698                                     x, y, z, transform,
3699                                     PRIOR_FACTOR) ;
3700         delta_E = new_ll - old_ll ;
3701         p = exp(delta_E / T) ;
3702         rn = randomNumber(0.0, 1.0) ;
3703 
3704         if (p > rn)
3705         {
3706           if (new_ll < log(1.0f/(float)gcan->total_training))
3707             nbad++ ;
3708           nchanged++ ;
3709           total_likelihood += new_ll ;
3710         }
3711         else
3712         {
3713           total_likelihood += old_ll ;
3714           if (old_ll < log(1.0f/(float)gcan->total_training))
3715             nbad++ ;
3716           MRIsetVoxVal(mri_dst, x, y, z,0,old_label) ;
3717         }
3718       }
3719     }
3720     T = T * 0.99 ;
3721     fprintf(stdout, "%03d: T = %2.2f, nchanged %d, nbad = %d, ll=%2.2f\n",
3722             iter, T, nchanged, nbad, total_likelihood/(double)nindices) ;
3723     if (!nchanged)
3724       break ;
3725   }
3726   while (iter++ < max_iter) ;
3727 
3728   free(x_indices) ;
3729   free(y_indices) ;
3730   free(z_indices) ;
3731   fflush(stdout) ;
3732   return(mri_dst) ;
3733 }
3734 
3735 GCA  *
3736 GCAreduce(GCA *gca_src)
3737 {
3738 #if 0
3739   GCA       *gca_dst ;
3740   int       xs, ys, zs, xd, yd, zd, swidth, sheight, sdepth,
3741   ns, nd, dwidth, dheight, ddepth, dof ;
3742   float     spacing = gca_src->spacing ;
3743   GCA_NODE  *gcan_src, *gcan_dst ;
3744   GC1D      *gc_src, *gc_dst ;
3745 
3746   swidth = gca_src->width ;
3747   sheight = gca_src->height;
3748   sdepth = gca_src->depth;
3749 
3750   gca_dst =
3751     GCAalloc(gca_src->ninputs, spacing*2, spacing*swidth,
3752              spacing*gca_src->height,spacing*sdepth, gca_src->flags) ;
3753 
3754 
3755   dwidth = gca_dst->width ;
3756   dheight = gca_dst->height;
3757   ddepth = gca_dst->depth;
3758 
3759   for (zs = 0 ; zs < sdepth ; zs++)
3760   {
3761     for (ys = 0 ; ys < sheight ; ys++)
3762     {
3763       for (xs = 0 ; xs < swidth ; xs++)
3764       {
3765         xd = xs/2 ;
3766         yd = ys/2 ;
3767         zd = zs/2 ;
3768         if (xd == 15 && yd == 22 && zd == 35)
3769           DiagBreak() ;
3770         gcan_src = &gca_src->nodes[xs][ys][zs] ;
3771         gcan_dst = &gca_dst->nodes[xd][yd][zd] ;
3772 
3773         for (ns = 0 ; ns < gcan_src->nlabels ; ns++)
3774         {
3775           gc_src = &gcan_src->gcs[ns] ;
3776           dof = gc_src->prior * gcan_src->total_training ;
3777 
3778           /* find label in destination */
3779           for (nd = 0 ; nd < gcan_dst->nlabels ; nd++)
3780           {
3781             if (gcan_dst->labels[nd] == gcan_src->labels[ns])
3782               break ;
3783           }
3784           if (nd >= gcan_dst->nlabels)  /* couldn't find it */
3785           {
3786             if (nd >= gcan_dst->max_labels)
3787             {
3788               int  old_max_labels ;
3789               char *old_labels ;
3790               GC1D *old_gcs ;
3791 
3792               old_max_labels = gcan_dst->max_labels ;
3793               gcan_dst->max_labels += 2 ;
3794               old_labels = gcan_dst->labels ;
3795               old_gcs = gcan_dst->gcs ;
3796 
3797               /* allocate new ones */
3798 #if 0
3799               gcan_dst->gcs =
3800                 (GC1D *)calloc(gcan_dst->max_labels,
3801                                sizeof(GC1D)) ;
3802 #else
3803               gcan_dst->gcs =
3804                 alloc_gcs(gcan_dst->max_labels,
3805                           gca_dst->flags, gca_dst->ninputs) ;
3806 #endif
3807               if (!gcan_dst->gcs)
3808                 ErrorExit(ERROR_NOMEMORY,
3809                           "GCANreduce: couldn't expand gcs to %d",
3810                           gcan_dst->max_labels) ;
3811               gcan_dst->labels =
3812                 (unsigned short *)calloc(gcan_dst->max_labels,
3813                                         sizeof(unsigned short)) ;
3814               if (!gcan_dst->labels)
3815                 ErrorExit(ERROR_NOMEMORY,
3816                           "GCANupdateNode: couldn't expand "
3817                           "labels to %d",
3818                           gcan_dst->max_labels) ;
3819 
3820               /* copy the old ones over */
3821 #if 0
3822               memmove(gcan_dst->gcs, old_gcs,
3823                       old_max_labels*sizeof(GC1D));
3824 #else
3825               copy_gcs(old_max_labels, old_gcs,
3826                        gcan_dst->gcs, gca->ninputs) ;
3827 #endif
3828 
3829               memmove(gcan_dst->labels, old_labels,
3830                       old_max_labels*sizeof(unsigned short)) ;
3831 
3832               /* free the old ones */
3833               free(old_gcs) ;
3834               free(old_labels) ;
3835             }
3836             gcan_dst->nlabels++ ;
3837           }
3838           gc_dst = &gcan_dst->gcs[nd] ;
3839           gc_dst->mean += dof*gc_src->mean ;
3840           gc_dst->var += dof*(gc_src->var) ;
3841           gc_dst->prior += dof ;
3842           gcan_dst->total_training += dof ;
3843           gcan_dst->labels[nd] = gcan_src->labels[ns] ;
3844         }
3845       }
3846     }
3847   }
3848 
3849   for (xd = 0 ; xd < gca_dst->width ; xd++)
3850   {
3851     for (yd = 0 ; yd < gca_dst->height ; yd++)
3852     {
3853       for (zd = 0 ; zd < gca_dst->depth ; zd++)
3854       {
3855         gcan_dst = &gca_dst->nodes[xd][yd][zd] ;
3856         for (nd = 0 ; nd < gcan_dst->nlabels ; nd++)
3857         {
3858           float var ;
3859 
3860           gc_dst = &gcan_dst->gcs[nd] ;
3861           dof = gc_dst->prior ;
3862           /* prior is count of # of occurences now */
3863           gc_dst->mean /= dof ;
3864           var = gc_dst->var / dof ;
3865           if (var < -0.1)
3866             DiagBreak() ;
3867           if (var < MIN_VAR)
3868             var = MIN_VAR ;
3869           gc_dst->var = var ;
3870           gc_dst->prior /= (float)gcan_dst->total_training ;
3871         }
3872       }
3873     }
3874   }
3875   return(gca_dst) ;
3876 #else
3877   /* have to update to include priors at different resolution than nodes */
3878   ErrorReturn(NULL, (ERROR_UNSUPPORTED,
3879                      "GCAreduce: not currently supported") ;) ;
3880 #endif
3881 }
3882 
3883 
3884 typedef struct
3885 {
3886   int   label ;
3887   float prob ;
3888   int   index ;
3889 }
3890 LABEL_PROB ;
3891 
3892 static int compare_sort_probabilities(const void *plp1, const void *plp2);
3893 MRI *
3894 GCAclassify(MRI *mri_inputs,GCA *gca,MRI *mri_dst,
3895             TRANSFORM *transform,int max_labels)
3896 {
3897   int        x, y, z, width, height, depth,
3898   xn, yn, zn, n ;
3899   GCA_NODE   *gcan ;
3900   GCA_PRIOR  *gcap ;
3901   GC1D       *gc ;
3902   float      max_p, p, total_p ;
3903   LABEL_PROB label_probs[1000] ;
3904   float      vals[MAX_GCA_INPUTS] ;
3905 
3906   if (max_labels > MAX_LABELS_PER_GCAN || max_labels <= 0)
3907     max_labels = MAX_LABELS_PER_GCAN ;
3908 
3909   if (!mri_dst)
3910   {
3911     int width = mri_inputs->width, height = mri_inputs->height,
3912                                             depth = mri_inputs->depth ;
3913 
3914     mri_dst = MRIallocSequence(width, height, depth,
3915                                MRI_UCHAR, 2*max_labels) ;
3916     if (!mri_dst)
3917       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
3918     MRIcopyHeader(mri_inputs, mri_dst) ;
3919   }
3920 
3921   /* go through each voxel in the input volume and find the canonical
3922      voxel (and hence the classifier) to which it maps. Then update the
3923      classifiers statistics based on this voxel's intensity and label.
3924   */
3925   width = mri_inputs->width ;
3926   height = mri_inputs->height;
3927   depth = mri_inputs->depth ;
3928   for (x = 0 ; x < width ; x++)
3929   {
3930     for (y = 0 ; y < height ; y++)
3931     {
3932       for (z = 0 ; z < depth ; z++)
3933       {
3934         if (x == 67 && y == 87 && z == 114)
3935           DiagBreak() ;
3936 
3937         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
3938 
3939         /* find the node associated with this coordinate and classify */
3940         if (!GCAsourceVoxelToNode(gca, mri_inputs,
3941                                   transform, x, y, z, &xn, &yn, &zn))
3942         {
3943           gcan = &gca->nodes[xn][yn][zn] ;
3944           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
3945           if (gcap==NULL)
3946             continue;
3947           max_p = 2*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE ;
3948           for (total_p = 0.0, n = 0 ; n < gcan->nlabels ; n++)
3949           {
3950             gc = &gcan->gcs[n] ;
3951 
3952             p = GCAcomputePosteriorDensity(gcap, gcan, n, vals,
3953                                            gca->ninputs) ;
3954             total_p += p ;
3955             label_probs[n].prob = p ;
3956             label_probs[n].label = gcan->labels[n] ;
3957           }
3958           /* now sort the labels and probabilities */
3959           qsort(label_probs, gcan->nlabels, sizeof(LABEL_PROB),
3960                 compare_sort_probabilities) ;
3961 
3962           for (n = 0 ; n < max_labels ; n++)
3963           {
3964             if (n < gcan->nlabels)
3965             {
3966               MRIseq_vox(mri_dst, x, y, z, n*2) =
3967                 label_probs[n].label ;
3968               MRIseq_vox(mri_dst, x, y, z, n*2+1) =
3969                 (BUFTYPE)nint(255.0*label_probs[n].prob/total_p) ;
3970             }
3971             else
3972             {
3973               MRIseq_vox(mri_dst, x, y, z, n*2) = 255 ;
3974               MRIseq_vox(mri_dst, x, y, z, n*2+1) = 0 ;
3975             }
3976           }
3977         }
3978       }
3979     }
3980   }
3981 
3982   return(mri_dst) ;
3983 }
3984 
3985 
3986 static int
3987 compare_sort_probabilities(const void *plp1, const void *plp2)
3988 {
3989   LABEL_PROB  *lp1, *lp2 ;
3990 
3991   lp1 = (LABEL_PROB *)plp1 ;
3992   lp2 = (LABEL_PROB *)plp2 ;
3993 
3994   if (lp1->prob > lp2->prob)
3995     return(1) ;
3996   else if (lp1->prob < lp2->prob)
3997     return(-1) ;
3998 
3999   return(0) ;
4000 }
4001 
4002 int
4003 GCAremoveOutlyingSamples(GCA *gca, GCA_SAMPLE *gcas, MRI *mri_inputs,
4004                          TRANSFORM *transform,int nsamples, float nsigma)
4005 {
4006   int        x, y, z, width, height, depth,
4007   i, nremoved, xp, yp, zp ;
4008   double     dist ;
4009   float      vals[MAX_GCA_INPUTS] ;
4010   /*  GC1D       *gc ;*/
4011 
4012 
4013   /* go through each GC in the sample and compute the probability of
4014      the image at that point.
4015   */
4016   width = mri_inputs->width ;
4017   height = mri_inputs->height;
4018   depth = mri_inputs->depth ;
4019   TransformInvert(transform, mri_inputs) ;
4020   for (nremoved = i = 0 ; i < nsamples ; i++)
4021   {
4022     if (i == Gdiag_no)
4023       DiagBreak() ;
4024     if (Gdiag_no == gcas[i].label)
4025       DiagBreak() ;
4026     if (gcas[i].label <= 0)
4027       continue ;
4028 
4029     xp = gcas[i].xp ;
4030     yp = gcas[i].yp ;
4031     zp = gcas[i].zp ;
4032     if (!GCApriorToSourceVoxel(gca, mri_inputs, transform,
4033                                xp, yp, zp, &x, &y, &z))
4034     {
4035       load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
4036 
4037       if (xp == Gxp && yp == Gyp && zp == Gzp)
4038         DiagBreak() ;
4039 
4040 #if 0
4041       gc = GCAfindPriorGC(gca, xp, yp, zp, gcas[i].label) ;
4042       if (gc == NULL)
4043       {
4044         ErrorPrintf(ERROR_BADPARM,
4045                     "gc %d not found in GCAremoveOutlyingSamples!", i) ;
4046         continue ;
4047       }
4048 #endif
4049 
4050       dist = sqrt(GCAsampleMahDist(&gcas[i], vals, gca->ninputs)) ;
4051       if (dist >= nsigma)
4052       {
4053         nremoved++ ;
4054         gcas[i].log_p = BIG_AND_NEGATIVE ;
4055         gcas[i].label = 0 ;
4056       }
4057     }
4058   }
4059 
4060   if (DIAG_VERBOSE_ON)
4061     printf("%d outlying samples removed...\n", nremoved) ;
4062 
4063   return(NO_ERROR) ;
4064 }
4065 float
4066 GCAnormalizedLogSampleProbability(GCA *gca, GCA_SAMPLE *gcas,
4067                                   MRI *mri_inputs,
4068                                   TRANSFORM *transform, int nsamples)
4069 {
4070   int        x, y, z, width, height, depth,
4071   xn, yn, zn, i, n, xp, yp, zp ;
4072   GCA_NODE   *gcan ;
4073   GCA_PRIOR  *gcap ;
4074   GC1D       *gc ;
4075   double     total_log_p, log_p, norm_log_p ;
4076   float      vals[MAX_GCA_INPUTS] ;
4077 
4078 
4079   /* go through each GC in the sample and compute the probability of
4080      the image at that point.
4081   */
4082   width = mri_inputs->width ;
4083   height = mri_inputs->height;
4084   depth = mri_inputs->depth ;
4085   TransformInvert(transform, mri_inputs) ;
4086   for (total_log_p = 0.0, i = 0 ; i < nsamples ; i++)
4087   {
4088     if (i == Gdiag_no)
4089       DiagBreak() ;
4090     if (Gdiag_no == gcas[i].label)
4091       DiagBreak() ;
4092 
4093     xp = gcas[i].xp ;
4094     yp = gcas[i].yp ;
4095     zp = gcas[i].zp ;
4096     // do the processing for valid points only
4097     if (!GCApriorToSourceVoxel(gca, mri_inputs,
4098                                transform, xp, yp, zp, &x, &y, &z))
4099       if (!GCApriorToNode(gca, xp, yp, zp, &xn, &yn, &zn))
4100       {
4101         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
4102         // use node and prior values
4103         gcan = &gca->nodes[xn][yn][zn] ;
4104         gcap = &gca->priors[xp][yp][zp] ;
4105         if (gcap==NULL)
4106           continue;
4107         if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
4108           DiagBreak() ;
4109 
4110         for (norm_log_p = 0.0f, n = 0 ; n < gcan->nlabels ; n++)
4111         {
4112           gc = &gcan->gcs[n] ;
4113           norm_log_p +=
4114             GCAcomputeConditionalDensity(gc, vals, gca->ninputs,
4115                                          gcan->labels[n]) ;
4116         }
4117         norm_log_p = log(norm_log_p) ;
4118         gc = GCAfindPriorGC(gca, xp, yp, zp, gcas[i].label) ;
4119         log_p = GCAcomputeConditionalDensity(gc, vals, gca->ninputs,
4120                                              gcas[i].label) ;
4121         log_p = log(log_p) + log(gcas[i].prior) ;
4122         log_p -= norm_log_p ;
4123         total_log_p += log_p ;
4124         gcas[i].log_p = log_p ;
4125 
4126         if (!check_finite("1", total_log_p))
4127         {
4128           fprintf(stdout,
4129                   "total log p not finite at (%d, %d, %d)\n", x, y, z) ;
4130           DiagBreak();
4131         }
4132       }
4133   }
4134   fflush(stdout) ;
4135   return((float)total_log_p) ;
4136 }
4137 
4138 float
4139 GCAcomputeLogSampleProbability(GCA *gca,
4140                                GCA_SAMPLE *gcas,
4141                                MRI *mri_inputs,
4142                                TRANSFORM *transform,
4143                                int nsamples)
4144 {
4145   int        x, y, z, width, height, depth, i, xp, yp, zp ;
4146   float      vals[MAX_GCA_INPUTS] ;
4147   double     total_log_p, log_p ;
4148   int        countOutside = 0;
4149   double     outside_log_p = 0.;
4150   /* go through each GC in the sample and compute the probability of
4151      the image at that point.
4152   */
4153   width = mri_inputs->width ;
4154   height = mri_inputs->height;
4155   depth = mri_inputs->depth ;
4156   // store inverse transformation .. forward:input->gca template,
4157   // inv: gca template->input
4158   TransformInvert(transform, mri_inputs) ;
4159 
4160   // go through all sample points
4161   for (total_log_p = 0.0, i = 0 ; i < nsamples ; i++)
4162   {
4163     /////////////////// diag code /////////////////////////////
4164     if (i == Gdiag_no)
4165       DiagBreak() ;
4166     if (Gdiag_no == gcas[i].label)
4167       DiagBreak() ;
4168     if (i == Gdiag_no ||
4169         (gcas[i].xp == Gxp && gcas[i].yp == Gyp && gcas[i].zp == Gzp))
4170       DiagBreak() ;
4171     ///////////////////////////////////////////////////////////
4172 
4173     // get prior coordinates
4174     xp = gcas[i].xp ;
4175     yp = gcas[i].yp ;
4176     zp = gcas[i].zp ;
4177     // if it is inside the source voxel
4178     if (!GCApriorToSourceVoxel(gca, mri_inputs, transform,
4179                                xp, yp, zp, &x, &y, &z))
4180     {
4181       // (x,y,z) is the source voxel position
4182       gcas[i].x = x ;
4183       gcas[i].y = y ;
4184       gcas[i].z = z ;
4185       // get values from all inputs
4186       load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
4187       log_p = gcaComputeSampleLogDensity(&gcas[i], vals, gca->ninputs) ;
4188       total_log_p += log_p ;
4189       gcas[i].log_p = log_p ;
4190 
4191       if (!check_finite("2", total_log_p))
4192       {
4193         fprintf(stdout,
4194                 "total log p not finite at (%d, %d, %d)\n",
4195                 x, y, z) ;
4196         DiagBreak() ;
4197       }
4198     }
4199     else  // outside the voxel
4200     {
4201       log_p = -1000000; // BIG_AND_NEGATIVE;
4202       // log(VERY_UNLIKELY); // BIG_AND_NEGATIVE;
4203       total_log_p += log_p;
4204       gcas[i].log_p = log_p;
4205       outside_log_p += log_p;
4206       countOutside++;
4207     }
4208   }
4209 
4210 #ifndef __OPTIMIZE__
4211 #if 0
4212   if (nsamples > 3000)
4213     fprintf(stdout, "good samples %d (outside %d) log_p = %.1f "
4214             "(outside %.1f)\n",
4215             nsamples-countOutside, countOutside, total_log_p, outside_log_p);
4216 #endif
4217 #endif
4218   fflush(stdout) ;
4219 
4220   return((float)total_log_p) ;
4221 }
4222 
4223 float
4224 GCAcomputeLogSampleProbabilityUsingCoords(GCA *gca, GCA_SAMPLE *gcas,
4225     MRI *mri_inputs,
4226     TRANSFORM *transform, int nsamples)
4227 {
4228   int        x, y, z, width, height, depth, xp, yp, zp,
4229   xn, yn, zn, i ;
4230   float      vals[MAX_GCA_INPUTS] ;
4231   double     total_log_p, log_p ;
4232 
4233 
4234   /* go through each GC in the sample and compute the probability of
4235      the image at that point.
4236   */
4237   width = mri_inputs->width ;
4238   height = mri_inputs->height;
4239   depth = mri_inputs->depth ;
4240   for (total_log_p = 0.0, i = 0 ; i < nsamples ; i++)
4241   {
4242     if (i == Gdiag_no)
4243       DiagBreak() ;
4244     if (Gdiag_no == gcas[i].label)
4245       DiagBreak() ;
4246 
4247     xp = gcas[i].xp ;
4248     yp = gcas[i].yp ;
4249     zp = gcas[i].zp ;
4250     // do the processing only for valid points
4251     if (!GCApriorToNode(gca, xp, yp, zp, &xn, &yn, &zn))
4252     {
4253       x = gcas[i].x ;
4254       y = gcas[i].y ;
4255       z = gcas[i].z ;
4256       load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
4257 
4258       log_p = gcaComputeSampleLogDensity(&gcas[i], vals, gca->ninputs) ;
4259       total_log_p += log_p ;
4260       gcas[i].log_p = log_p ;
4261 
4262       if (!check_finite("3", total_log_p))
4263       {
4264         DiagBreak() ;
4265         fprintf(stdout,
4266                 "total log p not finite at (%d, %d, %d)\n", x, y, z) ;
4267       }
4268     }
4269     else
4270     {
4271       log_p = log(VERY_UNLIKELY); // BIG_AND_NEGATIVE;
4272       total_log_p += log_p;
4273       gcas[i].log_p = log_p;
4274     }
4275   }
4276   fflush(stdout) ;
4277 
4278   return((float)total_log_p) ;
4279 }
4280 /*
4281   compute the probability of the image given the transform and the class
4282   stats.
4283 */
4284 float
4285 GCAcomputeLogImageProbability(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
4286                               TRANSFORM *transform)
4287 {
4288   int        x, y, z, width, height, depth,
4289   xn, yn, zn, n, label ;
4290   GCA_NODE   *gcan ;
4291   GCA_PRIOR  *gcap ;
4292   GC1D       *gc ;
4293   double     total_log_p ;
4294   float      vals[MAX_GCA_INPUTS] ;
4295 
4296 
4297   /* go through each voxel in the input volume and find the canonical
4298      voxel (and hence the classifier) to which it maps. Then update the
4299      classifiers statistics based on this voxel's intensity and label.
4300   */
4301   width = mri_inputs->width ;
4302   height = mri_inputs->height;
4303   depth = mri_inputs->depth ;
4304   for (total_log_p = 0.0, x = 0 ; x < width ; x++)
4305   {
4306     for (y = 0 ; y < height ; y++)
4307     {
4308       for (z = 0 ; z < depth ; z++)
4309       {
4310         if (x == 85 && y == 89 && z == 135)
4311           DiagBreak() ;
4312 
4313         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
4314         label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
4315 
4316         /* find the node associated with this coordinate and classify */
4317         if (!GCAsourceVoxelToNode(gca, mri_inputs,
4318                                   transform, x, y, z, &xn, &yn, &zn))
4319         {
4320           gcan = &gca->nodes[xn][yn][zn] ;
4321           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
4322           if (gcap==NULL)
4323             continue;
4324           for (n = 0 ; n < gcan->nlabels ; n++)
4325           {
4326             if (gcan->labels[n] == label)
4327               break ;
4328           }
4329           if (n < gcan->nlabels)
4330           {
4331             gc = &gcan->gcs[n] ;
4332 
4333             total_log_p +=
4334               gcaComputeLogDensity(gc, vals,
4335                                    gca->ninputs,
4336                                    getPrior(gcap, label),
4337                                    label) ;
4338 #if 0
4339             -log(sqrt(gc->var)) -
4340             0.5 * (dist*dist/gc->var) +
4341             log(getPrior(gcap, label)) ;
4342 #endif
4343             if (!check_finite("4", total_log_p))
4344             {
4345               DiagBreak() ;
4346               fprintf(stdout,
4347                       "total log p not finite at (%d, %d, %d)"
4348                       " n = %d,\n", x, y, z, n) ;
4349             }
4350           }
4351         }
4352       }
4353     }
4354   }
4355   fflush(stdout) ;
4356 
4357   return((float)total_log_p) ;
4358 }
4359 
4360 #if 0
4361 int
4362 GCAsampleStats(GCA *gca, MRI *mri, int class,
4363                Real x, Real y, Real z,
4364                Real *pmean, Real *pvar, Real *pprior)
4365 {
4366   int    xm, xp, ym, yp, zm, zp, width, height, depth, n ;
4367   Real   val, xmd, ymd, zmd, xpd, ypd, zpd ;  /* d's are distances */
4368   Real   prior, mean, var, wt ;
4369   GCAN   *gcan ;
4370   GC1D   *gc ;
4371 
4372   width = gca->node_width ;
4373   height = gca->node_height ;
4374   depth = gca->node_depth ;
4375 
4376   xm = MAX((int)x, 0) ;
4377   xp = MIN(width-1, xm+1) ;
4378   ym = MAX((int)y, 0) ;
4379   yp = MIN(height-1, ym+1) ;
4380   zm = MAX((int)z, 0) ;
4381   zp = MIN(depth-1, zm+1) ;
4382 
4383   xmd = x - (float)xm ;
4384   ymd = y - (float)ym ;
4385   zmd = z - (float)zm ;
4386   xpd = (1.0f - xmd) ;
4387   ypd = (1.0f - ymd) ;
4388   zpd = (1.0f - zmd) ;
4389 
4390   prior = mean = var = 0.0 ;
4391 
4392 
4393   gcan = &gca->nodes[xm][ym][zm] ;
4394   wt = xpd * ypd * zpd
4395        for (n = 0 ; n < gcan->nlabels ; n++)
4396        {
4397          if (gcan->labels[n] == class)
4398            break ;
4399        }
4400        if (n < gcan->nlabels)   /* found it */
4401        {
4402          gc = &gcan->gcs[n] ;
4403          prior += wt * gc->prior ;
4404        }
4405 
4406        gcan = &gca->nodes[xp][ym][zm] ;
4407   wt = xmd * ypd * zpd
4408 
4409        gcan = &gca->nodes[xm][yp][zm] ;
4410   wt = xpd * ymd * zpd ;
4411 
4412   gcan = &gca->nodes[xp][yp][zm] ;
4413   wt = xmd * ymd * zpd ;
4414 
4415   gcan = &gca->nodes[xm][ym][zp] ;
4416   wt = xpd * ypd * zmd ;
4417 
4418   gcan = &gca->nodes[xp][ym][zp] ;
4419   wt = xmd * ypd * zmd ;
4420 
4421   gcan = &gca->nodes[xm][yp][zp] ;
4422   wt = xpd * ymd * zmd ;
4423 
4424   gcan = &gca->nodes[xp][yp][zp] ;
4425   wt = xmd * ymd * zmd ;
4426   return(NO_ERROR) ;
4427 }
4428 #endif
4429 
4430 #define MIN_SPACING   8
4431 
4432 int
4433 GCAtransformSamples(GCA *gca_src, GCA *gca_dst, GCA_SAMPLE *gcas, int nsamples)
4434 {
4435   int       scale, i, label, xd, yd, zd, xs, ys, zs, n, xk, yk, zk,
4436   xd0, yd0, zd0, min_y_i, xdn, ydn, zdn ;
4437   float     max_p, min_v, vscale, min_y, prior ;
4438   GCA_NODE  *gcan ;
4439   GCA_PRIOR *gcap ;
4440   GC1D      *gc ;
4441   MRI       *mri_found ;
4442 
4443   vscale = 1 ;
4444   mri_found = MRIalloc(gca_dst->node_width*vscale,
4445                        gca_dst->node_height*vscale,
4446                        gca_dst->node_depth*vscale,
4447                        MRI_UCHAR) ;
4448   // change the voxel size
4449   mri_found->xsize = gca_dst->node_spacing*vscale;
4450   mri_found->ysize = gca_dst->node_spacing*vscale;
4451   mri_found->zsize = gca_dst->node_spacing*vscale;
4452 
4453   // copy direction cosines
4454   GCAcopyDCToMRI(gca_dst, mri_found);
4455 
4456   scale = gca_src->prior_spacing / gca_dst->prior_spacing ;
4457   min_y = 10000 ;
4458   min_y_i = -1 ;
4459   for (i = 0 ; i < nsamples ; i++)
4460   {
4461     label = gcas[i].label ;
4462 
4463     xs = gcas[i].xp ;
4464     ys = gcas[i].yp ;
4465     zs = gcas[i].zp ;
4466     xd0 = (int)(xs * scale) ;
4467     yd0 = (int)(ys * scale) ;
4468     zd0 = (int)(zs * scale) ;
4469     max_p = -1.0 ;  /* find appropriate label with highest prior in dst */
4470     min_v =  10000000.0f ;
4471     for (xk = -scale/2 ; xk <= scale/2 ; xk++)
4472     {
4473       xd = MIN(MAX(0, xd0+xk), gca_dst->prior_width-1) ;
4474       for (yk = -scale/2 ; yk <= scale/2 ; yk++)
4475       {
4476         yd = MIN(MAX(0, yd0+yk), gca_dst->prior_height-1) ;
4477         for (zk = -scale/2 ; zk <= scale/2 ; zk++)
4478         {
4479           zd = MIN(MAX(0, zd0+zk), gca_dst->prior_height-1) ;
4480           if (MRIvox(mri_found, (int)(xd*vscale), (int)(yd*vscale),
4481                      (int)(zd*vscale)))
4482             continue ;
4483           if (!GCApriorToNode(gca_dst, xd, yd, zd, &xdn, &ydn, &zdn))
4484           {
4485             gcan = &gca_dst->nodes[xdn][ydn][zdn] ;
4486             gcap = &gca_dst->priors[xd][yd][zd] ;
4487             if (gcap == NULL || gcap->nlabels <= 0)
4488               continue;
4489             for (n = 0 ; n < gcan->nlabels ; n++)
4490             {
4491               gc = &gcan->gcs[n] ;
4492               prior = getPrior(gcap, gcan->labels[n]) ;
4493               if (gcan->labels[n] == label &&
4494                   (prior > max_p
4495                    /*|| FEQUAL(prior,max_p) && gc->var < min_v)*/))
4496               {
4497                 /*              min_v = gc->var ;*/
4498                 max_p = prior ;
4499                 gcas[i].xp = xd ;
4500                 gcas[i].yp = yd ;
4501                 gcas[i].zp = zd ;
4502               }
4503             }
4504           }
4505         }
4506       }
4507     }
4508     if (max_p < 0)
4509     {
4510       fprintf(stdout, "WARNING: label %d not found at (%d,%d,%d)\n",
4511               label, gcas[i].xp, gcas[i].yp, gcas[i].zp) ;
4512       DiagBreak() ;
4513     }
4514     MRIvox(mri_found, (int)(gcas[i].xp*vscale),
4515            (int)(gcas[i].yp*vscale), (int)(gcas[i].zp*vscale))= 1;
4516     if (gcas[i].yp < min_y)
4517     {
4518       min_y = gcas[i].yp ;
4519       min_y_i = i ;
4520     }
4521   }
4522 
4523   i = min_y_i ;
4524   fprintf(stdout, "min_y = (%d, %d, %d) at i=%d, label=%d\n",
4525           gcas[i].xp, gcas[i].yp, gcas[i].zp, i, gcas[i].label) ;
4526   MRIfree(&mri_found) ;
4527   fflush(stdout) ;
4528   return(NO_ERROR) ;
4529 }
4530 
4531 /* don't use a label with prior less than this */
4532 #define MIN_MAX_PRIORS 0.5
4533 
4534 
4535 static int exclude_classes[] =
4536   {
4537     0 /*1, 6, 21, 22, 23, 24, 25, 30, 57, 61, 62, 63*/
4538   } ;
4539 
4540 
4541 #define TILES     3
4542 #define MAX_PCT   .1
4543 
4544 static int compare_gca_samples(const void *pc1, const void *pc2) ;
4545 
4546 static int
4547 compare_gca_samples(const void *pgcas1, const void *pgcas2)
4548 {
4549   register GCA_SAMPLE *gcas1, *gcas2 ;
4550 
4551   gcas1 = (GCA_SAMPLE *)pgcas1 ;
4552   gcas2 = (GCA_SAMPLE *)pgcas2 ;
4553 
4554   /*  return(c1 > c2 ? 1 : c1 == c2 ? 0 : -1) ;*/
4555   if (FEQUAL(gcas1->prior, gcas2->prior))
4556   {
4557 #if 0
4558     if (FEQUAL(gcas1->var, gcas2->var))
4559     {
4560       int  zv1, zv2 ;
4561 
4562       zv1 = gcas1->zn%10 ;
4563       zv2 = gcas2->zn%10 ;
4564       if (zv1 == zv2)
4565       {
4566         int  yv1, yv2 ;
4567 
4568         yv1 = gcas1->yn%10 ;
4569         zv2 = gcas2->yn%10 ;
4570         return(yv1-yv2) ;
4571       }
4572 
4573       return(zv1-zv2) ;
4574     }
4575 #endif
4576 
4577 #if 0
4578     if (gcas1->var > gcas2->var)
4579       return(1) ;
4580     else
4581       return(-1) ;
4582 #else
4583     /* check size of determinants */
4584     return(1) ;
4585 #endif
4586   }
4587 
4588   if (gcas1->prior > gcas2->prior)
4589     return(-1) ;
4590   else if (gcas1->prior < gcas2->prior)
4591     return(1) ;
4592 
4593   return(0) ;
4594 }
4595 #define MAX_SPACING   16  /* mm */
4596 
4597 GCA_SAMPLE *
4598 GCAfindStableSamplesByLabel(GCA *gca, int nsamples, float min_prior)
4599 {
4600   GCA_SAMPLE *gcas, *ordered_labels[MAX_DIFFERENT_LABELS], *gcas2 ;
4601   GCA_PRIOR  *gcap ;
4602   GC1D       *gc ;
4603   int        found[MAX_DIFFERENT_LABELS], x, y, z, width, height, depth, n,
4604   label, nfound, samples_added[MAX_DIFFERENT_LABELS] ;
4605   float      histo[MAX_DIFFERENT_LABELS], spacing, scale ;
4606   int        volume[TILES][TILES], max_class, total, extra, total_found,
4607   label_counts[MAX_DIFFERENT_LABELS],
4608   current_index[MAX_DIFFERENT_LABELS],
4609   ordered_label_counts[MAX_DIFFERENT_LABELS], i, index,
4610   *x_indices, *y_indices, *z_indices, nindices ;
4611 
4612   memset(histo, 0, sizeof(histo)) ;
4613   memset(label_counts, 0, sizeof(label_counts)) ;
4614   memset(samples_added, 0, sizeof(samples_added)) ;
4615   memset(current_index, 0, sizeof(current_index)) ;
4616   memset(ordered_label_counts, 0, sizeof(ordered_label_counts)) ;
4617   memset(found, 0, sizeof(found)) ;
4618   memset(volume, 0, sizeof(volume)) ;
4619   gcas = calloc(nsamples, sizeof(GCA_SAMPLE )) ;
4620   width = gca->prior_width ;
4621   height = gca->prior_height ;
4622   depth = gca->prior_depth ;
4623 
4624   /* compute the max priors and min variances for each class */
4625   for (x = 0 ; x < width ; x++)
4626   {
4627     for (y = 0 ; y < height ; y++)
4628     {
4629       for (z = 0 ; z < depth ; z++)
4630       {
4631         gcap = &gca->priors[x][y][z] ;
4632         if (gcap==NULL)
4633           continue;
4634         for (n = 0 ; n < gcap->nlabels ; n++)
4635         {
4636           label = gcap->labels[n] ;
4637           if (label == Gdiag_no)
4638             DiagBreak() ;
4639           histo[label] +=
4640             (float)nint(gcap->total_training*gcap->priors[n]) ;
4641           label_counts[label]++ ;
4642         }
4643       }
4644     }
4645   }
4646 
4647   for (max_class = MAX_DIFFERENT_LABELS ; max_class >= 0 ; max_class--)
4648     if (histo[max_class] > 0)
4649       break ;
4650   fprintf(stdout, "max class = %d\n", max_class) ;
4651 
4652   /* count total # of samples */
4653   for (total = 0, n = 1 ; n <= max_class ; n++)
4654     total += histo[n] ;
4655 
4656   fprintf(stdout, "%d total training samples found\n", total) ;
4657   fflush(stdout) ;
4658 
4659   /* turn histogram into samples/class */
4660   for (n = 1 ; n <= max_class ; n++)
4661     histo[n] = (float)nint(0.25+histo[n]*(float)nsamples/total) ;
4662 
4663   for (n = 0 ; n < sizeof(exclude_classes)/sizeof(exclude_classes[0]) ; n++)
4664     histo[exclude_classes[n]] = 0 ;
4665 
4666   /* crop max # per class */
4667   for (n = 1 ; n <= max_class ; n++)
4668     if (histo[n] > nint(MAX_PCT*nsamples))
4669       histo[n] = nint(MAX_PCT*nsamples) ;
4670 
4671   for (extra = 0, n = 1 ; n <= max_class ; n++)
4672     extra += histo[n] ;
4673   extra = nsamples-extra ;  /* from rounding */
4674   printf("%d extra samples for redistribution...\n", extra) ;
4675 
4676   /* first add to classes with only one sample */
4677   for (n = 1 ; extra > 0 && n <= max_class ; n++)
4678   {
4679     if (histo[n] == 1)
4680     {
4681       histo[n]++ ;
4682       extra-- ;
4683     }
4684   }
4685 
4686   while (extra > 0)  /* add 1 to each class */
4687   {
4688     for (n = 1 ; extra > 0 && n <= max_class ; n++)
4689     {
4690       if (histo[n] >= 1)
4691       {
4692         histo[n]++ ;
4693         extra-- ;
4694       }
4695     }
4696   }
4697 
4698   {
4699     FILE *fp ;
4700     fp = fopen("classes.dat", "w") ;
4701     for (n = 1 ; n <= max_class ; n++)
4702       if (!FZERO(histo[n]))
4703         fprintf(fp, "%d  %2.1f\n", n, histo[n]) ;
4704     fclose(fp) ;
4705   }
4706 
4707   /* allocate arrays that will be used for sorting */
4708   for (n = 1 ; n <= max_class ; n++)
4709     if (histo[n] > 0)
4710     {
4711       ordered_labels[n] =
4712         (GCA_SAMPLE *)calloc(label_counts[n], sizeof(GCA_SAMPLE)) ;
4713       if (!ordered_labels[n])
4714         ErrorExit(ERROR_NO_MEMORY,
4715                   "GCAfindStableSamplesByLabel: "
4716                   "could not allocate %d samples "
4717                   "for label %d", label_counts[n], n) ;
4718     }
4719 
4720 
4721   nindices = width*height*depth ;
4722   x_indices = (int *)calloc(nindices, sizeof(int)) ;
4723   y_indices = (int *)calloc(nindices, sizeof(int)) ;
4724   z_indices = (int *)calloc(nindices, sizeof(int)) ;
4725 
4726   for (i = 0 ; i < nindices ; i++)
4727   {
4728     x_indices[i] = i % width ;
4729     y_indices[i] = (i/width) % height ;
4730     z_indices[i] = (i / (width*height)) % depth ;
4731   }
4732   for (i = 0 ; i < nindices ; i++)
4733   {
4734     int tmp ;
4735     index = (int)randomNumber(0.0, (double)(nindices-0.0001)) ;
4736 
4737     tmp = x_indices[index] ;
4738     x_indices[index] = x_indices[i] ;
4739     x_indices[i] = tmp ;
4740 
4741     tmp = y_indices[index] ;
4742     y_indices[index] = y_indices[i] ;
4743     y_indices[i] = tmp ;
4744 
4745     tmp = z_indices[index] ;
4746     z_indices[index] = z_indices[i] ;
4747     z_indices[i] = tmp ;
4748   }
4749 
4750   for (index = 0 ; index < nindices ; index++)
4751   {
4752     x = x_indices[index] ;
4753     y = y_indices[index] ;
4754     z = z_indices[index] ;
4755     gcap = &gca->priors[x][y][z] ;
4756     if (gcap==NULL)
4757       continue;
4758     for (n = 0 ; n < gcap->nlabels ; n++)
4759     {
4760       label = gcap->labels[n] ;
4761       gc = GCAfindPriorGC(gca, x, y, z, label) ;
4762       if (histo[label] > 0)
4763       {
4764         i = ordered_label_counts[label] ;
4765         ordered_label_counts[label]++ ;
4766         ordered_labels[label][i].means =
4767           (float *)calloc(gca->ninputs, sizeof(float)) ;
4768         ordered_labels[label][i].covars =
4769           (float *)calloc((gca->ninputs*(gca->ninputs+1))/2,
4770                           sizeof(float)) ;
4771         if (!ordered_labels[label][i].means
4772             || !ordered_labels[label][i].covars)
4773           ErrorExit(ERROR_NOMEMORY,
4774                     "could not allocate mean (%d) and "
4775                     "covariance (%d) matrices",
4776                     gca->ninputs, gca->ninputs*(gca->ninputs+1)/2) ;
4777         ordered_labels[label][i].xp = x ;
4778         ordered_labels[label][i].yp = y ;
4779         ordered_labels[label][i].zp = z ;
4780         ordered_labels[label][i].label = label ;
4781         ordered_labels[label][i].prior = getPrior(gcap, label) ;
4782         if (!gc)
4783         {
4784           int  r, c, v ;
4785           for (v = r = 0 ; r < gca->ninputs ; r++)
4786           {
4787             ordered_labels[label][i].means[r] = 0.0 ;
4788             for (c = r ; c < gca->ninputs ; c++, v++)
4789             {
4790               if (c==r)
4791                 ordered_labels[label][i].covars[v] = 1.0 ;
4792               else
4793                 ordered_labels[label][i].covars[v] = 0 ;
4794             }
4795           }
4796         }
4797         else
4798         {
4799           int  r, c, v ;
4800           for (v = r = 0 ; r < gca->ninputs ; r++)
4801           {
4802             ordered_labels[label][i].means[r] = gc->means[r] ;
4803             for (c = r ; c < gca->ninputs ; c++, v++)
4804             {
4805               ordered_labels[label][i].covars[v] = gc->covars[v] ;
4806             }
4807           }
4808         }
4809       }
4810     }
4811   }
4812 
4813   free(x_indices) ;
4814   free(y_indices) ;
4815   free(z_indices) ;
4816 
4817   /* sort each list of labels by prior, then by variance */
4818   for (n = 1 ; n <= max_class ; n++)
4819     if (histo[n] > 0)
4820     {
4821       qsort(ordered_labels[n], ordered_label_counts[n], sizeof(GCA_SAMPLE),
4822             compare_gca_samples) ;
4823     }
4824 
4825   total_found = nfound = 0 ;
4826 
4827   for (spacing = MAX_SPACING ; spacing >= gca->node_spacing ; spacing /= 2)
4828   {
4829     MRI  *mri_found ;
4830     int  xv, yv, zv ;
4831 
4832     for (n = 1 ; n <= max_class ; n++)
4833       current_index[n] = 0 ;
4834 
4835     scale = gca->prior_spacing / spacing ;
4836     mri_found = MRIalloc(width*scale, height*scale, depth*scale, MRI_UCHAR);
4837 
4838     // change the size
4839     mri_found->xsize = gca->prior_spacing*scale;
4840     mri_found->ysize = gca->prior_spacing*scale;
4841     mri_found->zsize = gca->prior_spacing*scale;
4842 
4843     GCAcopyDCToMRI(gca, mri_found);
4844 
4845     for (i = 0 ; i < total_found ; i++)
4846     {
4847       xv = gcas[i].xp*scale ;
4848       yv = gcas[i].yp*scale ;
4849       zv = gcas[i].zp*scale ;
4850       MRIvox(mri_found, xv, yv, zv) = 1 ;
4851     }
4852 
4853     do
4854     {
4855 
4856       nfound = 0 ;
4857       for (n = 1 ; n <= max_class ; n++)
4858       {
4859         if (samples_added[n] < histo[n])
4860           /* add another sample from this class*/
4861         {
4862           while ((ordered_labels[n][current_index[n]].label < 0) &&
4863                  current_index[n] < ordered_label_counts[n])
4864             current_index[n]++ ;
4865           if (current_index[n] < ordered_label_counts[n])
4866           {
4867             gcas2 = &ordered_labels[n][current_index[n]] ;
4868             current_index[n]++ ;
4869             xv = gcas2->xp*scale ;
4870             yv = gcas2->yp*scale ;
4871             zv = gcas2->zp*scale;
4872 
4873             if (n == Gdiag_no)
4874               DiagBreak() ;
4875 
4876             if (!MRIvox(mri_found, xv, yv, zv))
4877               /* none at this location yet */
4878             {
4879               if (gcas2->label == Gdiag_no)
4880                 DiagBreak() ;
4881               samples_added[n]++ ;
4882               gcas[total_found+nfound++] = *gcas2 ;
4883               MRIvox(mri_found, xv, yv, zv) = gcas2->label ;
4884               gcas2->label = -1 ;
4885               if (nfound+total_found >= nsamples)
4886                 break ;
4887             }
4888           }
4889         }
4890       }
4891 
4892       total_found += nfound ;
4893     }
4894     while ((nfound > 0) && total_found < nsamples) ;
4895     MRIfree(&mri_found) ;
4896   }
4897 
4898   if (total_found != nsamples)
4899   {
4900     ErrorPrintf(ERROR_BADPARM,
4901                 "could only find %d samples!\n", total_found) ;
4902   }
4903   return(gcas) ;
4904 }
4905 
4906 
4907 GCA_SAMPLE *
4908 GCAfindContrastSamples(GCA *gca, int *pnsamples, int min_spacing,
4909                        float min_prior)
4910 {
4911 #if 0
4912   GCA_SAMPLE *gcas ;
4913   GC1D       *gc ;
4914   int        x, y, z, width, height, depth, label, nfound, prior_stride,
4915   label_counts[MAX_DIFFERENT_LABELS], best_label, nzeros,
4916   xi, yi, zi, xk, yk, zk, i, j, k, labels[3][3][3], found ;
4917   float      max_prior, total_mean,
4918   priors[3][3][3][MAX_DIFFERENT_LABELS],
4919   best_means[MAX_GCA_INPUTS], best_sigma,
4920   means[3][3][3][MAX_DIFFERENT_LABELS][MAX_GCA_INPUTS], mean, sigma,
4921   vars[3][3][3][MAX_DIFFERENT_LABELS] ;
4922 
4923   memset(label_counts, 0, sizeof(label_counts)) ;
4924   width = gca->prior_width ;
4925   height = gca->prior_height ;
4926   depth = gca->prior_depth ;
4927   gcas = calloc(width*height*depth, sizeof(GCA_SAMPLE)) ;
4928 
4929   prior_stride = min_spacing / gca->node_spacing ;
4930 
4931   total_mean = 0.0 ;
4932 
4933   /* compute the max priors and min variances for each class */
4934   for (nzeros = nfound = x = 0 ; x < width ; x += prior_stride)
4935   {
4936     for (y = 0 ; y < height ; y += prior_stride)
4937     {
4938       for (z = 0 ; z < depth ; z += prior_stride)
4939       {
4940         if (abs(x-31)<=prior_stride &&
4941             abs(y-22)<=prior_stride &&
4942             abs(z-36)<=prior_stride)
4943           DiagBreak() ;
4944         for (xk = -1 ; xk <= 1 ; xk++)
4945         {
4946           xi = x+xk ;
4947           i = xk+1 ;
4948           if (xi < 0 || xi >= width)
4949             continue ;
4950           for (yk = -1 ; yk <= 1 ; yk++)
4951           {
4952             yi = y+yk ;
4953             j = yk + 1 ;
4954             if (yi < 0 || yi >= height)
4955               continue ;
4956             for (zk = -1 ; zk <= 1 ; zk++)
4957             {
4958               zi = z+zk ;
4959               k = zk+1 ;
4960               if (zi < 0 || zi >= depth)
4961                 continue ;
4962               gcaRegionStats(gca, xi, yi, zi,
4963                              prior_stride/3,
4964                              priors[i][j][k],
4965                              vars[i][j][k],
4966                              means[i][j][k]) ;
4967               if (priors[i][j][k][4] > .5*min_prior ||
4968                   /* left lat ven */
4969                   priors[i][j][k][5] > .5*min_prior ||
4970                   /* inf left lat ven */
4971                   priors[i][j][k][14] > .5*min_prior ||
4972                   /* 3rd ven */
4973                   priors[i][j][k][15] > .5*min_prior ||
4974                   /* 4th ven */
4975                   priors[i][j][k][43] > .5*min_prior ||
4976                   priors[i][j][k][44] > .5*min_prior)
4977                 DiagBreak() ;
4978               max_prior = 0 ;
4979 
4980               /* find highest prior label */
4981               for (label = 0 ;
4982                    label < MAX_DIFFERENT_LABELS ;
4983                    label++)
4984               {
4985                 if (priors[i][j][k][label] > max_prior)
4986                 {
4987                   max_prior = priors[i][j][k][label] ;
4988                   labels[i][j][k] = label ;
4989                 }
4990               }
4991             }
4992           }
4993         }
4994 
4995         /* search nbrhd for high-contrast stable label */
4996         best_label = labels[1][1][1] ;
4997         found = 0 ;
4998         best_sigma = sqrt(vars[1][1][1][best_label]) ;
4999         for (r = 0 ; r < gca->ninputs ; r++)
5000           best_means[r] = means[1][1][1][best_label][r] ;
5001 
5002         gc = gcaFindHighestPriorGC(gca, x, y, z,
5003                                    best_label,prior_stride/3);
5004         if (!gc || get_node_prior(gca, best_label, x, y, z) < min_prior)
5005           continue ;
5006 
5007         for (xk = -1 ; xk <= 1 ; xk++)
5008         {
5009           xi = x+xk ;
5010           i = xk+1 ;
5011           if (xi < 0 || xi >= width)
5012             continue ;
5013           for (yk = -1 ; yk <= 1 ; yk++)
5014           {
5015             yi = y+yk ;
5016             j = yk + 1 ;
5017             if (yi < 0 || yi >= height)
5018               continue ;
5019             for (zk = -1 ; zk <= 1 ; zk++)
5020             {
5021               zi = z+zk ;
5022               k = zk+1 ;
5023               if (zi < 0 || zi >= depth)
5024                 continue ;
5025               if (i == 1 && j == 1 && k == 1)
5026                 continue ;
5027               label = labels[i][j][k] ;
5028               if (priors[i][j][k][label]
5029                   < min_prior || label == best_label)
5030                 continue ;
5031 
5032               mean = means[i][j][k][label] ;
5033               sigma = sqrt(vars[i][j][k][label]) ;
5034               gc =
5035                 gcaFindHighestPriorGC(gca, xi, yi, zi,
5036                                       label,prior_stride/3);
5037               if (!gc || get_node_prior(gca, label,
5038                                         xi, yi, zi) < min_prior)
5039                 continue ;
5040               if (abs(best_mean - mean) > 4*abs(best_sigma+sigma))
5041               {
5042 #if 0
5043                 if (gcaFindBestSample(gca, xi, yi, zi,
5044                                       label, prior_stride/3,
5045                                       &gcas[nfound]) == NO_ERROR)
5046 #else
5047                 if (gcaFindClosestMeanSample(gca, mean,
5048                                              min_prior,
5049                                              xi, yi, zi,
5050                                              label,
5051                                              prior_stride/3,
5052                                              &gcas[nfound]) ==
5053                     NO_ERROR)
5054 #endif
5055                 {
5056                   if (label == Gdiag_no)
5057                     DiagBreak() ;
5058                   found = 1 ;
5059                   if (label > 0)
5060                     total_mean += means[i][j][k][label] ;
5061                   else
5062                     nzeros++ ;
5063                   label_counts[label]++ ;
5064                   nfound++ ;
5065                 }
5066               }
5067             }
5068           }
5069         }
5070 
5071         if (found)   /* add central label */
5072         {
5073           if (best_label == Gdiag_no)
5074             DiagBreak() ;
5075 #if 0
5076           if (gcaFindBestSample(gca, x, y, z,
5077                                 best_label, prior_stride/3,
5078                                 &gcas[nfound]) == NO_ERROR)
5079 #else
5080           if (gcaFindClosestMeanSample(gca, best_mean,
5081                                        min_prior, x, y, z,
5082                                        best_label, prior_stride/3,
5083                                        &gcas[nfound]) ==
5084               NO_ERROR)
5085 #endif
5086           {
5087             if (best_label > 0)
5088             {
5089               for (r = 0 ; r < gca->ninputs ; r++)
5090                 total_means[r] += means[1][1][1][best_label][r] ;
5091             }
5092             else
5093               nzeros++ ;
5094             label_counts[best_label]++ ;
5095             nfound++ ;
5096           }
5097         }
5098       }
5099     }
5100   }
5101 
5102   fprintf(stdout, "total sample mean = %2.1f (%d zeros)\n",
5103           total_mean/((float)nfound-nzeros), nzeros) ;
5104 
5105   {
5106     int  n ;
5107     FILE *fp ;
5108 
5109     fp = fopen("classes.dat", "w") ;
5110     for (n = 0 ; n < MAX_DIFFERENT_LABELS ; n++)
5111       if (label_counts[n] > 0)
5112         fprintf(fp, "%d  %d\n", n, label_counts[n]) ;
5113     fclose(fp) ;
5114   }
5115 
5116   *pnsamples = nfound ;
5117   fflush(stdout) ;
5118 
5119   return(gcas) ;
5120 #else
5121   ErrorReturn(NULL, (ERROR_UNSUPPORTED,
5122                      "GCAfindContrastSamples: no longer supported")) ;
5123 #endif
5124 }
5125 
5126 
5127 GCA_SAMPLE *
5128 GCAfindStableSamples(GCA *gca,
5129                      int *pnsamples, int min_spacing,
5130                      float min_prior, int *exclude_list,
5131                      int unknown_nbr_spacing)
5132 {
5133   GCA_SAMPLE *gcas ;
5134   int        xi, yi, zi, width, height, depth, label, nfound,
5135   label_counts[MAX_DIFFERENT_LABELS], best_label, nzeros, r ;
5136   float      max_prior, total_means[MAX_GCA_INPUTS],
5137   /*mean_dist,*/ best_mean_dist,
5138   priors[MAX_DIFFERENT_LABELS], means[MAX_DIFFERENT_LABELS][MAX_GCA_INPUTS],
5139   vars[MAX_DIFFERENT_LABELS], max_priors[MAX_DIFFERENT_LABELS],
5140   prior_stride, x, y, z, min_unknown[MAX_GCA_INPUTS],\
5141   max_unknown[MAX_GCA_INPUTS], prior_factor ;
5142   MRI        *mri_filled ;
5143 
5144 #define MIN_UNKNOWN_DIST  2
5145 
5146   gcaFindMaxPriors(gca, max_priors) ;
5147   gcaFindIntensityBounds(gca, min_unknown, max_unknown) ;
5148   printf("bounding unknown intensity as < ") ;
5149   for (r = 0 ; r < gca->ninputs ; r++)
5150     printf("%2.1f ", min_unknown[r]) ;
5151   printf("or > ") ;
5152   for (r = 0 ; r < gca->ninputs ; r++)
5153     printf("%2.1f ", max_unknown[r]) ;
5154   printf("\n") ;
5155 
5156   memset(label_counts, 0, sizeof(label_counts)) ;
5157 
5158   width = gca->prior_width ;
5159   height = gca->prior_height ;
5160   depth = gca->prior_depth ;
5161 
5162   // samples size allocated is prior voxel points
5163   gcas = calloc(width*height*depth, sizeof(GCA_SAMPLE)) ;
5164   if (!gcas)
5165     ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %dK x %d samples\n",
5166               "GCAfindStableSamples",
5167               width*height*depth/1024, sizeof(GCA_SAMPLE)) ;
5168 
5169   // create a full size volume prior_width*prior_spacing = image width
5170   mri_filled = MRIalloc(width*gca->prior_spacing,height*gca->prior_spacing,
5171                         depth*gca->prior_spacing,MRI_UCHAR);
5172   // use the mri_prior_ header
5173 
5174   mri_filled->xsize = gca->xsize;
5175   mri_filled->ysize = gca->ysize;
5176   mri_filled->zsize = gca->zsize;
5177 
5178   GCAcopyDCToMRI(gca, mri_filled);
5179 
5180   prior_stride = (float)min_spacing / (float)gca->prior_spacing ;
5181   if (prior_stride >= 2.5)
5182     prior_factor = .5 ;
5183   else if (prior_stride >= 1.5)
5184     prior_factor = .75 ;
5185   else
5186     prior_factor = .9 ;
5187 
5188   for (r = 0 ; r < gca->ninputs ; r++)
5189     total_means[r] = 0.0 ;
5190 
5191   /* compute the max priors and min variances for each class */
5192   for (nzeros = nfound = x = 0 ; x < width ; x += prior_stride)
5193   {
5194     xi = nint(x) ;
5195     for (y = 0 ; y < height ; y += prior_stride)
5196     {
5197       yi = nint(y) ;
5198       for (z = 0 ; z < depth ; z += prior_stride)
5199       {
5200         zi = nint(z) ;
5201         if (xi == Gx && yi == Gy && zi == Gz)
5202           DiagBreak() ;
5203         if (abs(x-31)<=prior_stride &&
5204             abs(y-22)<=prior_stride &&
5205             abs(z-36)<=prior_stride)
5206           DiagBreak() ;
5207         gcaRegionStats(gca, x, y, z,
5208                        prior_stride/2, priors, vars, means) ;
5209 
5210         ///////////// diag code /////////////////////////////////////
5211         if (priors[4] > .5*min_prior ||  /* left lat ven */
5212             priors[5] > .5*min_prior ||  /* inf left lat ven */
5213             priors[14] > .5*min_prior ||  /* 3rd ven */
5214             priors[15] > .5*min_prior ||  /* 4th ven */
5215             priors[43] > .5*min_prior ||
5216             priors[44] > .5*min_prior)
5217           DiagBreak() ;
5218         /////////////////////////////////////////////////////////////
5219 
5220         best_mean_dist = 0.0 ;
5221         max_prior = -1 ;
5222 
5223         if ((different_nbr_max_labels(gca, x, y, z,
5224                                       unknown_nbr_spacing, 0) > 0) &&
5225             (exclude_list && exclude_list[0] == 0) &&
5226             (priors[0] >= min_prior) &&
5227             (priors[0] >= .5*max_priors[0]))
5228           best_label = 0 ;
5229         else
5230           best_label = -1 ;
5231 
5232         for (label = 1 ; label < MAX_DIFFERENT_LABELS ; label++)
5233         {
5234           /* ignore it if:
5235              1. It's prior is less than min_prior and
5236              it's prior is less than the max for this class.
5237              2. It's prior is less than 1/2 of min prior regardless.
5238           */
5239           if (((priors[label] < min_prior) && \
5240                (priors[label] < prior_factor*max_priors[label])) ||
5241               (priors[label] < .5*min_prior) ||
5242               (exclude_list && exclude_list[label] > 0))
5243             continue ;
5244 
5245           if ((best_label == 0) ||
5246               (priors[label] > max_prior) ||
5247               (FEQUAL(priors[label], max_prior) &&
5248                label_counts[best_label] > label_counts[label]))
5249           {
5250             best_label = label ;
5251             max_prior = priors[label] ;
5252           }
5253         }
5254 #if 1
5255         if (nfound > 0)
5256         {
5257           double p = randomNumber(0, 1.0) ;
5258           if (p < ((double)label_counts[best_label] / nfound))
5259             continue ;
5260         }
5261 #endif
5262         if (best_label >= 0)
5263         {
5264           if (best_label == 0)
5265           {
5266 #if 1
5267             if (gcaFindBestSample(gca, x, y, z,
5268                                   best_label, prior_stride/2,
5269                                   &gcas[nfound]) == NO_ERROR)
5270 #else
5271             gcaFindClosestMeanSample(gca, 255,
5272                                      min_prior, x, y, z, 0,
5273                                      prior_stride/2,
5274                                      &gcas[nfound]);
5275             if (means[0] > 100)
5276 #endif
5277             {
5278               int  xv, yv, zv ;
5279 
5280               if (((means[0] <= min_unknown) ||
5281                    (means[0] >= max_unknown))) /* disabled check */
5282               {
5283                 if (!GCApriorToVoxel(gca, mri_filled,
5284                                      x, y, z, &xv, &yv, &zv))
5285                 {
5286                   if (MRIvox(mri_filled, xv, yv, zv) == 0)
5287                   {
5288                     mriFillRegion(mri_filled,
5289                                   xv, yv, zv, 1,
5290                                   MIN_UNKNOWN_DIST) ;
5291                     /* MRIvox(mri_filled, xv, yv, zv) = 1 ;*/
5292                     nzeros++ ;
5293                     label_counts[best_label]++ ;
5294                     nfound++ ;
5295                   }
5296                 }
5297               }
5298               else
5299                 DiagBreak() ;
5300             }
5301           }
5302           else
5303           {
5304             /* find best gc with this label */
5305             if (gcaFindBestSample(gca, x, y, z,
5306                                   best_label, prior_stride/2,
5307                                   &gcas[nfound]) == NO_ERROR)
5308             {
5309               for (r = 0 ; r < gca->ninputs ; r++)
5310                 total_means[r] += means[best_label][r] ;
5311               label_counts[best_label]++ ;
5312               nfound++ ;
5313             }
5314           }
5315         }
5316       }
5317     }
5318   }
5319 
5320 
5321   fprintf(stdout, "total sample mean = %2.1f (%d zeros)\n",
5322           total_means[0]/((float)nfound-nzeros), nzeros) ;
5323 
5324   if (getenv("GCA_WRITE_CLASS"))
5325   {
5326     int  n ;
5327     FILE *fp ;
5328 
5329     fp = fopen("classes.dat", "w") ;
5330     if (fp)
5331     {
5332       for (n = 0 ; n < MAX_DIFFERENT_LABELS ; n++)
5333         if (label_counts[n] > 0)
5334           fprintf(fp, "%d  %d\n", n, label_counts[n]) ;
5335       fclose(fp) ;
5336     }
5337   }
5338 
5339   *pnsamples = nfound ;
5340   fflush(stdout) ;
5341 
5342   MRIfree(&mri_filled) ;
5343   return(gcas) ;
5344 }
5345 
5346 //////////////////////////////////////////////////////////////////
5347 // write segmented volume for sampled points
5348 // the values are set only at prior_spacing/size
5349 int
5350 GCAwriteSamples(GCA *gca, MRI *mri, GCA_SAMPLE *gcas, int nsamples,
5351                 char *fname)
5352 {
5353   int    n, xv, yv, zv ;
5354   MRI    *mri_dst ;
5355 
5356   mri_dst = MRIalloc(mri->width, mri->height, mri->depth, MRI_UCHAR) ;
5357   // add header information
5358   MRIcopyHeader(mri, mri_dst);
5359   GCAcopyDCToMRI(gca, mri_dst);
5360 
5361   // for each sample
5362   for (n = 0 ; n < nsamples ; n++)
5363   {
5364     // use the gcas to get prior value to get the volume position
5365     if (!GCApriorToVoxel(gca, mri_dst, gcas[n].xp, gcas[n].yp, gcas[n].zp,
5366                          &xv, &yv, &zv))
5367     {
5368       if (gcas[n].label > 0) // if label non-zero (!unknown)
5369         MRIsetVoxVal(mri_dst, xv, yv, zv, 0, gcas[n].label) ;
5370       else                                  // unknown label changed to
5371         MRIsetVoxVal(mri_dst, xv, yv, zv, 0, Left_undetermined) ;
5372       /* Left undetermined - to make it visible */
5373 
5374       /////////////// diagnostics //////////////////////////////////////
5375       if (DIAG_VERBOSE_ON && Gdiag & DIAG_SHOW)
5376         printf("label %d: (%d, %d, %d) <-- (%d, %d, %d)\n",
5377                gcas[n].label,gcas[n].xp,gcas[n].yp,gcas[n].zp,
5378                xv, yv, zv) ;
5379       /////////////////////////////////////////////////////////////////
5380     }
5381   }
5382   MRIwrite(mri_dst, fname) ;
5383   MRIfree(&mri_dst) ;
5384   return(NO_ERROR) ;
5385 }
5386 
5387 MRI *
5388 GCAmri(GCA *gca, MRI *mri)
5389 {
5390   int       frame, width, height, depth, x, y, z, xp, yp, zp, n, xn, yn, zn ;
5391   float     val ;
5392   GC1D      *gc ;
5393   GCA_PRIOR *gcap ;
5394 
5395   if (!mri)
5396   {
5397     mri = MRIallocSequence(gca->node_width,
5398                            gca->node_height,
5399                            gca->node_depth,
5400                            MRI_UCHAR,
5401                            gca->ninputs) ;
5402     mri->xsize = gca->xsize*gca->node_spacing;
5403     mri->ysize = gca->ysize*gca->node_spacing;
5404     mri->zsize = gca->zsize*gca->node_spacing;
5405   }
5406   // in order to create the gca volume,
5407   // the volume must have the same direction cosines
5408   GCAcopyDCToMRI(gca, mri);
5409 
5410   width = mri->width ;
5411   height = mri->height ;
5412   depth = mri->depth ;
5413 
5414   for (frame = 0 ; frame < gca->ninputs ; frame++)
5415   {
5416     for (x = 0 ; x < width ; x++)
5417     {
5418       for (y = 0 ; y < height ; y++)
5419       {
5420         for (z = 0 ; z < depth ; z++)
5421         {
5422           if (!GCAvoxelToPrior(gca, mri, x, y, z, &xp, &yp, &zp))
5423             if (!GCAvoxelToNode(gca, mri, x, y, z, &xn, &yn, &zn))
5424             {
5425               gcap = &gca->priors[xp][yp][zp] ;
5426               if (gcap==NULL)
5427                 continue;
5428               for (val = 0.0, n = 0 ; n < gcap->nlabels ; n++)
5429               {
5430                 gc = GCAfindGC(gca, xn, yn, zn, gcap->labels[n]) ;
5431                 if (gc)
5432                   val += gc->means[frame] * gcap->priors[n] ;
5433               }
5434               MRIsetVoxVal(mri, x, y, z, frame, val) ;
5435             }
5436         }
5437       }
5438     }
5439   }
5440   return(mri) ;
5441 }
5442 
5443 MRI *
5444 GCAlabelMri(GCA *gca, MRI *mri, int label, TRANSFORM *transform)
5445 {
5446   int      width, height, depth, x, y, z, xn, yn, zn, n, frame ;
5447   float    val ;
5448   GC1D     *gc = NULL ;
5449   GCA_NODE *gcan ;
5450   MRI      *mri_norm ;
5451 
5452   if (!mri)
5453   {
5454     mri = MRIallocSequence(gca->node_width,
5455                            gca->node_height,
5456                            gca->node_depth,
5457                            MRI_UCHAR,
5458                            gca->ninputs) ;
5459 
5460     mri->xsize = gca->xsize*gca->node_spacing;
5461     mri->ysize = gca->ysize*gca->node_spacing;
5462     mri->zsize = gca->zsize*gca->node_spacing;
5463     GCAcopyDCToMRI(gca, mri);
5464     // mri=NULL, then use the gca volume
5465     // mri!=NULL, then use the volume as it is to write the label
5466   }
5467   width = mri->width ;
5468   height = mri->height ;
5469   depth = mri->depth ;
5470   mri_norm = MRIalloc(width, height, depth, MRI_SHORT) ;
5471   MRIcopyHeader(mri, mri_norm);
5472 
5473   for (frame = 0 ; frame < gca->ninputs ; frame++)
5474   {
5475     MRIclear(mri_norm) ;
5476     for (x = 0 ; x < width ; x++)
5477     {
5478       for (y = 0 ; y < height ; y++)
5479       {
5480         for (z = 0 ; z < depth ; z++)
5481         {
5482           if (x == width/2 && y == height/2 && z == depth/2)
5483             DiagBreak() ;
5484           if (x == 19 && y == 14 && z == 15)
5485             DiagBreak() ;
5486 
5487           if (!GCAsourceVoxelToNode(gca, mri, transform,
5488                                     x, y, z, &xn, &yn, &zn))
5489           {
5490             gcan = &gca->nodes[xn][yn][zn] ;
5491             if (gcan->nlabels < 1)
5492               continue ;
5493             for (n = 0 ; n < gcan->nlabels ; n++)
5494             {
5495               gc = &gcan->gcs[n] ;
5496               if (gcan->labels[n] == label)
5497                 break ;
5498             }
5499             if (n >= gcan->nlabels)
5500               continue ;
5501             val = gc->means[frame] ;
5502             switch (mri->type)
5503             {
5504             default:
5505               ErrorReturn(NULL,
5506                           (ERROR_UNSUPPORTED,
5507                            "GCAlabelMri: unsupported image"
5508                            " type %d",
5509                            mri->type)) ;
5510             case MRI_UCHAR:
5511               MRIseq_vox(mri, x, y, z,frame) = (unsigned short)val ;
5512               break ;
5513             case MRI_SHORT:
5514               MRISseq_vox(mri, x, y, z,frame) = (short)val ;
5515               break ;
5516             case MRI_FLOAT:
5517               MRIFseq_vox(mri, x, y, z, frame) = (float)val ;
5518               break ;
5519             }
5520             MRISvox(mri_norm, x, y, z) += 1 ;
5521           }
5522         }
5523       }
5524     }
5525     for (x = 0 ; x < width ; x++)
5526     {
5527       for (y = 0 ; y < height ; y++)
5528       {
5529         for (z = 0 ; z < depth ; z++)
5530         {
5531           if (MRISvox(mri_norm, x, y, z) > 0)
5532             MRISseq_vox(mri, x, y, z, frame) =
5533               nint((float)MRISseq_vox(mri,x,y,z,frame)/ \
5534                    (float)MRISvox(mri_norm,x,y,z)) ;
5535         }
5536       }
5537     }
5538   }
5539   MRIfree(&mri_norm) ;
5540   return(mri) ;
5541 }
5542 
5543 static int
5544 different_nbr_max_labels(GCA *gca, int x, int y, int z, int wsize, int label)
5545 {
5546   int      xk, yk, zk, xi, yi, zi, nbrs, n, width, height, depth, max_label ;
5547   GCA_PRIOR *gcap ;
5548   double     max_p ;
5549 
5550   // look at prior volume
5551   width = gca->prior_width ;
5552   height = gca->prior_height ;
5553   depth = gca->prior_depth ;
5554   for (nbrs = 0, xk = -wsize ; xk <= wsize ; xk++)
5555   {
5556     xi = x+xk ;
5557     if (xi < 0 || xi >= width)
5558       continue ;
5559 
5560     for (yk = -wsize ; yk <= wsize ; yk++)
5561     {
5562       yi = y+yk ;
5563       if (yi < 0 || yi >= height)
5564         continue ;
5565 
5566       for (zk = -wsize ; zk <= wsize ; zk++)
5567       {
5568         zi = z+zk ;
5569         if (zi < 0 || zi >= depth)
5570           continue ;
5571 
5572         gcap = &gca->priors[xi][yi][zi] ;
5573         if (gcap == NULL)
5574           continue;
5575         if (gcap->nlabels == 0) // no priors nor labels exist
5576           continue;
5577 
5578         max_p = gcap->priors[0] ;
5579         max_label = gcap->labels[0] ;
5580         for (n = 1 ; n < gcap->nlabels ; n++)
5581           if (gcap->priors[n] >= max_p)
5582           {
5583             max_label = gcap->labels[n] ;
5584             max_p = gcap->priors[n] ;
5585           }
5586         if (max_label != label)
5587           // if the label is different from the one given
5588           nbrs++ ;              // count them
5589       }
5590     }
5591   }
5592   return(nbrs) ;
5593 }
5594 #if 0
5595 static int
5596 different_nbr_labels(GCA *gca,
5597                      int x, int y, int z,
5598                      int wsize, int label, float pthresh)
5599 {
5600   int      xk, yk, zk, xi, yi, zi, nbrs, n, width, height, depth ;
5601   GCA_PRIOR *gcap ;
5602 
5603   width = gca->prior_width ;
5604   height = gca->prior_height ;
5605   depth = gca->prior_depth ;
5606   for (nbrs = 0, xk = -wsize ; xk <= wsize ; xk++)
5607   {
5608     xi = x+xk ;
5609     if (xi < 0 || xi >= width)
5610       continue ;
5611 
5612     for (yk = -wsize ; yk <= wsize ; yk++)
5613     {
5614       yi = y+yk ;
5615       if (yi < 0 || yi >= height)
5616         continue ;
5617 
5618       for (zk = -wsize ; zk <= wsize ; zk++)
5619       {
5620         zi = z+zk ;
5621         if (zi < 0 || zi >= depth)
5622           continue ;
5623 
5624         gcap = &gca->priors[xi][yi][zi] ;
5625         if (gcap==NULL)
5626           continue;
5627         for (n = 0 ; n < gcap->nlabels ; n++)
5628           if ((gcap->labels[n] != label) && (gcap->priors[n] >= pthresh))
5629             nbrs++ ;
5630       }
5631     }
5632   }
5633   return(nbrs) ;
5634 }
5635 #endif
5636 static int
5637 gcaRegionStats(GCA *gca, int x, int y, int z, int wsize,
5638                float *priors, float *vars,
5639                float means[MAX_DIFFERENT_LABELS][MAX_GCA_INPUTS])
5640 {
5641   int        xk, yk, zk, xi, yi, zi, width, height, depth, label, n,
5642   total_training, r, l ;
5643   GCA_PRIOR  *gcap  ;
5644   GC1D       *gc ;
5645   float      dof ;
5646 
5647   if (x == 28 && y == 24 && z == 36)
5648     DiagBreak() ;
5649 
5650   memset(priors, 0, MAX_DIFFERENT_LABELS*sizeof(float)) ;
5651   memset(vars, 0, MAX_DIFFERENT_LABELS*sizeof(float)) ;
5652   for (l = 0 ; l < MAX_DIFFERENT_LABELS ; l++)
5653     for (r = 0 ; r < gca->ninputs ; r++)
5654       means[l][r] = 0 ;
5655 
5656   width = gca->prior_width ;
5657   height = gca->prior_height ;
5658   depth = gca->prior_depth ;
5659   total_training = 0 ;
5660   for (xk = -wsize ; xk <= wsize ; xk++)
5661   {
5662     xi = x+xk ;
5663     if (xi < 0 || xi >= width)
5664       continue ;
5665 
5666     for (yk = -wsize ; yk <= wsize ; yk++)
5667     {
5668       yi = y+yk ;
5669       if (yi < 0 || yi >= height)
5670         continue ;
5671 
5672       for (zk = -wsize ; zk <= wsize ; zk++)
5673       {
5674         zi = z+zk ;
5675         if (zi < 0 || zi >= depth)
5676           continue ;
5677 
5678         gcap = &gca->priors[xi][yi][zi] ;
5679         if (gcap==NULL)
5680           continue;
5681         total_training += gcap->total_training ;
5682 
5683         for (n = 0 ; n < gcap->nlabels ; n++)
5684         {
5685           label = gcap->labels[n] ;
5686           if (label == Gdiag_no)
5687             DiagBreak() ;
5688           gc = GCAfindPriorGC(gca, xi, yi, zi, label) ;
5689           if (gc)
5690           {
5691             dof = (gcap->priors[n] * (float)gcap->total_training) ;
5692 
5693             vars[label] +=
5694               dof * covariance_determinant(gc, gca->ninputs) ;
5695             for (r = 0 ; r < gca->ninputs ; r++)
5696               means[label][r] += dof * gc->means[r] ;
5697             priors[label] += dof ;
5698           }
5699         }
5700       }
5701     }
5702   }
5703 
5704   for (label = 0 ; label < MAX_DIFFERENT_LABELS ; label++)
5705   {
5706     dof = priors[label] ;
5707     if (dof > 0)
5708     {
5709       vars[label] /= dof ;
5710       priors[label] /= total_training ;
5711       for (r = 0 ; r < gca->ninputs ; r++)
5712         means[label][r] /= dof ;
5713     }
5714   }
5715   return(NO_ERROR) ;
5716 }
5717 static int
5718 gcaFindBestSample(GCA *gca, int x, int y, int z,int label,int wsize,
5719                   GCA_SAMPLE *gcas)
5720 {
5721   int        xk, yk, zk, xi, yi, zi, width, height, depth, n,
5722   best_n, best_x, best_y, best_z, xn, yn, zn, r, c, v ;
5723   GCA_PRIOR  *gcap ;
5724   GC1D       *gc, *best_gc ;
5725   float      max_prior, min_var, prior ;
5726 
5727   width = gca->prior_width ;
5728   height = gca->prior_height ;
5729   depth = gca->prior_depth ;
5730   max_prior = 0.0 ;
5731   min_var = 10000.0f ;
5732   best_gc = NULL ;
5733   best_x = best_y = best_z = -1 ;
5734   best_n = -1 ;
5735   for (xk = -wsize ; xk <= wsize ; xk++)
5736   {
5737     xi = x+xk ;
5738     if (xi < 0 || xi >= width)
5739       continue ;
5740 
5741     for (yk = -wsize ; yk <= wsize ; yk++)
5742     {
5743       yi = y+yk ;
5744       if (yi < 0 || yi >= height)
5745         continue ;
5746 
5747       for (zk = -wsize ; zk <= wsize ; zk++)
5748       {
5749         zi = z+zk ;
5750         if (zi < 0 || zi >= depth)
5751           continue ;
5752 
5753         gcap = &gca->priors[xi][yi][zi] ;
5754         if (gcap==NULL)
5755           continue;
5756         for (n = 0 ; n < gcap->nlabels ; n++)
5757         {
5758           if (gcap->labels[n] != label)
5759             continue ;
5760           DiagBreak() ;
5761           prior = gcap->priors[n] ;
5762           if (!GCApriorToNode(gca, xi, yi, zi, &xn, &yn, &zn))
5763           {
5764             gc = GCAfindGC(gca, xn, yn, zn, label) ;
5765             if (!gc)
5766               continue ;
5767 
5768             if (prior > max_prior
5769 #if 0
5770                 ||
5771                 (FEQUAL(prior, max_prior) && (gc->var < min_var)) ||
5772                 (label == 0 && gc->mean > best_gc->mean)
5773 #endif
5774                )
5775             {
5776               max_prior = prior ; /*min_var = gc->var ;*/
5777               best_gc = gc ;
5778               best_x = xi ;
5779               best_y = yi ;
5780               best_z = zi ;
5781               best_n = n ;
5782             }
5783           }
5784         }
5785       }
5786     }
5787   }
5788 
5789   if (best_x < 0)
5790   {
5791     ErrorPrintf(ERROR_BADPARM,
5792                 "could not find GC1D for label %d at (%d,%d,%d)\n",
5793                 label, x, y, z) ;
5794     return(ERROR_BADPARM) ;
5795   }
5796   if (best_x == 145/4 && best_y == 89/4 && best_z == 125/4)
5797     DiagBreak() ;
5798   gcas->xp = best_x ;
5799   gcas->yp = best_y ;
5800   gcas->zp = best_z ;
5801   gcas->label = label ;
5802   gcas->means = (float *)calloc(gca->ninputs, sizeof(float)) ;
5803   gcas->covars = (float *)calloc((gca->ninputs*(gca->ninputs+1))/2,
5804                                  sizeof(float)) ;
5805   if (!gcas->means || !gcas->covars)
5806     ErrorExit(ERROR_NOMEMORY,
5807               "GCAfindStableSamples: could not allocate "
5808               "mean (%d) and covariance (%d) matrices",
5809               gca->ninputs, gca->ninputs*(gca->ninputs+1)/2) ;
5810   for (r = v = 0 ; r < gca->ninputs ; r++)
5811   {
5812     gcas->means[r] = best_gc->means[r] ;
5813     for (c = r ; c < gca->ninputs ; c++, v++)
5814       gcas->covars[v] = best_gc->covars[v] ;
5815   }
5816   gcas->prior = max_prior ;
5817 
5818   return(NO_ERROR) ;
5819 }
5820 #if 0
5821 static GC1D *
5822 gcaFindHighestPriorGC(GCA *gca, int x, int y, int z,int label,int wsize)
5823 {
5824   int        xk, yk, zk, xi, yi, zi, width, height, depth, n ;
5825   GCA_PRIOR  *gcap  ;
5826   GC1D       *best_gc ;
5827   float      max_prior, prior ;
5828 
5829   width = gca->prior_width ;
5830   height = gca->prior_height ;
5831   depth = gca->prior_depth ;
5832   max_prior = 0.0 ;
5833   best_gc = NULL ;
5834   for (xk = -wsize ; xk <= wsize ; xk++)
5835   {
5836     xi = x+xk ;
5837     if (xi < 0 || xi >= width)
5838       continue ;
5839 
5840     for (yk = -wsize ; yk <= wsize ; yk++)
5841     {
5842       yi = y+yk ;
5843       if (yi < 0 || yi >= height)
5844         continue ;
5845 
5846       for (zk = -wsize ; zk <= wsize ; zk++)
5847       {
5848         zi = z+zk ;
5849         if (zi < 0 || zi >= depth)
5850           continue ;
5851 
5852         gcap = &gca->priors[xi][yi][zi] ;
5853         if (gcap == NULL || gcap->nlabels <= 0)
5854           continue;
5855         for (n = 0 ; n < gcap->nlabels ; n++)
5856         {
5857           if (gcap->labels[n] != label)
5858             continue ;
5859           prior = gcap->priors[n] ;
5860           if (prior > max_prior)
5861           {
5862             max_prior = prior ;
5863             best_gc = GCAfindPriorGC(gca, x, y, z, label) ;
5864           }
5865         }
5866       }
5867     }
5868   }
5869 
5870   if (best_gc == NULL)
5871   {
5872     ErrorPrintf(ERROR_BADPARM,
5873                 "could not find GC for label %d at (%d,%d,%d)\n",
5874                 label, x, y, z) ;
5875     return(NULL) ;
5876   }
5877 
5878   return(best_gc) ;
5879 }
5880 static int
5881 gcaFindClosestMeanSample(GCA *gca,
5882                          float *means, float min_prior,
5883                          int x, int y, int z, int label,
5884                          int wsize, GCA_SAMPLE *gcas)
5885 {
5886   int        xk, yk, zk, xi, yi, zi, width, height, depth, n,
5887   best_x, best_y, best_z, r, c, v ;
5888   GCA_NODE   *gcan  ;
5889   GC1D       *gc, *best_gc ;
5890   float      min_dist, best_prior, prior, dist ;
5891 
5892   width = gca->node_width ;
5893   height = gca->node_height ;
5894   depth = gca->node_depth ;
5895   min_dist = 1000000.0f ;
5896   best_gc = NULL ;
5897   best_prior = 0.0 ;
5898   best_x = best_y = best_z = -1 ;
5899   for (xk = -wsize ; xk <= wsize ; xk++)
5900   {
5901     xi = x+xk ;
5902     if (xi < 0 || xi >= width)
5903       continue ;
5904 
5905     for (yk = -wsize ; yk <= wsize ; yk++)
5906     {
5907       yi = y+yk ;
5908       if (yi < 0 || yi >= height)
5909         continue ;
5910 
5911       for (zk = -wsize ; zk <= wsize ; zk++)
5912       {
5913         zi = z+zk ;
5914         if (zi < 0 || zi >= depth)
5915           continue ;
5916 
5917         gcan = &gca->nodes[xi][yi][zi] ;
5918 
5919         for (n = 0 ; n < gcan->nlabels ; n++)
5920         {
5921           gc = &gcan->gcs[n] ;
5922           prior = get_node_prior(gca, gcan->labels[n], xi, yi, zi) ;
5923           if (gcan->labels[n] != label || prior < min_prior)
5924             continue ;
5925           for (dist = 0, r = 0 ; r < gca->ninputs ; r++)
5926             dist += SQR(gc->means[r] - means[r]) ;
5927           if (dist < min_dist)
5928           {
5929             min_dist = dist ;
5930             best_gc = gc ;
5931             best_x = xi ;
5932             best_y = yi ;
5933             best_z = zi ;
5934             best_prior = prior ;
5935           }
5936         }
5937       }
5938     }
5939   }
5940 
5941   if (best_x < 0)
5942   {
5943     ErrorPrintf(ERROR_BADPARM,
5944                 "could not find GC for label %d at (%d,%d,%d)\n",
5945                 label, x, y, z) ;
5946     return(ERROR_BADPARM) ;
5947   }
5948   if (best_x == 141/4 && best_y == 37*4 && best_z == 129*4)
5949     DiagBreak() ;
5950   gcas->xp = best_x ;
5951   gcas->yp = best_y ;
5952   gcas->zp = best_z ;
5953   gcas->label = label ;
5954   for (v = r = 0 ; r < gca->ninputs ; r++)
5955   {
5956     gcas->means[r] = best_gc->means[r] ;
5957     for (c = r ; c < gca->ninputs ; c++, v++)
5958       gcas->covars[v] = best_gc->covars[v] ;
5959   }
5960 
5961   gcas->prior = best_prior ;
5962   return(NO_ERROR) ;
5963 }
5964 #endif
5965 
5966 // create a volume mapped to the current mri volume
5967 int
5968 GCAtransformAndWriteSamples(GCA *gca, MRI *mri, GCA_SAMPLE *gcas,
5969                             int nsamples,char *fname,TRANSFORM *transform)
5970 {
5971   int    n, xv, yv, zv, label ;
5972   MRI    *mri_dst ;
5973 
5974   mri_dst = MRIalloc(mri->width, mri->height, mri->depth, MRI_UCHAR) ;
5975   MRIcopyHeader(mri, mri_dst);
5976 
5977   TransformInvert(transform, mri) ;
5978   for (n = 0 ; n < nsamples ; n++)
5979   {
5980     if (gcas[n].label == Gdiag_no)
5981       DiagBreak() ;
5982     if (!GCApriorToSourceVoxel(gca, mri_dst, transform,
5983                                gcas[n].xp, gcas[n].yp, gcas[n].zp,
5984                                &xv, &yv, &zv))
5985     {
5986       if (gcas[n].label > 0)
5987         label = gcas[n].label ;
5988       else if (gcas[n].label == 0)
5989         label = 29 ;  /* Left undetermined - visible */
5990       else
5991         label = 0 ;  /* Left undetermined - visible */
5992 
5993       mriFillRegion(mri_dst, xv, yv, zv, label, 0) ;
5994 
5995       if (gcas[n].x == Gx && gcas[n].y == Gy && gcas[n].z == Gz)
5996         DiagBreak() ;
5997 
5998       gcas[n].x = xv ;
5999       gcas[n].y = yv ;
6000       gcas[n].z = zv ;
6001 
6002       //////////// diag /////////////////////////
6003       if (gcas[n].x == Gx && gcas[n].y == Gy && gcas[n].z == Gz)
6004         DiagBreak() ;
6005       if (DIAG_VERBOSE_ON && Gdiag & DIAG_SHOW)
6006         printf("label %d: (%d, %d, %d) <-- (%d, %d, %d)\n",
6007                gcas[n].label,gcas[n].xp,gcas[n].yp,gcas[n].zp,
6008                xv, yv, zv) ;
6009       //////////////////////////////////////////////
6010     }
6011   }
6012   fprintf(stdout, "writing samples to %s...\n", fname) ;
6013   MRIwrite(mri_dst, fname) ;
6014   MRIfree(&mri_dst) ;
6015   fflush(stdout) ;
6016 
6017   return(NO_ERROR) ;
6018 }
6019 
6020 static int
6021 mriFillRegion(MRI *mri, int x, int y, int z, int fill_val, int whalf)
6022 {
6023   int   xi, xk, yi, yk, zi, zk ;
6024 
6025   for (xk = -whalf ; xk <= whalf ; xk++)
6026   {
6027     xi = mri->xi[x+xk] ;
6028     for (yk = -whalf ; yk <= whalf ; yk++)
6029     {
6030       yi = mri->yi[y+yk] ;
6031       for (zk = -whalf ; zk <= whalf ; zk++)
6032       {
6033         zi = mri->zi[z+zk] ;
6034         MRIvox(mri, xi, yi, zi) = fill_val ;
6035       }
6036     }
6037   }
6038   return(NO_ERROR) ;
6039 }
6040 
6041 static int
6042 gcaFindIntensityBounds(GCA *gca, float *pmin, float *pmax)
6043 {
6044   int      width, depth, height, x, y, z, n, label, r ;
6045   GCA_NODE *gcan ;
6046   GC1D     *gc ;
6047   float    mn[MAX_GCA_INPUTS], mx[MAX_GCA_INPUTS], offset ;
6048 
6049   for (r = 0 ; r < gca->ninputs ; r++)
6050   {
6051     mn[r] = 100000.0f ;
6052     mx[r] = -mn[r] ;
6053   }
6054   width = gca->node_width ;
6055   height = gca->node_height ;
6056   depth = gca->node_depth ;
6057 
6058   for (x = 0 ; x < width ; x++)
6059   {
6060     for (y = 0 ; y < height ; y++)
6061     {
6062       for (z = 0 ; z < depth ; z++)
6063       {
6064         gcan = &gca->nodes[x][y][z] ;
6065         for (n = 0 ; n < gcan->nlabels ; n++)
6066         {
6067           gc = &gcan->gcs[n] ;
6068           label = gcan->labels[n] ;
6069           if (label == 0)  /* don't include unknowns */
6070             continue ;
6071           if (get_node_prior(gca, label, x, y, z) < 0.1)
6072             continue ;
6073           /* exclude unlikely stuff (errors in labeling) */
6074           offset = 0.5*pow(covariance_determinant\
6075                            (gc, gca->ninputs),
6076                            1.0/(double)gca->ninputs) ;
6077           for (r = 0 ; r < gca->ninputs ; r++)
6078           {
6079             if (gc->means[r] + offset > mx[r])
6080             {
6081               mx[r] = gc->means[r] + offset ;
6082             }
6083             if (gc->means[r]  < mn[r])
6084             {
6085               mn[r] = gc->means[r] ;
6086             }
6087 #if 0
6088             if (mn[r] < 5)
6089               mn = 5 ;
6090             if (mx[r] > 225)
6091               mx[r] = 225 ;
6092 #endif
6093           }
6094         }
6095       }
6096     }
6097   }
6098   for (r = 0 ; r < gca->ninputs ; r++)
6099   {
6100     pmin[r] = mn[r] ;
6101     pmax[r] = mx[r] ;
6102   }
6103   return(NO_ERROR) ;
6104 }
6105 static int
6106 gcaFindMaxPriors(GCA *gca, float *max_priors)
6107 {
6108   int       width, depth, height, x, y, z, n, label ;
6109   GCA_PRIOR *gcap ;
6110 
6111   memset(max_priors, 0, MAX_DIFFERENT_LABELS*sizeof(float)) ;
6112   width = gca->prior_width ;
6113   height = gca->prior_height ;
6114   depth = gca->prior_depth ;
6115 
6116   for (x = 0 ; x < width ; x++)
6117   {
6118     for (y = 0 ; y < height ; y++)
6119     {
6120       for (z = 0 ; z < depth ; z++)
6121       {
6122         gcap = &gca->priors[x][y][z] ;
6123         if (gcap == NULL || gcap->nlabels <= 0)
6124           continue;
6125         for (n = 0 ; n < gcap->nlabels ; n++)
6126         {
6127           label = gcap->labels[n] ;
6128           if (gcap->priors[n] > max_priors[label])
6129           {
6130             if (label == Ggca_label)
6131               DiagBreak() ;
6132             if ((gcap->priors[n] > 0.89) && (label == Ggca_label))
6133               DiagBreak() ;
6134             max_priors[label] = gcap->priors[n] ;
6135           }
6136         }
6137       }
6138     }
6139   }
6140   return(NO_ERROR) ;
6141 }
6142 
6143 #if 0
6144 static int xn_bad = 15 ;
6145 static int yn_bad = 24 ;
6146 static int zn_bad = 27 ;
6147 static int xl_bad = 56 ;
6148 static int yl_bad = 99 ;
6149 static int zl_bad = 106 ;
6150 static int label_bad = 42 ;
6151 static int nbr_label_bad = 42 ;
6152 static int bad_i = 0 ;
6153 #endif
6154 
6155 //                                 segmented volume here
6156 static int
6157 GCAupdateNodeGibbsPriors(GCA *gca, MRI*mri, int xn, int yn, int zn,
6158                          int xl, int yl, int zl, int label)
6159 {
6160   int       n, i, xnbr, ynbr, znbr, nbr_label ;
6161   GCA_NODE *gcan ;
6162   GC1D     *gc ;
6163 
6164   gcan = &gca->nodes[xn][yn][zn] ;
6165 
6166   // look for this label
6167   for (n = 0 ; n < gcan->nlabels ; n++)
6168   {
6169     if (gcan->labels[n] == label)
6170       break ;
6171   }
6172   // not found
6173   if (n >= gcan->nlabels)  /* have to allocate a new classifier */
6174     ErrorExit(ERROR_BADPARM, "gca(%d, %d, %d): could not find label %d",
6175               xn, yn, zn, label) ;
6176 
6177   gc = &gcan->gcs[n] ;
6178   for (i = 0 ; i < GIBBS_NEIGHBORHOOD ; i++)
6179   {
6180     /* coordinates of neighboring point */
6181     xnbr = mri->xi[xl+xnbr_offset[i]] ;// xnbr_offset 1, -1, 0,  0, 0,  0
6182     ynbr = mri->yi[yl+ynbr_offset[i]] ;// ynbr_offset 0,  0, 1, -1, 0,  0
6183     znbr = mri->zi[zl+znbr_offset[i]] ;// znbr_offset 0,  0, 0,  0, 1, -1
6184 
6185     // get the label from the neighbor
6186     nbr_label = nint(MRIgetVoxVal(mri, xnbr, ynbr, znbr, 0)) ;
6187     if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z && label == Ggca_label
6188         && (xnbr_offset[i] == 1) && (nbr_label == Ggca_nbr_label))
6189     {
6190       printf("(%d, %d, %d) --> node (%d, %d, %d), "
6191              "label %s (%d), nbr (%d, %d, %d) = %s (%d)\n",
6192              xl, yl, zl, xn, yn, zn, cma_label_to_name(label), label,
6193              xnbr, ynbr, znbr, cma_label_to_name(nbr_label), nbr_label) ;
6194 
6195     }
6196 
6197     /* now see if this label exists already as a nbr */
6198     for (n = 0 ; n < gc->nlabels[i] ; n++)
6199       if (gc->labels[i][n] == nbr_label)
6200         break ;
6201 
6202     if (n >= gc->nlabels[i])   /* not there - reallocate stuff */
6203     {
6204 #if 1
6205       unsigned short *old_labels ;
6206       float *old_label_priors ;
6207 
6208       old_labels = gc->labels[i] ;
6209       old_label_priors = gc->label_priors[i] ;
6210 
6211       /* allocate new ones */
6212       gc->label_priors[i] =
6213         (float *)calloc(gc->nlabels[i]+1, sizeof(float)) ;
6214       if (!gc->label_priors[i])
6215         ErrorExit(ERROR_NOMEMORY, "GCAupdateNodeGibbsPriors: "
6216                   "couldn't expand gcs to %d" ,gc->nlabels[i]+1) ;
6217       gc->labels[i] =
6218         (unsigned short *)calloc(gc->nlabels[i]+1, sizeof(unsigned short)) ;
6219       if (!gc->labels[i])
6220         ErrorExit(ERROR_NOMEMORY,
6221                   "GCANupdateNode: couldn't expand labels to %d",
6222                   gc->nlabels[i]+1) ;
6223 
6224       if (gc->nlabels[i] > 0)  /* copy the old ones over */
6225       {
6226         memmove(gc->label_priors[i], old_label_priors,
6227                 gc->nlabels[i]*sizeof(float)) ;
6228         memmove(gc->labels[i], old_labels,
6229                 gc->nlabels[i]*sizeof(unsigned short)) ;
6230 
6231         /* free the old ones */
6232         free(old_label_priors) ;
6233         free(old_labels) ;
6234       }
6235       gc->labels[i][gc->nlabels[i]++] = nbr_label ;
6236 #else
6237       if (n >= MAX_NBR_LABELS)   /* not there - reallocate stuff */
6238       {
6239         ErrorPrintf(ERROR_NOMEMORY,
6240                     "GCAupdateNodeGibbsPriors: "
6241                     "gca(%d,%d,%d) has more than %d "
6242                     "different neighbors", xn, yn, zn, MAX_NBR_LABELS);
6243         continue ;
6244       }
6245       else
6246         gc->labels[i][gc->nlabels[i]++] = nbr_label ;
6247 #endif
6248     }
6249     gc->label_priors[i][n] += 1.0f ; // counter increment at this label
6250   }
6251 
6252   return(NO_ERROR) ;
6253 }
6254 
6255 #if 0
6256 MRI  *
6257 GCAreclassifyUsingGibbsPriors(MRI *mri_inputs,
6258                               GCA *gca,
6259                               MRI *mri_dst,
6260                               TRANSFORM *transform,
6261                               int max_iter)
6262 {
6263   int      x, y, z, width, height, depth, label, val, iter,
6264   xn, yn, zn, n, i, j, nchanged, xnbr, ynbr, znbr, nbr_label,
6265   index, nindices ;
6266   short    *x_indices, *y_indices, *z_indices ;
6267   GCA_NODE *gcan ;
6268   GC1D     *gc ;
6269   double   dist, max_p, p, prior, ll, lcma = 0.0, new_ll, old_ll ;
6270   MRI      *mri_changed, *mri_probs ;
6271 
6272   nindices = mri_dst->width * mri_dst->height * mri_dst->depth ;
6273   x_indices = (short *)calloc(nindices, sizeof(short)) ;
6274   y_indices = (short *)calloc(nindices, sizeof(short)) ;
6275   z_indices = (short *)calloc(nindices, sizeof(short)) ;
6276   if (!x_indices || !y_indices || !z_indices)
6277     ErrorExit(ERROR_NOMEMORY, "GCAreclassifyUsingGibbsPriors: "
6278               "could not allocate index set") ;
6279 
6280 
6281   width = mri_inputs->width ;
6282   height = mri_inputs->height;
6283   depth = mri_inputs->depth ;
6284   iter = 0 ;
6285   if (!mri_dst)
6286   {
6287     mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
6288     if (!mri_dst)
6289       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
6290     MRIcopyHeader(mri_inputs, mri_dst) ;
6291   }
6292 
6293   mri_changed = MRIclone(mri_dst, NULL) ;
6294 
6295 
6296   /* go through each voxel in the input volume and find the canonical
6297      voxel (and hence the classifier) to which it maps. Then update the
6298      classifiers statistics based on this voxel's intensity and label.
6299   */
6300   for (x = 0 ; x < width ; x++)
6301     for (y = 0 ; y < height ; y++)
6302       for (z = 0 ; z < depth ; z++)
6303         MRIvox(mri_changed,x,y,z) = 1 ;
6304 
6305 #if 0
6306   {
6307     MRI   *mri_cma ;
6308     char  fname[STRLEN], *cp ;
6309 
6310     strcpy(fname, mri_inputs->fname) ;
6311     cp = strrchr(fname, '/') ;
6312     if (cp)
6313     {
6314       strcpy(cp+1, "parc") ;
6315       mri_cma = MRIread(fname) ;
6316       if (mri_cma)
6317       {
6318 
6319         ll = gcaGibbsImageLogLikelihood(gca, mri_dst, mri_inputs, lta) ;
6320         lcma = gcaGibbsImageLogLikelihood(gca, mri_cma, mri_inputs, lta) ;
6321         lcma /= (double)(width*depth*height) ;
6322         ll /= (double)(width*depth*height) ;
6323         fprintf(stdout, "image ll: %2.3f (CMA=%2.3f)\n", ll, lcma) ;
6324         MRIfree(&mri_cma) ;
6325       }
6326     }
6327   }
6328 #endif
6329   fflush(stdout) ;
6330 
6331   do
6332   {
6333     if (iter == 0)
6334     {
6335       mri_probs = GCAlabelProbabilities(mri_inputs, gca, NULL, lta) ;
6336       MRIorderIndices(mri_probs, x_indices, y_indices, z_indices) ;
6337       MRIfree(&mri_probs) ;
6338     }
6339     else
6340       MRIcomputeVoxelPermutation(mri_inputs, x_indices, y_indices,
6341                                  z_indices) ;
6342 
6343     nchanged = 0 ;
6344     for (index = 0 ; index < nindices ; index++)
6345     {
6346       x = x_indices[index] ;
6347       y = y_indices[index] ;
6348       z = z_indices[index] ;
6349       if (!GCAsourceVoxelToNode(gca, mri_inputs,
6350                                 transform, x, y, z, &xn, &yn, &zn))
6351       {
6352         if (x == 100 && y == 104 && z == 130)
6353           DiagBreak() ;
6354 
6355 #if 1
6356         if (MRIvox(mri_changed, x, y, z) == 0)
6357           continue ;
6358 #endif
6359 
6360         if (x == 63 && y == 107 && z == 120)
6361           DiagBreak() ;
6362 
6363         val = MRIgetVoxVal(mri_inputs, x, y, z, 0) ;
6364 
6365         /* find the node associated with this coordinate and classify */
6366         // this is checked above
6367         GCAsourceVoxelToNode(gca, mri_inputs,
6368                              transform, x, y, z, &xn, &yn, &zn) ;
6369         gcan = &gca->nodes[xn][yn][zn] ;
6370         label = 0 ;
6371         max_p = 2*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE ;
6372         for (n = 0 ; n < gcan->nlabels ; n++)
6373         {
6374           gc = &gcan->gcs[n] ;
6375 
6376           /* compute 1-d Mahalanobis distance */
6377           dist = (val-gc->mean) ;
6378 #define USE_LOG_PROBS  1
6379           p =
6380             -log(sqrt(gc->var))
6381             - .5*(dist*dist/gc->var)
6382             + log(gc->prior);
6383 
6384           for (prior = 0.0f, i = 0 ; i < GIBBS_NEIGHBORS ; i++)
6385           {
6386             xnbr = mri_dst->xi[x+xnbr_offset[i]] ;
6387             ynbr = mri_dst->yi[y+ynbr_offset[i]] ;
6388             znbr = mri_dst->zi[z+znbr_offset[i]] ;
6389             nbr_label = nint(MRIgetVoxVal(mri_dst, xnbr, ynbr, znbr,0)) ;
6390             for (j = 0 ; j < gc->nlabels[i] ; j++)
6391             {
6392               if (nbr_label == gc->labels[i][j])
6393                 break ;
6394             }
6395             if (j < gc->nlabels[i])  /* found this label */
6396             {
6397               if (!FZERO(gc->label_priors[i][j]))
6398                 prior += log(gc->label_priors[i][j]) ;
6399               else
6400                 prior += log(0.1f/(float)(gcan->total_training)) ;
6401               /*BIG_AND_NEGATIVE*/
6402             }
6403             else
6404             {
6405               if (x == 141 && y == 62 && z == 126)
6406                 DiagBreak() ;
6407               prior += log(0.1f/(float)(gcan->total_training));
6408               /*2*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE */
6409               /* never occurred - make it unlikely */
6410             }
6411             p += prior ;
6412             if (p > max_p)
6413             {
6414               max_p = p ;
6415               label = gcan->labels[n] ;
6416             }
6417           }
6418 
6419           if (FZERO(max_p))
6420           {
6421             label = 0 ;
6422             max_p = 2*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE ;
6423             for (n = 0 ; n < gcan->nlabels ; n++)
6424             {
6425               gc = &gcan->gcs[n] ;
6426 
6427               /* compute 1-d Mahalanobis distance */
6428               dist = (val-gc->mean) ;
6429               if (FZERO(gc->var))  /* make it a delta function */
6430               {
6431                 if (FZERO(dist))
6432                   p = 1.0 ;
6433                 else
6434                   p = 0.0 ;
6435               }
6436               else
6437                 p = 1 / sqrt(gc->var * 2 * M_PI)
6438                     * exp(-dist*dist/gc->var) ;
6439 
6440               p *= gc->prior ;
6441               if (p > max_p)
6442               {
6443                 max_p = p ;
6444                 label = gcan->labels[n] ;
6445               }
6446             }
6447           }
6448         }
6449         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
6450         {
6451           printf(
6452             "(%d, %d, %d): old label %s (%d), "
6453             "new label %s (%d) (p=%2.3f)\n",
6454             x, y, z, cma_label_to_name(nint(MRIgetVoxVal(mri_dst,x,y,z,0))),
6455             nint(MRIgetVoxVal(mri_dst,x,y,z,0)),
6456             cma_label_to_name(label), label, max_p) ;
6457           if (label == Ggca_label)
6458           {
6459             DiagBreak() ;
6460           }
6461         }
6462 
6463         if (nint(MRIgetVoxVal(mri_dst, x, y, z,0)) != label)
6464         {
6465           int old_label = nint(MRIgetVoxVal(mri_dst, x, y, z, 0)) ;
6466           if (x == 100 && y == 104 && z == 130)
6467             DiagBreak() ;
6468           old_ll =
6469             gcaNbhdGibbsLogLikelihood(gca,
6470                                       mri_dst,
6471                                       mri_inputs,
6472                                       x, y, z, transform,
6473                                       PRIOR_FACTOR) ;
6474           MRIsetVoxVal(mri_dst, x, y, z, 0, label) ;
6475           new_ll =
6476             gcaNbhdGibbsLogLikelihood(gca,
6477                                       mri_dst,
6478                                       mri_inputs,
6479                                       x, y, z, transform,
6480                                       PRIOR_FACTOR) ;
6481           if (new_ll > old_ll)
6482           {
6483             MRIvox(mri_changed, x, y, z) = 1 ;
6484             nchanged++ ;
6485           }
6486           else
6487           {
6488             MRIsetVoxVal(mri_dst, x, y, z, 0, old_label) ;
6489             MRIvox(mri_changed, x, y, z) = 0 ;
6490           }
6491         }
6492         else
6493           MRIvox(mri_changed, x, y, z) = 0 ;
6494       } // if (!GCAsource...)
6495     } // index loop
6496     ll = gcaGibbsImageLogLikelihood(gca, mri_dst, mri_inputs, lta) ;
6497     ll /= (double)(width*depth*height) ;
6498     if (!FZERO(lcma))
6499       printf("pass %d: %d changed. image ll: %2.3f (CMA=%2.3f)\n",
6500              iter+1, nchanged, ll, lcma) ;
6501     else
6502       printf("pass %d: %d changed. image ll: %2.3f\n",
6503              iter+1, nchanged, ll) ;
6504     MRIdilate(mri_changed, mri_changed) ;
6505 
6506   }
6507   while (nchanged > 0 && iter++ < max_iter) ;
6508 
6509   free(x_indices) ;
6510   free(y_indices) ;
6511   free(z_indices) ;
6512   MRIfree(&mri_changed) ;
6513 
6514 
6515   return(mri_dst) ;
6516 }
6517 #endif
6518 
6519 MRI  *
6520 GCAanneal(MRI *mri_inputs, GCA *gca, MRI *mri_dst,TRANSFORM *transform,
6521           int max_iter)
6522 {
6523   int      x, y, z, width, height, depth, label, val, iter,
6524   xn, yn, zn, n, nchanged,
6525   index, nindices, old_label ;
6526   short    *x_indices, *y_indices, *z_indices ;
6527   GCA_NODE *gcan ;
6528   double   ll, lcma = 0.0, old_ll, new_ll, min_ll ;
6529   MRI      *mri_changed, *mri_probs ;
6530 
6531   printf("performing simulated annealing...\n") ;
6532 
6533   nindices = mri_dst->width * mri_dst->height * mri_dst->depth ;
6534   x_indices = (short *)calloc(nindices, sizeof(short)) ;
6535   y_indices = (short *)calloc(nindices, sizeof(short)) ;
6536   z_indices = (short *)calloc(nindices, sizeof(short)) ;
6537   if (!x_indices || !y_indices || !z_indices)
6538     ErrorExit(ERROR_NOMEMORY, "GCAanneal: "
6539               "could not allocate index set") ;
6540 
6541 
6542   width = mri_inputs->width ;
6543   height = mri_inputs->height;
6544   depth = mri_inputs->depth ;
6545   iter = 0 ;
6546   if (!mri_dst)
6547   {
6548     mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
6549     if (!mri_dst)
6550       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
6551     MRIcopyHeader(mri_inputs, mri_dst) ;
6552   }
6553 
6554   mri_changed = MRIclone(mri_dst, NULL) ;
6555 
6556   /* go through each voxel in the input volume and find the canonical
6557      voxel (and hence the classifier) to which it maps. Then update the
6558      classifiers statistics based on this voxel's intensity and label.
6559   */
6560   for (x = 0 ; x < width ; x++)
6561     for (y = 0 ; y < height ; y++)
6562       for (z = 0 ; z < depth ; z++)
6563         MRIvox(mri_changed,x,y,z) = 1 ;
6564 
6565   old_ll = gcaGibbsImageLogLikelihood(gca, mri_dst, mri_inputs, transform) ;
6566   old_ll /= (double)(width*depth*height) ;
6567 #if 0
6568   {
6569     MRI   *mri_cma ;
6570     char  fname[STRLEN], *cp ;
6571 
6572     strcpy(fname, mri_inputs->fname) ;
6573     cp = strrchr(fname, '/') ;
6574     if (cp)
6575     {
6576       strcpy(cp+1, "parc") ;
6577       mri_cma = MRIread(fname) ;
6578       if (mri_cma)
6579       {
6580 
6581         lcma = gcaGibbsImageLogLikelihood(gca, mri_cma,
6582                                           mri_inputs, transform) ;
6583         lcma /= (double)(width*depth*height) ;
6584         fprintf(stdout, "image ll: %2.3f (CMA=%2.3f)\n", old_ll, lcma) ;
6585         MRIfree(&mri_cma) ;
6586       }
6587     }
6588   }
6589 #endif
6590   fflush(stdout) ;
6591 
6592   do
6593   {
6594     if (iter == 0)
6595     {
6596       mri_probs = GCAlabelProbabilities(mri_inputs,
6597                                         gca, mri_dst, transform) ;
6598       MRIorderIndices(mri_probs, x_indices, y_indices, z_indices) ;
6599       MRIfree(&mri_probs) ;
6600     }
6601     else
6602       MRIcomputeVoxelPermutation(mri_inputs, x_indices, y_indices,
6603                                  z_indices) ;
6604 
6605     nchanged = 0 ;
6606     for (index = 0 ; index < nindices ; index++)
6607     {
6608       x = x_indices[index] ;
6609       y = y_indices[index] ;
6610       z = z_indices[index] ;
6611       if (x == 155 && y == 126 && z == 128)
6612         DiagBreak() ;
6613 
6614 #if 1
6615       if (MRIvox(mri_changed, x, y, z) == 0)
6616         continue ;
6617 #endif
6618 
6619       if (x == 63 && y == 107 && z == 120)
6620         DiagBreak() ;
6621 
6622       val = MRIgetVoxVal(mri_inputs, x, y, z, 0) ;
6623 
6624       /* find the node associated with this coordinate and classify */
6625       if (!GCAsourceVoxelToNode(gca, mri_inputs,
6626                                 transform, x, y, z, &xn, &yn, &zn))
6627       {
6628         gcan = &gca->nodes[xn][yn][zn] ;
6629 
6630 
6631         label = old_label = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
6632         min_ll = gcaNbhdGibbsLogLikelihood(gca,
6633                                            mri_dst,
6634                                            mri_inputs,
6635                                            x, y,z,transform,
6636                                            PRIOR_FACTOR);
6637 
6638         for (n = 0 ; n < gcan->nlabels ; n++)
6639         {
6640           if (gcan->labels[n] == old_label)
6641             continue ;
6642           MRIsetVoxVal(mri_dst, x, y, z, 0, gcan->labels[n]) ;
6643           new_ll =
6644             gcaNbhdGibbsLogLikelihood(gca,
6645                                       mri_dst, mri_inputs,
6646                                       x, y,z,transform,
6647                                       PRIOR_FACTOR);
6648           if (new_ll > min_ll)
6649           {
6650             min_ll = new_ll ;
6651             label = gcan->labels[n] ;
6652           }
6653         }
6654         if (label != old_label)
6655         {
6656           nchanged++ ;
6657           MRIvox(mri_changed, x, y, z) = 1 ;
6658         }
6659         else
6660           MRIvox(mri_changed, x, y, z) = 0 ;
6661         MRIsetVoxVal(mri_dst, x, y, z, 0,label) ;
6662       }
6663     } // index loop
6664     if (nchanged > 10000)
6665     {
6666       ll = gcaGibbsImageLogLikelihood(gca, mri_dst, mri_inputs,
6667                                       transform) ;
6668       ll /= (double)(width*depth*height) ;
6669       if (!FZERO(lcma))
6670         printf("pass %d: %d changed. image ll: %2.3f (CMA=%2.3f)\n",
6671                iter+1, nchanged, ll, lcma) ;
6672       else
6673         printf("pass %d: %d changed. image ll: %2.3f\n",
6674                iter+1, nchanged, ll);
6675     }
6676     else
6677       printf("pass %d: %d changed.\n", iter+1, nchanged) ;
6678     MRIdilate(mri_changed, mri_changed) ;
6679   }
6680   while (nchanged > 0 && iter++ < max_iter) ;
6681 
6682   free(x_indices) ;
6683   free(y_indices) ;
6684   free(z_indices) ;
6685   MRIfree(&mri_changed) ;
6686 
6687   return(mri_dst) ;
6688 }
6689 
6690 char *gca_write_fname = NULL ;
6691 int gca_write_iterations = 0 ;
6692 
6693 #define MAX_PRIOR_FACTOR 1.0
6694 #define MIN_PRIOR_FACTOR 1
6695 
6696 MRI  *
6697 GCAreclassifyUsingGibbsPriors(MRI *mri_inputs,
6698                               GCA *gca,
6699                               MRI *mri_dst,
6700                               TRANSFORM *transform,
6701                               int max_iter, MRI *mri_fixed, int restart,
6702                               void (*update_func)(MRI *))
6703 {
6704   int      x, y, z, width, height, depth, label, val, iter,
6705   n, nchanged, min_changed, index, nindices, old_label, fixed , max_label ;
6706 short    *x_indices, *y_indices, *z_indices ;
6707 GCA_PRIOR *gcap ;
6708 double   ll, lcma = 0.0, old_ll, new_ll, max_ll ;
6709 MRI      *mri_changed, *mri_probs /*, *mri_zero */ ;
6710 
6711 // fixed is the label fixed volume, e.g. wm
6712 fixed = (mri_fixed != NULL) ;
6713 
6714 #if 0
6715   GCAannealUnlikelyVoxels(mri_inputs, gca, mri_dst, transform, max_iter*100,
6716                           mri_fixed) ;
6717   {
6718     char  fname[STRLEN], *cp ;
6719 
6720     strcpy(fname, mri_inputs->fname) ;
6721     cp = strrchr(fname, '/') ;
6722     if (cp)
6723     {
6724       strcpy(cp+1, "anneal") ;
6725       fprintf(stdout, "writing results of annealing to %s...\n", fname) ;
6726       MRIwrite(mri_dst, fname) ;
6727     }
6728   }
6729 #endif
6730 
6731   nindices = mri_dst->width * mri_dst->height * mri_dst->depth ;
6732   x_indices = (short *)calloc(nindices, sizeof(short)) ;
6733   y_indices = (short *)calloc(nindices, sizeof(short)) ;
6734   z_indices = (short *)calloc(nindices, sizeof(short)) ;
6735   if (!x_indices || !y_indices || !z_indices)
6736     ErrorExit(ERROR_NOMEMORY, "GCAreclassifyUsingGibbsPriors: "
6737               "could not allocate index set") ;
6738 
6739 
6740 #if 0
6741   mri_zero = MRIclone(mri_inputs, NULL) ;
6742 #endif
6743   width = mri_inputs->width ;
6744   height = mri_inputs->height;
6745   depth = mri_inputs->depth ;
6746   iter = 0 ;
6747   if (!mri_dst)
6748   {
6749     mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
6750     if (!mri_dst)
6751       ErrorExit(ERROR_NOMEMORY, "GCAlabel: could not allocate dst") ;
6752     MRIcopyHeader(mri_inputs, mri_dst) ;
6753   }
6754 
6755   mri_changed = MRIclone(mri_dst, NULL) ;
6756 
6757   /* go through each voxel in the input volume and find the canonical
6758      voxel (and hence the classifier) to which it maps. Then update the
6759      classifiers statistics based on this voxel's intensity and label.
6760   */
6761   // mark changed location
6762   for (x = 0 ; x < width ; x++)
6763     for (y = 0 ; y < height ; y++)
6764       for (z = 0 ; z < depth ; z++)
6765       {
6766         if (restart && mri_fixed)
6767         {
6768           // mark only fixed voxels
6769           if (MRIvox(mri_fixed, x, y, z))
6770             MRIvox(mri_changed,x,y,z) = 1 ;
6771         }
6772         else
6773           // everything is marked
6774           MRIvox(mri_changed,x,y,z) = 1 ;
6775       }
6776 
6777   if (restart && mri_fixed)
6778     MRIdilate(mri_changed, mri_changed) ;
6779 
6780   if (!restart)
6781   {
6782     // calculate the statistics
6783     old_ll = gcaGibbsImageLogLikelihood(gca, mri_dst,
6784                                         mri_inputs, transform) ;
6785     // get the per voxel value
6786     old_ll /= (double)(width*depth*height) ;
6787   }
6788   else
6789     old_ll = 0 ;
6790 
6791 #if 0
6792   if (0)
6793   {
6794     MRI   *mri_cma ;
6795     char  fname[STRLEN], *cp ;
6796 
6797     strcpy(fname, mri_inputs->fname) ;
6798     cp = strrchr(fname, '/') ;
6799     if (cp)
6800     {
6801       strcpy(cp+1, "parc") ;
6802       mri_cma = MRIread(fname) ;
6803       if (mri_cma)
6804       {
6805         lcma = gcaGibbsImageLogLikelihood(gca, mri_cma,
6806                                           mri_inputs, transform) ;
6807         lcma /= (double)(width*depth*height) ;
6808         fprintf(stdout, "image ll: %2.3f (CMA=%2.3f)\n", old_ll, lcma) ;
6809         MRIfree(&mri_cma) ;
6810       }
6811     }
6812   }
6813 #endif
6814 
6815   PRIOR_FACTOR = MIN_PRIOR_FACTOR ;
6816   do
6817   {
6818     if (restart)
6819     {
6820       for (index = x = 0 ; x < width ; x++)
6821         for (y = 0 ; y < height ; y++)
6822           for (z = 0 ; z < depth ; z++)
6823           {
6824             // not fixed voxel, but changed
6825             if (MRIvox(mri_fixed, x, y, z) == 0 &&
6826                 (MRIvox(mri_changed,x,y,z) > 0))
6827             {
6828               x_indices[index] = x ;
6829               y_indices[index] = y ;
6830               z_indices[index] = z ;
6831               index++ ;
6832             }
6833           }
6834       nindices = index ;
6835     }
6836     else if (iter == 0)
6837     {
6838       /*      char  fname[STRLEN], *cp ;*/
6839       /*      int   nfixed ;*/
6840 
6841       if (gca_write_iterations)
6842       {
6843         char fname[STRLEN] ;
6844         sprintf(fname, "%s%03d.mgz", gca_write_fname, iter) ;
6845         printf("writing snapshot to %s...\n", fname) ;
6846         MRIwrite(mri_dst, fname) ;
6847       }
6848       // probs has 0 to 255 values
6849       mri_probs = GCAlabelProbabilities(mri_inputs, gca, NULL, transform) ;
6850       // sorted according to ascending order of probs
6851       MRIorderIndices(mri_probs, x_indices, y_indices, z_indices) ;
6852       MRIfree(&mri_probs) ;
6853     }
6854     else
6855       // randomize the indices value ((0 -> width*height*depth)
6856       MRIcomputeVoxelPermutation(mri_inputs, x_indices, y_indices,
6857                                  z_indices) ;
6858 
6859     ///////////////  relabel with neighborhood likelihood  //////////////
6860     nchanged = 0 ;
6861     if (G_write_probs && !mri_probs)
6862     {
6863       mri_probs = MRIalloc(mri_inputs->width, mri_inputs->height,
6864                            mri_inputs->depth, MRI_FLOAT) ;
6865       MRIcopyHeader(mri_inputs, mri_probs) ;
6866     }
6867     for (index = 0 ; index < nindices ; index++)
6868     {
6869       x = x_indices[index] ;
6870       y = y_indices[index] ;
6871       z = z_indices[index] ;
6872       if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
6873         DiagBreak() ;
6874 
6875       // if the label is fixed, don't do anything
6876       if (mri_fixed && MRIvox(mri_fixed, x, y, z))
6877         continue ;
6878 
6879       // if not marked, don't do anything
6880       if (MRIvox(mri_changed, x, y, z) == 0)
6881         continue ;
6882 
6883       // get the grey value
6884       val = MRIgetVoxVal(mri_inputs, x, y, z, 0) ;
6885 
6886       /* find the node associated with this coordinate and classify */
6887       gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
6888       // it is not in the right place
6889       if (gcap==NULL)
6890         continue;
6891       // only one label associated, don't do anything
6892       if (gcap->nlabels == 1)
6893         continue ;
6894 
6895       // save the current label
6896       label = old_label = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
6897       // calculate neighborhood likelihood
6898       max_ll = gcaNbhdGibbsLogLikelihood(gca, mri_dst,
6899                                          mri_inputs, x, y,z,transform,
6900                                          PRIOR_FACTOR);
6901 
6902       // go through all labels at this point
6903       for (n = 0 ; n < gcap->nlabels ; n++)
6904       {
6905         // skip the current label
6906         if (gcap->labels[n] == old_label)
6907           continue ;
6908         // assign the new label
6909         MRIsetVoxVal(mri_dst, x, y, z, 0,gcap->labels[n]) ;
6910         // calculate neighborhood likelihood
6911         new_ll =
6912           gcaNbhdGibbsLogLikelihood(gca, mri_dst,
6913                                     mri_inputs, x, y,z,transform,
6914                                     PRIOR_FACTOR);
6915         // if it is bigger than the old one, then replace the label
6916         // and change max_ll
6917         if (new_ll > max_ll)
6918         {
6919           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
6920               (label == Ggca_label || old_label ==
6921                Ggca_label || Ggca_label < 0))
6922             fprintf(stdout,
6923                     "NbhdGibbsLogLikelihood at (%d, %d, %d):"
6924                     " old = %d (ll=%.2f) new = %d (ll=%.2f)\n",
6925                     x, y, z, old_label, max_ll,
6926                     gcap->labels[n], new_ll);
6927 
6928           max_ll = new_ll ;
6929           label = gcap->labels[n] ;
6930         }
6931       }
6932 
6933       /*#ifndef __OPTIMIZE__*/
6934       if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
6935           (label == Ggca_label || old_label ==
6936            Ggca_label || Ggca_label < 0))
6937       {
6938         int       xn, yn, zn ;
6939         GCA_NODE *gcan ;
6940 
6941         if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
6942                                   x, y, z, &xn, &yn, &zn))
6943         {
6944           gcan = &gca->nodes[xn][yn][zn] ;
6945           printf("(%d, %d, %d): old label %s (%d), "
6946                  "new label %s (%d) (log(p)=%2.3f)\n",
6947                  x, y, z, cma_label_to_name(old_label), old_label,
6948                  cma_label_to_name(label), label, max_ll) ;
6949           dump_gcan(gca, gcan, stdout, 0, gcap) ;
6950           if (label == Right_Caudate)
6951             DiagBreak() ;
6952         }
6953       }
6954       /*#endif*/
6955 
6956       // if label changed
6957       if (label != old_label)
6958       {
6959         nchanged++ ;
6960         // mark it as changed
6961         MRIvox(mri_changed, x, y, z) = 1 ;
6962       }
6963       else
6964         MRIvox(mri_changed, x, y, z) = 0 ;
6965       // assign new label
6966       MRIsetVoxVal(mri_dst, x, y, z, 0, label) ;
6967       if (mri_probs)
6968         MRIsetVoxVal(mri_probs, x, y, z, 0, -max_ll) ;
6969     }
6970     if (mri_probs)
6971     {
6972       char fname[STRLEN] ;
6973 
6974       sprintf(fname, "%s%03d.mgz", G_write_probs, iter) ;
6975       printf("writing probabilities to %s...\n", fname) ;
6976       MRIwrite(mri_probs, fname) ;
6977       MRIfree(&mri_probs) ;
6978     }
6979 
6980     if (0)
6981       // reclassify connected compontents of unlikely labels as a whole
6982     {
6983       MRI_SEGMENTATION *mriseg ;
6984       MRI              *mri_impossible, *mri_impossible_label ;
6985       int              label, s, nchanged, iter ;
6986       char             fname[STRLEN] ;
6987       double           old_ll, new_ll ;
6988 
6989       max_label = GCAmaxLabel(gca) ;
6990       old_ll = gcaGibbsImageLogLikelihood(gca, mri_dst,
6991                                           mri_inputs,
6992                                           transform)/(double)
6993                (width*depth*height) ;
6994       iter = 0 ;
6995       printf("%02d: ll %2.5f\n", iter, old_ll) ;
6996 
6997       do
6998       {
6999         nchanged = 0 ;
7000         mri_impossible =
7001           GCAmarkImpossible(gca, mri_dst, NULL, transform) ;
7002         if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
7003           MRIwrite(mri_impossible, "imp.mgz") ;
7004         mri_impossible_label = MRIclone(mri_impossible, NULL) ;
7005         if (gca_write_iterations > 0)
7006         {
7007           char fname[STRLEN] ;
7008           static int fno = 0 ;
7009 
7010           sprintf(fname, "%s_before%03d.mgz",
7011                   gca_write_fname, fno+1) ;
7012           fno++ ;
7013           printf("writing snapshot to %s...\n", fname) ;
7014           MRIwrite(mri_dst, fname) ;
7015         }
7016         for (label = 1 ; label <= max_label ; label++)
7017         {
7018           MRIclear(mri_impossible_label) ;
7019 
7020           // find voxels that have label and aren't possible
7021           if (MRIcopyLabeledVoxels(mri_impossible,
7022                                    mri_dst,
7023                                    mri_impossible_label,
7024                                    label) == 0)
7025             continue ;  // no voxels in label
7026 
7027           sprintf(fname, "mimp_label%d.mgz", label) ;
7028           if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
7029             MRIwrite(mri_impossible_label, fname) ;
7030           mriseg = MRIsegment(mri_impossible_label, 0.5, 256) ;
7031 
7032           if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
7033             printf("%d low probability segments "
7034                    "found for label %s (%d)...\n",
7035                    mriseg->nsegments, cma_label_to_name(label),
7036                    label) ;
7037 
7038           for (s = 0 ; s < mriseg->nsegments ; s++)
7039           {
7040             if (gcaRelabelSegment(gca, transform, mri_inputs,
7041                                   mri_dst, &mriseg->segments[s]) > 0)
7042             {
7043               MRIsetSegmentValue(mri_changed, mriseg, s, 1) ;
7044               nchanged++ ;
7045             }
7046           }
7047           MRIsegmentFree(&mriseg) ;
7048         }
7049         MRIfree(&mri_impossible_label) ;
7050         MRIfree(&mri_impossible) ;
7051         new_ll = gcaGibbsImageLogLikelihood(gca,
7052                                             mri_dst, mri_inputs,
7053                                             transform)/
7054                  (double)(width*depth*height);
7055         printf("%02d: ll %2.5f (%d segments changed)\n",
7056                iter+1, new_ll, nchanged) ;
7057       }
7058       while ((nchanged > 0) && (iter++ < 10));
7059     }
7060 
7061     /////////////////////////////////////////////////////////////////////////
7062     // print info
7063     if (nchanged > 10000 && iter < 2 && !restart)
7064     {
7065       ll = gcaGibbsImageLogLikelihood(gca, mri_dst,
7066                                       mri_inputs, transform) ;
7067       // get the average value
7068       ll /= (double)(width*depth*height) ;
7069       if (!FZERO(lcma))
7070         printf("pass %d: %d changed. image ll: %2.3f "
7071                "(CMA=%2.3f), PF=%2.3f\n",
7072                iter+1, nchanged, ll, lcma, PRIOR_FACTOR) ;
7073       else // currently this is executed
7074         printf("pass %d: %d changed. image ll: %2.3f, PF=%2.3f\n",
7075                iter+1, nchanged, ll, PRIOR_FACTOR) ;
7076     }
7077     else
7078       printf("pass %d: %d changed.\n", iter+1, nchanged) ;
7079 
7080     // get the largest 6 neighbor values,
7081     // that is, originally 0 could become 1
7082     MRIdilate(mri_changed, mri_changed) ;
7083     // if unpdate_func is present, use it
7084     if (update_func)
7085       (*update_func)(mri_dst) ;
7086 
7087 #if 0
7088     if (!iter && DIAG_VERBOSE_ON)
7089     {
7090       char  fname[STRLEN], *cp ;
7091       /*      int   nvox ;*/
7092 
7093       strcpy(fname, mri_inputs->fname) ;
7094       cp = strrchr(fname, '/') ;
7095       if (cp)
7096       {
7097         strcpy(cp+1, "zero") ;
7098         nvox = MRIvoxelsInLabel(mri_zero, 255) ;
7099         fprintf(stdout, "writing %d low probability points to %s...\n",
7100                 nvox, fname) ;
7101         MRIwrite(mri_zero, fname) ;
7102         MRIfree(&mri_zero) ;
7103       }
7104     }
7105 #endif
7106 #define MIN_CHANGED 5000
7107     min_changed = restart ? 0 : MIN_CHANGED ;
7108     if (nchanged <= min_changed ||
7109         (restart && iter >= max_iter))
7110     {
7111       if (restart)
7112         iter = 0 ;
7113 #if 0
7114       if (restart)
7115         break ;
7116 #endif
7117 
7118       if (!restart)  /* examine whole volume next time */
7119       {
7120         for (x = 0 ; x < width ; x++)
7121           for (y = 0 ; y < height ; y++)
7122             for (z = 0 ; z < depth ; z++)
7123               MRIvox(mri_changed,x,y,z) = 1 ;
7124       }
7125       if (fixed && !restart)
7126       {
7127         printf("removing fixed flag...\n") ;
7128         if (mri_fixed)
7129           MRIclear(mri_fixed) ;
7130         fixed = 0 ;
7131     }
7132     else
7133     {
7134       PRIOR_FACTOR *= 2 ;
7135       if (PRIOR_FACTOR < MAX_PRIOR_FACTOR)
7136           fprintf(stdout, "setting PRIOR_FACTOR to %2.4f\n",
7137                   PRIOR_FACTOR) ;
7138       }
7139       if (gca_write_iterations > 0)
7140       {
7141         char fname[STRLEN] ;
7142 
7143         sprintf(fname, "%s_iter%d.mgz", gca_write_fname, iter+1) ;
7144         printf("writing snapshot to %s...\n", fname) ;
7145         MRIwrite(mri_dst, fname) ;
7146       }
7147     }
7148     if ((gca_write_iterations > 0) && !(iter % gca_write_iterations))
7149     {
7150       char fname[STRLEN] ;
7151       sprintf(fname, "%s%03d.mgz", gca_write_fname, iter+1) ;
7152       printf("writing snapshot to %s...\n", fname) ;
7153       MRIwrite(mri_dst, fname) ;
7154     }
7155   }
7156   while ((nchanged > MIN_CHANGED || PRIOR_FACTOR < MAX_PRIOR_FACTOR) &&
7157          (iter++ < max_iter)) ;
7158 
7159 #if 0
7160   {
7161     char  fname[STRLEN], *cp ;
7162     int   nzero, n_nonzero ;
7163 
7164     strcpy(fname, mri_inputs->fname) ;
7165     cp = strrchr(fname, '/') ;
7166     if (cp)
7167     {
7168       strcpy(cp+1, "indices") ;
7169       mri_probs = GCAcomputeProbabilities(mri_inputs, gca,
7170                                           mri_dst,NULL, transform) ;
7171       MRIorderIndices(mri_probs, x_indices, y_indices, z_indices) ;
7172       for (nzero = index = 0 ; index < nindices ; index++, nzero++)
7173       {
7174         x = x_indices[index] ;
7175         y = y_indices[index] ;
7176         z = z_indices[index] ;
7177         if (MRIvox(mri_probs, x, y, z) != 255)
7178           break ;
7179         MRIvox(mri_probs, x, y, z) = 0 ;
7180       }
7181       n_nonzero = nindices - nzero ;
7182       for ( ; index < nindices ; index++)
7183       {
7184         x = x_indices[index] ;
7185         y = y_indices[index] ;
7186         z = z_indices[index] ;
7187         if (MRIvox(mri_probs, x, y, z) == 255)
7188           MRIvox(mri_probs, x, y, z) = 0 ;
7189         else
7190         {
7191           MRIvox(mri_probs, x, y, z) =
7192             100 * (float)(n_nonzero-index)/n_nonzero ;
7193         }
7194       }
7195       MRIwrite(mri_probs, fname) ;
7196     }
7197   }
7198 #endif
7199 
7200 
7201 
7202   if (mri_probs)
7203     MRIfree(&mri_probs) ;
7204 
7205   free(x_indices) ;
7206   free(y_indices) ;
7207   free(z_indices) ;
7208   MRIfree(&mri_changed) ;
7209 
7210   return(mri_dst) ;
7211 }
7212 int
7213 MRIcomputeVoxelPermutation(MRI *mri, short *x_indices, short *y_indices,
7214                            short *z_indices)
7215 {
7216   int width, height, depth, tmp, nindices, i, index ;
7217 
7218   width = mri->width, height = mri->height ;
7219   depth = mri->depth ;
7220   nindices = width*height*depth ;
7221 
7222   for (i = 0 ; i < nindices ; i++)
7223   {
7224     x_indices[i] = i % width ;
7225     y_indices[i] = (i/width) % height ;
7226     z_indices[i] = (i / (width*height)) % depth ;
7227   }
7228   for (i = 0 ; i < nindices ; i++)
7229   {
7230     index = (int)randomNumber(0.0, (double)(nindices-0.0001)) ;
7231 
7232     tmp = x_indices[index] ;
7233     x_indices[index] = x_indices[i] ;
7234     x_indices[i] = tmp ;
7235 
7236     tmp = y_indices[index] ;
7237     y_indices[index] = y_indices[i] ;
7238     y_indices[i] = tmp ;
7239 
7240     tmp = z_indices[index] ;
7241     z_indices[index] = z_indices[i] ;
7242     z_indices[i] = tmp ;
7243   }
7244   return(NO_ERROR) ;
7245 }
7246 
7247 #if 0
7248 static int
7249 gcaGibbsSort(GCA *gca, MRI *mri_labels, MRI *mri_inputs,
7250              TRANSFORM *transform)
7251 {
7252   int    x, y, z, width, depth, height ;
7253   double total_log_likelihood, log_likelihood ;
7254   MRI    *mri_probs ;
7255 
7256   width = mri_labels->width ;
7257   height = mri_labels->height ;
7258   depth = mri_labels->depth ;
7259   mri_probs = MRIclone(mri_labels, NULL) ;
7260 
7261   for (total_log_likelihood = 0.0, x = 0 ; x < width ; x++)
7262   {
7263     for (y = 0 ; y < height ; y++)
7264     {
7265       for (z = 0 ; z < depth ; z++)
7266       {
7267         log_likelihood =
7268           gcaVoxelGibbsLogLikelihood(gca, mri_labels,
7269                                      mri_inputs, x, y, z,transform,
7270                                      PRIOR_FACTOR);
7271         log_likelihood *= 20 ;
7272         if (log_likelihood > 255)
7273           log_likelihood = 255 ;
7274         MRIvox(mri_probs,x,y,z) = log_likelihood ;
7275         total_log_likelihood += log_likelihood ;
7276       }
7277     }
7278   }
7279   MRIorderIndices(mri_probs, x_indices, y_indices, z_indices) ;
7280   MRIfree(&mri_probs) ;
7281   return(NO_ERROR) ;
7282 }
7283 #endif
7284 
7285 static double
7286 gcaGibbsImageLogLikelihood(GCA *gca, MRI *mri_labels, MRI *mri_inputs,
7287                            TRANSFORM *transform)
7288 {
7289   int    x, y, z, width, depth, height ;
7290   double total_log_likelihood, log_likelihood ;
7291 
7292   width = mri_labels->width ;
7293   height = mri_labels->height ;
7294   depth = mri_labels->depth ;
7295 
7296   for (total_log_likelihood = 0.0, x = 0 ; x < width ; x++)
7297   {
7298     for (y = 0 ; y < height ; y++)
7299     {
7300       for (z = 0 ; z < depth ; z++)
7301       {
7302         log_likelihood =
7303           gcaVoxelGibbsLogLikelihood(gca, mri_labels,
7304                                      mri_inputs, x, y, z,transform,
7305                                      PRIOR_FACTOR);
7306         if (check_finite("gcaGibbsImageLoglikelihood",
7307                          log_likelihood) == 0)
7308           DiagBreak() ;
7309         total_log_likelihood += log_likelihood ;
7310         if (total_log_likelihood > 1e10)
7311           DiagBreak() ;
7312       }
7313     }
7314   }
7315   return(total_log_likelihood) ;
7316 }
7317 static double
7318 gcaGibbsImpossibleConfiguration(GCA *gca, MRI *mri_labels,
7319                                 int x, int y, int z, TRANSFORM *transform)
7320 {
7321   int       xn, yn, zn, xnbr, ynbr, znbr, nbr_label, label, i,j, n;
7322   GCA_NODE  *gcan ;
7323   GC1D      *gc ;
7324 
7325   label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
7326 
7327   /* find the node associated with this coordinate and classify */
7328   if (!GCAsourceVoxelToNode(gca, mri_labels, transform,
7329                             x, y, z, &xn, &yn, &zn))
7330   {
7331     gcan = &gca->nodes[xn][yn][zn] ;
7332 
7333     for (n = 0 ; n < gcan->nlabels ; n++)
7334     {
7335       if (gcan->labels[n] == label)
7336         break ;
7337     }
7338     if (n >= gcan->nlabels)
7339       return(1) ;  /* never occurred */
7340 
7341     gc = &gcan->gcs[n] ;
7342 
7343     for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
7344     {
7345       xnbr = mri_labels->xi[x+xnbr_offset[i]] ;
7346       ynbr = mri_labels->yi[y+ynbr_offset[i]] ;
7347       znbr = mri_labels->zi[z+znbr_offset[i]] ;
7348       nbr_label = nint(MRIgetVoxVal(mri_labels, xnbr, ynbr, znbr,0)) ;
7349       for (j = 0 ; j < gc->nlabels[i] ; j++)
7350       {
7351         if (nbr_label == gc->labels[i][j])
7352           break ;
7353       }
7354       if (j < gc->nlabels[i])
7355       {
7356         if (FZERO(gc->label_priors[i][j]))
7357           return(1) ; /* never occurred (and this never should) */
7358       }
7359       else   /* never occurred - make it unlikely */
7360       {
7361         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
7362           DiagBreak() ;
7363         if (FZERO(gc->label_priors[i][j]))
7364           return(1) ; /* never occurred (and this never should) */
7365       }
7366     }
7367   }
7368   return(0) ;
7369 }
7370 
7371 
7372 static double
7373 gcaNbhdGibbsLogLikelihood(GCA *gca,
7374                           MRI *mri_labels,
7375                           MRI *mri_inputs,
7376                           int x, int y, int z,
7377                           TRANSFORM *transform,
7378                           double gibbs_coef)
7379 {
7380   double total_log_likelihood/*, log_likelihood*/ ;
7381   /*  int    i, xnbr, ynbr, znbr ;*/
7382 
7383 
7384   total_log_likelihood =
7385     gcaVoxelGibbsLogLikelihood(gca, mri_labels, mri_inputs, x, y, z, transform,
7386                                gibbs_coef) ;
7387 
7388 #if 0
7389   for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
7390   {
7391     xnbr = mri_inputs->xi[x+xnbr_offset[i]] ;
7392     ynbr = mri_inputs->yi[y+ynbr_offset[i]] ;
7393     znbr = mri_inputs->zi[z+znbr_offset[i]] ;
7394     log_likelihood =
7395       gcaVoxelGibbsLogLikelihood(gca, mri_labels, mri_inputs, xnbr, ynbr,
7396                                  znbr, transform, gibbs_coef) ;
7397     total_log_likelihood += log_likelihood ;
7398   }
7399 #endif
7400 
7401   if (check_finite("gcaNbhdGibbsLogLikelihood: final",
7402                    total_log_likelihood)  == 0)
7403     DiagBreak() ;
7404 
7405   return(total_log_likelihood) ;
7406 }
7407 
7408 static double
7409 gcaVoxelGibbsLogLikelihood(GCA *gca,
7410                            MRI *mri_labels,
7411                            MRI *mri_inputs,
7412                            int x, int y, int z,
7413                            TRANSFORM *transform,
7414                            double gibbs_coef)
7415 {
7416   double    log_likelihood/*, dist*/, nbr_prior ;
7417   int       xn, yn, zn, xnbr, ynbr, znbr, nbr_label, label,
7418   i,j, n;
7419   GCA_NODE  *gcan =0;
7420   GCA_PRIOR *gcap =0;
7421   GC1D      *gc =0;
7422   float     vals[MAX_GCA_INPUTS] ;
7423 #if INTERP_PERIOR
7424   float       prior ;
7425 #endif
7426   // float     tmp = 0;
7427 
7428   // signify error
7429   log_likelihood = 0.;
7430 
7431   // get the grey value
7432   load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
7433   // get the label
7434   label = nint(MRIgetVoxVal(mri_labels, x, y, z,0)) ;
7435   // what happens with higher number > CMA_MAX?
7436   /* find the node associated with this coordinate and classify */
7437   if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
7438                             x, y, z, &xn, &yn, &zn))
7439   {
7440     gcan = &gca->nodes[xn][yn][zn] ;
7441     gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
7442     if (gcap == NULL || gcap->nlabels <= 0)
7443     {
7444       if (label == Unknown)  // okay for there to be an
7445         // unknown label out of the fov
7446         return(0.0) ;
7447       else
7448         return (10*BIG_AND_NEGATIVE);
7449     }
7450 
7451     ////////////////// debug code (this should not occur ) /////////
7452     if (label > MAX_CMA_LABEL)
7453     {
7454       printf("\ngcaVoxelGibbsLogLikelihood() is called "
7455              "with label %d at (%d, %d, %d)\n", label, x, y, z);
7456       printf("gcan = %p, gcap = %p\n", gcan, gcap);
7457       if (gcan)
7458       {
7459         printf("gcan->nlabels = %d, gcan->total_training = %d ",
7460                gcan->nlabels, gcan->total_training);
7461         printf("log(return) = %.2f\n",
7462                log(0.01f/((float)
7463                           gcan->total_training*GIBBS_NEIGHBORS)));
7464         printf("labels for this location\n");
7465         for (n=0; n < gcan->nlabels; n++)
7466           printf("label=%s (%d); ",
7467                  cma_label_to_name(gcan->labels[n]), gcan->labels[n]);
7468       }
7469     }
7470     /////////////////////////////////////////////////////////////////
7471     for (n = 0 ; n < gcan->nlabels ; n++)
7472     {
7473       if (gcan->labels[n] == label)
7474         break ;
7475     }
7476     // could not find the label, then
7477     if (n >= gcan->nlabels)
7478     {
7479       // if (gcan->total_training > 0)
7480       // return(log(0.01f/((float)gcan->total_training*GIBBS_NEIGHBORS))) ;
7481       /* 10*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE*/
7482       // else
7483       return (10*BIG_AND_NEGATIVE);
7484       //return(log(VERY_UNLIKELY)) ;
7485     }
7486 
7487     gc = &gcan->gcs[n] ;
7488 
7489     /* compute 1-d Mahalanobis distance */
7490     log_likelihood =
7491       GCAcomputeConditionalLogDensity(gc,vals,gca->ninputs, gcan->labels[n]);
7492     if (check_finite("gcaVoxelGibbsLogLikelihood: conditional log density",
7493                      log_likelihood) == 0)
7494       DiagBreak() ;
7495 
7496     nbr_prior = 0.0 ;
7497     for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
7498     {
7499       xnbr = mri_labels->xi[x+xnbr_offset[i]] ;
7500       ynbr = mri_labels->yi[y+ynbr_offset[i]] ;
7501       znbr = mri_labels->zi[z+znbr_offset[i]] ;
7502       nbr_label = nint(MRIgetVoxVal(mri_labels, xnbr, ynbr, znbr,0)) ;
7503       for (j = 0 ; j < gc->nlabels[i] ; j++)
7504       {
7505         if (nbr_label == gc->labels[i][j])
7506           break ;
7507       }
7508       if (j < gc->nlabels[i])
7509       {
7510         if (!FZERO(gc->label_priors[i][j]))
7511           nbr_prior += log(gc->label_priors[i][j]) ;
7512         else
7513           nbr_prior += log(0.1f/(float)gcan->total_training) ;
7514         /*BIG_AND_NEGATIVE */
7515         check_finite("gcaVoxelGibbsLogLikelihood: label_priors",
7516                      nbr_prior) ;
7517       }
7518       else   /* never occurred - make it unlikely */
7519       {
7520         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
7521           DiagBreak() ;
7522         nbr_prior += log(0.1f/(float)gcan->total_training) ;
7523         /*BIG_AND_NEGATIVE*/
7524       }
7525     }
7526     // added to the previous value
7527 #if INTERP_PRIOR
7528     prior = gcaComputePrior(gca, mri_inputs, transform, x, y, z, label) ;
7529     log_likelihood += (gibbs_coef * nbr_prior + log(prior)) ;
7530 #else
7531     log_likelihood += (gibbs_coef * nbr_prior + log(getPrior(gcap, label))) ;
7532 #endif
7533     if (check_finite("gcaVoxelGibbsLogLikelihood: final",
7534                      log_likelihood)  == 0)
7535       DiagBreak() ;
7536   }
7537   else
7538   {
7539     return (10*BIG_AND_NEGATIVE);
7540     // return (log(VERY_UNLIKELY)) ;
7541   }
7542 
7543   // just check
7544 #if 0
7545   tmp = log(0.01f/((float) gcan->total_training*GIBBS_NEIGHBORS));
7546   if (tmp > log_likelihood)
7547   {
7548     printf("gcaVoxelLogLikelihood: (%d, %d, %d)\n", x, y, z);
7549     printf("label %s(%d) log_likelihood %.2f is less"
7550            " than no label found %.2f\n",
7551            cma_label_to_name(label), label, log_likelihood, tmp);
7552   }
7553 #endif
7554   return(log_likelihood) ;
7555 }
7556 // the likelihood of an image given a segmentation without any MRF
7557 double
7558 GCAimagePosteriorLogProbability(GCA *gca, MRI *mri_labels, MRI *mri_inputs, TRANSFORM *transform)
7559 {
7560   double  log_likelihood ;
7561   int     x, y, z, num = 0 ;
7562 
7563   for (log_likelihood = 0.0, x = 0 ; x < mri_labels->width ; x++)
7564     for (y = 0 ; y < mri_labels->height ; y++)
7565       for (z = 0 ; z < mri_labels->depth ; z++)
7566       {
7567         if (x == Gx && y == Gy && z == Gz)
7568           DiagBreak() ;
7569         if ((int)MRIgetVoxVal(mri_labels, x, y, z, 0) == 0)
7570           continue ;
7571         log_likelihood += gcaVoxelLogLikelihood(gca, 
7572                                                 mri_labels, 
7573                                                 mri_inputs, 
7574                                                 x, y, z, 
7575                                                 transform);
7576         num++ ;
7577         if (!finite(log_likelihood))
7578           DiagBreak() ;
7579       }
7580   return(log_likelihood/(float)num) ;
7581 }
7582 
7583 static double
7584 gcaVoxelLogLikelihood(GCA *gca,
7585                       MRI *mri_labels,
7586                       MRI *mri_inputs,
7587                       int x, int y, int z,
7588                       TRANSFORM *transform)
7589 {
7590   double    log_likelihood/*, dist*/ ;
7591   int       xn, yn, zn, label, n;
7592   GCA_NODE  *gcan =0;
7593   GCA_PRIOR *gcap =0;
7594   GC1D      *gc =0;
7595   float     vals[MAX_GCA_INPUTS] ;
7596 #if INTERP_PERIOR
7597   float       prior ;
7598 #endif
7599   // float     tmp = 0;
7600 
7601   // signify error
7602   log_likelihood = 0.;
7603 
7604   load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ; // get the grey value
7605   label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ; // get the label
7606   // what happens with higher number > CMA_MAX?
7607   /* find the node associated with this coordinate and classify */
7608   if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
7609                             x, y, z, &xn, &yn, &zn))
7610   {
7611     gcan = &gca->nodes[xn][yn][zn] ;
7612     gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
7613     if (gcap == NULL || gcap->nlabels <= 0)
7614     {
7615       if (label == Unknown)  // okay for there to be an
7616         return(0.0) ; // unknown label out of the fov
7617       else
7618         return (10*BIG_AND_NEGATIVE);
7619     }
7620 
7621     ////////////////// debug code (this should not occur ) /////////
7622     if (label > MAX_CMA_LABEL)
7623     {
7624       printf("\ngcaVoxelGibbsLogLikelihood() is called "
7625              "with label %d at (%d, %d, %d)\n", label, x, y, z);
7626       printf("gcan = %p, gcap = %p\n", gcan, gcap);
7627       if (gcan)
7628       {
7629         printf("gcan->nlabels = %d, gcan->total_training = %d ",
7630                gcan->nlabels, gcan->total_training);
7631         printf("log(return) = %.2f\n",
7632                log(0.01f/((float)
7633                           gcan->total_training*GIBBS_NEIGHBORS)));
7634         printf("labels for this location\n");
7635         for (n=0; n < gcan->nlabels; n++)
7636           printf("label=%s (%d); ",
7637                  cma_label_to_name(gcan->labels[n]), gcan->labels[n]);
7638       }
7639     }
7640     /////////////////////////////////////////////////////////////////
7641     for (n = 0 ; n < gcan->nlabels ; n++)
7642     {
7643       if (gcan->labels[n] == label)
7644         break ;
7645     }
7646     // could not find the label, then
7647     if (n >= gcan->nlabels)
7648     {
7649       // if (gcan->total_training > 0)
7650       // return(log(0.01f/((float)gcan->total_training*GIBBS_NEIGHBORS))) ;
7651       /* 10*GIBBS_NEIGHBORS*BIG_AND_NEGATIVE*/
7652       // else
7653       return (10*BIG_AND_NEGATIVE);
7654       //return(log(VERY_UNLIKELY)) ;
7655     }
7656 
7657     gc = &gcan->gcs[n] ;
7658 
7659     /* compute 1-d Mahalanobis distance */
7660     log_likelihood =
7661       GCAcomputeConditionalLogDensity(gc,vals,gca->ninputs, gcan->labels[n]);
7662     if (check_finite("gcaVoxelGibbsLogLikelihood: conditional log density",
7663                      log_likelihood) == 0)
7664       DiagBreak() ;
7665 
7666     // added to the previous value
7667 #if INTERP_PRIOR
7668     prior = gcaComputePrior(gca, mri_inputs, transform, x, y, z, label) ;
7669     log_likelihood += (log(prior)) ;
7670 #else
7671     log_likelihood += (log(getPrior(gcap, label))) ;
7672 #endif
7673     if (check_finite("gcaVoxelGibbsLogLikelihood: final",
7674                      log_likelihood)  == 0)
7675       DiagBreak() ;
7676   }
7677   else
7678   {
7679     return (10*BIG_AND_NEGATIVE);
7680     // return (log(VERY_UNLIKELY)) ;
7681   }
7682 
7683   return(log_likelihood) ;
7684 }
7685 
7686 static int compare_sort_mri(const void *plp1, const void *plp2);
7687 typedef struct
7688 {
7689   unsigned char x, y, z, val ;
7690 }
7691 SORT_VOXEL ;
7692 
7693 static int
7694 MRIorderIndices(MRI *mri, short *x_indices, short *y_indices, short *z_indices)
7695 {
7696   int         width, height, depth, nindices, index, x, y, z ;
7697   SORT_VOXEL  *sort_voxels ;
7698 
7699   width = mri->width, height = mri->height ;
7700   depth = mri->depth ;
7701   nindices = width*height*depth ;
7702 
7703   sort_voxels = (SORT_VOXEL *)calloc(nindices, sizeof(SORT_VOXEL)) ;
7704   if (!sort_voxels)
7705     ErrorExit(ERROR_NOMEMORY,"MRIorderIndices: could not allocate sort table");
7706 
7707   for (index = x = 0 ; x < width ; x++)
7708   {
7709     for (y = 0 ; y < height ; y++)
7710     {
7711       for (z = 0 ; z < depth ; z++, index++)
7712       {
7713         sort_voxels[index].x = x ;
7714         sort_voxels[index].y = y ;
7715         sort_voxels[index].z = z ;
7716         sort_voxels[index].val = MRIgetVoxVal(mri, x, y, z,0) ;
7717       }
7718     }
7719   }
7720   qsort(sort_voxels, nindices, sizeof(SORT_VOXEL), compare_sort_mri) ;
7721 
7722   for (index = 0 ; index < nindices ; index++)
7723   {
7724     x_indices[index] = sort_voxels[index].x ;
7725     y_indices[index] = sort_voxels[index].y ;
7726     z_indices[index] = sort_voxels[index].z ;
7727   }
7728 
7729   free(sort_voxels) ;
7730   return(NO_ERROR) ;
7731 }
7732 
7733 static int
7734 compare_sort_mri(const void *psv1, const void *psv2)
7735 {
7736   SORT_VOXEL  *sv1, *sv2 ;
7737 
7738   sv1 = (SORT_VOXEL *)psv1 ;
7739   sv2 = (SORT_VOXEL *)psv2 ;
7740 
7741   if (sv1->val > sv2->val)
7742     return(1) ;
7743   else if (sv1->val < sv2->val)
7744     return(-1) ;
7745 
7746   return(0) ;
7747 }
7748 
7749 MRI *
7750 GCAbuildMostLikelyVolume(GCA *gca, MRI *mri)
7751 {
7752   int       x,  y, z, xn, yn, zn, width, depth, height, n, xp, yp, zp, r ;
7753   GCA_NODE  *gcan ;
7754   GCA_PRIOR *gcap ;
7755   double    max_prior ;
7756   int       max_label ;
7757   GC1D      *gc_max ;
7758 
7759   if (!mri)
7760   {
7761     mri = MRIallocSequence(gca->prior_width, gca->prior_height,
7762                            gca->prior_depth, MRI_FLOAT, gca->ninputs) ;
7763     // hey create gca volume and thus copies gca prior values
7764     mri->xsize = gca->xsize*gca->prior_spacing ;
7765     mri->ysize = gca->ysize*gca->prior_spacing ;
7766     mri->zsize = gca->zsize*gca->prior_spacing ;
7767   }
7768   // most likely volume should agree with direction cosines
7769   GCAcopyDCToMRI(gca, mri);
7770 
7771   if (mri->nframes != gca->ninputs)
7772     ErrorExit(ERROR_BADPARM, "GCAbuildMostLikelyVolume: mri->frames "
7773               "(%d) does not match gca->ninputs (%d)",
7774               mri->nframes, gca->ninputs) ;
7775 
7776 
7777   // mri is prior if mri = NULL
7778   width = mri->width ;
7779   depth = mri->depth ;
7780   height = mri->height ;
7781   for (z = 0 ; z < depth ; z++)
7782   {
7783     for (y = 0 ; y < height ; y++)
7784     {
7785       for (x = 0 ; x < width ; x++)
7786       {
7787         if (x == Gx && y == Gy && z == Gz)
7788           DiagBreak() ;
7789         // get node value
7790         if (GCAvoxelToNode(gca, mri, x, y, z, &xn, &yn, &zn) == NO_ERROR)
7791         {
7792           // get prior value
7793           if (GCAvoxelToPrior(gca, mri, x, y, z,
7794                               &xp, &yp, &zp) == NO_ERROR)
7795           {
7796             gcan = &gca->nodes[xn][yn][zn] ;
7797             gcap = &gca->priors[xp][yp][zp] ;
7798             if (gcap==NULL || gcap->nlabels <= 0)
7799               continue;
7800             // initialize
7801             max_prior = gcap->priors[0] ;
7802             max_label = gcap->labels[0] ;
7803             gc_max = NULL ;
7804             // prior labels
7805             for (n = 1 ; n < gcap->nlabels ; n++)
7806             {
7807               if (gcap->priors[n] >= max_prior)
7808               {
7809                 max_prior = gcap->priors[n] ;
7810                 max_label = gcap->labels[n] ;
7811               }
7812             }
7813             // get max_prior, max_label
7814             // go through node labels
7815             for (n = 0 ; n < gcan->nlabels ; n++)
7816             {
7817               if (gcan->labels[n] == max_label)
7818                 gc_max = &gcan->gcs[n] ;
7819             }
7820 
7821             if (!gc_max)
7822               continue ;
7823             for (r = 0 ; r < gca->ninputs ; r++)
7824             {
7825               MRIsetVoxVal(mri, x, y, z, r, gc_max->means[r]) ;
7826             }
7827           }
7828           else
7829           {
7830             for (r = 0 ; r < gca->ninputs ; r++)
7831             {
7832               MRIsetVoxVal(mri, x, y, z, r, 0) ;
7833             }
7834           }
7835         }
7836         else
7837         {
7838           for (r = 0 ; r < gca->ninputs ; r++)
7839           {
7840             MRIsetVoxVal(mri, x, y, z, r, 0) ;
7841           }
7842         }
7843       }
7844     }
7845   }
7846 
7847   return(mri) ;
7848 }
7849 
7850 MRI *
7851 GCAbuildMostLikelyVolumeFrame(GCA *gca, MRI *mri, int frame)
7852 {
7853   int       x,  y, z, xn, yn, zn, width, depth, height, n, xp, yp, zp ;
7854   GCA_NODE  *gcan ;
7855   GCA_PRIOR *gcap ;
7856   double    max_prior ;
7857   int       max_label ;
7858   GC1D      *gc_max ;
7859 
7860   if (!mri)
7861   {
7862     mri = MRIallocSequence(gca->prior_width, gca->prior_height,
7863                            gca->prior_depth, MRI_FLOAT, 1) ;
7864     mri->xsize = gca->xsize*gca->prior_spacing;
7865     mri->ysize = gca->ysize*gca->prior_spacing;
7866     mri->zsize = gca->zsize*gca->prior_spacing;
7867   }
7868   // gca volume direction cosines must be copied
7869   GCAcopyDCToMRI(gca, mri);
7870 
7871   width = mri->width ;
7872   depth = mri->depth ;
7873   height = mri->height ;
7874 
7875   for (z = 0 ; z < depth ; z++)
7876   {
7877     for (y = 0 ; y < height ; y++)
7878     {
7879       for (x = 0 ; x < width ; x++)
7880       {
7881         if (x == Gx && y == Gy && z == Gz)
7882           DiagBreak() ;
7883         if (!GCAvoxelToNode(gca, mri, x, y, z, &xn, &yn, &zn))
7884           if (!GCAvoxelToPrior(gca, mri, x, y, z, &xp, &yp, &zp))
7885           {
7886             gcan = &gca->nodes[xn][yn][zn] ;
7887             gcap = &gca->priors[xp][yp][zp] ;
7888             if (gcap == NULL || gcap->nlabels <= 0)
7889               continue;
7890             if (gcap->nlabels ==0)
7891               continue;
7892             max_prior = gcap->priors[0] ;
7893             max_label = gcap->labels[0] ;
7894             gc_max = NULL ;
7895             for (n = 1 ; n < gcap->nlabels ; n++)
7896             {
7897               if (gcap->priors[n] >= max_prior)
7898               {
7899                 max_prior = gcap->priors[n] ;
7900                 max_label = gcap->labels[n] ;
7901               }
7902             }
7903             for (n = 0 ; n < gcan->nlabels ; n++)
7904             {
7905               if (gcan->labels[n] == max_label)
7906                 gc_max = &gcan->gcs[n] ;
7907             }
7908 
7909             if (!gc_max)
7910               continue ;
7911             MRIsetVoxVal(mri, x, y, z, 0, gc_max->means[frame]) ;
7912           }
7913       }
7914     }
7915   }
7916 
7917   return(mri) ;
7918 }
7919 
7920 GC1D *
7921 GCAfindPriorGC(GCA *gca, int xp, int yp, int zp,int label)
7922 {
7923   int xn, yn, zn ;
7924 
7925   if (!GCApriorToNode(gca, xp, yp, zp, &xn, &yn, &zn))
7926     return(GCAfindGC(gca, xn, yn, zn, label)) ;
7927   else
7928     return NULL;
7929 }
7930 
7931 #if 1
7932 GC1D *
7933 GCAfindGC(GCA *gca, int xn, int yn, int zn,int label)
7934 {
7935   int        n ;
7936   GCA_NODE   *gcan  ;
7937 
7938   gcan = &gca->nodes[xn][yn][zn] ;
7939 
7940   for (n = 0 ; n < gcan->nlabels ; n++)
7941   {
7942     if (gcan->labels[n] == label)
7943       return(&gcan->gcs[n]) ;
7944   }
7945 
7946   return(NULL) ;
7947 }
7948 #endif
7949 
7950 #include "mrisegment.h"
7951 /* each segment must be at least this much of total to be retained */
7952 #define MIN_SEG_PCT  0.15
7953 
7954 static int gcaReclassifySegment(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
7955                                 MRI_SEGMENT *mseg,
7956                                 int old_label, TRANSFORM *transform);
7957 static int gcaReclassifyVoxel(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
7958                               int x, int y, int z,
7959                               int old_label, TRANSFORM *transform);
7960 MRI *
7961 GCAconstrainLabelTopology(GCA *gca, MRI *mri_inputs,MRI *mri_src, MRI *mri_dst,
7962                           TRANSFORM *transform)
7963 {
7964   int              i, j, nvox; /*, x, y, z, width, height, depth*/
7965   ;
7966   MRI_SEGMENTATION *mriseg ;
7967 
7968   mri_dst = MRIcopy(mri_src, mri_dst) ;
7969 
7970   for (i = 1 ; i <= MAX_CMA_LABEL ; i++)
7971   {
7972     if (!IS_BRAIN(i)) // label is not brain, ignore
7973       continue ;
7974     // count number of label i in dst
7975     nvox = MRIvoxelsInLabel(mri_dst, i) ;
7976     // no such label, continue
7977     if (!nvox)
7978       continue ;
7979     // if hypointensities, continue
7980     if (LABEL_WITH_NO_TOPOLOGY_CONSTRAINT(i))
7981       continue ;
7982     /*    printf("label %03d: %d voxels\n", i, nvox) ;*/
7983     mriseg = MRIsegment(mri_src, (float)i, (float)i) ;
7984     if (!mriseg)
7985     {
7986       ErrorPrintf(Gerror,"GCAconstrainLabelTopology: "
7987                   "label %s failed (%d vox)",
7988                   cma_label_to_name(i), nvox) ;
7989       continue ;
7990     }
7991 
7992     /*    printf("\t%d segments:\n", mriseg->nsegments) ;*/
7993     for (j = 0 ; j < mriseg->nsegments ; j++)
7994     {
7995       if (IS_LAT_VENT(i) && mriseg->segments[j].nvoxels > 500)
7996         continue ;
7997       /* printf("\t\t%02d: %d voxels", j, mriseg->segments[j].nvoxels) ;*/
7998       if ((float)mriseg->segments[j].nvoxels / (float)nvox < MIN_SEG_PCT)
7999       {
8000         // printf(" - reclassifying...") ;
8001         gcaReclassifySegment(gca,mri_inputs,mri_dst,
8002                              &mriseg->segments[j], i,
8003                              transform);
8004       }
8005       // printf("\n") ;
8006     }
8007     MRIsegmentFree(&mriseg) ;
8008   }
8009 
8010 #if 0
8011   width = mri_dst->width ;
8012   height = mri_dst->height ;
8013   depth  = mri_dst->depth ;
8014   for (z = 0 ; z < depth ; z++)
8015   {
8016     for (y = 0 ; y < height ; y++)
8017     {
8018       for (x = 0 ; x < width ; x++)
8019       {
8020         if (x == 144 && y == 118 && z == 127)
8021           DiagBreak() ;
8022         if (nint(MRIgetVoxVal(mri_dst, x, y, z,0)) == LABEL_UNDETERMINED)
8023           gcaReclassifyVoxel(gca, mri_inputs, mri_dst,
8024                              x, y, z, LABEL_UNDETERMINED, transform) ;
8025       }
8026     }
8027   }
8028 #endif
8029 
8030   return(mri_dst) ;
8031 }
8032 
8033 static int
8034 gcaReclassifySegment(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
8035                      MRI_SEGMENT *mseg, int old_label, TRANSFORM *transform)
8036 {
8037   int   i ;
8038 
8039   for (i = 0 ; i < mseg->nvoxels ; i++)
8040   {
8041 #if 1
8042     gcaReclassifyVoxel(gca, mri_inputs, mri_labels,
8043                        mseg->voxels[i].x,
8044                        mseg->voxels[i].y,
8045                        mseg->voxels[i].z,
8046                        old_label, transform) ;
8047 #else
8048     MRIsetVoxVal(mri_labels, 
8049                                  mseg->voxels[i].x,
8050                                  mseg->voxels[i].y,
8051                                  mseg->voxels[i].z, 0
8052                                  LABEL_UNDETERMINED ;
8053 #endif
8054   }
8055 
8056   return(NO_ERROR) ;
8057 }
8058 
8059 static int
8060 gcaReclassifyVoxel(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
8061                    int x, int y, int z, int old_label, TRANSFORM *transform)
8062 {
8063   int     nbr_labels[255], xi, yi, zi, xk, yk, zk, i, new_label ;
8064   double  max_p, p ;
8065 
8066   memset(nbr_labels, 0, sizeof(nbr_labels)) ;
8067   // get 6 neighbors
8068   for (zk = -1 ; zk <= 1 ; zk++)
8069   {
8070     zi = mri_labels->zi[z+zk] ;
8071     for (yk = -1 ; yk <= 1 ; yk++)
8072     {
8073       yi = mri_labels->yi[y+yk] ;
8074       for (xk = -1 ; xk <= 1 ; xk++)
8075       {
8076         xi = mri_labels->xi[x+xk] ;
8077         // get the label histogram
8078         nbr_labels[nint(MRIgetVoxVal(mri_labels, xi, yi, zi,0))]++ ;
8079       }
8080     }
8081   }
8082   new_label = 0 ;
8083   max_p = 10*BIG_AND_NEGATIVE ;
8084   nbr_labels[old_label] = 0 ; // don't look at old_label
8085 
8086   // for (i = 0 ; i <= 255 ; i++) // should not go up to 255 but MAX_CMA_LABEL
8087   for (i=0; i < MAX_CMA_LABEL; i++)
8088   {
8089     if (mri_labels->type == MRI_UCHAR && i >= 256)
8090       break ;
8091     if (nbr_labels[i] > 0)  // if neighbors has this label, then
8092     {
8093       MRIsetVoxVal(mri_labels, x, y, z, 0, i) ;
8094       // set to the current label and see what happens
8095       p = gcaVoxelGibbsLogLikelihood(gca, mri_labels, mri_inputs,
8096                                      x, y, z,transform,
8097                                      PRIOR_FACTOR);
8098       // debug ///////////////////////////////////////
8099       if (x==Ggca_x && y == Ggca_y && z == Ggca_z)
8100       {
8101         printf("gcaReclassifyVoxel: nbr_labels[%d] = %d\n",
8102                i, nbr_labels[i]);
8103         printf("gcaReclassifyVoxel:(%d, %d, %d): Label = %s (%d), "
8104                "VoxelGibbsLogLikelihood = %.2f, max_p = %.2f\n",
8105                x, y, z, cma_label_to_name(i), i, p, max_p);
8106         if (p >= max_p)
8107           printf("   replacing max_p with this p and "
8108                  "label from %s(%d) to %s(%d)\n",
8109                  cma_label_to_name(old_label), old_label,
8110                  cma_label_to_name(i), i);
8111       }
8112       ////////////////////////////////////////////////
8113       if (p >= max_p)
8114       {
8115         max_p = p ;
8116         new_label = i ;
8117       }
8118     }
8119   }
8120   MRIsetVoxVal(mri_labels, x, y, z, 0, new_label) ;
8121   return(NO_ERROR) ;
8122 }
8123 #define MAX_VENTRICLE_ITERATIONS  30
8124 #define V_WSIZE (5)
8125 #define V_WHALF (V_WSIZE-1)/2
8126 #define V_THRESH ((V_WSIZE*V_WSIZE/2))
8127 #if 1
8128 MRI *
8129 GCAexpandVentricle(GCA *gca, MRI *mri_inputs, MRI *mri_src,
8130                    MRI *mri_dst, TRANSFORM *transform, int target_label)
8131 {
8132   int      nchanged, x, y, z, width, height, depth, xn, yn, zn, xk, yk, zk,
8133   xi, yi, zi, label, total_changed, i, j, count,
8134   found, xmin, xmax, ymin, ymax, zmin, zmax ;
8135   GCA_NODE *gcan ;
8136   GC1D     *gc ;
8137   float    v_means[MAX_GCA_INPUTS], v_var, dist_ven, 
8138     dist_label, vals[MAX_GCA_INPUTS] ;
8139 
8140   /* compute label mean and variance */
8141 
8142   GCAcomputeLabelStats(gca, target_label, &v_var, v_means) ;
8143   printf("ventricle intensity = ") ;
8144   for (i = 0 ; i < gca->ninputs ; i++)
8145     printf("%2.1f ", v_means[i]) ;
8146   printf(" +- %2.1f\n", sqrt(v_var)) ;
8147 
8148 
8149   if (mri_src != mri_dst)
8150     mri_dst = MRIcopy(mri_src, mri_dst) ;
8151 
8152   width = mri_src->width ;
8153   height = mri_src->height ;
8154   depth = mri_src->depth ;
8155 
8156   i = total_changed = 0 ;
8157   xmin = mri_dst->width ;
8158   ymin = mri_dst->height ;
8159   zmin = mri_dst->depth ;
8160   xmax = ymax = zmax = -1 ;
8161   for (z = 0 ; z < mri_dst->depth ; z++)
8162   {
8163     for (y = 0 ; y < mri_dst->height ; y++)
8164     {
8165       for (x = 0 ; x < mri_dst->width ; x++)
8166       {
8167         label = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
8168         if (label == target_label)
8169         {
8170           if (x > xmax)
8171             xmax = x ;
8172           if (y > ymax)
8173             ymax = y ;
8174           if (z > zmax)
8175             zmax = z ;
8176           if (x < xmin)
8177             xmin = x ;
8178           if (y < ymin)
8179             ymin = y ;
8180           if (z < zmin)
8181             zmin = z ;
8182         }
8183       }
8184     }
8185   }
8186   // expand bounding box to allow for ventricle to expand
8187   xmin = mri_dst->xi[xmin-1] ;
8188   ymin = mri_dst->yi[ymin-1] ;
8189   zmin = mri_dst->zi[zmin-1] ;
8190   xmax = mri_dst->xi[xmax+1] ;
8191   ymax = mri_dst->yi[ymax+1] ;
8192   zmax = mri_dst->zi[zmax+1] ;
8193 
8194   do
8195   {
8196     nchanged = 0 ;
8197     for (z = zmin ; z <= zmax ; z++)
8198     {
8199       for (y = ymin ; y <= ymax ; y++)
8200       {
8201         for (x = xmin ; x <= xmax ; x++)
8202         {
8203           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
8204             DiagBreak() ;
8205           label = nint(MRIgetVoxVal(mri_dst, x, y, z, 0)) ;
8206           if (label == target_label)
8207             continue ;
8208           found = 0 ;
8209 
8210           for (yk = -1 ; found == 0 && yk <= 1 ; yk += 2)
8211           {
8212             yi = mri_dst->yi[y+yk] ;  // look superior/inferior
8213 
8214             // only change it if there is a "wall" of 
8215             // ventricle superior or inferior
8216             count = MRIlabelsInPlanarNbhd
8217               (mri_dst, x, yi, z, V_WHALF, target_label, MRI_HORIZONTAL) ;
8218             if (count >= V_THRESH)
8219               found = 1 ;
8220           }
8221           for (xk = -1 ; found == 0 && xk <= 1 ; xk += 2)
8222           {
8223             xi = mri_dst->xi[x+xk] ;  // look superior/inferior
8224 
8225             // only change it if there is a "wall" of 
8226             // ventricle superior or inferior
8227             count = MRIlabelsInPlanarNbhd
8228               (mri_dst, xi, y, z, V_WHALF, target_label, MRI_SAGITTAL) ;
8229             if (count >= V_THRESH)
8230               found = 1 ;
8231           }
8232           for (zk = -1 ; found == 0 && zk <= 1 ; zk += 2)
8233           {
8234             zi = mri_dst->zi[z+zk] ;  // look superior/inferior
8235 
8236             // only change it if there is a "wall" of 
8237             // ventricle anterior or posterior
8238             count = MRIlabelsInPlanarNbhd
8239               (mri_dst, x, y, zi, V_WHALF, target_label, MRI_CORONAL) ;
8240             if (count >= V_THRESH)
8241               found = 1 ;
8242           }
8243           if (found == 0)
8244             continue ;
8245           if (GCAsourceVoxelToNode(gca, mri_dst,transform,x, y, z,
8246                                    &xn, &yn, &zn) == NO_ERROR)
8247           {
8248             gcan = &gca->nodes[xn][yn][zn] ;
8249 
8250             if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
8251               DiagBreak() ;
8252 
8253             load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
8254             for (dist_ven = 0, j = 0 ; j < gca->ninputs ; j++)
8255               dist_ven += SQR(vals[j]-v_means[j]);
8256             gc = GCAfindGC(gca, xn, yn, zn, label) ;
8257             if (gc == NULL)
8258               dist_label = 10000 ; // ???
8259             else
8260               dist_label = GCAmahDistIdentityCovariance(gc, vals,gca->ninputs);
8261             gc = GCAfindGC(gca, xn, yn, zn,target_label) ;
8262             if (2*dist_ven < dist_label)   // much more like ventricle 
8263                                            //than anything else
8264             {
8265               if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
8266               {
8267                 int olabel = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
8268                 printf("GCAexpandVentricle:voxel"
8269                        "(%d, %d, %d) changed from %s (%d) "
8270                        "to %s (%d), because current label d = %2.0f "
8271                        "and new lable d = %2.0f\n",
8272                        x, y, z,
8273                        cma_label_to_name(olabel), olabel,
8274                        cma_label_to_name(target_label), target_label,
8275                        dist_label, dist_ven);
8276               }
8277               // change it to ventricle
8278               nchanged++ ;
8279               MRIsetVoxVal(mri_dst, x, y, z, target_label, 0) ;
8280               if (x <= xmin)
8281                 xmin = mri_dst->xi[x-1] ;
8282               if (y <= ymin)
8283                 ymin = mri_dst->yi[y-1] ;
8284               if (z <= zmin)
8285                 zmin = mri_dst->zi[z-1] ;
8286               if (x >= xmax)
8287                 xmax = mri_dst->xi[x+1] ;
8288               if (y >= ymax)
8289                 ymax = mri_dst->yi[y+1] ;
8290               if (z >= zmax)
8291                 zmax = mri_dst->zi[z+1] ;
8292             }
8293           }
8294         }
8295       }
8296     }
8297 
8298     total_changed += nchanged ;
8299     if (++i > MAX_VENTRICLE_ITERATIONS)
8300       break ;
8301   }
8302   while (nchanged > 0) ;
8303 
8304   printf("%d labels changed to %s...\n",
8305          total_changed, cma_label_to_name(target_label)) ;
8306   return(mri_dst) ;
8307 }
8308 #else
8309 MRI *
8310 GCAexpandVentricle(GCA *gca, MRI *mri_inputs, MRI *mri_src,
8311                    MRI *mri_dst, TRANSFORM *transform, int target_label)
8312 {
8313   int      nchanged, x, y, z, width, height, depth, xn, yn, zn, xi, yi, zi,
8314   xk, yk, zk, label, total_changed, i ;
8315   GCA_NODE *gcan ;
8316   GC1D     *gc, *gc_vent ;
8317   float    v_means[MAX_GCA_INPUTS], v_var, pv, plabel, vals[MAX_GCA_INPUTS] ;
8318   MRI      *mri_tmp ;
8319 
8320   /* compute label mean and variance */
8321 
8322   GCAcomputeLabelStats(gca, target_label, &v_var, v_means) ;
8323   printf("ventricle intensity = ") ;
8324   for (i = 0 ; i < gca->ninputs ; i++)
8325     printf("%2.1f ", v_means[i]) ;
8326   printf(" +- %2.1f\n", sqrt(v_var)) ;
8327 
8328 
8329   if (mri_src != mri_dst)
8330     mri_dst = MRIcopy(mri_src, mri_dst) ;
8331 
8332   mri_tmp = MRIcopy(mri_dst, NULL) ;
8333 
8334   width = mri_src->width ;
8335   height = mri_src->height ;
8336   depth = mri_src->depth ;
8337 
8338   i = total_changed = 0 ;
8339   do
8340   {
8341     nchanged = 0 ;
8342     for (z = 0 ; z < depth ; z++)
8343     {
8344       for (y = 0 ; y < height ; y++)
8345       {
8346         for (x = 0 ; x < width ; x++)
8347         {
8348           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
8349             DiagBreak() ;
8350 
8351           if (!GCAsourceVoxelToNode(gca, mri_dst, transform,
8352                                     x, y, z, &xn, &yn, &zn))
8353           {
8354             gc_vent = GCAfindGC(gca, xn, yn, zn, target_label) ;
8355             if (gc_vent == NULL)
8356               continue ;
8357             label = nint(MRIgetVoxVal(mri_dst, x, y, z)) ;
8358 
8359             if (label == target_label)
8360             {
8361               for (zk = -1 ; zk <= 1 ; zk++)
8362               {
8363                 for (yk = -1 ; yk <= 1 ; yk++)
8364                 {
8365                   for (xk = -1 ; xk <= 1 ; xk++)
8366                   {
8367                     if (fabs(xk) + fabs(yk) + fabs(zk) > 1)
8368                       continue ;
8369                     xi = mri_src->xi[x+xk] ;
8370                     yi = mri_src->yi[y+yk] ;
8371                     zi = mri_src->zi[z+zk] ;
8372                     label = nint(MRIgetVoxVal(mri_dst, xi, yi, zi, 0)) ;
8373                     if (label != target_label)
8374                       /* should it be changed? */
8375                     {
8376                       if (!GCAsourceVoxelToNode(gca,
8377                                                 mri_dst,
8378                                                 transform,
8379                                                 xi, yi, zi,
8380                                                 &xn,
8381                                                 &yn,
8382                                                 &zn))
8383                       {
8384                         gcan = &gca->nodes[xn][yn][zn] ;
8385 
8386                         if (xi == Ggca_x
8387                             && yi == Ggca_y
8388                             && zi == Ggca_z)
8389                           DiagBreak() ;
8390 
8391                         load_vals(mri_inputs,
8392                                   xi, yi, zi,
8393                                   vals, gca->ninputs) ;
8394                         gc = GCAfindGC(gca,
8395                                        xn, yn, zn,
8396                                        label) ;
8397                         if (gc == NULL)
8398                           plabel = 0.0 ;
8399                         else
8400                           plabel =
8401                             GCAcomputeConditionalDensity
8402                             (gc,
8403                              vals,
8404                              gca->ninputs,
8405                              label) ;
8406                         gc = GCAfindGC(gca,
8407                                        xn, yn, zn,
8408                                        target_label) ;
8409                         if (gc == NULL)
8410                           /* use neighboring gc */
8411                           /*to allow for variability */
8412                           /*in ventricles */
8413                           gc = gc_vent ;
8414                         pv =
8415                           GCAcomputeConditionalDensity
8416                           (gc,
8417                            vals,
8418                            gca->ninputs,
8419                            target_label);
8420                         if (pv > 5*plabel)
8421                         {
8422                           if (xi == Ggca_x
8423                               && yi == Ggca_y
8424                               && zi == Ggca_z)
8425                           {
8426                             int olabel =
8427                               nint(MRIgetVoxVal(mri_tmp,xi, yi, zi,0)) ;
8428                             printf("GCAexpandVentricle:voxel"
8429                                    "(%d, %d, %d) changed from %s (%d) "
8430                                    "to %s (%d), because current "
8431                                    "label p = %.2f "
8432                                    "and new lable p = %.2f\n",
8433                                    xi, yi, zi,
8434                                    cma_label_to_name(olabel), olabel,
8435                                    cma_label_to_name(target_label), 
8436                                    target_label,
8437                                    plabel, pv);
8438                           }
8439                           if (xi == 140
8440                               && yi == 79
8441                               && zi == 136)
8442                             DiagBreak() ;
8443                           /* v should be wm */
8444                           nchanged++ ;
8445                           MRIsetVoxVal(mri_tmp, xi, yi, zi, 0,target_label) ;
8446                         }
8447                       }
8448                     }
8449                   }
8450                 }
8451               }
8452             }
8453           }
8454         }
8455       }
8456     }
8457     MRIcopy(mri_tmp, mri_dst) ;
8458     total_changed += nchanged ;
8459     if (++i > MAX_VENTRICLE_ITERATIONS)
8460       break ;
8461   }
8462   while (nchanged > 0) ;
8463 
8464   MRIfree(&mri_tmp) ;
8465   printf("%d labels changed to %s...\n",
8466          total_changed, cma_label_to_name(target_label)) ;
8467   return(mri_dst) ;
8468 }
8469 #endif
8470 #define MAX_CORTICAL_ITERATIONS  10
8471 MRI *
8472 GCAexpandCortex(GCA *gca, MRI *mri_inputs, MRI *mri_src,
8473                 MRI *mri_dst, TRANSFORM *transform)
8474 {
8475   int      nchanged, x, y, z, width, height, depth, xn, yn, zn, xi, yi, zi,
8476   xk, yk, zk, label, total_changed, i, wm_nbr, gray_nbr, left ;
8477   GCA_NODE *gcan ;
8478   float    wm_means[MAX_GCA_INPUTS],\
8479   wm_var, gray_means[MAX_GCA_INPUTS], gray_var, ldist, wdist, gdist ;
8480   MRI      *mri_tmp ;
8481   float    vals[MAX_GCA_INPUTS] ;
8482   GC1D     *gc_wm, *gc_gm, *gc_label ;
8483 
8484 
8485   /* compute label mean and variance */
8486 
8487   GCAcomputeLabelStats(gca, Left_Cerebral_White_Matter, &wm_var, wm_means) ;
8488   GCAcomputeLabelStats(gca, Left_Cerebral_Cortex, &gray_var, gray_means) ;
8489   printf("cortex mean - gray ") ;
8490   for (i = 0 ; i < gca->ninputs ; i++)
8491     printf("%2.1f ", gray_means[i]) ;
8492   printf("+- %2.1f, white ", sqrt(gray_var)) ;
8493   for (i = 0 ; i < gca->ninputs ; i++)
8494     printf("%2.1f ", wm_means[i]) ;
8495   printf("+- %2.1f\n", sqrt(wm_var)) ;
8496 
8497   if (mri_src != mri_dst)
8498     mri_dst = MRIcopy(mri_src, mri_dst) ;
8499 
8500   mri_tmp = MRIcopy(mri_dst, NULL) ;
8501 
8502   width = mri_src->width ;
8503   height = mri_src->height ;
8504   depth = mri_src->depth ;
8505 
8506   i = total_changed = 0 ;
8507   do
8508   {
8509     nchanged = 0 ;
8510     for (z = 0 ; z < depth ; z++)
8511     {
8512       for (y = 0 ; y < height ; y++)
8513       {
8514         for (x = 0 ; x < width ; x++)
8515         {
8516           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
8517             DiagBreak() ;
8518 
8519           label = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
8520 
8521           if (label == Unknown ||
8522               label == Left_Cerebral_Cortex ||
8523               label == Right_Cerebral_Cortex ||
8524               label == Left_Cerebral_White_Matter ||
8525               label == Right_Cerebral_White_Matter
8526              )
8527           {
8528             if (label != Unknown)
8529               left = (label == Left_Cerebral_Cortex || \
8530                       label == Left_Cerebral_White_Matter) ;
8531             else
8532             {
8533               left = -1 ;
8534               for (zk = -1 ; left < 0 && zk <= 1 ; zk++)
8535               {
8536                 for (yk = -1 ; left < 0 && yk <= 1 ; yk++)
8537                 {
8538                   for (xk = -1 ; left < 0 && xk <= 1 ; xk++)
8539                   {
8540                     xi = mri_src->xi[x+xk] ;
8541                     yi = mri_src->yi[y+yk] ;
8542                     zi = mri_src->zi[z+zk] ;
8543                     label = nint(MRIgetVoxVal(mri_dst, xi, yi, zi,0)) ;
8544                     if (label == Left_Cerebral_Cortex || \
8545                         label == Left_Cerebral_White_Matter)
8546                       left = 1 ;
8547                     else if (label ==
8548                              Right_Cerebral_Cortex
8549                              || \
8550                              label ==
8551                              Right_Cerebral_White_Matter)
8552                       left = 0 ;
8553                   }
8554                 }
8555               }
8556             }
8557 
8558             gray_nbr = wm_nbr = 0 ;
8559             gc_wm = GCAfindSourceGC(gca, mri_src, transform,
8560                                     x, y, z,
8561                                     left ? \
8562                                     Left_Cerebral_White_Matter : \
8563                                     Right_Cerebral_White_Matter) ;
8564             gc_gm = GCAfindSourceGC(gca, mri_src, transform,
8565                                     x, y, z,
8566                                     left ? \
8567                                     Left_Cerebral_Cortex : \
8568                                     Right_Cerebral_Cortex) ;
8569             if (gc_gm)
8570               gray_nbr = left ? Left_Cerebral_Cortex :
8571                          Right_Cerebral_Cortex ;
8572             if (gc_wm)
8573               wm_nbr = left ? Left_Cerebral_White_Matter : \
8574                        Right_Cerebral_White_Matter ;
8575             if (gc_gm == NULL || gc_wm == NULL)
8576               for (zk = -1 ; zk <= 1 ; zk++)
8577               {
8578                 for (yk = -1 ; yk <= 1 ; yk++)
8579                 {
8580                   for (xk = -1 ; xk <= 1 ; xk++)
8581                   {
8582                     if (fabs(xk) + fabs(yk) + fabs(zk) > 1)
8583                       continue ;
8584                     xi = mri_src->xi[x+xk] ;
8585                     yi = mri_src->yi[y+yk] ;
8586                     zi = mri_src->zi[z+zk] ;
8587                     label = nint(MRIgetVoxVal(mri_dst, xi, yi, zi, 0)) ;
8588                     if ((label ==  Left_Cerebral_Cortex ||
8589                          label ==  Right_Cerebral_Cortex) && \
8590                         (gc_gm == NULL))
8591                     {
8592                       gray_nbr = label ;
8593                       gc_gm = GCAfindSourceGC(gca, mri_src,
8594                                               transform,
8595                                               xi, yi, zi,
8596                                               label) ;
8597                       if (!gc_gm)
8598                         gray_nbr = 0 ;
8599                       /* shouldn't ever happen */
8600                     }
8601                     else
8602                       if ((label ==
8603                            Left_Cerebral_White_Matter
8604                            ||
8605                            label ==
8606                            Right_Cerebral_White_Matter)
8607                           && (gc_wm == NULL))
8608                       {
8609                         wm_nbr = label ;
8610                         gc_wm = GCAfindSourceGC(gca,
8611                                                 mri_src,
8612                                                 transform,
8613                                                 xi, yi, zi,
8614                                                 label) ;
8615                         if (!gc_wm)
8616                           wm_nbr = 0 ;
8617                         /* shouldn't ever happen */
8618                       }
8619                   }
8620                 }
8621               }
8622             if (!wm_nbr && !gray_nbr)
8623               continue ;
8624 
8625             load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
8626             if (wm_nbr)
8627               wdist =
8628                 sqrt(GCAmahDistIdentityCovariance(gc_wm, vals,
8629                                                   gca->ninputs)) ;
8630             else
8631               wdist = 1e10 ;
8632             if (gray_nbr)
8633               gdist =
8634                 sqrt(GCAmahDistIdentityCovariance(gc_gm, vals,
8635                                                   gca->ninputs)) ;
8636             else
8637               gdist = 1e10 ;
8638 
8639             if (gc_wm == NULL || \
8640                 sqrt(GCAmahDist(gc_wm, vals, gca->ninputs)) > 1.5)
8641               wdist = 1e10 ; /* hack - don't label unlikely white */
8642             if (gc_gm == NULL || \
8643                 sqrt(GCAmahDist(gc_gm, vals, gca->ninputs)) > 1.5)
8644               gdist = 1e10 ;  /* hack - don't label unlikely gray */
8645 
8646             if (!GCAsourceVoxelToNode(gca, mri_dst, \
8647                                       transform, x, y, z,
8648                                       &xn, &yn, &zn))
8649             {
8650               gcan = &gca->nodes[xn][yn][zn] ;
8651               gc_label = GCAfindGC(gca, xn, yn, zn, label) ;
8652               if (gc_label)
8653                 ldist =
8654                   sqrt(GCAmahDistIdentityCovariance(gc_label, \
8655                                                     vals,
8656                                                     gca->ninputs));
8657               else
8658                 ldist = 1e10 ;
8659               ldist *= .75 ;  /* bias towards retaining label */
8660 
8661               if ((wdist < gdist) && gc_wm)
8662                 /* might change to wm */
8663               {
8664                 if (wdist < ldist && GCAisPossible(gca, \
8665                                                    mri_inputs,
8666                                                    wm_nbr,
8667                                                    transform,
8668                                                    x, y, z, 0))
8669                 {
8670                   if (x == Ggca_x
8671                       && y == Ggca_y
8672                       && z == Ggca_z)
8673                   {
8674                     int olabel = nint(MRIgetVoxVal(mri_tmp, x, y, z, 0)) ;
8675                     if (olabel != wm_nbr)
8676                       printf(
8677                         "GCAexpandCortex:voxel (%d, %d, %d)"
8678                         " changed from %s (%d) "
8679                         "to %s (%d), wdist=%.2f, gdist=%.2f,"
8680                         " ldist=%.2f\n", x, y, z,
8681                         cma_label_to_name(olabel), olabel,
8682                         cma_label_to_name(wm_nbr), wm_nbr,
8683                         wdist, gdist, ldist);
8684                   }
8685                   nchanged++ ;
8686                   MRIsetVoxVal(mri_tmp, x, y, z, 0, wm_nbr) ;
8687                 }
8688               }
8689               else if (gc_gm)            /* might change to gm */
8690               {
8691                 if (gdist < ldist && GCAisPossible(gca,
8692                                                    mri_inputs,
8693                                                    gray_nbr,
8694                                                    transform,
8695                                                    x, y, z, 0))
8696                 {
8697                   int olabel = nint(MRIgetVoxVal(mri_tmp, x, y, z,0)) ;
8698                   if (x == Ggca_x
8699                       && y == Ggca_y
8700                       && z == Ggca_z)
8701                   {
8702                     if (olabel != gray_nbr)
8703                       printf
8704                       (
8705                         "GCAexpandCortex:voxel "
8706                         "(%d, %d, %d) changed from %s (%d) "
8707                         "to %s (%d), wdist=%.2f, "
8708                         "gdist=%.2f, ldist=%.2f\n",
8709                         x, y, z,
8710                         cma_label_to_name(olabel), olabel,
8711                         cma_label_to_name(gray_nbr),
8712                         gray_nbr,
8713                         wdist, gdist, ldist);
8714                   }
8715                   if (olabel != gray_nbr)
8716                     nchanged++ ;
8717 
8718                   MRIsetVoxVal(mri_tmp, x, y, z, 0, gray_nbr) ;
8719                 }
8720               }
8721             }
8722           }
8723         }
8724       }
8725     }
8726     MRIcopy(mri_tmp, mri_dst) ;
8727     total_changed += nchanged ;
8728     if (++i > MAX_CORTICAL_ITERATIONS)
8729       break ;
8730   }
8731   while (nchanged > 0) ;
8732 
8733   MRIfree(&mri_tmp) ;
8734   printf("%d labels changed to cortex...\n", total_changed) ;
8735   return(mri_dst) ;
8736 }
8737 
8738 MRI   *
8739 GCAexpandLabelIntoWM(GCA *gca, MRI *mri_inputs, MRI *mri_src,
8740                      MRI *mri_dst,
8741                      TRANSFORM *transform, MRI *mri_fixed, int target_label)
8742 {
8743   int      nchanged, x, y, z, width, height, depth, xn, yn, zn, xi, yi, zi,
8744   xk, yk, zk, nbr_label, n, label, total_changed, i ;
8745   GCA_NODE *gcan, *gcan_nbr ;
8746   GC1D     *gc_label, *gc_wm ;
8747   MRI      *mri_tmp ;
8748   float    vals[MAX_GCA_INPUTS] ;
8749   double   prior ;
8750 
8751   if (mri_src != mri_dst)
8752     mri_dst = MRIcopy(mri_src, mri_dst) ;
8753 
8754   mri_tmp = MRIcopy(mri_dst, NULL) ;
8755 
8756   width = mri_src->width ;
8757   height = mri_src->height ;
8758   depth = mri_src->depth ;
8759 
8760   i = total_changed = 0 ;
8761   do
8762   {
8763     nchanged = 0 ;
8764     for (z = 0 ; z < depth ; z++)
8765     {
8766       for (y = 0 ; y < height ; y++)
8767       {
8768         for (x = 0 ; x < width ; x++)
8769         {
8770 #if 0
8771           if (x == 140 && y == 111 && z == 139)
8772             DiagBreak() ;  /* should be wm */
8773           if (x == 138 && y == 103 && z == 139)
8774             DiagBreak() ;  /* should be pallidum */
8775 #endif
8776           // get the label
8777           label = nint(MRIgetVoxVal(mri_dst, x, y, z,0)) ;
8778 
8779           if (!GCAsourceVoxelToNode(gca, mri_dst,
8780                                     transform, x, y, z, &xn, &yn, &zn))
8781           {
8782             gcan = &gca->nodes[xn][yn][zn] ;
8783 
8784             // if this label is the same as the target label,
8785             // then expand
8786             // into neighbors if conditions are satisfied.
8787             if (label == target_label)
8788             {
8789               gc_label = GCAfindGC(gca, xn, yn, zn, label) ;
8790               // find wm gaussian classifier
8791               gc_wm = NULL ;
8792               for (n = 0 ; n < gcan->nlabels ; n++)
8793               {
8794                 if
8795                 ((gcan->labels[n] ==
8796                     Left_Cerebral_White_Matter) ||
8797                     (gcan->labels[n] ==
8798                      Right_Cerebral_White_Matter))
8799                   gc_wm = GCAfindGC(gca, xn, yn, zn,
8800                                     gcan->labels[n]) ;
8801               }
8802               // look around the neighbors
8803               for (zk = -1 ; zk <= 1 ; zk++)
8804               {
8805                 for (yk = -1 ; yk <= 1 ; yk++)
8806                 {
8807                   for (xk = -1 ; xk <= 1 ; xk++)
8808                   {
8809                     if (fabs(xk) + fabs(yk) + fabs(zk) > 1)
8810                       continue ;
8811                     xi = mri_src->xi[x+xk] ;
8812                     yi = mri_src->yi[y+yk] ;
8813                     zi = mri_src->zi[z+zk] ;
8814                     if (xi == Ggca_x
8815                         && yi == Ggca_y
8816                         && zi == Ggca_z)
8817                       DiagBreak() ;
8818                     // get the neighbor label
8819                     nbr_label = nint(MRIgetVoxVal(mri_dst, xi, yi, zi,0)) ;
8820                     if ((nbr_label ==
8821                          Right_Cerebral_White_Matter) ||
8822                         (nbr_label ==
8823                          Left_Cerebral_White_Matter))
8824                     {
8825                       // if it is wm, then load
8826                       //grey values at this neighbor
8827                       load_vals(mri_inputs,
8828                                 xi, yi, zi,
8829                                 vals, gca->ninputs) ;
8830                       if (!GCAsourceVoxelToNode(gca,
8831                                                 mri_dst,
8832                                                 transform,
8833                                                 xi, yi, zi,
8834                                                 &xn,
8835                                                 &yn,
8836                                                 &zn))
8837                       {
8838                         // get the wm gc
8839                         gc_wm = GCAfindGC(gca,
8840                                           xn, yn, zn,
8841                                           nbr_label) ;
8842                         // get the target label gc
8843                         gc_label =
8844                           GCAfindGC(gca,
8845                                     xn, yn, zn,
8846                                     target_label);
8847                         if (!gc_wm || !gc_label)
8848                           continue ;
8849                         // calculate distance
8850                         // to wm and target label.
8851                         // if wm is bigger
8852                         if (GCAmahDistIdentityCovariance\
8853                             (gc_wm,
8854                              vals,
8855                              gca->ninputs) >
8856                             GCAmahDistIdentityCovariance\
8857                             (gc_label,
8858                              vals,
8859                              gca->ninputs))
8860                         {
8861                           gcan_nbr =
8862                             &gca->nodes[xn][yn][zn] ;
8863                           for (prior = 0.0f, n = 0;
8864                                n < gcan_nbr->nlabels;
8865                                n++)
8866                           {
8867                             // look for the
8868                             // target label
8869                             // in this neighbor
8870                             if (gcan_nbr->labels[n]
8871                                 == \
8872                                 target_label)
8873                             {
8874                               prior =
8875                                 get_node_prior
8876                                 (gca,
8877                                  target_label,
8878                                  xn, yn, zn) ;
8879                               if (prior != 0)
8880                                 break ;
8881                             }
8882                           }
8883                           // if not found,
8884                           // prior stays 0.0f
8885 #define PRIOR_THRESH 0.01
8886                           if (prior >= PRIOR_THRESH)
8887                             /* target is possible */
8888                           {
8889                             if (x == Ggca_x
8890                                 &&
8891                                 y == Ggca_y
8892                                 &&
8893                                 z == Ggca_z)
8894                             {
8895                               printf("GCAexpandLabelIntoWM:voxel (%d, %d, %d) "
8896                                      "changed from %s (%d) "
8897                                      "to %s (%d), prior=%.2f\n",
8898                                      xi, yi, zi,
8899                                      cma_label_to_name(nbr_label), nbr_label,
8900                                      cma_label_to_name(target_label), 
8901                                      target_label,
8902                                      prior);
8903                             }
8904                             nchanged++ ;
8905                             MRIsetVoxVal(mri_tmp, xi, yi, zi, 0, target_label);
8906                             /* MRIvox(mri_fixed,
8907                                xi, yi, zi) = 0 ;*/
8908                           }
8909                         }
8910                       }
8911                       ///////////////////
8912                     }
8913                   }
8914                 }
8915               }
8916             }
8917           }
8918           /////////////////////////////////////////////
8919         }
8920       }
8921     }
8922     MRIcopy(mri_tmp, mri_dst) ;
8923     total_changed += nchanged ;
8924     if (++i >= 1)
8925       break ;
8926   }
8927   while (nchanged > 0) ;
8928 
8929   MRIfree(&mri_tmp) ;
8930   printf("%d labels changed to %s...\n",
8931          total_changed, cma_label_to_name(target_label)) ;
8932   return(mri_dst) ;
8933 }
8934 
8935 
8936 int
8937 GCArankSamples(GCA *gca, GCA_SAMPLE *gcas, int nsamples, int *ordered_indices)
8938 {
8939   LABEL_PROB  *label_probs ;
8940   int         i ;
8941 
8942   label_probs = (LABEL_PROB *)calloc(nsamples, sizeof(LABEL_PROB)) ;
8943   for (i = 0 ; i < nsamples ; i++)
8944   {
8945     label_probs[i].label = i ;
8946     label_probs[i].prob =  gcas[i].log_p ;
8947   }
8948 
8949   /* now sort the samples by probability */
8950   qsort(label_probs, nsamples, sizeof(LABEL_PROB),
8951         compare_sort_probabilities) ;
8952 
8953   for (i = 0 ; i < nsamples ; i++)
8954   {
8955     ordered_indices[i] = label_probs[nsamples-(i+1)].label ;
8956   }
8957 
8958   free(label_probs) ;
8959   return(NO_ERROR) ;
8960 }
8961 
8962 #include "mrinorm.h"
8963 MRI *
8964 GCAnormalizeSamples(MRI *mri_in, GCA *gca, GCA_SAMPLE *gcas, int nsamples,
8965                     TRANSFORM *transform, char *ctl_point_fname)
8966 {
8967   MRI    *mri_dst, *mri_ctrl, *mri_bias ;
8968   int    xv, yv, zv, n, x, y, z,
8969   width, height, depth, xn, yn, zn, num, total, input,
8970   T1_index = 0 ;
8971   float   bias ;
8972   double  mean, sigma ;
8973   Real    val ;
8974   float      gm_means[MAX_GCA_INPUTS], gray_white_CNR;
8975 
8976   if (nsamples == 0)   /* only using control points from file */
8977   {
8978     float      wm_means[MAX_GCA_INPUTS], tmp[MAX_GCA_INPUTS], max_wm ;
8979     int        r ;
8980 
8981     GCAlabelMean(gca, Left_Cerebral_White_Matter, wm_means) ;
8982     //    GCAlabelMean(gca, Left_Cerebral_White_Matter, tmp) ;
8983     GCAlabelMean(gca, Right_Cerebral_White_Matter, tmp) ;
8984 
8985 #if 0
8986     max_wm = 0 ;
8987     for (r = 0 ; r < gca->ninputs ; r++)
8988     {
8989       wm_means[r] = (wm_means[r] + tmp[r]) / 2 ;
8990       if (wm_means[r] > max_wm)
8991       {
8992         T1_index = r ;
8993         max_wm = wm_means[r] ;
8994       }
8995     }
8996 #else
8997     GCAlabelMean(gca, Left_Cerebral_Cortex, gm_means) ;
8998     gray_white_CNR = wm_means[0] - gm_means[0];
8999     for (r = 0 ; r < gca->ninputs ; r++)
9000     {
9001       wm_means[r] = (wm_means[r] + tmp[r]) / 2 ;
9002       if ((wm_means[r] - gm_means[r]) > gray_white_CNR)
9003       {
9004         T1_index = r ;
9005         gray_white_CNR = (wm_means[r] - gm_means[r]);
9006       }
9007     }
9008     max_wm = wm_means[T1_index];
9009 #endif
9010     printf("using volume %d as most T1-weighted for normalization\n",
9011            T1_index) ;
9012   }
9013   width = mri_in->width ;
9014   height = mri_in->height ;
9015   depth = mri_in->depth ;
9016   mri_dst = MRIclone(mri_in, NULL) ;
9017   mri_ctrl = MRIalloc(width, height, depth, MRI_UCHAR) ;
9018   MRIcopyHeader(mri_in, mri_ctrl);
9019   mri_bias = MRIalloc(mri_in->width,mri_in->height,mri_in->depth,MRI_SHORT);
9020   if (!mri_bias)
9021     ErrorExit(ERROR_NOMEMORY,
9022               "GCAnormalizeSamples: could not allocate "
9023               "(%d,%d,%d,2) bias image",
9024               mri_in->width,mri_in->height,mri_in->depth) ;
9025   MRIcopyHeader(mri_in, mri_bias);
9026 
9027 #define MAX_BIAS 1250
9028 #define NO_BIAS  1000
9029 #define MIN_BIAS  750
9030 
9031   if (ctl_point_fname)
9032   {
9033     MRI3dUseFileControlPoints(mri_ctrl, ctl_point_fname) ;
9034     MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ;
9035   }
9036 
9037   /* add control points from file */
9038   for (z = 0 ; z < depth ; z++)
9039   {
9040     for (y = 0 ; y < height ; y++)
9041     {
9042       for (x = 0 ; x < width ; x++)
9043       {
9044         if (x == Gx && y == Gy && z == Gz)
9045           DiagBreak() ;
9046         MRISvox(mri_bias, x,y,z) = NO_BIAS ;  /* by default */
9047         if (MRIvox(mri_ctrl, x, y, z) != CONTROL_MARKED)
9048           /* not read from file */
9049           continue ;
9050 
9051         if (nsamples == 0)   /* only using file control points */
9052         {
9053           MRIsampleVolumeFrame(mri_in, x, y, z, T1_index, &val) ;
9054           bias = NO_BIAS*DEFAULT_DESIRED_WHITE_MATTER_VALUE / val ;
9055           MRISvox(mri_bias, x, y, z) = (short)nint(bias) ;
9056         }
9057         else    /* find atlas point this maps to */
9058         {
9059           int       n, max_n ;
9060           GC1D      *gc ;
9061           GCA_NODE  *gcan ;
9062           GCA_PRIOR *gcap ;
9063           double    max_p ;
9064 
9065           if (!GCAsourceVoxelToNode(gca, mri_dst,
9066                                     transform,
9067                                     x, y, z, &xn, &yn, &zn))
9068           {
9069             gcan = &gca->nodes[xn][yn][zn] ;
9070             gcap = getGCAP(gca, mri_dst, transform, x, y, z) ;
9071             if (gcap==NULL)
9072               continue;
9073             max_p = 0 ;
9074             for (max_n = -1, n = 0 ; n < gcan->nlabels ; n++)
9075             {
9076               if ((0 == IS_WM(gcan->labels[n])) &&
9077                   (0 == IS_CEREBELLAR_WM(gcan->labels[n])) &&
9078                   (gcan->labels[n] != Brain_Stem))
9079                 continue ;
9080               gc = &gcan->gcs[n] ;
9081               if (getPrior(gcap, gcan->labels[n]) >= max_p)
9082               {
9083                 max_p = getPrior(gcap, gcan->labels[n]) ;
9084                 max_n = n ;
9085               }
9086             }
9087             if (max_n < 0)
9088               /* couldn't find any valid label at this location */
9089               continue ;
9090             gc = &gcan->gcs[max_n] ;
9091 
9092             for (bias = 0.0, input = 0 ;
9093                  input < gca->ninputs ;
9094                  input++)
9095             {
9096               MRIsampleVolumeFrame(mri_in, x, y, z, input, &val) ;
9097               if (FZERO(val))
9098                 val = 1 ;
9099               bias += (float)NO_BIAS*((float)gc->means[input]/val);
9100             }
9101             bias /= (float)gca->ninputs ;
9102             if (bias < 100 || bias > 5000)
9103               DiagBreak() ;
9104             if (bias < MIN_BIAS)
9105               bias = MIN_BIAS ;
9106             if (bias > MAX_BIAS)
9107               bias = MAX_BIAS ;
9108 
9109             MRISvox(mri_bias, x, y, z) = (short)nint(bias) ;
9110           }
9111           /////////////////////////////////////////////////////
9112         }
9113       }
9114     }
9115   }
9116 
9117   TransformInvert(transform, mri_in) ;
9118   for (n = 0 ; n < nsamples ; n++)
9119   {
9120     if (gcas[n].xp == Gxp && gcas[n].yp == Gyp && gcas[n].zp == Gzp)
9121       DiagBreak() ;
9122 
9123     if (!GCApriorToSourceVoxel(gca, mri_dst, transform,
9124                                gcas[n].xp, gcas[n].yp, gcas[n].zp,
9125                                &xv, &yv, &zv))
9126     {
9127       if (xv == 181 && yv == 146 && zv == 128)
9128         DiagBreak() ;
9129       if (xv == Ggca_x && yv == Ggca_y && zv == Ggca_z)
9130         DiagBreak() ;
9131       if (gcas[n].label == 29 || gcas[n].label == 61)
9132       {
9133         gcas[n].label = 0 ;
9134         DiagBreak() ;
9135       }
9136       if (gcas[n].label > 0)
9137       {
9138         MRIvox(mri_ctrl, xv, yv, zv) = CONTROL_MARKED ;
9139 
9140         for (bias = 0.0, input = 0 ; input < gca->ninputs ; input++)
9141         {
9142           MRIsampleVolumeFrame(mri_in, xv, yv, zv, input, &val) ;
9143           if (FZERO(val))
9144             val = 1 ;
9145           bias += (float)NO_BIAS*((float)gcas[n].means[input]/val) ;
9146         }
9147         bias /= (float)gca->ninputs ;
9148         if (bias < 100 || bias > 5000)
9149           DiagBreak() ;
9150 #if 0
9151         if (bias < MIN_BIAS)
9152           bias = MIN_BIAS ;
9153         if (bias > MAX_BIAS)
9154           bias = MAX_BIAS ;
9155 #endif
9156 
9157         MRISvox(mri_bias, xv, yv, zv) = (short)nint(bias) ;
9158       }
9159       else
9160         MRIvox(mri_ctrl, xv, yv, zv) = CONTROL_NONE ;
9161     }
9162   }
9163 
9164   /* now check for and remove outliers */
9165   mean = sigma = 0.0 ;
9166   for (num = z = 0 ; z < depth ; z++)
9167   {
9168     for (y = 0 ; y < height ; y++)
9169     {
9170       for (x = 0 ; x < width ; x++)
9171       {
9172         if (x == Gx && y == Gy && z == Gz)
9173           DiagBreak() ;
9174         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9175         {
9176           num++ ;
9177           bias = (double)MRISvox(mri_bias, x, y, z) ;
9178           mean += bias ;
9179           sigma += (bias*bias) ;
9180         }
9181       }
9182     }
9183   }
9184 
9185   if (num > 0)
9186   {
9187     mean /= (double)num ;
9188     sigma  = sqrt(sigma / (double)num - mean*mean) ;
9189     printf("bias field = %2.3f +- %2.3f\n", mean/NO_BIAS, sigma/NO_BIAS) ;
9190   }
9191 
9192   /* now check for and remove outliers */
9193   for (total = num = z = 0 ; z < depth ; z++)
9194   {
9195     for (y = 0 ; y < height ; y++)
9196     {
9197       for (x = 0 ; x < width ; x++)
9198       {
9199         if (x == Gx && y == Gy && z == Gz)
9200           DiagBreak() ;
9201         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9202         {
9203           bias = (double)MRISvox(mri_bias, x, y, z) ;
9204           total++ ;
9205           if (fabs(bias-mean) > 4*sigma)
9206           {
9207             MRIvox(mri_ctrl, x, y, z) = CONTROL_NONE ;
9208             num++ ;
9209             MRISvox(mri_bias, x, y, z) = NO_BIAS ;
9210           }
9211         }
9212       }
9213     }
9214   }
9215 
9216   printf("%d of %d control points discarded\n", num, total) ;
9217 
9218   MRIbuildVoronoiDiagram(mri_bias, mri_ctrl, mri_bias) ;
9219   /*  MRIwrite(mri_bias, "bias.mgz") ;*/
9220 #if 1
9221   {
9222     MRI *mri_kernel, *mri_smooth, *mri_down ;
9223     float sigma = 16.0f ;
9224 
9225     mri_down = MRIdownsample2(mri_bias, NULL) ;
9226     mri_kernel = MRIgaussian1d(sigma, 100) ;
9227     mri_smooth = MRIconvolveGaussian(mri_down, NULL, mri_kernel) ;
9228     MRIfree(&mri_bias) ;
9229     MRIfree(&mri_kernel) ;
9230     mri_bias = MRIupsample2(mri_smooth, NULL) ;
9231     sigma = 2.0f ;
9232     MRIfree(&mri_down) ;
9233     MRIfree(&mri_smooth) ;
9234     mri_kernel = MRIgaussian1d(sigma, 100) ;
9235     mri_smooth = MRIconvolveGaussian(mri_bias, NULL, mri_kernel) ;
9236     MRIfree(&mri_bias) ;
9237     mri_bias = mri_smooth ;
9238     MRIfree(&mri_kernel) ;
9239   }
9240 #else
9241   MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, 10) ;
9242 #endif
9243   /*  MRIwrite(mri_bias, "smooth_bias.mgz") ;*/
9244 
9245 
9246   width = mri_in->width ;
9247   height = mri_in->height ;
9248   depth = mri_in->depth ;
9249   for (z = 0 ; z < depth ; z++)
9250   {
9251     for (y = 0 ; y < height ; y++)
9252     {
9253       for (x = 0 ; x < width ; x++)
9254       {
9255         bias = (float)MRISvox(mri_bias, x, y, z)/NO_BIAS ;
9256         if (bias < 0)
9257           DiagBreak() ;
9258         for (input = 0 ; input < gca->ninputs ; input++)
9259         {
9260           MRIsampleVolumeFrame(mri_in, x, y, z, input, &val) ;
9261           val *= bias ;   /* corrected value */
9262           switch (mri_in->type)
9263           {
9264           case MRI_UCHAR:
9265             if (val < 0)
9266               val = 0 ;
9267             else if (val > 255)
9268               val = 255 ;
9269             MRIseq_vox(mri_dst, x, y, z, input) =
9270               (BUFTYPE)nint(val) ;
9271             break ;
9272           case MRI_SHORT:
9273             MRISseq_vox(mri_dst, x, y, z, input) =
9274               (short)nint(val) ;
9275             break ;
9276           case MRI_FLOAT:
9277             MRIFseq_vox(mri_dst, x, y, z, input) = val ;
9278             break ;
9279           default:
9280             ErrorReturn(NULL,
9281                         (ERROR_UNSUPPORTED,
9282                          "GCAnormalizeSamples: "
9283                          "unsupported input type %d",
9284                          mri_in->type));
9285             break ;
9286           }
9287         }
9288       }
9289     }
9290   }
9291 
9292   MRIfree(&mri_bias) ;
9293   MRIfree(&mri_ctrl) ;
9294   return(mri_dst) ;
9295 }
9296 
9297 
9298 void GCAnormalizeSamplesOneChannel(MRI *mri_in, GCA *gca,
9299                                    GCA_SAMPLE *gcas, int nsamples,
9300                                    TRANSFORM *transform,
9301                                    char *ctl_point_fname, int input_index)
9302 /* This function is added by xhan, trying to normalize a single channel */
9303 {
9304 
9305   MRI    *mri_dst, *mri_ctrl, *mri_bias ;
9306   int    xv, yv, zv, n, x, y, z, width, height, depth, xn, yn, zn, num, total;
9307   float   bias ;
9308   double  mean, sigma ;
9309   Real    val ;
9310 
9311   width = mri_in->width ;
9312   height = mri_in->height ;
9313   depth = mri_in->depth ;
9314   mri_dst = mri_in;
9315   mri_ctrl = MRIalloc(width, height, depth, MRI_UCHAR) ;
9316   MRIcopyHeader(mri_in, mri_ctrl);
9317   mri_bias = MRIalloc(mri_in->width,mri_in->height,mri_in->depth,MRI_SHORT);
9318   if (!mri_bias)
9319     ErrorExit(ERROR_NOMEMORY,
9320               "GCAnormalizeSamples: could not allocate "
9321               "(%d,%d,%d,2) bias image",
9322               mri_in->width,mri_in->height,mri_in->depth) ;
9323   MRIcopyHeader(mri_in, mri_bias);
9324 
9325 #define MAX_BIAS 1250
9326 #define NO_BIAS  1000
9327 #define MIN_BIAS  750
9328 
9329   if (ctl_point_fname)
9330   {
9331     MRI3dUseFileControlPoints(mri_ctrl, ctl_point_fname) ;
9332     MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ;
9333   }
9334 
9335   /* add control points from file */
9336   for (z = 0 ; z < depth ; z++)
9337   {
9338     for (y = 0 ; y < height ; y++)
9339     {
9340       for (x = 0 ; x < width ; x++)
9341       {
9342         if (x == Gx && y == Gy && z == Gz)
9343           DiagBreak() ;
9344         MRISvox(mri_bias, x,y,z) = NO_BIAS ;  /* by default */
9345         if (MRIvox(mri_ctrl, x, y, z) != CONTROL_MARKED)
9346           /* not read from file */
9347           continue ;
9348 
9349         if (nsamples == 0)   /* only using file control points */
9350         {
9351           MRIsampleVolumeFrame(mri_in, x, y, z, input_index, &val) ;
9352           bias = NO_BIAS*DEFAULT_DESIRED_WHITE_MATTER_VALUE / val ;
9353           MRISvox(mri_bias, x, y, z) = (short)nint(bias) ;
9354         }
9355         else    /* find atlas point this maps to */
9356         {
9357           int       n, max_n ;
9358           GC1D      *gc ;
9359           GCA_NODE  *gcan ;
9360           GCA_PRIOR *gcap ;
9361           double    max_p ;
9362 
9363           if (!GCAsourceVoxelToNode(gca, mri_dst, transform,
9364                                     x, y, z, &xn, &yn, &zn))
9365           {
9366             gcan = &gca->nodes[xn][yn][zn] ;
9367             gcap = getGCAP(gca, mri_dst, transform, x, y, z) ;
9368             if (gcap==NULL)
9369               continue;
9370             max_p = 0 ;
9371             for (max_n = -1, n = 0 ; n < gcan->nlabels ; n++)
9372             {
9373               if ((0 == IS_WM(gcan->labels[n])) &&
9374                   (0 == IS_CEREBELLAR_WM(gcan->labels[n])) &&
9375                   (gcan->labels[n] != Brain_Stem))
9376                 continue ;
9377               gc = &gcan->gcs[n] ;
9378               if (getPrior(gcap, gcan->labels[n]) >= max_p)
9379               {
9380                 max_p = getPrior(gcap, gcan->labels[n]) ;
9381                 max_n = n ;
9382               }
9383             }
9384             if (max_n < 0)
9385               /* couldn't find any valid label at this location */
9386               continue ;
9387             gc = &gcan->gcs[max_n] ;
9388 
9389 
9390             MRIsampleVolumeFrame(mri_in, x, y, z,
9391                                  input_index, &val) ;
9392             if (FZERO(val))
9393               val = 1 ;
9394             bias =
9395               (float)NO_BIAS*((float)gc->means[input_index]/val) ;
9396 
9397             if (bias < 100 || bias > 5000)
9398               DiagBreak() ;
9399             if (bias < MIN_BIAS)
9400               bias = MIN_BIAS ;
9401             if (bias > MAX_BIAS)
9402               bias = MAX_BIAS ;
9403 
9404             MRISvox(mri_bias, x, y, z) = (short)nint(bias) ;
9405           }
9406           /////////////////////////////////////////////////////
9407         }
9408       }
9409     }
9410   }
9411 
9412   TransformInvert(transform, mri_in) ;
9413   for (n = 0 ; n < nsamples ; n++)
9414   {
9415     if (gcas[n].xp == Ggca_x && gcas[n].yp == Ggca_y && gcas[n].zp == Ggca_z)
9416       DiagBreak() ;
9417 
9418     if (!GCApriorToSourceVoxel(gca, mri_dst, transform,
9419                                gcas[n].xp, gcas[n].yp, gcas[n].zp,
9420                                &xv, &yv, &zv))
9421     {
9422       if (xv == 181 && yv == 146 && zv == 128)
9423         DiagBreak() ;
9424       if (xv == Ggca_x && yv == Ggca_y && zv == Ggca_z)
9425         DiagBreak() ;
9426       if (gcas[n].label == 29 || gcas[n].label == 61)
9427       {
9428         gcas[n].label = 0 ;
9429         DiagBreak() ;
9430       }
9431       if (gcas[n].label > 0)
9432       {
9433         MRIvox(mri_ctrl, xv, yv, zv) = CONTROL_MARKED ;
9434 
9435 
9436         MRIsampleVolumeFrame(mri_in, xv, yv, zv, input_index, &val) ;
9437         if (FZERO(val))
9438           val = 1 ;
9439         bias = (float)NO_BIAS*((float)gcas[n].means[input_index]/val) ;
9440 
9441         if (bias < 100 || bias > 5000)
9442           DiagBreak() ;
9443 #if 0
9444         if (bias < MIN_BIAS)
9445           bias = MIN_BIAS ;
9446         if (bias > MAX_BIAS)
9447           bias = MAX_BIAS ;
9448 #endif
9449 
9450         MRISvox(mri_bias, xv, yv, zv) = (short)nint(bias) ;
9451       }
9452       else
9453         MRIvox(mri_ctrl, xv, yv, zv) = CONTROL_NONE ;
9454     }
9455   }
9456 
9457   /* now check for and remove outliers */
9458   mean = sigma = 0.0 ;
9459   for (num = z = 0 ; z < depth ; z++)
9460   {
9461     for (y = 0 ; y < height ; y++)
9462     {
9463       for (x = 0 ; x < width ; x++)
9464       {
9465         if (x == Gx && y == Gy && z == Gz)
9466           DiagBreak() ;
9467         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9468         {
9469           num++ ;
9470           bias = (double)MRISvox(mri_bias, x, y, z) ;
9471           mean += bias ;
9472           sigma += (bias*bias) ;
9473         }
9474       }
9475     }
9476   }
9477 
9478   if (num > 0)
9479   {
9480     mean /= (double)num ;
9481     sigma  = sqrt(sigma / (double)num - mean*mean) ;
9482     printf("bias field = %2.3f +- %2.3f\n", mean/NO_BIAS, sigma/NO_BIAS) ;
9483   }
9484 
9485   /* now check for and remove outliers */
9486   for (total = num = z = 0 ; z < depth ; z++)
9487   {
9488     for (y = 0 ; y < height ; y++)
9489     {
9490       for (x = 0 ; x < width ; x++)
9491       {
9492         if (x == Gx && y == Gy && z == Gz)
9493           DiagBreak() ;
9494         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9495         {
9496           bias = (double)MRISvox(mri_bias, x, y, z) ;
9497           total++ ;
9498           if (fabs(bias-mean) > 4*sigma)
9499           {
9500             MRIvox(mri_ctrl, x, y, z) = CONTROL_NONE ;
9501             num++ ;
9502             MRISvox(mri_bias, x, y, z) = NO_BIAS ;
9503           }
9504         }
9505       }
9506     }
9507   }
9508 
9509   printf("%d of %d control points discarded\n", num, total) ;
9510 
9511   MRIbuildVoronoiDiagram(mri_bias, mri_ctrl, mri_bias) ;
9512   /*  MRIwrite(mri_bias, "bias.mgz") ;*/
9513 #if 1
9514   {
9515     MRI *mri_kernel, *mri_smooth, *mri_down ;
9516     float sigma = 16.0f ;
9517 
9518     mri_down = MRIdownsample2(mri_bias, NULL) ;
9519     mri_kernel = MRIgaussian1d(sigma, 100) ;
9520     mri_smooth = MRIconvolveGaussian(mri_down, NULL, mri_kernel) ;
9521     MRIfree(&mri_bias) ;
9522     MRIfree(&mri_kernel) ;
9523     mri_bias = MRIupsample2(mri_smooth, NULL) ;
9524     sigma = 2.0f ;
9525     MRIfree(&mri_down) ;
9526     MRIfree(&mri_smooth) ;
9527     mri_kernel = MRIgaussian1d(sigma, 100) ;
9528     mri_smooth = MRIconvolveGaussian(mri_bias, NULL, mri_kernel) ;
9529     MRIfree(&mri_bias) ;
9530     mri_bias = mri_smooth ;
9531     MRIfree(&mri_kernel) ;
9532   }
9533 #else
9534   MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, 10) ;
9535 #endif
9536   /*  MRIwrite(mri_bias, "smooth_bias.mgz") ;*/
9537 
9538 
9539   width = mri_in->width ;
9540   height = mri_in->height ;
9541   depth = mri_in->depth ;
9542   for (z = 0 ; z < depth ; z++)
9543   {
9544     for (y = 0 ; y < height ; y++)
9545     {
9546       for (x = 0 ; x < width ; x++)
9547       {
9548         bias = (float)MRISvox(mri_bias, x, y, z)/NO_BIAS ;
9549         if (bias < 0)
9550           DiagBreak() ;
9551 
9552         MRIsampleVolumeFrame(mri_in, x, y, z, input_index, &val) ;
9553         val *= bias ;   /* corrected value */
9554         switch (mri_in->type)
9555         {
9556         case MRI_UCHAR:
9557           if (val < 0)
9558             val = 0 ;
9559           else if (val > 255)
9560             val = 255 ;
9561           MRIseq_vox(mri_dst, x, y, z, input_index) =
9562             (BUFTYPE)nint(val) ;
9563           break ;
9564         case MRI_SHORT:
9565           MRISseq_vox(mri_dst, x, y, z, input_index) =
9566             (short)nint(val) ;
9567           break ;
9568         case MRI_FLOAT:
9569           MRIFseq_vox(mri_dst, x, y, z, input_index) = val ;
9570           break ;
9571         default:
9572           ErrorPrintf(ERROR_UNSUPPORTED,
9573                       "GCAnormalizeSamples: unsupported input type %d",
9574                       mri_in->type);
9575           break ;
9576         }
9577 
9578       }
9579     }
9580   }
9581 
9582   MRIfree(&mri_bias) ;
9583   MRIfree(&mri_ctrl) ;
9584   return;
9585 }
9586 
9587 MRI *
9588 GCAnormalizeSamplesAllChannels(MRI *mri_in,
9589                                GCA *gca,
9590                                GCA_SAMPLE *gcas,
9591                                int nsamples,
9592                                TRANSFORM *transform,
9593                                char *ctl_point_fname)
9594 {
9595   MRI    *mri_dst;
9596   int input;
9597 
9598   mri_dst = MRIcopy(mri_in, NULL);
9599 
9600   for (input = 0; input < gca->ninputs; input++)
9601   {
9602     GCAnormalizeSamplesOneChannel(mri_dst, gca, gcas, nsamples,
9603                                   transform, ctl_point_fname, input);
9604   }
9605 
9606   return (mri_dst);
9607 
9608 }
9609 
9610 MRI *
9611 GCAnormalizeSamplesT1PD(MRI *mri_in, GCA *gca,
9612                         GCA_SAMPLE *gcas, int nsamples,
9613                         TRANSFORM *transform, char *ctl_point_fname)
9614 {
9615   MRI    *mri_dst, *mri_ctrl, *mri_bias ;
9616   int    xv, yv, zv, n, x, y, z, width, height, depth, \
9617   out_val, xn, yn, zn, num, total ;
9618   Real   val ;
9619   float   bias ;
9620   double  mean, sigma ;
9621 
9622   mri_dst = MRIclone(mri_in, NULL) ;
9623   mri_ctrl = MRIalloc(mri_in->width,mri_in->height,mri_in->depth,MRI_UCHAR);
9624   MRIcopyHeader(mri_in, mri_ctrl);
9625   mri_bias = MRIalloc(mri_in->width,mri_in->height,mri_in->depth,MRI_SHORT);
9626   if (!mri_bias)
9627     ErrorExit(ERROR_NOMEMORY,
9628               "GCAnormalize: could not allocate (%d,%d,%d,2) bias image",
9629               mri_in->width,mri_in->height,mri_in->depth) ;
9630   MRIcopyHeader(mri_in, mri_bias);
9631 
9632 #define MAX_BIAS 1250
9633 #define NO_BIAS  1000
9634 #define MIN_BIAS  750
9635 
9636   if (ctl_point_fname)
9637   {
9638     MRI3dUseFileControlPoints(mri_ctrl, ctl_point_fname) ;
9639     MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ;
9640   }
9641   width = mri_in->width ;
9642   height = mri_in->height ;
9643   depth = mri_in->depth ;
9644 
9645   /* add control points from file */
9646   for (z = 0 ; z < depth ; z++)
9647   {
9648     for (y = 0 ; y < height ; y++)
9649     {
9650       for (x = 0 ; x < width ; x++)
9651       {
9652         if (x == Gx && y == Gy && z == Gz)
9653           DiagBreak() ;
9654         MRISvox(mri_bias, x,y,z) = NO_BIAS ;  /* by default */
9655         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9656           /* read from file */
9657         {
9658           int       n, max_n ;
9659           GC1D      *gc ;
9660           GCA_NODE  *gcan ;
9661           GCA_PRIOR *gcap ;
9662           double    max_p ;
9663 
9664           if (!GCAsourceVoxelToNode(gca, mri_dst,
9665                                     transform,
9666                                     x, y, z, &xn, &yn, &zn))
9667           {
9668             gcan = &gca->nodes[xn][yn][zn] ;
9669             gcap = getGCAP(gca, mri_dst, transform, x, y, z) ;
9670             if (gcap==NULL)
9671               continue;
9672             max_p = 0 ;
9673             for (max_n = -1, n = 0 ; n < gcan->nlabels ; n++)
9674             {
9675               if ((0 == IS_WM(gcan->labels[n])) &&
9676                   (0 == IS_CEREBELLAR_WM(gcan->labels[n])))
9677                 continue ;
9678               gc = &gcan->gcs[n] ;
9679               if (getPrior(gcap, gcan->labels[n]) >= max_p)
9680               {
9681                 max_p = getPrior(gcap, gcan->labels[n]) ;
9682                 max_n = n ;
9683               }
9684             }
9685             if (max_n < 0)
9686               /* couldn't find any valid label at this location */
9687               continue ;
9688             gc = &gcan->gcs[max_n] ;
9689 
9690             MRIsampleVolumeFrameType(mri_in, x, y, z, 1,
9691                                      SAMPLE_NEAREST, &val) ;
9692             if (FZERO(val))
9693               val = 1 ;
9694             bias = (float)NO_BIAS*((float)gc->means[1]/val) ;
9695             if (bias < 100 || bias > 5000)
9696               DiagBreak() ;
9697             if (bias < MIN_BIAS)
9698               bias = MIN_BIAS ;
9699             if (bias > MAX_BIAS)
9700               bias = MAX_BIAS ;
9701 
9702             MRISvox(mri_bias, x, y, z) = (short)nint(bias) ;
9703           }
9704           ////////////////////////////////////////////////
9705         }
9706       }
9707     }
9708   }
9709 
9710 
9711   TransformInvert(transform, mri_in) ;
9712   for (n = 0 ; n < nsamples ; n++)
9713   {
9714     if (gcas[n].xp == Ggca_x && gcas[n].yp == Ggca_y && gcas[n].zp == Ggca_z)
9715       DiagBreak() ;
9716 
9717     if (!GCApriorToSourceVoxel(gca, mri_dst, transform,
9718                                gcas[n].xp, gcas[n].yp, gcas[n].zp,
9719                                &xv, &yv, &zv))
9720     {
9721 
9722       if (xv == 181 && yv == 146 && zv == 128)
9723         DiagBreak() ;
9724       if (xv == Ggca_x && yv == Ggca_y && zv == Ggca_z)
9725         DiagBreak() ;
9726       if (gcas[n].label == 29 || gcas[n].label == 61)
9727       {
9728         gcas[n].label = 0 ;
9729         DiagBreak() ;
9730       }
9731       if (gcas[n].label > 0)
9732       {
9733         MRIvox(mri_ctrl, xv, yv, zv) = CONTROL_MARKED ;
9734         MRIsampleVolumeFrameType(mri_in, xv, yv, zv, 1,
9735                                  SAMPLE_NEAREST, &val) ;
9736         if (FZERO(val))
9737           val = 1 ;
9738         bias = (float)NO_BIAS*((float)gcas[n].means[1]/val) ;
9739         if (bias < 100 || bias > 5000)
9740           DiagBreak() ;
9741 #if 0
9742         if (bias < MIN_BIAS)
9743           bias = MIN_BIAS ;
9744         if (bias > MAX_BIAS)
9745           bias = MAX_BIAS ;
9746 #endif
9747 
9748         MRISvox(mri_bias, xv, yv, zv) = (short)nint(bias) ;
9749       }
9750       else
9751         MRIvox(mri_ctrl, xv, yv, zv) = CONTROL_NONE ;
9752     }
9753   }
9754 
9755   /* now check for and remove outliers */
9756   mean = sigma = 0.0 ;
9757   for (num = z = 0 ; z < depth ; z++)
9758   {
9759     for (y = 0 ; y < height ; y++)
9760     {
9761       for (x = 0 ; x < width ; x++)
9762       {
9763         if (x == Gx && y == Gy && z == Gz)
9764           DiagBreak() ;
9765         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9766         {
9767           num++ ;
9768           bias = (double)MRISvox(mri_bias, x, y, z) ;
9769           mean += bias ;
9770           sigma += (bias*bias) ;
9771         }
9772       }
9773     }
9774   }
9775 
9776   if (num > 0)
9777   {
9778     mean /= (double)num ;
9779     sigma  = sqrt(sigma / (double)num - mean*mean) ;
9780     printf("bias field = %2.3f +- %2.3f\n", mean/NO_BIAS, sigma/NO_BIAS) ;
9781   }
9782 
9783   /* now check for and remove outliers */
9784   for (total = num = z = 0 ; z < depth ; z++)
9785   {
9786     for (y = 0 ; y < height ; y++)
9787     {
9788       for (x = 0 ; x < width ; x++)
9789       {
9790         if (x == Gx && y == Gy && z == Gz)
9791           DiagBreak() ;
9792         if (MRIvox(mri_ctrl, x, y, z) == CONTROL_MARKED)
9793         {
9794           bias = (double)MRISvox(mri_bias, x, y, z) ;
9795           total++ ;
9796           if (fabs(bias-mean) > 4*sigma)
9797           {
9798             MRIvox(mri_ctrl, x, y, z) = CONTROL_NONE ;
9799             num++ ;
9800             MRISvox(mri_bias, x, y, z) = NO_BIAS ;
9801           }
9802         }
9803       }
9804     }
9805   }
9806 
9807   printf("%d of %d control points discarded\n", num, total) ;
9808 
9809   MRIbuildVoronoiDiagram(mri_bias, mri_ctrl, mri_bias) ;
9810   /*  MRIwrite(mri_bias, "bias.mgz") ;*/
9811 #if 0
9812   {
9813     MRI *mri_kernel, *mri_smooth ;
9814 
9815     mri_kernel = MRIgaussian1d(2.0f, 100) ;
9816     mri_smooth = MRIconvolveGaussian(mri_bias, NULL, mri_kernel) ;
9817     MRIfree(&mri_bias) ;
9818     mri_bias = mri_smooth ;
9819     MRIfree(&mri_kernel) ;
9820   }
9821 #else
9822   MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, 10) ;
9823 #endif
9824   /*  MRIwrite(mri_bias, "smooth_bias.mgz") ;*/
9825 
9826 
9827   width = mri_in->width ;
9828   height = mri_in->height ;
9829   depth = mri_in->depth ;
9830   for (z = 0 ; z < depth ; z++)
9831   {
9832     for (y = 0 ; y < height ; y++)
9833     {
9834       for (x = 0 ; x < width ; x++)
9835       {
9836         bias = (float)MRISvox(mri_bias, x, y, z)/NO_BIAS ;
9837         if (bias < 0)
9838           DiagBreak() ;
9839         MRIsampleVolumeFrameType(mri_in, x, y, z, 1,
9840                                  SAMPLE_NEAREST, &val) ;
9841         out_val = nint((float)val*bias) ;
9842         MRISseq_vox(mri_dst, x, y, z, 1) = (short)nint(out_val) ;
9843       }
9844     }
9845   }
9846 
9847   MRIcopyFrame(mri_in, mri_dst, 0, 0) ;  /* copy over T1 frame */
9848   MRIfree(&mri_bias) ;
9849   MRIfree(&mri_ctrl) ;
9850   return(mri_dst) ;
9851 }
9852 
9853 float
9854 GCAlabelProbability(MRI *mri_src, GCA *gca, TRANSFORM *transform,
9855                     float x, float y, float z, int label)
9856 {
9857   int      xn, yn, zn ;
9858   GCA_NODE *gcan ;
9859   GC1D     *gc ;
9860   float    plabel, vals[MAX_GCA_INPUTS] ;
9861 
9862   if (x == Gx && y == Gy && z == Gz)
9863     DiagBreak() ;
9864 
9865   if (!GCAsourceVoxelToNode(gca, mri_src, transform, x, y, z, &xn, &yn, &zn))
9866   {
9867     gcan = &gca->nodes[xn][yn][zn] ;
9868 
9869     load_vals(mri_src, x, y, z, vals, gca->ninputs) ;
9870     gc = GCAfindGC(gca, xn, yn, zn, label) ;
9871     if (gc == NULL || gc->ntraining == 0)
9872       gc = findClosestValidGC(gca, xn, yn, zn, label, 0) ;
9873 
9874     if (gc == NULL)
9875       plabel = 0.0 ;
9876     else
9877       plabel = GCAcomputeConditionalDensity(gc, vals, gca->ninputs, label) ;
9878   }
9879   else
9880     plabel = 0.0;
9881   return(plabel) ;
9882 }
9883 
9884 static GCA_NODE *
9885 findSourceGCAN(GCA *gca, MRI *mri_src, TRANSFORM *transform,
9886                int x, int y, int z)
9887 {
9888   int      xn, yn, zn ;
9889   GCA_NODE *gcan=NULL;
9890 
9891   if (!GCAsourceVoxelToNode(gca, mri_src, transform, x, y, z, &xn, &yn, &zn))
9892   {
9893     gcan = &gca->nodes[xn][yn][zn] ;
9894   }
9895   return(gcan) ;
9896 }
9897 #if 0
9898 static int
9899 getLabelMean(GCA_NODE *gcan, int label, float *pvar, float *means, int ninputs)
9900 {
9901   int   n, r ;
9902   float mean = -1.0f ;
9903 
9904   if (*pvar)
9905     *pvar = 0.0f ;
9906   for (n = 0 ; n < gcan->nlabels ; n++)
9907   {
9908     if (gcan->labels[n] == label)
9909     {
9910       for (r = 0 ; r < ninputs ; r++)
9911         mean = gcan->gcs[n].means[r] ;
9912       if (pvar)
9913         *pvar = covariance_determinant(&gcan->gcs[n], ninputs) ;
9914       ;
9915       break ;
9916     }
9917   }
9918   return(NO_ERROR) ;
9919 }
9920 #endif
9921 MRI   *
9922 GCAmaxLikelihoodBorders(GCA *gca, MRI *mri_inputs, MRI *mri_src,
9923                         MRI *mri_dst, TRANSFORM *transform,
9924                         int max_iter, float min_ratio)
9925 {
9926   int      nchanged, x, y, z, width, height, depth, label, total_changed, i ;
9927   MRI      *mri_tmp ;
9928 
9929   if (mri_src != mri_dst)
9930     mri_dst = MRIcopy(mri_src, mri_dst) ;
9931 
9932   mri_tmp = MRIcopy(mri_dst, NULL) ;
9933 
9934   width = mri_src->width ;
9935   height = mri_src->height ;
9936   depth = mri_src->depth ;
9937 
9938   for (total_changed = i = 0 ; i < max_iter ; i++)
9939   {
9940     nchanged = 0 ;
9941     for (z = 0 ; z < depth ; z++)
9942     {
9943       for (y = 0 ; y < height ; y++)
9944       {
9945         for (x = 0 ; x < width ; x++)
9946         {
9947           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
9948             DiagBreak() ;
9949           if (x == 99 && y == 129 && z == 127)
9950             DiagBreak() ;  /* gray should be wm */
9951           if (x == 98 && y == 124 && z == 127)
9952             DiagBreak() ;  /* wm should be hippo */
9953 
9954           if (borderVoxel(mri_dst,x,y,z))
9955           {
9956             label = GCAmaxLikelihoodBorderLabel(gca,
9957                                                 mri_inputs,
9958                                                 mri_dst,transform,
9959                                                 x, y, z, min_ratio) ;
9960             if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
9961                 (label == Ggca_label
9962                  || nint(MRIgetVoxVal(mri_tmp,x,y,z,0)) == Ggca_label ||
9963                  Ggca_label < 0))
9964             {
9965               DiagBreak() ;
9966 
9967               if (label != nint(MRIgetVoxVal(mri_dst, x, y, z,0)))
9968                 printf(
9969                   "MLE (%d, %d, %d): old label %s (%d), "
9970                   "new label %s (%d)\n",
9971                   x, y, z,
9972                   cma_label_to_name(nint(MRIgetVoxVal(mri_tmp,x,y,z,0))),
9973                   nint(MRIgetVoxVal(mri_tmp,x,y,z,0)),
9974                   cma_label_to_name(label),
9975                   label) ;
9976             }
9977             if (label != nint(MRIgetVoxVal(mri_dst, x, y, z,0)))
9978             {
9979               nchanged++ ;
9980               MRIsetVoxVal(mri_tmp, x, y, z, 0, label) ;
9981             }
9982           }
9983         }
9984       }
9985     }
9986     MRIcopy(mri_tmp, mri_dst) ;
9987     total_changed += nchanged ;
9988     if (!nchanged)
9989       break ;
9990   }
9991 
9992   MRIfree(&mri_tmp) ;
9993   printf("%d border labels changed to MLE ...\n", total_changed) ;
9994   return(mri_dst) ;
9995 }
9996 static int
9997 borderVoxel(MRI *mri, int x, int y, int z)
9998 {
9999   int   xi, yi, zi, xk, yk, zk, label ;
10000 
10001   label = nint(MRIgetVoxVal(mri, x, y, z,0)) ;
10002 
10003   for (xk = -1 ; xk <= 1 ; xk++)
10004   {
10005     xi = mri->xi[x+xk] ;
10006     for (yk = -1 ; yk <= 1 ; yk++)
10007     {
10008       for (zk = -1 ; zk <= 1 ; zk++)
10009       {
10010         if (abs(xk)+abs(yk)+abs(zk) != 1)
10011           continue ;
10012         yi = mri->yi[y+yk] ;
10013         zi = mri->zi[z+zk] ;
10014         if (nint(MRIgetVoxVal(mri, xi, yi, zi, 0)) != label)
10015           return(1) ;
10016       }
10017     }
10018   }
10019   return(0) ;
10020 }
10021 
10022 static int
10023 GCAmaxLikelihoodBorderLabel(GCA *gca, MRI *mri_inputs, MRI *mri_labels,
10024                             TRANSFORM *transform,
10025                             int x, int y, int z, float min_ratio)
10026 {
10027   float    p, max_p, vals[MAX_GCA_INPUTS] ;
10028   int      label, i, xi, yi, zi, best_label, orig_label, n ;
10029   GCA_NODE *gcan ;
10030   GC1D     *gc ;
10031 
10032   if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
10033     DiagBreak() ;
10034 
10035   load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
10036   orig_label = best_label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
10037 
10038   // current GCA_NODE at this point
10039   gcan = findSourceGCAN(gca, mri_inputs, transform, x, y, z) ;
10040   if (gcan == NULL)
10041     return(orig_label) ;
10042 
10043   // current label
10044   // look for classifier for this label and get the p value
10045   gc = NULL ;
10046   for (n = 0 ; n < gcan->nlabels ; n++)
10047     if (gcan->labels[n] == best_label)
10048     {
10049       gc  = &gcan->gcs[n] ;
10050       break ;
10051     }
10052 
10053   if (gc == NULL)
10054   {
10055     ErrorPrintf(ERROR_BADPARM,
10056                 "GCAmaxLikelihoodBorderLabel(%d, %d, %d): "
10057                 "couldn't find gc for label %d",
10058                 x, y, z, best_label) ;
10059     max_p = 0.0 ;
10060   }
10061   else
10062     max_p = GCAcomputeConditionalDensity(gc, vals, gca->ninputs, best_label) ;
10063 
10064   // look around neighbors ///////////////////////////////
10065   for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
10066   {
10067     xi = mri_inputs->xi[x+xnbr_offset[i]] ;
10068     yi = mri_inputs->yi[y+ynbr_offset[i]] ;
10069     zi = mri_inputs->zi[z+znbr_offset[i]] ;
10070     gcan = findSourceGCAN(gca, mri_inputs, transform, xi, yi, zi) ;
10071     if (gcan == NULL)
10072       continue ;
10073     // get the neighbor label
10074     label = nint(MRIgetVoxVal(mri_labels, xi, yi, zi, 0)) ;
10075     gc = NULL ;
10076     for (n = 0 ; n < gcan->nlabels ; n++)
10077       if (gcan->labels[n] == label)
10078       {
10079         // get the classifier for this label at this location
10080         gc  = &gcan->gcs[n] ;
10081         break ;
10082       }
10083     if (gc == NULL)
10084       continue ;  /* label can't occur here */
10085 
10086     // set the label to this neighbor value
10087     MRIsetVoxVal(mri_labels, x, y, z, 0, label) ;
10088     // check if possible
10089     if (gcaGibbsImpossibleConfiguration(gca, mri_labels,
10090                                         x, y, z, transform))
10091     {
10092       MRIsetVoxVal(mri_labels, x, y, z, 0, orig_label) ; // added by xh
10093       continue ; // shouldn't put the original label back ???? -xh
10094     }
10095     // restore the old value
10096     MRIsetVoxVal(mri_labels, x, y, z, 0, orig_label) ;
10097 
10098     // calculate p for this neighbor label
10099     p = GCAcomputeConditionalDensity(gc, vals, gca->ninputs, label) ;
10100     //
10101     if (((best_label == orig_label && p > min_ratio*max_p) ||
10102          // starting loop
10103          (best_label != orig_label && p >= max_p)) &&
10104         // later in the loop
10105         GCAisPossible(gca, mri_labels, label, transform, x, y, z, 0))
10106     {
10107       max_p = p ;
10108       best_label = label ;
10109     }
10110   }
10111 
10112   /* test to make sure that it is not an impossible Gibbs configuration */
10113   if (best_label != nint(MRIgetVoxVal(mri_labels, x, y, z, 0)))
10114   {
10115     label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
10116     MRIsetVoxVal(mri_labels, x, y, z, 0, best_label) ; /* test potential new label */
10117     if (gcaGibbsImpossibleConfiguration(gca, mri_labels, x, y,z, transform))
10118       best_label = label ;  /* revert back to old label */
10119     MRIsetVoxVal(mri_labels, x, y, z, 0, label) ;
10120     /* caller will change it if needed */
10121   }
10122   return(best_label) ;
10123 }
10124 
10125 
10126 int
10127 GCAcomputeLabelStats(GCA *gca, int target_label, float *pvar, float *means)
10128 {
10129   int      x, y, z, n, r ;
10130   double   var, dof, total_dof ;
10131   GC1D     *gc ;
10132   GCA_NODE *gcan ;
10133   float fval;
10134 
10135   var = total_dof = 0.0 ;
10136   memset(means, 0, gca->ninputs*sizeof(float)) ;
10137   for (x = 0 ; x < gca->node_width ; x++)
10138   {
10139     for (y = 0 ; y < gca->node_height ; y++)
10140     {
10141       for (z = 0 ; z < gca->node_depth ; z++)
10142       {
10143         gcan = &gca->nodes[x][y][z] ;
10144 
10145         for (n = 0 ; n < gcan->nlabels ; n++)
10146         {
10147           if (gcan->labels[n] == target_label)
10148           {
10149             gc = &gcan->gcs[n] ;
10150             fval = get_node_prior(gca, target_label, x,y,z);
10151             if (fval != 0)
10152             {
10153               dof =
10154                 get_node_prior(gca, target_label, x, y, z) \
10155                 * gcan->total_training ;
10156               for (r = 0 ; r < gca->ninputs ; r++)
10157                 means[r] += dof*gc->means[r] ;
10158               var += dof*covariance_determinant(gc, gca->ninputs) ;
10159               total_dof += dof ;
10160             }
10161           }
10162         }
10163       }
10164     }
10165   }
10166 
10167   if (total_dof > 0.0)
10168   {
10169     for (r = 0 ; r < gca->ninputs ; r++)
10170       means[r] /= total_dof ;
10171     var /= total_dof ;
10172   }
10173   if (pvar)
10174     *pvar = var ;
10175   return(NO_ERROR) ;
10176 }
10177 int
10178 GCAhistogramTissueStatistics(GCA *gca, MRI *mri_T1,MRI *mri_PD,
10179                              MRI *mri_labeled,
10180                              TRANSFORM *transform, char *fname)
10181 {
10182   int              x, y, z, n, label, biggest_label, T1, PD, xp, yp, zp ;
10183   GCA_NODE         *gcan ;
10184   GCA_TISSUE_PARMS *gca_tp ;
10185   VECTOR           *v_parc, *v_T1 ;
10186   static VECTOR *v_ras_cor = NULL, *v_ras_flash ;
10187   FILE             *fp ;
10188   float            xf, yf, zf ;
10189 
10190   fp = fopen(fname, "w") ;
10191   if (!fp)
10192     ErrorExit(ERROR_NOFILE, "GCAhistogramTissueStatistics: could not open %s",
10193               fname) ;
10194 
10195   v_parc = VectorAlloc(4, MATRIX_REAL) ;
10196   v_T1 = VectorAlloc(4, MATRIX_REAL) ;
10197   *MATRIX_RELT(v_parc, 4, 1) = 1.0 ;
10198   *MATRIX_RELT(v_T1, 4, 1) = 1.0 ;
10199 
10200   /* first build a list of all labels that exist */
10201   for (biggest_label = x = 0 ; x < gca->node_width ; x++)
10202   {
10203     for (y = 0 ; y < gca->node_height ; y++)
10204     {
10205       for (z = 0 ; z < gca->node_height ; z++)
10206       {
10207         gcan = &gca->nodes[x][y][z] ;
10208         for (n = 0 ; n < gcan->nlabels ; n++)
10209         {
10210           gca->tissue_parms[(int)gcan->labels[n]].label
10211           = gcan->labels[n] ;
10212           if (gcan->labels[n] > biggest_label)
10213             biggest_label = gcan->labels[n] ;
10214         }
10215       }
10216     }
10217   }
10218 
10219   for (label = 0 ; label <= biggest_label ; label++)
10220   {
10221     if (gca->tissue_parms[label].label <= 0)
10222       continue ;
10223     gca_tp = &gca->tissue_parms[label] ;
10224 
10225     for (z = 0 ; z < mri_T1->depth ; z++)
10226     {
10227       V3_Z(v_parc) = z ;
10228       for (y = 0 ; y < mri_T1->height ; y++)
10229       {
10230         V3_Y(v_parc) = y ;
10231         for (x = 0 ; x < mri_T1->width ; x++)
10232         {
10233           if (nint(MRIgetVoxVal(mri_labeled, x, y, z, 0)) != label)
10234             continue ;
10235           if (borderVoxel(mri_labeled, x, y, z))
10236             continue ;
10237           if (transform)
10238           {
10239             MATRIX *m_tmp ;
10240             V3_X(v_parc) = x ;
10241 
10242             TransformSample(transform,
10243                             x*mri_T1->xsize,
10244                             y*mri_T1->ysize,
10245                             z*mri_T1->zsize,
10246                             &xf, &yf, &zf) ;
10247             xp = nint(xf) ;
10248             yp = nint(zf) ;
10249             zp = nint(zf) ;
10250             V3_X(v_T1) = xp ;
10251             V3_Y(v_T1) = yp ;
10252             V3_Z(v_T1) = zp ;
10253 
10254             m_tmp = MRIgetVoxelToRasXform(mri_labeled) ;
10255             v_ras_cor = MatrixMultiply(m_tmp, v_parc, v_ras_cor);
10256             MatrixFree(&m_tmp) ;
10257             m_tmp = MRIgetVoxelToRasXform(mri_T1) ;
10258             v_ras_flash = MatrixMultiply(m_tmp, v_T1, v_ras_flash);
10259             MatrixFree(&m_tmp) ;
10260             if (!x && !y && !z && 0)
10261             {
10262               MatrixPrint(stdout, v_ras_cor) ;
10263               MatrixPrint(stdout, v_ras_flash) ;
10264             }
10265 
10266             if ((xp < 0 || xp >= mri_T1->width) ||
10267                 (yp < 0 || yp >= mri_T1->height) ||
10268                 (zp < 0 || zp >= mri_T1->depth))
10269               continue ;
10270           }
10271           else
10272           {
10273             xp = x ;
10274             yp = y ;
10275             zp = z ;
10276           }
10277 
10278           T1 = MRISvox(mri_T1, xp, yp, zp) ;
10279           PD = MRISvox(mri_PD, xp, yp, zp) ;
10280           fprintf(fp, "%d %d %d\n", label, T1, PD) ;
10281           gca_tp->total_training++ ;
10282           gca_tp->T1_mean += T1 ;
10283           gca_tp->T1_var += T1*T1 ;
10284           gca_tp->PD_mean += PD ;
10285           gca_tp->PD_var += PD*PD ;
10286         }
10287       }
10288     }
10289   }
10290 
10291   fclose(fp) ;
10292   return(NO_ERROR) ;
10293 }
10294 
10295 int
10296 GCAnormalizeTissueStatistics(GCA *gca)
10297 {
10298   int              n ;
10299   double           nsamples ;
10300   GCA_TISSUE_PARMS *gca_tp ;
10301 
10302   for (n = 0 ; n < MAX_GCA_LABELS ; n++)
10303   {
10304     gca_tp = &gca->tissue_parms[n] ;
10305     if (gca_tp->total_training <= 0)
10306       continue ;
10307     nsamples = gca_tp->total_training ;
10308     gca_tp->T1_mean /= nsamples ;
10309     gca_tp->PD_mean /= nsamples ;
10310     gca_tp->T2_mean /= nsamples ;
10311     gca_tp->T1_var =
10312       gca_tp->T1_var / nsamples - gca_tp->T1_mean*gca_tp->T1_mean;
10313     gca_tp->PD_var =
10314       gca_tp->PD_var / nsamples - gca_tp->PD_mean*gca_tp->PD_mean;
10315     printf("%s: T1=%4d +- %4d, PD=%4d +- %4d \n",
10316            cma_label_to_name(n),
10317            nint(gca_tp->T1_mean), nint(sqrt(gca_tp->T1_var)),
10318            nint(gca_tp->PD_mean), nint(sqrt(gca_tp->PD_var))) ;
10319   }
10320 
10321   return(NO_ERROR) ;
10322 }
10323 
10324 
10325 char *
10326 cma_label_to_name(int label)
10327 {
10328   static char name[STRLEN] ;
10329 
10330   if (label == Unknown)
10331     return("Unknown") ;
10332   if (label == Left_Cerebral_Exterior)
10333     return("Left_Cerebral_Exterior") ;
10334   if (label == Left_Cerebral_White_Matter)
10335     return("Left_Cerebral_White_Matter") ;
10336   if (label == Left_Cerebral_Cortex)
10337     return("Left_Cerebral_Cortex") ;
10338   if (label == Left_Lateral_Ventricle)
10339     return("Left_Lateral_Ventricle") ;
10340   if (label == Left_Inf_Lat_Vent)
10341     return("Left_Inf_Lat_Vent") ;
10342   if (label == Left_Cerebellum_Exterior)
10343     return("Left_Cerebellum_Exterior") ;
10344   if (label == Left_Cerebellum_White_Matter)
10345     return("Left_Cerebellum_White_Matter") ;
10346   if (label == Left_Cerebellum_Cortex)
10347     return("Left_Cerebellum_Cortex") ;
10348   if (label == Left_Thalamus)
10349     return("Left_Thalamus") ;
10350   if (label == Left_Thalamus_Proper)
10351     return("Left_Thalamus_Proper") ;
10352   if (label == Left_Caudate)
10353     return("Left_Caudate") ;
10354   if (label == Left_Putamen)
10355     return("Left_Putamen") ;
10356   if (label == Left_Pallidum)
10357     return("Left_Pallidum") ;
10358   if (label == Third_Ventricle)
10359     return("Third_Ventricle") ;
10360   if (label == Fourth_Ventricle)
10361     return("Fourth_Ventricle") ;
10362   if (label == Brain_Stem)
10363     return("Brain_Stem") ;
10364   if (label == Left_Hippocampus)
10365     return("Left_Hippocampus") ;
10366   if (label == Left_Amygdala)
10367     return("Left_Amygdala") ;
10368   if (label == Left_Amygdala_Anterior)
10369     return("Left_Amygdala_Anterior") ;
10370   if (label == Left_Insula)
10371     return("Left_Insula") ;
10372   if (label == Left_Operculum)
10373     return("Left_Operculum") ;
10374   if (label == Line_1)
10375     return("Line_1") ;
10376   if (label == Line_2)
10377     return("Line_2") ;
10378   if (label == Line_3)
10379     return("Line_3") ;
10380   if (label == CSF)
10381     return("CSF") ;
10382   if (label == Left_Lesion)
10383     return("Left_Lesion") ;
10384   if (label == Left_Accumbens_area)
10385     return("Left_Accumbens_area") ;
10386   if (label == Left_Substancia_Nigra)
10387     return("Left_Substancia_Nigra") ;
10388   if (label == Left_VentralDC)
10389     return("Left_VentralDC") ;
10390   if (label == Left_undetermined)
10391     return("Left_undetermined") ;
10392   if (label == Left_vessel)
10393     return("Left_vessel") ;
10394   if (label == Left_choroid_plexus)
10395     return("Left_choroid_plexus") ;
10396   if (label == Left_F3orb)
10397     return("Left_F3orb") ;
10398   if (label == Left_lOg)
10399     return("Left_lOg") ;
10400   if (label == Left_aOg)
10401     return("Left_aOg") ;
10402   if (label == Left_mOg)
10403     return("Left_mOg") ;
10404   if (label == Left_pOg)
10405     return("Left_pOg") ;
10406   if (label == Left_Stellate)
10407     return("Left_Stellate") ;
10408   if (label == Left_Porg)
10409     return("Left_Porg") ;
10410   if (label == Left_Aorg)
10411     return("Left_Aorg") ;
10412   if (label == Right_Cerebral_Exterior)
10413     return("Right_Cerebral_Exterior") ;
10414   if (label == Right_Cerebral_White_Matter)
10415     return("Right_Cerebral_White_Matter") ;
10416   if (label == Right_Cerebral_Cortex)
10417     return("Right_Cerebral_Cortex") ;
10418   if (label == Right_Lateral_Ventricle)
10419     return("Right_Lateral_Ventricle") ;
10420   if (label == Right_Inf_Lat_Vent)
10421     return("Right_Inf_Lat_Vent") ;
10422   if (label == Right_Cerebellum_Exterior)
10423     return("Right_Cerebellum_Exterior") ;
10424   if (label == Right_Cerebellum_White_Matter)
10425     return("Right_Cerebellum_White_Matter") ;
10426   if (label == Right_Cerebellum_Cortex)
10427     return("Right_Cerebellum_Cortex") ;
10428   if (label == Right_Thalamus)
10429     return("Right_Thalamus") ;
10430   if (label == Right_Thalamus_Proper)
10431     return("Right_Thalamus_Proper") ;
10432   if (label == Right_Caudate)
10433     return("Right_Caudate") ;
10434   if (label == Right_Putamen)
10435     return("Right_Putamen") ;
10436   if (label == Right_Pallidum)
10437     return("Right_Pallidum") ;
10438   if (label == Right_Hippocampus)
10439     return("Right_Hippocampus") ;
10440   if (label == Right_Amygdala)
10441     return("Right_Amygdala") ;
10442   if (label == Right_Amygdala_Anterior)
10443     return("Right_Amygdala_Anterior") ;
10444   if (label == Right_Insula)
10445     return("Right_Insula") ;
10446   if (label == Right_Operculum)
10447     return("Right_Operculum") ;
10448   if (label == Right_Lesion)
10449     return("Right_Lesion") ;
10450   if (label == Right_Accumbens_area)
10451     return("Right_Accumbens_area") ;
10452   if (label == Right_Substancia_Nigra)
10453     return("Right_Substancia_Nigra") ;
10454   if (label == Right_VentralDC)
10455     return("Right_VentralDC") ;
10456   if (label == Right_undetermined)
10457     return("Right_undetermined") ;
10458   if (label == Right_vessel)
10459     return("Right_vessel") ;
10460   if (label == Right_choroid_plexus)
10461     return("Right_choroid_plexus") ;
10462   if (label == Right_F3orb)
10463     return("Right_F3orb") ;
10464   if (label == Right_lOg)
10465     return("Right_lOg") ;
10466   if (label == Right_aOg)
10467     return("Right_aOg") ;
10468   if (label == Right_mOg)
10469     return("Right_mOg") ;
10470   if (label == Right_pOg)
10471     return("Right_pOg") ;
10472   if (label == Right_Stellate)
10473     return("Right_Stellate") ;
10474   if (label == Right_Porg)
10475     return("Right_Porg") ;
10476   if (label == Right_Aorg)
10477     return("Right_Aorg") ;
10478   if (label == Bone)
10479     return("Bone") ;
10480   if (label == Fat)
10481     return("Fat") ;
10482   if (label == Bright_Unknown)
10483     return("Bright Unknown") ;
10484   if (label == Dark_Unknown)
10485     return("Dark Unknown") ;
10486 
10487   if (label == Left_Interior)
10488     return("Left_Interior") ;
10489   if (label == Right_Interior)
10490     return("Right_Interior") ;
10491   if (label == Left_Lateral_Ventricles)
10492     return("Left_Lateral_Ventricles") ;
10493   if (label == Right_Lateral_Ventricles)
10494     return("Right_Lateral_Ventricles") ;
10495   if (label == WM_hypointensities)
10496     return("WM_hypointensities") ;
10497   if (label == Left_WM_hypointensities)
10498     return("Left_WM_hypointensities") ;
10499   if (label == Right_WM_hypointensities)
10500     return("Right_WM_hypointensities") ;
10501   if (label == non_WM_hypointensities)
10502     return("non_WM_hypointensities") ;
10503   if (label == Left_non_WM_hypointensities)
10504     return("Left_non_WM_hypointensities") ;
10505   if (label == Right_non_WM_hypointensities)
10506     return("Right_non_WM_hypointensities") ;
10507   if (label == Fifth_Ventricle)
10508     return("Fifth_Ventricle") ;
10509   if (label == Optic_Chiasm)
10510     return("Optic_Chiasm") ;
10511   if (label == Cranium)
10512     return("Cranium") ;
10513   if (label == Dura)
10514     return("Dura") ;
10515   if (label == CSF_SA)
10516     return("CSF_SA") ;
10517   if (label == Ear)
10518     return("Ear") ;
10519   if (label == Muscle)
10520     return("Muscle") ;
10521   if (label == Epidermis)
10522     return("Epidermis") ;
10523   if (label == Conn_Tissue)
10524     return("Conn_Tissue") ;
10525   if (label == SC_FAT_MUSCLE)
10526     return("SC-Fat/Muscle") ;
10527   if (label == Fatty_Tissue)
10528     return("Fatty_Tissue") ;
10529   if (label == Spinal_Cord)
10530     return("Spinal_Cord") ;
10531   if (label == Soft_Tissue)
10532     return("Soft_Tissue") ;
10533   if (label == Nerve)
10534     return("Nerve") ;
10535   if (label == Bone)
10536     return("Bone") ;
10537   if (label == Air)
10538     return("Air") ;
10539   if (label == Orbit)
10540     return("Orbit") ;
10541   if (label == Tongue)
10542     return("Tongue") ;
10543   if (label == Nasal_Structures)
10544     return("Nasal_Structures") ;
10545   if (label == Globe)
10546     return("Globe") ;
10547   if (label == Teeth)
10548     return("Teeth") ;
10549 
10550   if (label == alveus)
10551     return("alveus") ;
10552   if (label == perforant_pathway    )
10553     return("perforant_pathway") ;
10554   if (label == parasubiculum    )
10555     return("parasubiculum") ;
10556   if (label == presubiculum     )
10557     return("presubiculum") ;
10558   if (label == subiculum      )
10559     return("subiculum") ;
10560   if (label == CA1        )
10561     return("CA1") ;
10562   if (label == CA2        )
10563     return("CA2") ;
10564   if (label == CA3        )
10565     return("CA3") ;
10566   if (label == CA4        )
10567     return("CA4") ;
10568   if (label == GC_DG      )
10569     return("GC_DG") ;
10570   if (label == HATA       )
10571     return("HATA") ;
10572   if (label == fimbria  )
10573     return("fimbria") ;
10574   if (label == lateral_ventricle    )
10575     return("lateral_ventricle") ;
10576   if (label == molecular_layer_HP  )
10577     return("molecular_layer_HP") ;
10578   if (label == hippocampal_fissure  )
10579     return("hippocampal_fissure") ;
10580   if (label == entorhinal_cortex  )
10581     return("entorhinal_cortex") ;
10582   if (label == molecular_layer_subiculum)
10583     return("molecular_layer_subiculum") ;
10584   if (label == Amygdala)
10585     return("Amygdala") ;
10586   if (label == Cerebral_White_Matter  )
10587     return("Cerebral_White_Matter") ;
10588   if (label == Cerebral_Cortex  )
10589     return("Cerebral_Cortex") ;
10590   if (label == Inf_Lat_Vent  )
10591     return("Inf_Lat_Vent") ;
10592 #if 0
10593   if (Left_hippocampal_fissure == label)
10594     return("Left_hippocampal_fissure") ;
10595   if (Left_CADG_head == label)
10596     return("Left_CADG_head") ;
10597   if (Left_subiculum == label)
10598     return("Left_subiculum") ;
10599   if (Left_fimbria == label)
10600     return("Left_fimbria") ;
10601   if (Right_hippocampal_fissure == label)
10602     return("Right_hippocampal_fissure") ;
10603   if (Right_CADG_head == label)
10604     return("Right_CADG_head") ;
10605   if (Right_subiculum == label)
10606     return("Right_subiculum") ;
10607   if (Right_fimbria == label)
10608     return("Right_fimbria") ;
10609 #endif
10610   if (Fornix == label)
10611     return("Fornix") ;
10612 
10613   if (label == BA17)
10614     return("BA17") ;
10615   if (label == BA18)
10616     return("BA18") ;
10617   if (label == BA44)
10618     return("BA44") ;
10619   if (label == BA45)
10620     return("BA45") ;
10621   if (label == BA4a)
10622     return("BA4a") ;
10623   if (label == BA4p)
10624     return("BA4p") ;
10625   if (label == BA6)
10626     return("BA6") ;
10627   if (label == BA2)
10628     return("BA2") ;
10629   if (label == BAun1)
10630     return("BAun1") ;
10631   if (label == BAun2)
10632     return("BAun2") ;
10633   if (label == right_CA2_3)
10634     return("right_CA2_3") ;
10635   if (label == right_alveus)
10636     return("right_alveus") ;
10637   if (label == right_CA1)
10638     return("right_CA1") ;
10639   if (label == right_fimbria)
10640     return("right_fimbria") ;
10641   if (label == right_presubiculum)
10642     return("right_presubiculum") ;
10643   if (label == right_hippocampal_fissure)
10644     return("right_hippocampal_fissure") ;
10645   if (label == right_CA4_DG)
10646     return("right_CA4_DG") ;
10647   if (label == right_subiculum)
10648     return("right_subiculum") ;
10649   if (label == left_CA2_3)
10650     return("left_CA2_3") ;
10651   if (label == left_alveus)
10652     return("left_alveus") ;
10653   if (label == left_CA1)
10654     return("left_CA1") ;
10655   if (label == left_fimbria)
10656     return("left_fimbria") ;
10657   if (label == left_presubiculum)
10658     return("left_presubiculum") ;
10659   if (label == left_hippocampal_fissure)
10660     return("left_hippocampal_fissure") ;
10661   if (label == left_CA4_DG)
10662     return("left_CA4_DG") ;
10663   if (label == left_subiculum)
10664     return("left_subiculum") ;
10665 
10666 
10667   if (label == left_fornix)
10668     return("left_fornix") ;
10669   if (label == right_fornix)
10670     return("right_fornix") ;
10671 
10672   return(name) ;
10673 }
10674 MRI *
10675 GCArelabel_cortical_gray_and_white(GCA *gca,
10676                                    MRI *mri_inputs,
10677                                    MRI *mri_src,
10678                                    MRI *mri_dst,
10679                                    TRANSFORM *transform)
10680 {
10681   int      nchanged, x, y, z, width, height, depth, total_changed,
10682   label, xn, yn, zn, left, new_wm, new_gray ;
10683   MRI      *mri_tmp ;
10684   GCA_NODE *gcan ;
10685   GC1D     *gc_gray, *gc_wm ;
10686   float    vals[MAX_GCA_INPUTS], gray_dist, wm_dist ;
10687   float    grayPrior;
10688   float    wmPrior;
10689   int      xp, yp, zp;
10690 
10691   GCA_PRIOR *gcap = 0;
10692 
10693   if (mri_src != mri_dst)
10694     mri_dst = MRIcopy(mri_src, mri_dst) ;
10695 
10696   mri_tmp = MRIcopy(mri_dst, NULL) ;
10697 
10698   width = mri_src->width ;
10699   height = mri_src->height ;
10700   depth = mri_src->depth ;
10701 
10702   total_changed = new_wm = new_gray = 0 ;
10703   do
10704   {
10705     nchanged = 0 ;
10706     for (z = 0 ; z < depth ; z++)
10707     {
10708       for (y = 0 ; y < height ; y++)
10709       {
10710         for (x = 0 ; x < width ; x++)
10711         {
10712           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
10713             DiagBreak() ;
10714 
10715           label = nint(MRIgetVoxVal(mri_src, x, y, z, 0)) ;
10716           if (label != Left_Cerebral_Cortex &&
10717               label != Left_Cerebral_White_Matter &&
10718               label != Right_Cerebral_Cortex &&
10719               label != Right_Cerebral_White_Matter)
10720             continue ;
10721 
10722           load_vals(mri_inputs, x, y, z, vals, gca->ninputs);
10723           if (!GCAsourceVoxelToNode(gca, mri_dst,
10724                                     transform,
10725                                     x, y, z, &xn, &yn, &zn))
10726           {
10727             gcan = &gca->nodes[xn][yn][zn] ;
10728             // label is left cortex or wm
10729             if (label == Left_Cerebral_Cortex ||
10730                 label == Left_Cerebral_White_Matter)
10731             {
10732               left = 1 ;
10733               gc_gray =
10734                 GCAfindGC(gca, xn, yn, zn,
10735                           Left_Cerebral_Cortex) ;
10736               gc_wm =
10737                 GCAfindGC(gca, xn, yn, zn,
10738                           Left_Cerebral_White_Matter) ;
10739             }
10740             // label is right cortex or wm
10741             else
10742             {
10743               gc_gray = GCAfindGC(gca, xn, yn, zn,
10744                                   Right_Cerebral_Cortex) ;
10745               gc_wm = GCAfindGC(gca, xn, yn, zn,
10746                                 Right_Cerebral_White_Matter) ;
10747               left = 0 ;
10748             }
10749             // can't be found
10750             if (!gc_wm || !gc_gray)
10751               continue ;
10752             // calculate Mahalanobis distance
10753             gray_dist = sqrt(GCAmahDistIdentityCovariance
10754                              (gc_gray,
10755                               vals,
10756                               gca->ninputs)) ;
10757             wm_dist = sqrt(GCAmahDistIdentityCovariance
10758                            (gc_wm,
10759                             vals, gca->ninputs)) ;
10760 
10761             // get the prior coordinate
10762             if (!GCAsourceVoxelToPrior(gca, mri_dst,
10763                                        transform,
10764                                        x, y, z, &xp, &yp, &zp))
10765             {
10766               gcap = &gca->priors[xp][yp][zp];
10767               if (gcap==NULL)
10768                 continue;
10769               // labeling gray but check Prior
10770               if (left)
10771               {
10772                 grayPrior = getPrior(gcap, Left_Cerebral_Cortex);
10773                 wmPrior = getPrior(gcap,
10774                                    Left_Cerebral_White_Matter);
10775               }
10776               else
10777               {
10778                 grayPrior = getPrior(gcap,
10779                                      Right_Cerebral_Cortex);
10780                 wmPrior = getPrior(gcap,
10781                                    Right_Cerebral_White_Matter);
10782               }
10783             }
10784             else
10785             {
10786               grayPrior = -1;
10787               wmPrior = -1;
10788             }
10789             // if grey < wm
10790             if (gray_dist < wm_dist && grayPrior > 0 && wmPrior > 0)
10791               // if ((5*gray_dist) < wm_dist &&
10792               // grayPrior > 0 && wmPrior > 0)
10793             {
10794               // if prior is not high, then you
10795               // can change white->gray
10796               if (wmPrior < 0.9)
10797                 // label cortex
10798                 label = left ? Left_Cerebral_Cortex :
10799                         Right_Cerebral_Cortex ;
10800               // else
10801               // printf("(%d,%d,%d) had gray_dist(%.2f) "
10802               //"< wm_dist (%.2f),
10803               // but grayPrior(%.2f) < wmPrior(%.2f)\n",
10804               // x, y, z, gray_dist, wm_dist, grayPrior, wmPrior);
10805             }
10806             else
10807             {
10808               // if prior is not high,
10809               // then you can change gray->white
10810               if (grayPrior < 0.9 && grayPrior > 0 && wmPrior > 0)
10811                 // label wm
10812                 //if ((5*wm_dist < gray_dist)
10813                 // && grayPrior > 0 && wmPrior > 0)
10814                 label =
10815                   left ? Left_Cerebral_White_Matter : \
10816                   Right_Cerebral_White_Matter ;
10817               // else
10818               // printf("(%d,%d,%d) had gray_dist(%.2f) > "
10819               //"wm_dist (%.2f), but grayPrior(%.2f)
10820               // > wmPrior(%.2f)\n",
10821               //    x, y, z, gray_dist, wm_dist,
10822               // grayPrior, wmPrior);
10823             }
10824             // if label changed from the current one
10825             // and it is possible
10826             if (label != nint(MRIgetVoxVal(mri_dst, x, y, z,0)) && \
10827                 GCAisPossible(gca, mri_dst, label,
10828                               transform, x, y, z,0))
10829             {
10830               if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
10831                   (label == Ggca_label || Ggca_label < 0))
10832               {
10833                 int in ;
10834                 VECTOR *v_means = 0;
10835 
10836                 printf("relabel_cortical_gray_and_white: "
10837                        "voxel(%d,%d,%d), inputs=", x, y, z) ;
10838                 for (in = 0 ;in < gca->ninputs ; in++)
10839                   printf("%2.1f ", vals[in]) ;
10840                 printf("label=%s (%d)\n",
10841                        cma_label_to_name(label),label);
10842                 printf(" gray_dist = %.2f, wm_dist = %.2f\n",
10843                        gray_dist, wm_dist);
10844                 v_means = load_mean_vector(gc_gray,
10845                                            v_means,
10846                                            gca->ninputs);
10847                 printf("v_means for gray = ");
10848                 MatrixPrint(stdout, v_means);
10849                 v_means = load_mean_vector(gc_wm,
10850                                            v_means,
10851                                            gca->ninputs);
10852                 printf("v_means for wm = ");
10853                 MatrixPrint(stdout, v_means);
10854                 VectorFree(&v_means);
10855               }
10856               // count changed label
10857               if (label == Left_Cerebral_Cortex ||label == \
10858                   Right_Cerebral_Cortex)
10859                 new_gray++ ;
10860               else
10861                 new_wm++ ;
10862               nchanged++ ;
10863               MRIsetVoxVal(mri_tmp, x, y, z, 0, label) ;
10864             }
10865           }
10866           //////////////////////////////////
10867         }
10868       }
10869     }
10870     MRIcopy(mri_tmp, mri_dst) ;
10871     total_changed += nchanged ;
10872   }
10873   while (nchanged > 0) ;
10874 
10875   MRIfree(&mri_tmp) ;
10876   printf("%d gm and wm labels changed (%%%2.0f to gray, %%%2.0f to "
10877          "white out of all changed labels)\n",
10878          total_changed, 100.0f*(float)new_gray/total_changed,
10879          100.0f*(float)new_wm/total_changed) ;
10880   return(mri_dst) ;
10881 }
10882 int
10883 GCAdump(GCA *gca,MRI *mri,int x, int y, int z,
10884         TRANSFORM *transform, FILE *fp, int verbose)
10885 {
10886   int       xn, yn, zn, xp, yp, zp ;
10887   GCA_NODE  *gcan ;
10888   GCA_PRIOR *gcap ;
10889 
10890   if (!GCAsourceVoxelToNode(gca, mri, transform, x, y, z, &xn, &yn, &zn))
10891   {
10892     if (!GCAsourceVoxelToPrior(gca, mri, transform, x, y, z, &xp, &yp, &zp))
10893     {
10894       printf("\nGCA node at voxel (%d, %d, %d) --> node "
10895              "(%d, %d, %d), prior (%d, %d, %d)\n",
10896              x, y, z, xn, yn, zn, xp, yp, zp) ;
10897       gcan = &gca->nodes[xn][yn][zn] ;
10898       gcap = getGCAP(gca, mri, transform, x, y, z) ;
10899       if (gcap==NULL)
10900         printf("\nGCAdump: prior point is outside.\n");
10901       dump_gcan(gca, gcan, fp, verbose, gcap) ;
10902     }
10903     else
10904       printf("\nGCAdump: prior point is outside.\n");
10905   }
10906   else
10907     printf("\nGCAdump: node point is outside.\n");
10908   return(NO_ERROR) ;
10909 }
10910 
10911 #if 0
10912 static GCA_SAMPLE *
10913 gcaExtractRegionLabelAsSamples(GCA *gca, MRI *mri_labeled,
10914                                TRANSFORM *transform,
10915                                int *pnsamples, int label, int xp, int yp,
10916                                int zp, int wsize)
10917 {
10918   int         i, nsamples, width, height, depth, x, y, z,
10919   xi, yi, zi, xk, yk, zk, whalf ;
10920   GCA_SAMPLE  *gcas ;
10921   GCA_PRIOR   *gcap ;
10922   GC1D        *gc ;
10923 
10924   width = mri_labeled->width ;
10925   height = mri_labeled->height ;
10926   depth = mri_labeled->depth ;
10927   whalf = (wsize-1)/2 ;
10928   gcap = &gca->priors[xp][yp][zp] ;
10929 
10930   TransformInvert(transform, mri_labeled) ;
10931   if (!GCApriorToSourceVoxel(gca, mri_labeled, transform,
10932                              xp, yp, zp, &x, &y, &z))
10933   {
10934     for (nsamples = 0, zk = -whalf  ; zk <= whalf ; zk++)
10935     {
10936       zi = mri_labeled->zi[z + zk] ;
10937       for (yk = -whalf ; yk <= whalf ; yk++)
10938       {
10939         yi = mri_labeled->yi[y + yk] ;
10940         for (xk = -whalf ; xk <= whalf ; xk++)
10941         {
10942           xi = mri_labeled->xi[x + xk] ;
10943           if (nint(MRIgetVoxVal(mri_labeled, xi, yi, zi, 0)) != label)
10944             continue ;
10945           if (xi == Ggca_x && yi == Ggca_y && zi == Ggca_z)
10946             DiagBreak() ;
10947           nsamples++ ;
10948         }
10949       }
10950     }
10951   }
10952   gcas = (GCA_SAMPLE *)calloc(nsamples, sizeof(GCA_SAMPLE)) ;
10953   if (!gcas)
10954     ErrorExit(ERROR_NOMEMORY,
10955               "gcaExtractLabelAsSamples(%d): could not allocate %d samples\n",
10956               label, nsamples) ;
10957 
10958 
10959   /* go through region again and fill in samples */
10960   for (i = 0, zk = -whalf  ; zk <= whalf ; zk++)
10961   {
10962     zi = mri_labeled->zi[z + zk] ;
10963     for (yk = -whalf ; yk <= whalf ; yk++)
10964     {
10965       yi = mri_labeled->yi[y + yk] ;
10966       for (xk = -whalf ; xk <= whalf ; xk++)
10967       {
10968         xi = mri_labeled->xi[x + xk] ;
10969         if (nint(MRIgetVoxVal(mri_labeled, xi, yi, zi, 0)) != label)
10970           continue ;
10971         if (xi == Ggca_x && yi == Ggca_y && zi == Ggca_z)
10972           DiagBreak() ;
10973 
10974         gcap = getGCAP(gca, mri_labeled, transform, xi, yi, zi) ;
10975         if (gcap==NULL)
10976           continue;
10977         if (!GCAsourceVoxelToPrior(gca, mri_labeled,
10978                                    transform, xi, yi, zi, &xp, &yp, &zp))
10979         {
10980           gc = GCAfindPriorGC(gca, xp, yp, zp, label) ;
10981           if (!gc || !gcap)
10982           {
10983             nsamples-- ;   /* shouldn't happen */
10984             continue ;
10985           }
10986 
10987           gcas[i].label = label ;
10988           gcas[i].xp = xp ;
10989           gcas[i].yp = yp ;
10990           gcas[i].zp = zp ;
10991           gcas[i].x = xi ;
10992           gcas[i].y = yi ;
10993           gcas[i].z = zi ;
10994           gcas[i].var = gc->var ;
10995           gcas[i].mean = gc->mean ;
10996           gcas[i].prior = getPrior(gcap, label) ;
10997           if (FZERO(gcas[i].prior))
10998             DiagBreak() ;
10999           i++ ;
11000         }// !GCAsourceVoxel
11001       }
11002     }
11003   }
11004 
11005   *pnsamples = nsamples ;
11006   return(gcas) ;
11007 }
11008 #endif
11009 
11010 static GCA_SAMPLE *
11011 gcaExtractThresholdedRegionLabelAsSamples(GCA *gca, MRI *mri_labeled,
11012     TRANSFORM *transform,
11013     int *pnsamples,
11014     int label, int xp, int yp,
11015     int zp, int wsize, float pthresh)
11016 {
11017   int         i, width, height, depth, x, y, z,
11018   xi, yi, zi, xk, yk, zk, whalf, r, c, v ;
11019   int         nsamples = 0;
11020   GCA_SAMPLE  *gcas ;
11021   GCA_PRIOR   *gcap ;
11022   GC1D        *gc ;
11023   float       prior ;
11024 
11025   width = mri_labeled->width ;
11026   height = mri_labeled->height ;
11027   depth = mri_labeled->depth ;
11028   whalf = (wsize-1)/2 ;
11029   gcap = &gca->priors[xp][yp][zp] ;
11030   if (gcap==NULL)
11031     return NULL;
11032   TransformInvert(transform, mri_labeled) ;
11033   if (!GCApriorToSourceVoxel(gca, mri_labeled, transform,
11034                              xp, yp, zp, &x, &y, &z))
11035   {
11036     for (nsamples = 0, zk = -whalf  ; zk <= whalf ; zk++)
11037     {
11038       zi = mri_labeled->zi[z + zk] ;
11039       for (yk = -whalf ; yk <= whalf ; yk++)
11040       {
11041         yi = mri_labeled->yi[y + yk] ;
11042         for (xk = -whalf ; xk <= whalf ; xk++)
11043         {
11044           xi = mri_labeled->xi[x + xk] ;
11045           if (nint(MRIgetVoxVal(mri_labeled, xi, yi, zi, 0)) != label)
11046             continue ;
11047           if (xi == Ggca_x && yi == Ggca_y && zi == Ggca_z)
11048             DiagBreak() ;
11049           nsamples++ ;
11050         }
11051       }
11052     }
11053   }
11054 
11055   gcas = (GCA_SAMPLE *)calloc(nsamples, sizeof(GCA_SAMPLE)) ;
11056   if (!gcas)
11057     ErrorExit(ERROR_NOMEMORY,
11058               "gcaExtractLabelAsSamples(%d): could not allocate %d samples\n",
11059               label, nsamples) ;
11060 
11061 
11062   /* go through region again and fill in samples */
11063   for (i = 0, zk = -whalf  ; zk <= whalf ; zk++)
11064   {
11065     zi = mri_labeled->zi[z + zk] ;
11066     for (yk = -whalf ; yk <= whalf ; yk++)
11067     {
11068       yi = mri_labeled->yi[y + yk] ;
11069       for (xk = -whalf ; xk <= whalf ; xk++)
11070       {
11071         xi = mri_labeled->xi[x + xk] ;
11072         if (nint(MRIgetVoxVal(mri_labeled, xi, yi, zi, 0)) != label)
11073           continue ;
11074         if (xi == Ggca_x && yi == Ggca_y && zi == Ggca_z)
11075           DiagBreak() ;
11076 
11077         gcap = getGCAP(gca, mri_labeled, transform, xi, yi, zi) ;
11078         if (gcap==NULL)
11079           continue;
11080         if (!GCAsourceVoxelToPrior(gca, mri_labeled,
11081                                    transform, xi, yi, zi, &xp, &yp, &zp))
11082         {
11083           gc = GCAfindPriorGC(gca, xp, yp, zp, label) ;
11084           if (gcap)
11085             prior = getPrior(gcap, label) ;
11086           else
11087             prior = 0 ;
11088           if (!gc || !gcap || prior < pthresh)
11089           {
11090             nsamples-- ;   /* shouldn't happen */
11091             continue ;
11092           }
11093 
11094           gcas[i].label = label ;
11095           gcas[i].xp = xp ;
11096           gcas[i].yp = yp ;
11097           gcas[i].zp = zp ;
11098           gcas[i].x = xi ;
11099           gcas[i].y = yi ;
11100           gcas[i].z = zi ;
11101           gcas[i].means =
11102             (float *)calloc(gca->ninputs, sizeof(float)) ;
11103           gcas[i].covars =
11104             (float *)calloc((gca->ninputs*(gca->ninputs+1))/2,
11105                             sizeof(float)) ;
11106           if (!gcas[i].means || !gcas[i].covars)
11107             ErrorExit(ERROR_NOMEMORY,
11108                       "GCArenormalizeAdapative: could not allocate "
11109                       "mean (%d) and covariance (%d) matrices",
11110                       gca->ninputs, gca->ninputs*(gca->ninputs+1)/2) ;
11111           for (r = v = 0 ; r < gca->ninputs ; r++)
11112           {
11113             gcas[i].means[r] = gc->means[r] ;
11114             for (c = r ; c < gca->ninputs ; c++)
11115               gcas[i].covars[v] = gc->covars[v] ;
11116           }
11117           gcas[i].prior = prior ;
11118           if (FZERO(gcas[i].prior))
11119             DiagBreak() ;
11120           i++ ;
11121         }
11122       }
11123     }
11124   }
11125 
11126   *pnsamples = nsamples ;
11127   return(gcas) ;
11128 }
11129 
11130 static GCA_SAMPLE *
11131 gcaExtractLabelAsSamples(GCA *gca, MRI *mri_labeled, TRANSFORM *transform,
11132                          int *pnsamples, int label)
11133 {
11134   int         i, nsamples, width, height, depth,
11135   x, y, z, xp, yp, zp, n, r, c, v ;
11136   GCA_SAMPLE  *gcas ;
11137   GCA_PRIOR    *gcap ;
11138   GC1D        *gc ;
11139 
11140   width = mri_labeled->width ;
11141   height = mri_labeled->height ;
11142   depth = mri_labeled->depth ;
11143 
11144   for (nsamples = z = 0 ; z < depth ; z++)
11145   {
11146     for (y = 0 ; y < height ; y++)
11147     {
11148       for (x = 0 ; x < width ; x++)
11149       {
11150         if (nint(MRIgetVoxVal(mri_labeled, x, y, z, 0)) != label)
11151           continue ;
11152         nsamples++ ;
11153       }
11154     }
11155   }
11156 
11157   gcas = (GCA_SAMPLE *)calloc(nsamples, sizeof(GCA_SAMPLE)) ;
11158   if (!gcas)
11159     ErrorExit(ERROR_NOMEMORY,
11160               "gcaExtractLabelAsSamples(%d): could not allocate %d samples\n",
11161               label, nsamples) ;
11162 
11163 
11164   for (i = z = 0 ; z < depth ; z++)
11165   {
11166     for (y = 0 ; y < height ; y++)
11167     {
11168       for (x = 0 ; x < width ; x++)
11169       {
11170         if (nint(MRIgetVoxVal(mri_labeled, x, y, z, 0)) != label)
11171           continue ;
11172 
11173         if (!GCAsourceVoxelToPrior(gca, mri_labeled,
11174                                    transform, x, y, z, &xp, &yp, &zp))
11175         {
11176           gcap = &gca->priors[xp][yp][zp] ;
11177           if (gcap==NULL)
11178             continue;
11179           for (n = 0 ; n < gcap->nlabels ; n++)
11180           {
11181             if (gcap->labels[n] == label)
11182               break ;
11183           }
11184 
11185           gc = GCAfindPriorGC(gca, xp, yp, zp, label) ;
11186           if (n >= gcap->nlabels || !gc)
11187           {
11188             nsamples-- ;   /* doesn't exist at this location */
11189             continue ;   /* ?? */
11190           }
11191           gcas[i].label = label ;
11192           gcas[i].xp = xp ;
11193           gcas[i].yp = yp ;
11194           gcas[i].zp = zp ;
11195           gcas[i].x = x ;
11196           gcas[i].y = y ;
11197           gcas[i].z = z ;
11198           for (r = v = 0 ; r < gca->ninputs ; r++)
11199           {
11200             gcas[i].means[r] = gc->means[r] ;
11201             for (c = r ; c < gca->ninputs ; c++)
11202               gcas[i].covars[v] = gc->covars[v] ;
11203           }
11204           gcas[i].prior = getPrior(gcap, label) ;
11205           if (FZERO(gcas[i].prior))
11206             DiagBreak() ;
11207           i++ ;               // this i is never used??????
11208         } // !GCAsourceVoxelToPrior
11209       }
11210     }
11211   }
11212 
11213   *pnsamples = nsamples ;
11214   return(gcas) ;
11215 }
11216 
11217 #define MIN_MEAN_SAMPLES      10
11218 #define SAMPLE_PCT       0.20
11219 
11220 int
11221 GCArenormalize(MRI *mri_in, MRI *mri_labeled, GCA *gca, TRANSFORM *transform)
11222 {
11223   int              x, y, z, n, label, biggest_label, nsamples, val,
11224   *ordered_indices, i, index, width, height, depth ;
11225   float            mean, var, *means, *stds, *gca_means ;
11226   GCA_NODE         *gcan ;
11227   GCA_SAMPLE       *gcas ;
11228   GC1D             *gc ;
11229 
11230   if (gca->ninputs > 1)
11231     ErrorExit(ERROR_UNSUPPORTED,
11232               "GCArenormalize: can only renormalize scalars") ;
11233 
11234   /* first build a list of all labels that exist */
11235   for (nsamples = biggest_label = x = 0 ; x < gca->node_width ; x++)
11236   {
11237     for (y = 0 ; y < gca->node_height ; y++)
11238     {
11239       for (z = 0 ; z < gca->node_height ; z++)
11240       {
11241         gcan = &gca->nodes[x][y][z] ;
11242         for (n = 0 ; n < gcan->nlabels ; n++)
11243         {
11244           if (gcan->labels[n] > biggest_label)
11245             biggest_label = gcan->labels[n] ;
11246         }
11247       }
11248     }
11249   }
11250 
11251   gca_means = (float *)calloc(biggest_label+1, sizeof(float)) ;
11252   means = (float *)calloc(biggest_label+1, sizeof(float)) ;
11253   stds = (float *)calloc(biggest_label+1, sizeof(float)) ;
11254   if (!gca_means || !means || !stds)
11255     ErrorExit(ERROR_NOMEMORY, "%s: could not allocated %d vector",
11256               Progname, biggest_label+1) ;
11257 
11258   /* do unknown labels separately */
11259   for (mean = var = 0.0, nsamples = x = 0 ; x < mri_in->width ; x++)
11260   {
11261     for (y = 0 ; y < mri_in->height ; y++)
11262     {
11263       for (z = 0 ; z < mri_in->height ; z++)
11264       {
11265         if (nint(MRIgetVoxVal(mri_labeled, x, y, z, 0)) == Unknown)
11266         {
11267           nsamples++ ;
11268           val = MRIgetVoxVal(mri_in, x, y, z, 0) ;
11269           mean += val ;
11270           var += (val*val) ;
11271         }
11272       }
11273     }
11274   }
11275 
11276   if (DIAG_VERBOSE_ON && 0)
11277   {
11278     HISTOGRAM *histo ;
11279     char  fname[STRLEN] ;
11280 
11281     label = Right_Hippocampus ;
11282     histo = MRIhistogramLabel(mri_in, mri_labeled, label, 256) ;
11283     sprintf(fname, "%s.plt", cma_label_to_name(label)) ;
11284     HISTOplot(histo, fname) ;
11285     HISTOfree(&histo) ;
11286   }
11287 
11288 #if 1
11289   label = Unknown ;
11290   if (!FZERO(nsamples))
11291   {
11292     mean /= nsamples ;
11293     means[label] = mean ;
11294     stds[label] = sqrt(var/nsamples - mean*mean) ;
11295     GCAlabelMean(gca, label, &gca_means[label]) ;
11296     printf("scaling label %s by %2.2f (%2.2f / %2.2f) "
11297            "(%d samples, std=%2.1f)\n",
11298            cma_label_to_name(label),
11299            means[label] / gca_means[label],
11300            means[label], gca_means[label], nsamples, stds[label]) ;
11301   }
11302   else
11303   {
11304     gca_means[label] = stds[label] = means[label] = 1.0 ;
11305   }
11306 
11307   gca_means[label] = stds[label] = means[label] = 1.0 ;
11308 #endif
11309 
11310   for (label = 1 ; label <= biggest_label ; label++)
11311   {
11312     gcas = gcaExtractLabelAsSamples(gca,
11313                                     mri_labeled,transform,&nsamples,label);
11314     if (!nsamples)
11315       continue ;
11316     if (nsamples < MIN_MEAN_SAMPLES)
11317       /* not enough sample to estimate mean */
11318     {
11319       free(gcas) ;
11320       continue ;
11321     }
11322     ordered_indices = (int *)calloc(nsamples, sizeof(int)) ;
11323     GCAcomputeLogSampleProbability(gca, gcas, mri_in, transform, nsamples) ;
11324     GCArankSamples(gca, gcas, nsamples, ordered_indices) ;
11325 
11326     if (nint(nsamples*SAMPLE_PCT) < MIN_MEAN_SAMPLES)
11327       nsamples = MIN_MEAN_SAMPLES ;
11328     else
11329       nsamples = nint(SAMPLE_PCT * (float)nsamples) ;
11330 
11331 
11332     /* compute mean and variance of image intensities in this label */
11333     for (var = mean = 0.0f, i = 0 ; i < nsamples ; i++)
11334     {
11335       index = ordered_indices[i] ;
11336       val = MRIgetVoxVal(mri_in,
11337                                                  gcas[index].x,
11338                                                  gcas[index].y,
11339                                                  gcas[index].z, 0);
11340       mean += val ;
11341       var += val*val ;
11342     }
11343     mean /= (float)nsamples ;
11344     var = var / nsamples - mean*mean ;
11345     var = sqrt(var);
11346 #if 0
11347     printf("label %s: using %d samples to estimate mean = %2.1f +- %2.1f\n",
11348            cma_label_to_name(label), nsamples, mean, var) ;
11349 #endif
11350     means[label] = mean ;
11351     stds[label] = var ;
11352     GCAlabelMean(gca, label, &gca_means[label]) ;
11353     free(gcas) ;
11354     free(ordered_indices) ;
11355     printf("scaling label %s by %2.2f (%2.2f / %2.2f) "
11356            "(%d samples, std=%2.1f)\n",
11357            cma_label_to_name(label),
11358            means[label] / gca_means[label],
11359            means[label], gca_means[label], nsamples, stds[label]) ;
11360     if (FZERO(gca_means[label]))
11361       DiagBreak() ;
11362   }
11363 
11364   width = gca->node_width ;
11365   height = gca->node_height ;
11366   depth = gca->node_depth ;
11367   for (x = 0 ; x < width ; x++)
11368   {
11369     for (y = 0 ; y < height ; y++)
11370     {
11371       for (z = 0 ; z < depth ; z++)
11372       {
11373         gcan = &gca->nodes[x][y][z] ;
11374         for (n = 0 ; n < gcan->nlabels ; n++)
11375         {
11376           label = gcan->labels[n] ;
11377           gc = &gcan->gcs[n] ;
11378           mean = gc->means[0] * means[label] / gca_means[label] ;
11379           gc->means[0] = mean ;
11380         }
11381       }
11382     }
11383   }
11384 
11385   free(means) ;
11386   free(stds) ;
11387   free(gca_means) ;
11388   return(NO_ERROR) ;
11389 }
11390 int
11391 GCArenormalizeAdaptive(MRI *mri_in, MRI *mri_labeled,
11392                        GCA *gca, TRANSFORM *transform,
11393                        int wsize, float pthresh)
11394 {
11395   int              x, y, z, n, label, xp,yp, zp, peak, orig_wsize, frame ;
11396 #if 0
11397   int              i, index, *ordered_indices ;
11398   float            mean, var ;
11399   Real             val ;
11400 #endif
11401   GCA_NODE         *gcan ;
11402   GCA_SAMPLE       *gcas ;
11403   GC1D             *gc ;
11404   HISTOGRAM        *histo, *hsmooth ;
11405   float            fmin, fmax ;
11406   int              nsamples=0;
11407 
11408   orig_wsize = wsize ;
11409   MRIvalRange(mri_in, &fmin, &fmax) ;
11410   histo = HISTOalloc((int)(fmax-fmin+1)) ;
11411   hsmooth = HISTOalloc((int)(fmax-fmin+1)) ;
11412 
11413   /* go through GCA renormalizing each entry */
11414   for (x = 0 ; x < gca->node_width ; x++)
11415   {
11416     for (y = 0 ; y < gca->node_height ; y++)
11417     {
11418       for (z = 0 ; z < gca->node_depth ; z++)
11419       {
11420         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
11421           DiagBreak() ;
11422         gcan = &gca->nodes[x][y][z] ;
11423         for (n = 0 ; n < gcan->nlabels ; n++)
11424         {
11425           label = gcan->labels[n] ;
11426           if (label == Unknown)
11427             continue ;
11428           if ( gcaNodeToPrior(gca, x, y, z, &xp, &yp, &zp)==NO_ERROR)
11429           {
11430             gc = &gcan->gcs[n] ;
11431 
11432 #define MIN_SAMPLES 20
11433             wsize = orig_wsize ;
11434             if (label == Ggca_label)
11435               DiagBreak() ;
11436             do
11437             {
11438               gcas =
11439                 gcaExtractThresholdedRegionLabelAsSamples
11440                 (gca, \
11441                  mri_labeled,
11442                  transform,
11443                  &nsamples,
11444                  label,
11445                  xp, yp, zp,
11446                  wsize,pthresh);
11447 
11448               if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
11449                 DiagBreak() ;
11450               wsize += 2;
11451               if (gcas && nsamples < MIN_SAMPLES)
11452                 GCAfreeSamples(&gcas, nsamples) ;
11453             }
11454             while ((nsamples < MIN_SAMPLES) \
11455                    && (wsize < 2*orig_wsize));
11456 
11457             if (nsamples < MIN_SAMPLES)
11458               /* couldn't find any in this nbhd */
11459               continue ;
11460 
11461             for (frame = 0 ; frame < gca->ninputs ; frame++)
11462             {
11463               gcaHistogramSamples(gca, gcas, mri_in,
11464                                   transform, nsamples,
11465                                   histo, frame);
11466               HISTOsmooth(histo, hsmooth, 2) ;
11467               if (IS_WM(label) && gca->ninputs == 1)
11468                 peak = HISTOfindLastPeakRelative
11469                        (hsmooth,
11470                         HISTO_WINDOW_SIZE,.3);
11471               else if (IS_LAT_VENT(label) && gca->ninputs == 1)
11472                 peak = HISTOfindFirstPeakRelative
11473                        (hsmooth,
11474                         HISTO_WINDOW_SIZE,.3);
11475               else
11476                 peak =
11477                   HISTOfindHighestPeakInRegion(hsmooth,
11478                                                0,
11479                                                (fmax-fmin)*\
11480                                                hsmooth->bin_size) ;
11481               if (peak < 0)
11482                 continue ;
11483 #if 0
11484               ordered_indices =
11485                 (int *)calloc(nsamples, sizeof(int)) ;
11486               GCAcomputeLogSampleProbability(gca,
11487                                              gcas,
11488                                              mri_in,
11489                                              transform,
11490                                              nsamples) ;
11491               GCArankSamples(gca, gcas, nsamples,
11492                              ordered_indices) ;
11493 
11494               if (nsamples > MIN_SAMPLES)
11495               {
11496                 if (nint(nsamples*SAMPLE_PCT) < MIN_SAMPLES)
11497                   nsamples = MIN_SAMPLES ;
11498                 else
11499                   nsamples = nint(SAMPLE_PCT * (float)nsamples) ;
11500               }
11501 
11502 
11503               /* compute mean and variance of image */
11504               /*intensities in this label */
11505               for (var = mean = 0.0f, i = 0 ; i < nsamples ; i++)
11506               {
11507                 index = ordered_indices[i] ;
11508                 MRIsampleVolumeFrame(mri_in,
11509                                      gcas[index].x,
11510                                      gcas[index].y,
11511                                      gcas[index].z,
11512                                      frame, &val);
11513                 mean += val ;
11514                 var += val*val ;
11515                 if (gcas[index].x == Ggca_x &&
11516                     gcas[index].y == Ggca_y &&
11517                     gcas[index].z == Ggca_z)
11518                   DiagBreak() ;
11519               }
11520               mean /= (float)nsamples ;
11521               var = var / nsamples - mean*mean ;
11522               var = sqrt(var);
11523               free(ordered_indices) ;
11524               gc->means[0] = mean ;
11525 #endif
11526               gc->means[frame] = (float)peak ;
11527             }
11528             GCAfreeSamples(&gcas, nsamples) ;
11529           }
11530         }
11531       }
11532     }
11533   }
11534 
11535   HISTOfree(&histo) ;
11536   HISTOfree(&hsmooth) ;
11537   return(NO_ERROR) ;
11538 }
11539 
11540 
11541 #define MEAN_RESOLUTION  8
11542 
11543 int
11544 GCArenormalizeLabels(MRI *mri_in,
11545                      MRI *mri_labeled,
11546                      GCA *gca,
11547                      TRANSFORM *transform)
11548 {
11549   int              x, y, z, n, label, biggest_label, nsamples, xv, yv, zv,
11550   *ordered_indices, i, index, width, height, depth ;
11551   float            mean, var, val ;
11552   GCA_NODE         *gcan ;
11553   GCA_SAMPLE       *gcas ;
11554   GC1D             *gc ;
11555   MRI              *mri_means, *mri_control, *mri_tmp ;
11556   char             fname[STRLEN] ;
11557 
11558   if (gca->ninputs > 1)
11559     ErrorExit(ERROR_UNSUPPORTED,
11560               "GCArenormalizeLabels: can only renormalize scalars") ;
11561 
11562   /* first build a list of all labels that exist */
11563   for (biggest_label = x = 0 ; x < gca->node_width ; x++)
11564   {
11565     for (y = 0 ; y < gca->node_height ; y++)
11566     {
11567       for (z = 0 ; z < gca->node_height ; z++)
11568       {
11569         gcan = &gca->nodes[x][y][z] ;
11570         for (n = 0 ; n < gcan->nlabels ; n++)
11571         {
11572           if (gcan->labels[n] > biggest_label)
11573             biggest_label = gcan->labels[n] ;
11574         }
11575       }
11576     }
11577   }
11578 
11579   for (label = 1 ; label <= biggest_label ; label++)
11580   {
11581     gcas = gcaExtractLabelAsSamples(gca, mri_labeled,
11582                                     transform,&nsamples,label);
11583     if (!nsamples)
11584       continue ;
11585     if (nsamples < MIN_SAMPLES/SAMPLE_PCT)
11586     {
11587       free(gcas) ;
11588       continue ;
11589     }
11590     ordered_indices = (int *)calloc(nsamples, sizeof(int)) ;
11591     GCAcomputeLogSampleProbability(gca, gcas, mri_in, transform, nsamples) ;
11592     GCArankSamples(gca, gcas, nsamples, ordered_indices) ;
11593 
11594     if (nint(nsamples*SAMPLE_PCT) < MIN_SAMPLES)
11595       nsamples = MIN_SAMPLES ;
11596     else
11597       nsamples = nint(SAMPLE_PCT * (float)nsamples) ;
11598 
11599 
11600     for (var = mean = 0.0f, i = 0 ; i < nsamples ; i++)
11601     {
11602       index = ordered_indices[i] ;
11603       val = MRIgetVoxVal(mri_in,
11604                           gcas[index].x,
11605                           gcas[index].y,
11606                           gcas[index].z, 0);
11607       mean += val ;
11608       var += val*val ;
11609     }
11610     mean /= (float)nsamples ;
11611     var = var / nsamples - mean*mean ;
11612     var = sqrt(var);
11613     printf("label %s: using %d samples to estimate mean = %2.1f +- %2.1f\n",
11614            cma_label_to_name(label), nsamples, mean, var) ;
11615 
11616     width = nint(mri_in->width / MEAN_RESOLUTION) ;
11617     height = nint(mri_in->height / MEAN_RESOLUTION) ;
11618     depth = nint(mri_in->depth / MEAN_RESOLUTION) ;
11619     mri_means = MRIalloc(width, height, depth, MRI_FLOAT) ;
11620     MRIcopyHeader(mri_in, mri_means);
11621     mri_control = MRIalloc(width, height, depth, MRI_SHORT) ;
11622     MRIcopyHeader(mri_in, mri_control);
11623     MRIsetResolution(mri_means,
11624                      MEAN_RESOLUTION,MEAN_RESOLUTION,MEAN_RESOLUTION) ;
11625     MRIsetResolution(mri_control,
11626                      MEAN_RESOLUTION,MEAN_RESOLUTION,MEAN_RESOLUTION) ;
11627 
11628     GCAlabelMri(gca, mri_means, label, transform) ;
11629     if (DIAG_VERBOSE_ON && Gdiag & DIAG_WRITE)
11630     {
11631       sprintf(fname, "%s_label.mgz", cma_label_to_name(label)) ;
11632       MRIwrite(mri_means, fname) ;
11633     }
11634 
11635     for (mean = 0.0f, n = z = 0 ; z < depth ; z++)
11636     {
11637       for (y = 0 ; y < height ; y++)
11638       {
11639         for (x = 0 ; x < width ; x++)
11640         {
11641           if (MRIFvox(mri_means, x, y, z) > 1)
11642           {
11643             n++ ;
11644             mean += MRIFvox(mri_means, x, y, z) ;
11645           }
11646         }
11647       }
11648     }
11649     mean /= (float)n ;
11650     printf("mean GCA value %2.1f\n", mean) ;
11651     for (z = 0 ; z < depth ; z++)
11652     {
11653       for (y = 0 ; y < height ; y++)
11654       {
11655         for (x = 0 ; x < width ; x++)
11656         {
11657           if (MRIFvox(mri_means, x, y, z) < 1)
11658           {
11659             MRIFvox(mri_means, x, y, z) = mean ;
11660           }
11661         }
11662       }
11663     }
11664 
11665     TransformInvert(transform, mri_in) ;
11666     for (i = 0 ; i < nsamples ; i++)
11667     {
11668       index = ordered_indices[i] ;
11669       if (!GCApriorToSourceVoxel(gca, mri_means, transform,
11670                                  gcas[index].xp,
11671                                  gcas[index].yp,
11672                                  gcas[index].zp,
11673                                  &x, &y, &z))
11674       {
11675         val = MRIgetVoxVal(mri_in,
11676                                                      gcas[index].x,
11677                                                      gcas[index].y,
11678                                                      gcas[index].z, 0);
11679         if (x == 19 && y == 14 && z == 15)
11680           DiagBreak() ;
11681         if (MRISvox(mri_control, x, y, z) == 0)
11682           MRIFvox(mri_means, x, y, z) = val ;
11683         else
11684           MRIFvox(mri_means, x, y, z) += val ;
11685         MRISvox(mri_control, x, y, z)++ ;
11686       }
11687     }
11688 
11689     for (z = 0 ; z < depth ; z++)
11690     {
11691       for (y = 0 ; y < height ; y++)
11692       {
11693         for (x = 0 ; x < width ; x++)
11694         {
11695           if (x == 19 && y == 14 && z == 15)
11696             DiagBreak() ;
11697           if (MRISvox(mri_control, x, y, z) > 0)
11698           {
11699             MRIFvox(mri_means,x,y,z) =
11700               nint((float)MRIFvox(mri_means,x,y,z)/
11701                    (float)MRISvox(mri_control,x,y,z)) ;
11702             MRISvox(mri_control, x, y, z) = 1 ;
11703           }
11704         }
11705       }
11706     }
11707 
11708     if (DIAG_VERBOSE_ON && Gdiag & DIAG_WRITE)
11709     {
11710       sprintf(fname, "%s_means.mgz", cma_label_to_name(label)) ;
11711       MRIwrite(mri_means, fname) ;
11712     }
11713 
11714     mri_tmp = MRIalloc(width, height, depth, MRI_SHORT) ;
11715     MRIcopy(mri_means, mri_tmp) ;
11716     MRIfree(&mri_means) ;
11717     mri_means = mri_tmp ;
11718 
11719     mri_tmp = MRIalloc(width, height, depth, MRI_UCHAR) ;
11720     MRIcopy(mri_control, mri_tmp) ;
11721     MRIfree(&mri_control) ;
11722     mri_control = mri_tmp ;
11723 
11724     MRIsoapBubble(mri_means, mri_control, mri_means, 10) ;
11725     MRIclear(mri_control) ;
11726     MRIsoapBubble(mri_means, mri_control, mri_means, 1) ;
11727 
11728     if (DIAG_VERBOSE_ON && Gdiag & DIAG_WRITE)
11729     {
11730       sprintf(fname, "%s_soap.mgz", cma_label_to_name(label)) ;
11731       MRIwrite(mri_means, fname) ;
11732 
11733       sprintf(fname, "%s_control.mgz", cma_label_to_name(label)) ;
11734       MRIwrite(mri_control, fname) ;
11735     }
11736 
11737 
11738     width = gca->node_width ;
11739     height = gca->node_height ;
11740     depth = gca->node_depth ;
11741     for (z = 0 ; z < depth ; z++)
11742     {
11743       for (y = 0 ; y < height ; y++)
11744       {
11745         for (x = 0 ; x < width ; x++)
11746         {
11747           if (x == Gx && y == Gy && z == Gz)
11748             DiagBreak() ;
11749           gcan = &gca->nodes[x][y][z] ;
11750           for (n = 0 ; n < gcan->nlabels ; n++)
11751           {
11752             if (gcan->labels[n] == label)
11753             {
11754               if (x == Gx && y == Gy && z == Gz)
11755                 DiagBreak() ;
11756               gc = &gcan->gcs[n] ;
11757               if (GCAnodeToVoxel(gca, mri_means,
11758                                  x, y, z,
11759                                  &xv, &yv, &zv)==NO_ERROR)
11760                 gc->means[0] =
11761                   (float)MRISvox(mri_means, xv, yv, zv);
11762               break ;
11763             }
11764           }
11765         }
11766       }
11767     }
11768 
11769     MRIfree(&mri_means) ;
11770     MRIfree(&mri_control) ;
11771     free(gcas) ;
11772     free(ordered_indices) ;
11773   }
11774 
11775   return(NO_ERROR) ;
11776 }
11777 
11778 int
11779 GCArenormalizeIntensities(GCA *gca, int *labels, float *intensities, int num)
11780 {
11781   float     wm_mean, scale_factor, gray_mean, prior ;
11782   int       xn, yn, zn, n, i, label ;
11783   GCA_NODE  *gcan ;
11784   GC1D      *gc ;
11785   double    *means, *wts ;
11786 
11787   if (gca->ninputs > 1)
11788     ErrorExit(ERROR_UNSUPPORTED,
11789               "GCArenormalizeIntensities: can only renormalize scalars") ;
11790 
11791   means = (double *)calloc(num, sizeof(double)) ;
11792   wts = (double *)calloc(num, sizeof(double)) ;
11793   if (!means || !wts)
11794     ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %d wt and mean vectors",
11795               Progname, num) ;
11796 
11797   /* compute overall white matter mean to use as anchor for rescaling */
11798   for (zn = 0 ; zn < gca->node_depth ; zn++)
11799   {
11800     for (yn = 0 ; yn < gca->node_height ; yn++)
11801     {
11802       for (xn = 0 ; xn < gca->node_width ; xn++)
11803       {
11804         if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
11805           DiagBreak() ;
11806         gcan = &gca->nodes[xn][yn][zn] ;
11807         for (n = 0 ; n < gcan->nlabels ; n++)
11808         {
11809           /* find index in lookup table for this label */
11810           label = gcan->labels[n] ;
11811           for (i = 0 ; i < num ; i++)
11812             if (label == labels[i])
11813               break ;
11814 
11815           if (i >= num)
11816             continue ;  /* shouldn't happen */
11817 
11818           gc = &gcan->gcs[n] ;
11819           prior = get_node_prior(gca, label, xn, yn, zn);
11820           if (prior != 0)
11821           {
11822             wts[i] += prior ;
11823             means[i] += gc->means[0]*prior ;
11824           }
11825         }
11826       }
11827     }
11828   }
11829   gray_mean = scale_factor = wm_mean = -1 ;
11830   for (i = 0 ; i < num ; i++)
11831   {
11832     if (!FZERO(wts[i]))
11833       means[i] /= wts[i] ;
11834     if (labels[i] == Left_Cerebral_White_Matter)
11835     {
11836       wm_mean = means[i] ;
11837       scale_factor = wm_mean / intensities[i] ;
11838     }
11839     if (labels[i] == Left_Cerebral_Cortex)
11840       gray_mean = means[i] ;
11841   }
11842   if (wm_mean < 0)
11843     ErrorReturn(ERROR_BADPARM,
11844                 (ERROR_BADPARM, "GCArenormalizeIntensities: "
11845                  "could not find white matter in intensity table")) ;
11846   scale_factor = 1 ;
11847   printf("mean wm intensity = %2.1f, scaling gray to %2.2f (from %2.2f)\n",
11848          wm_mean, scale_factor*gray_mean, gray_mean) ;
11849 
11850   /* now go through each label and scale it by gca wm to norm wm ratio */
11851   /* compute overall white matter mean to use as anchor for rescaling */
11852   for (zn = 0 ; zn < gca->node_depth ; zn++)
11853   {
11854     for (yn = 0 ; yn < gca->node_height ; yn++)
11855     {
11856       for (xn = 0 ; xn < gca->node_width ; xn++)
11857       {
11858         gcan = &gca->nodes[xn][yn][zn] ;
11859         if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
11860           DiagBreak() ;
11861         for (n = 0 ; n < gcan->nlabels ; n++)
11862         {
11863           label = gcan->labels[n] ;
11864           if (label == Gdiag_no)
11865             DiagBreak() ;
11866 
11867           /* find index in lookup table for this label */
11868           for (i = 0 ; i < num ; i++)
11869             if (label == labels[i])
11870               break ;
11871           if (i >= num)
11872             continue ;
11873 
11874           gc = &gcan->gcs[n] ;
11875           gc->means[0] =
11876             scale_factor*intensities[i]*gc->means[0]/means[i] ;
11877         }
11878       }
11879     }
11880   }
11881 
11882   free(wts) ;
11883   free(means) ;
11884   return(NO_ERROR) ;
11885 }
11886 
11887 int
11888 GCAunifyVariance(GCA *gca)
11889 {
11890   int        xn, yn, zn, n, r, c, v ;
11891   GCA_NODE   *gcan ;
11892   GC1D       *gc ;
11893 
11894   for (zn = 0 ; zn < gca->node_depth ; zn++)
11895   {
11896     for (yn = 0 ; yn < gca->node_height ; yn++)
11897     {
11898       for (xn = 0 ; xn < gca->node_width ; xn++)
11899       {
11900         gcan = &gca->nodes[xn][yn][zn] ;
11901         for (n = 0 ; n < gcan->nlabels ; n++)
11902         {
11903           gc = &gcan->gcs[n] ;
11904           for (r = v = 0 ; r < gca->ninputs ; r++)
11905           {
11906             for (c = r ; c < gca->ninputs ; c++, v++)
11907             {
11908               if (r == c)
11909                 gc->covars[v] = MIN_VAR ;
11910               else
11911                 gc->covars[v] = 0.0 ;
11912             }
11913           }
11914         }
11915       }
11916     }
11917   }
11918 
11919   return(NO_ERROR) ;
11920 }
11921 
11922 
11923 int
11924 GCAlabelMode(GCA *gca, int label, float *modes)
11925 {
11926   int       xn, yn, zn, n, r ;
11927   GCA_NODE  *gcan ;
11928   GC1D      *gc ;
11929   float     prior ;
11930   HISTOGRAM *h ;
11931   int       b ;
11932 
11933   h = HISTOalloc(256) ;
11934   for (b = 0 ; b < h->nbins ; b++)
11935     h->bins[b] = b ;
11936 
11937   memset(modes, 0, gca->ninputs*sizeof(float)) ;
11938   for (zn = 0 ; zn < gca->node_depth ; zn++)
11939   {
11940     for (yn = 0 ; yn < gca->node_height ; yn++)
11941     {
11942       for (xn = 0 ; xn < gca->node_width ; xn++)
11943       {
11944         gcan = &gca->nodes[xn][yn][zn] ;
11945         for (n = 0 ; n < gcan->nlabels ; n++)
11946         {
11947           /* find index in lookup table for this label */
11948           if (gcan->labels[n] != label)
11949             continue ;
11950           gc = &gcan->gcs[n] ;
11951           prior = get_node_prior(gca, label, xn, yn, zn) ;
11952           if (prior != 0)
11953           {
11954             for (r = 0 ; r < gca->ninputs ; r++)
11955             {
11956               b = nint(gc->means[r]) ;
11957               h->counts[b] += prior ;
11958               if (!finite(gc->means[r]))
11959                 DiagBreak() ;
11960             }
11961           }
11962 
11963         }
11964       }
11965     }
11966   }
11967   if (Gdiag & DIAG_WRITE)
11968   {
11969     char  fname[STRLEN] ;
11970     sprintf(fname, "gca_label%d.plt", label) ;
11971     HISTOplot(h, fname) ;
11972   }
11973 
11974   for (r = 0 ; r < gca->ninputs ; r++)
11975   {
11976     b = HISTOfindHighestPeakInRegion(h, 0, h->nbins) ;
11977     modes[r] = h->bins[b] ;
11978   }
11979   return(NO_ERROR) ;
11980 }
11981 int
11982 GCAclassMode(GCA *gca, int class, float *modes)
11983 {
11984   int       xn, yn, zn, n, r ;
11985   GCA_NODE  *gcan ;
11986   GC1D      *gc ;
11987   float     prior ;
11988   HISTOGRAM *h ;
11989   int       b, label ;
11990 
11991   h = HISTOalloc(256) ;
11992   for (b = 0 ; b < h->nbins ; b++)
11993     h->bins[b] = b ;
11994 
11995   memset(modes, 0, gca->ninputs*sizeof(float)) ;
11996   for (zn = 0 ; zn < gca->node_depth ; zn++)
11997   {
11998     for (yn = 0 ; yn < gca->node_height ; yn++)
11999     {
12000       for (xn = 0 ; xn < gca->node_width ; xn++)
12001       {
12002         gcan = &gca->nodes[xn][yn][zn] ;
12003         for (n = 0 ; n < gcan->nlabels ; n++)
12004         {
12005           label = gcan->labels[n] ;
12006           switch (class)  // check to make sure it is
12007             // the specified class
12008           {
12009           case WM_CLASS:
12010             if (IS_WHITE_CLASS(gcan->labels[n]) == 0)
12011               continue ;
12012             break ;
12013           case GM_CLASS:
12014             if (IS_GRAY_CLASS(gcan->labels[n]) == 0)
12015               continue ;
12016             break ;
12017           case CSF_CLASS:
12018             if (IS_CSF_CLASS(gcan->labels[n]) == 0)
12019               continue ;
12020             break ;
12021           default:
12022             break ;
12023           }
12024           prior = get_node_prior(gca, label, xn, yn, zn) ;
12025           gc = GCAfindGC(gca, xn, yn, zn, label) ;
12026           if (gc == NULL)
12027             continue ;
12028           if (prior != 0)
12029           {
12030             for (r = 0 ; r < gca->ninputs ; r++)
12031             {
12032               b = nint(gc->means[r]) ;
12033               h->counts[b] += prior ;
12034               if (!finite(gc->means[r]))
12035                 DiagBreak() ;
12036             }
12037           }
12038 
12039         }
12040       }
12041     }
12042   }
12043   if (Gdiag & DIAG_WRITE)
12044   {
12045     char  fname[STRLEN] ;
12046     sprintf(fname, "gca_label%d.plt", class) ;
12047     HISTOplot(h, fname) ;
12048   }
12049 
12050   for (r = 0 ; r < gca->ninputs ; r++)
12051   {
12052     b = HISTOfindHighestPeakInRegion(h, 0, h->nbins) ;
12053     modes[r] = h->bins[b] ;
12054   }
12055   return(NO_ERROR) ;
12056 }
12057 
12058 int
12059 GCAlabelMean(GCA *gca, int label, float *means)
12060 {
12061   int       xn, yn, zn, n, r ;
12062   GCA_NODE  *gcan ;
12063   GC1D      *gc ;
12064   double    wt ;
12065   float     prior ;
12066 
12067   /* compute overall white matter mean to use as anchor for rescaling */
12068   memset(means, 0, gca->ninputs*sizeof(float)) ;
12069   for (wt = 0.0, zn = 0 ; zn < gca->node_depth ; zn++)
12070   {
12071     for (yn = 0 ; yn < gca->node_height ; yn++)
12072     {
12073       for (xn = 0 ; xn < gca->node_width ; xn++)
12074       {
12075         gcan = &gca->nodes[xn][yn][zn] ;
12076         for (n = 0 ; n < gcan->nlabels ; n++)
12077         {
12078           /* find index in lookup table for this label */
12079           if (gcan->labels[n] != label)
12080             continue ;
12081           gc = &gcan->gcs[n] ;
12082           prior = get_node_prior(gca, label, xn, yn, zn) ;
12083           if (prior != 0)
12084           {
12085             wt += prior ;
12086             for (r = 0 ; r < gca->ninputs ; r++)
12087             {
12088               means[r] += gc->means[r]*prior ;
12089               if (!finite(gc->means[r]))
12090                 DiagBreak() ;
12091             }
12092           }
12093 
12094         }
12095       }
12096     }
12097   }
12098   if (FZERO(wt))
12099     return(NO_ERROR) ;
12100   for (r = 0 ; r < gca->ninputs ; r++)
12101     means[r] /= wt ;
12102   return(NO_ERROR) ;
12103 }
12104 int
12105 GCAclassMean(GCA *gca, int class, float *means)
12106 {
12107   int       xn, yn, zn, n, r, label ;
12108   GCA_NODE  *gcan ;
12109   GC1D      *gc ;
12110   double    wt ;
12111   float     prior ;
12112 
12113   /* compute overall white matter mean to use as anchor for rescaling */
12114   memset(means, 0, gca->ninputs*sizeof(float)) ;
12115   for (wt = 0.0, zn = 0 ; zn < gca->node_depth ; zn++)
12116   {
12117     for (yn = 0 ; yn < gca->node_height ; yn++)
12118     {
12119       for (xn = 0 ; xn < gca->node_width ; xn++)
12120       {
12121         gcan = &gca->nodes[xn][yn][zn] ;
12122         for (n = 0 ; n < gcan->nlabels ; n++)
12123         {
12124           label = gcan->labels[n] ;
12125           switch (class)  // check to make sure it is
12126             // the specified class
12127           {
12128           case WM_CLASS:
12129             if (IS_WHITE_CLASS(gcan->labels[n]) == 0)
12130               continue ;
12131             break ;
12132           case GM_CLASS:
12133             if (IS_GRAY_CLASS(gcan->labels[n]) == 0)
12134               continue ;
12135             break ;
12136           case CSF_CLASS:
12137             if (IS_CSF_CLASS(gcan->labels[n]) == 0)
12138               continue ;
12139             break ;
12140           default:
12141             break ;
12142           }
12143           /* find index in lookup table for this label */
12144           gc = &gcan->gcs[n] ;
12145           prior = get_node_prior(gca, label, xn, yn, zn) ;
12146           if (prior != 0)
12147           {
12148             wt += prior ;
12149             for (r = 0 ; r < gca->ninputs ; r++)
12150             {
12151               means[r] += gc->means[r]*prior ;
12152               if (!finite(gc->means[r]))
12153                 DiagBreak() ;
12154             }
12155           }
12156 
12157         }
12158       }
12159     }
12160   }
12161   if (FZERO(wt))
12162     return(NO_ERROR) ;
12163   for (r = 0 ; r < gca->ninputs ; r++)
12164     means[r] /= wt ;
12165   return(NO_ERROR) ;
12166 }
12167 
12168 int
12169 GCAregularizeConditionalDensities(GCA *gca, float smooth)
12170 {
12171   int       xn, yn, zn, n, i, label, max_label, r ;
12172   GCA_NODE  *gcan ;
12173   GC1D      *gc ;
12174   double    **means, *wts ;
12175   float     prior ;
12176 
12177   means = (double **)calloc(gca->ninputs, sizeof(double *)) ;
12178   wts = (double *)calloc(MAX_GCA_LABELS, sizeof(double)) ;
12179   if (!means || !wts)
12180     ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %d wt and mean vectors",
12181               Progname, MAX_GCA_LABELS) ;
12182   for (r = 0 ; r < gca->ninputs ; r++)
12183   {
12184     means[r] = (double *)calloc(MAX_GCA_LABELS, sizeof(double)) ;
12185     if (!means[r])
12186       ErrorExit(ERROR_NOMEMORY,
12187                 "%s: could not allocate %d wt and mean vectors",
12188                 Progname, MAX_GCA_LABELS) ;
12189   }
12190 
12191   /* compute overall mean for each class */
12192   for (max_label = 1, zn = 0 ; zn < gca->node_depth ; zn++)
12193   {
12194     for (yn = 0 ; yn < gca->node_height ; yn++)
12195     {
12196       for (xn = 0 ; xn < gca->node_width ; xn++)
12197       {
12198         gcan = &gca->nodes[xn][yn][zn] ;
12199         for (n = 0 ; n < gcan->nlabels ; n++)
12200         {
12201           /* find index in lookup table for this label */
12202           label = gcan->labels[n] ;
12203 
12204           gc = &gcan->gcs[n] ;
12205           prior = get_node_prior(gca, label, xn, yn, zn) ;
12206           if (prior != 0)
12207           {
12208             wts[label] += prior ;
12209             for (r = 0 ; r < gca->ninputs ; r++)
12210               means[r][label] += gc->means[r]*prior ;
12211             if (label > max_label)
12212               max_label = label ;
12213           }
12214         }
12215       }
12216     }
12217   }
12218 
12219   for (i = 0 ; i <= max_label ; i++)
12220   {
12221     if (!FZERO(wts[i]))
12222     {
12223       for (r = 0 ; r < gca->ninputs ; r++)
12224         means[r][i] /= wts[i] ;
12225     }
12226   }
12227 
12228   /* now impose regularization */
12229   for (zn = 0 ; zn < gca->node_depth ; zn++)
12230   {
12231     for (yn = 0 ; yn < gca->node_height ; yn++)
12232     {
12233       for (xn = 0 ; xn < gca->node_width ; xn++)
12234       {
12235         gcan = &gca->nodes[xn][yn][zn] ;
12236         for (n = 0 ; n < gcan->nlabels ; n++)
12237         {
12238           /* find index in lookup table for this label */
12239           label = gcan->labels[n] ;
12240           if (label <= 0)
12241             continue ;
12242 
12243           gc = &gcan->gcs[n] ;
12244           for (r = 0 ; r < gca->ninputs ; r++)
12245             gc->means[r] =
12246               means[r][label]*smooth + gc->means[r]*(1.0f-smooth) ;
12247         }
12248       }
12249     }
12250   }
12251 
12252   for (r = 0 ; r < gca->ninputs ; r++)
12253     free(means[r]) ;
12254   free(wts) ;
12255   free(means) ;
12256   return(NO_ERROR) ;
12257 }
12258 int
12259 GCArenormalizeToFlash(GCA *gca, char *tissue_parms_fname, MRI *mri)
12260 {
12261   FILE     *fp ;
12262   char     *cp, line[STRLEN] ;
12263   int      labels[MAX_GCA_LABELS], nlabels ;
12264   float   intensities[MAX_GCA_LABELS], TR, alpha, T1, PD ;
12265 
12266   TR = mri->tr ;
12267   alpha = mri->flip_angle ;
12268 
12269   fp = fopen(tissue_parms_fname, "r") ;
12270   if (!fp)
12271     ErrorReturn(ERROR_NOFILE,
12272                 (ERROR_NOFILE,
12273                  "GCArenormalizeToFlash: could not open tissue parms file %s",
12274                  tissue_parms_fname)) ;
12275 
12276   cp = fgetl(line, STRLEN-1, fp) ;
12277   nlabels = 0 ;
12278   while (cp)
12279   {
12280     if (sscanf(cp, "%d %f %f", &labels[nlabels], &T1, &PD)
12281         != 3)
12282       ErrorReturn(ERROR_BADFILE,
12283                   (ERROR_BADFILE,
12284                    "GCArenormalizeToFlash: "
12285                    "could not parse %dth line %s in %s",
12286                    nlabels+1, cp, tissue_parms_fname)) ;
12287 
12288     intensities[nlabels] = FLASHforwardModel(T1, PD, TR, alpha, 3) ;
12289 
12290     nlabels++ ;
12291     cp = fgetl(line, STRLEN-1, fp) ;
12292   }
12293   fclose(fp) ;
12294   GCArenormalizeIntensities(gca, labels, intensities, nlabels) ;
12295   return(NO_ERROR) ;
12296 }
12297 
12298 int
12299 GCAmeanFilterConditionalDensities(GCA *gca, float navgs)
12300 {
12301   /* won't work for covariances */
12302   int       xn, yn, zn, xn1, yn1, zn1, n, label, max_label, niter, f ;
12303   GCA_NODE  *gcan ;
12304   GC1D      *gc ;
12305   double    means[MAX_GCA_INPUTS], wt ;
12306   MRI       *mri_means ;
12307   float     prior ;
12308 
12309   mri_means = MRIallocSequence(gca->node_width,
12310                                gca->node_height,
12311                                gca->node_depth,
12312                                MRI_FLOAT, gca->ninputs) ;
12313 
12314   mri_means->xsize = gca->node_spacing;
12315   mri_means->ysize = gca->node_spacing;
12316   mri_means->zsize = gca->node_spacing;
12317 
12318   GCAcopyDCToMRI(gca, mri_means);
12319 
12320   /* compute overall mean for each class */
12321   for (max_label = 1, zn = 0 ; zn < gca->node_depth ; zn++)
12322   {
12323     for (yn = 0 ; yn < gca->node_height ; yn++)
12324     {
12325       for (xn = 0 ; xn < gca->node_width ; xn++)
12326       {
12327         gcan = &gca->nodes[xn][yn][zn] ;
12328         if (xn == Gx && yn == Gy && zn == Gz)
12329           DiagBreak() ;
12330         for (n = 0 ; n < gcan->nlabels ; n++)
12331         {
12332           /* find index in lookup table for this label */
12333           label = gcan->labels[n] ;
12334 
12335           gc = &gcan->gcs[n] ;
12336           if (label > max_label)
12337             max_label = label ;
12338         }
12339       }
12340     }
12341   }
12342 
12343   /* now impose regularization */
12344   for (niter = 0 ; niter < navgs ; niter++)
12345   {
12346     for (label = 0 ; label <= max_label ; label++)
12347     {
12348       if (label == Gdiag_no)
12349         DiagBreak() ;
12350       if (IS_UNKNOWN(label))
12351         continue ;
12352       for (zn = 0 ; zn < gca->node_depth ; zn++)
12353       {
12354         for (yn = 0 ; yn < gca->node_height ; yn++)
12355         {
12356           for (xn = 0 ; xn < gca->node_width ; xn++)
12357           {
12358             if (xn == Gx && yn == Gy && zn == Gz)
12359               DiagBreak() ;
12360             wt = 0.0 ;
12361             for (f = 0 ; f < gca->ninputs ; f++)
12362               means[f] = 0 ;
12363             for (xn1 = xn-1 ; xn1 <= xn+1 ; xn1++)
12364             {
12365               if (xn1 < 0 || xn1 >= gca->node_width)
12366                 continue ;
12367               for (yn1 = yn-1 ; yn1 <= yn+1 ; yn1++)
12368               {
12369                 if (yn1 < 0 || yn1 >= gca->node_height)
12370                   continue ;
12371                 for (zn1 = zn-1 ; zn1 <= zn+1 ; zn1++)
12372                 {
12373                   if (zn1 < 0 || zn1 >= gca->node_depth)
12374                     continue ;
12375                   if (xn1 == xn && yn1 == yn && zn1 == zn)
12376                     DiagBreak() ;
12377                   gcan = &gca->nodes[xn1][yn1][zn1] ;
12378                   for (n = 0 ; n < gcan->nlabels ; n++)
12379                   {
12380                     /* find index in lookup table
12381                        for this label */
12382                     if (gcan->labels[n] != label)
12383                       continue ;
12384 
12385                     gc = &gcan->gcs[n] ;
12386                     prior = get_node_prior(gca, label,
12387                                            xn1, yn1, zn1) ;
12388                     if (prior != 0)
12389                     {
12390                       for (f = 0 ; f < gca->ninputs ; f++)
12391                       {
12392                         means[f] += prior*gc->means[f] ;
12393                         if (!finite(means[f] / wt))
12394                           DiagBreak() ;
12395                       }
12396                       wt += prior ;
12397                       break ;
12398                     }
12399                   }
12400                 }
12401               }
12402             }
12403             if (FZERO(wt))
12404               continue ;   /* label didn't occur here */
12405             for (f = 0 ; f < gca->ninputs ; f++)
12406             {
12407               if (!finite(means[f] / wt))
12408                 DiagBreak() ;
12409               MRIFseq_vox(mri_means, xn, yn, zn, f)
12410               = means[f] / wt ;
12411               if (!finite(MRIFseq_vox(mri_means,xn,yn,zn,f)))
12412                 DiagBreak() ;
12413             }
12414           }
12415         }
12416       }
12417 
12418       for (zn = 0 ; zn < gca->node_depth ; zn++)
12419       {
12420         for (yn = 0 ; yn < gca->node_height ; yn++)
12421         {
12422           for (xn = 0 ; xn < gca->node_width ; xn++)
12423           {
12424             gcan = &gca->nodes[xn][yn][zn] ;
12425             for (n = 0 ; n < gcan->nlabels ; n++)
12426             {
12427               if (gcan->labels[n] != label)
12428                 continue ;
12429               gc = &gcan->gcs[n] ;
12430               if (xn == Gx && yn == Gy && zn == Gz)
12431                 DiagBreak() ;
12432               for (f = 0 ; f < gca->ninputs ; f++)
12433               {
12434                 gc->means[f] =
12435                   MRIFseq_vox(mri_means, xn, yn, zn, f) ;
12436                 if (!finite(gc->means[f]))
12437                   DiagBreak() ;
12438               }
12439               break ;
12440             }
12441           }
12442         }
12443       }
12444     }
12445   }
12446 
12447   MRIfree(&mri_means) ;
12448   return(NO_ERROR) ;
12449 }
12450 
12451 #define OFFSET_SIZE  25
12452 double BOX_SIZE =   60;   /* mm */
12453 double HALF_BOX=   (60/2);
12454 int
12455 GCAhistoScaleImageIntensities(GCA *gca, MRI *mri)
12456 {
12457   float      x0, y0, z0, fmin, fmax, min_real_val ;
12458   int        mri_peak, r, max_T1_weighted_image = 0, min_real_bin, peak ;
12459   float      wm_means[MAX_GCA_INPUTS], tmp[MAX_GCA_INPUTS],
12460   scales[MAX_GCA_INPUTS], max_wm/*, scale*/ ;
12461   HISTOGRAM *h_mri, *h_smooth, *h_gca ;
12462   MRI_REGION box ;
12463   MRI        *mri_frame, *mri_mask ;
12464 
12465   float      gm_means[MAX_GCA_INPUTS], gray_white_CNR;
12466 
12467   GCAlabelMean(gca, Left_Cerebral_White_Matter, wm_means) ;
12468   //GCAlabelMean(gca, Left_Cerebral_White_Matter, tmp) ;
12469   GCAlabelMean(gca, Right_Cerebral_White_Matter, tmp) ;
12470 
12471   // the following rule some times fails for BIRN data, so changed it
12472   // on 08-01-05 by xhan
12473 #if 0
12474   max_wm = 0 ;
12475   for (r = 0 ; r < gca->ninputs ; r++)
12476   {
12477     wm_means[r] = (wm_means[r] + tmp[r]) / 2 ;
12478     if (wm_means[r] > max_wm)
12479     {
12480       max_T1_weighted_image = r ;
12481       max_wm = wm_means[r] ;
12482     }
12483   }
12484 #else
12485   GCAlabelMean(gca, Left_Cerebral_Cortex, gm_means) ;
12486   for (r = 0 ; r < gca->ninputs ; r++)
12487   {
12488     // use modes instead of means
12489     h_gca = gcaGetLabelHistogram(gca, Left_Cerebral_White_Matter, r) ;
12490     peak = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
12491     printf("resetting wm mean[%d]: %2.0f --> %2.0f\n",
12492            r, wm_means[r], h_gca->bins[peak]) ;
12493     wm_means[r] = h_gca->bins[peak] ;
12494     if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
12495       HISTOplot(h_gca, "wm.plt") ;
12496     HISTOfree(&h_gca) ;
12497 
12498     h_gca = gcaGetLabelHistogram(gca, Left_Cerebral_Cortex, r) ;
12499     peak = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
12500     gm_means[r] = h_gca->bins[peak] ;
12501     printf("resetting gm mean[%d]: %2.0f --> %2.0f\n",
12502            r, gm_means[r], h_gca->bins[peak]) ;
12503     if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
12504       HISTOplot(h_gca, "gm.plt") ;
12505     HISTOfree(&h_gca) ;
12506   }
12507   gray_white_CNR = wm_means[0] - gm_means[0];
12508   for (r = 0 ; r < gca->ninputs ; r++)
12509   {
12510     //                wm_means[r] = (wm_means[r] + tmp[r]) / 2 ;
12511     if ((wm_means[r] - gm_means[r]) > gray_white_CNR)
12512     {
12513       max_T1_weighted_image = r ;
12514       gray_white_CNR = (wm_means[r] - gm_means[r]);
12515     }
12516   }
12517 #endif
12518   printf("input volume #%d is the most T1-like\n",
12519          max_T1_weighted_image +1);
12520 
12521 
12522   max_wm = wm_means[max_T1_weighted_image];
12523 
12524   mri_frame = MRIcopyFrame(mri, NULL, max_T1_weighted_image, 0) ;
12525   MRIvalRange(mri_frame, &fmin, &fmax) ;
12526   h_mri = MRIhistogram(mri_frame, nint(fmax-fmin+1)) ;
12527   HISTOclearZeroBin(h_mri) ; /* ignore background */
12528   h_smooth = HISTOsmooth(h_mri, NULL, 2) ;
12529 #if 0
12530   mri_peak = HISTOfindHighestPeakInRegion(h_smooth, 0, h_smooth->nbins/3) ;
12531 #else
12532   mri_peak = HISTOfindFirstPeak(h_smooth, 5, .1) ;
12533 #endif
12534   min_real_bin = HISTOfindEndOfPeak(h_smooth, mri_peak, .25) ;
12535   min_real_val = h_smooth->bins[min_real_bin] ;
12536   if (min_real_val > 0.25*fmax)   /* for skull-stripped images */
12537     min_real_val = 0.25*fmax ;
12538   printf("using real data threshold=%2.1f\n", min_real_val) ;
12539 
12540   MRIfindApproximateSkullBoundingBox(mri_frame, min_real_val, &box) ;
12541   mri_mask = MRIbinarize(mri_frame, NULL, min_real_val, 0, 1) ;
12542   MRIfree(&mri_frame) ;
12543   HISTOfree(&h_mri) ;
12544   HISTOfree(&h_smooth) ;
12545 
12546   //why divided by 3 for x and y?? mistake or experience?? -xh
12547   x0 = box.x+box.dx/3 ;
12548   y0 = box.y+box.dy/3 ;
12549   z0 = box.z+box.dz/2 ;
12550   printf("using (%.0f, %.0f, %.0f) as brain centroid...\n",x0, y0, z0) ;
12551 #if 0
12552   box.x = x0 - HALF_BOX*mri->xsize ;
12553   box.dx = BOX_SIZE*mri->xsize ;
12554   box.y = y0 - HALF_BOX*mri->ysize ;
12555   box.dy = BOX_SIZE*mri->ysize ;
12556   box.z = z0 - HALF_BOX*mri->zsize ;
12557   box.dz = BOX_SIZE*mri->zsize ;
12558 #else
12559   box.dx /= 4 ;
12560   box.x = x0 - box.dx/2;
12561   box.dy /= 4 ;
12562   box.y = y0 - box.dy/2;
12563   box.dz /= 4 ;
12564   box.z = z0 - box.dz/2;
12565 #endif
12566   for (r = 0 ; r < gca->ninputs ; r++)
12567   {
12568     mri_frame = MRIcopyFrame(mri, NULL, r, 0) ;
12569     MRImask(mri_frame, mri_mask, mri_frame, 0,0) ;  /* remove stuff that is 
12570                                                        background or csf */
12571 
12572     printf("mean wm in atlas = %2.0f, using box (%d,%d,%d) --> (%d, %d,%d) "
12573            "to find MRI wm\n", wm_means[r], box.x, box.y, box.z,
12574            box.x+box.dx-1,box.y+box.dy-1, box.z+box.dz-1) ;
12575 
12576     h_mri = MRIhistogramRegion(mri_frame, 0, NULL, &box) ;
12577     if (gca->ninputs == 1)
12578       HISTOclearBins(h_mri, h_mri, 0, min_real_val) ;
12579     if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
12580       HISTOplot(h_mri, "mri.histo") ;
12581     HISTOclearZeroBin(h_mri) ;
12582     if (gca->ninputs == 1)   /* assume it is T1-weighted */
12583       mri_peak = HISTOfindLastPeak(h_mri, 2*HISTO_WINDOW_SIZE,MIN_HISTO_PCT);
12584     else
12585       mri_peak = HISTOfindHighestPeakInRegion(h_mri, 1, h_mri->nbins);
12586     mri_peak = h_mri->bins[mri_peak] ;
12587     printf("before smoothing, mri peak at %d\n", mri_peak) ;
12588     h_smooth = HISTOsmooth(h_mri, NULL, 2) ;
12589     if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
12590       HISTOplot(h_smooth, "mri_smooth.histo") ;
12591     /* assume it is the right-most peak of image
12592        is supposed to be T1-weighted */
12593     if (gca->ninputs == 1 &&
12594         (gca->type == GCA_UNKNOWN || gca->type == GCA_NORMAL ||
12595          (gca->type == GCA_FLASH && (DEGREES(mri->flip_angle)>15))))
12596       mri_peak =
12597         HISTOfindLastPeak(h_smooth, HISTO_WINDOW_SIZE,MIN_HISTO_PCT);
12598     else
12599       mri_peak = HISTOfindHighestPeakInRegion(h_smooth, 1, h_mri->nbins);
12600     mri_peak = h_smooth->bins[mri_peak] ;
12601     printf("after smoothing, mri peak at %d, scaling input intensities "
12602            "by %2.3f\n", mri_peak, wm_means[r]/mri_peak) ;
12603 #if 0
12604     MRIscalarMul(mri_frame, mri_frame, wm_means[r]/mri_peak) ;
12605     MRIcopyFrame(mri_frame, mri, 0, r) ;
12606     /* put it back in multi-frame image */
12607 #endif
12608     if (mri_peak == 0)
12609       ErrorExit(ERROR_BADPARM,
12610                 "GCAhistoScaleImageIntensities: could not find wm peak") ;
12611     scales[r] = wm_means[r]/mri_peak ;
12612 
12613     MRIfree(&mri_frame) ;
12614     HISTOfree(&h_mri) ;
12615     HISTOfree(&h_smooth) ;
12616 
12617   }
12618 
12619 #if 0
12620   for (scale = 0.0, r = 0 ; r < gca->ninputs ; r++)
12621     scale += scales[r] ;
12622   scale /= (double)gca->ninputs ;
12623   printf("scaling all frames by %2.3f\n", scale) ;
12624   MRIscalarMul(mri, mri, scale) ;
12625 #else
12626   // scale each frame independently -xhan
12627   for (r = 0 ; r < gca->ninputs ; r++)
12628   {
12629     printf("scaling channel %d by %g\n", r, scales[r]);
12630     MRIscalarMulFrame(mri, mri, scales[r], r);
12631   }
12632 #endif
12633   MRIfree(&mri_mask) ;
12634   return(NO_ERROR) ;
12635 }
12636 
12637 int
12638 GCAhisto(GCA *gca, int nbins, int **pcounts)
12639 {
12640   int   *counts, x, y, z ;
12641   GCA_NODE *gcan ;
12642 
12643   *pcounts = counts = (int *)calloc(nbins+1, sizeof(int)) ;
12644 
12645   for (x = 0 ; x < gca->node_width ; x++)
12646   {
12647     for (y = 0 ; y < gca->node_height ; y++)
12648     {
12649       for (z = 0 ; z < gca->node_depth ; z++)
12650       {
12651         gcan = &gca->nodes[x][y][z] ;
12652         if (gcan->nlabels == 0 || (gcan->nlabels == 1 &&
12653                                    GCAfindGC(gca,x,y,z,Unknown) != NULL))
12654           continue ;
12655         counts[gcan->nlabels]++ ;
12656       }
12657     }
12658   }
12659 
12660   return(NO_ERROR) ;
12661 }
12662 
12663 int
12664 GCArenormalizeToExample(GCA *gca, MRI *mri_seg, MRI *mri_T1)
12665 {
12666   float     intensities[MAX_CMA_LABEL+1] ;
12667   int       x, y, z, label, labels[MAX_CMA_LABEL+1], width, height, depth,
12668   counts[MAX_CMA_LABEL+1] ;
12669 
12670   for (label = 0 ; label <= MAX_CMA_LABEL ; label++)
12671     labels[label] = label ;
12672   memset(intensities, 0, MAX_CMA_LABEL*sizeof(float)) ;
12673   memset(counts, 0, MAX_CMA_LABEL*sizeof(int)) ;
12674 
12675   width = mri_seg->width ;
12676   height = mri_seg->height ;
12677   depth = mri_seg->height;
12678   for (z = 0 ; z < depth ; z++)
12679   {
12680     for (y = 0 ; y < height ; y++)
12681     {
12682       for (x = 0 ; x < width ; x++)
12683       {
12684         label = nint(MRIgetVoxVal(mri_seg, x, y, z, 0)) ;
12685         if (label == Gdiag_no)
12686           DiagBreak() ;
12687         if (label > MAX_CMA_LABEL)
12688         {
12689           ErrorPrintf(ERROR_BADPARM,
12690                       "GCArenormalizeToExample: bad label %d", label) ;
12691           continue ;
12692         }
12693         intensities[label] += MRIgetVoxVal(mri_T1, x, y, z, 0) ;
12694         counts[label]++ ;
12695       }
12696     }
12697   }
12698 
12699   for (label = 0 ; label <= MAX_CMA_LABEL ; label++)
12700   {
12701     if (counts[label] <= 0)
12702       continue ;
12703     intensities[label] /= (float)counts[label] ;
12704   }
12705   GCArenormalizeIntensities(gca, labels, intensities, MAX_CMA_LABEL) ;
12706 
12707   return(NO_ERROR) ;
12708 }
12709 
12710 static GC1D *
12711 findGCInWindow(GCA *gca, int x0, int y0, int z0, int label, int wsize)
12712 {
12713   GC1D       *gc, *gc_min ;
12714   int        x, y, z, n, whalf ;
12715   double     dist, min_dist ;
12716   GCA_NODE   *gcan ;
12717 
12718   min_dist = gca->node_width+gca->node_height+gca->node_depth ;
12719   gc_min = NULL ;
12720   whalf = (wsize-1)/2 ;
12721   for (x = x0-whalf ; x <= x0+whalf ; x++)
12722   {
12723     if (x < 0 || x >= gca->node_width)
12724       continue ;
12725     for (y = y0-whalf ; y <= y0+whalf ; y++)
12726     {
12727       if (y < 0 || y >= gca->node_height)
12728         continue ;
12729       for (z = z0-whalf ; z <= z0+whalf  ; z++)
12730       {
12731         if (z < 0 || z >= gca->node_depth)
12732           continue ;
12733         gcan = &gca->nodes[x][y][z] ;
12734         for (n = 0 ; n < gcan->nlabels && min_dist > 1 ; n++)
12735         {
12736           if (gcan->labels[n] != label)
12737             continue ;
12738           gc = &gcan->gcs[n] ;
12739           dist = sqrt(SQR(x-x0)+SQR(y-y0)+SQR(z-z0)) ;
12740           if (dist < min_dist)
12741           {
12742             gc_min = gc ;
12743             min_dist = dist ;
12744           }
12745         }
12746       }
12747     }
12748   }
12749   return(gc_min) ;
12750 }
12751 
12752 static GC1D *
12753 findClosestValidGC(GCA *gca, int x0, int y0, int z0, int label, int check_var)
12754 {
12755   GC1D       *gc, *gc_min ;
12756   int        x, y, z, n, wsize ;
12757   double     dist, min_dist, det ;
12758   GCA_NODE   *gcan ;
12759   MATRIX     *m_cov_inv ;
12760 
12761   min_dist = gca->node_width+gca->node_height+gca->node_depth ;
12762   wsize = 1 ;
12763   gc_min = NULL ;
12764   do
12765   {
12766     for (x = x0-wsize ; x <= x0+wsize ; x++)
12767     {
12768       if (x < 0 || x >= gca->node_width)
12769         continue ;
12770       for (y = y0-wsize ; y <= y0+wsize ; y++)
12771       {
12772         if (y < 0 || y >= gca->node_height)
12773           continue ;
12774         for (z = z0-wsize ; z <= z0+wsize  ; z++)
12775         {
12776           if (z < 0 || z >= gca->node_depth)
12777             continue ;
12778           dist = sqrt(SQR(x-x0)+SQR(y-y0)+SQR(z-z0)) ;
12779           if (dist < wsize-2)
12780             continue ;  // already checked
12781 
12782           gcan = &gca->nodes[x][y][z] ;
12783           for (n = 0 ; n < gcan->nlabels ; n++)
12784           {
12785             if (gcan->labels[n] != label)
12786               continue ;
12787             gc = &gcan->gcs[n] ;
12788             det = covariance_determinant(gc, gca->ninputs) ;
12789             m_cov_inv =
12790               load_inverse_covariance_matrix(gc, NULL, gca->ninputs) ;
12791             if (m_cov_inv == NULL)
12792               det = -1 ;
12793             else
12794               MatrixFree(&m_cov_inv) ;
12795             if ((check_var && det <= MIN_DET) || gc->ntraining == 0)
12796               continue ;
12797             if (dist < min_dist)
12798             {
12799               gc_min = gc ;
12800               min_dist = dist ;
12801               if (FEQUAL(dist, 1.0))
12802                 return(gc_min) ;
12803             }
12804           }
12805         }
12806       }
12807     }
12808     wsize += 2 ;   // search next ring
12809         if (wsize > MAX(MAX(gca->node_width, gca->node_height),gca->node_depth))
12810             break ;
12811   } while (gc_min == NULL) ;
12812 
12813   if (gc_min)   /* found one in immediate nbhd */
12814     return(gc_min) ;
12815 
12816   /* couldn't find one close - search everywhere */
12817   for (x = 0 ; x < gca->node_width && min_dist > 1 ; x++)
12818   {
12819     for (y = 0 ; y < gca->node_height && min_dist > 1 ; y++)
12820     {
12821       for (z = 0 ; z < gca->node_depth && min_dist > 1 ; z++)
12822       {
12823         gcan = &gca->nodes[x][y][z] ;
12824         for (n = 0 ; n < gcan->nlabels && min_dist > 1 ; n++)
12825         {
12826           if (gcan->labels[n] != label)
12827             continue ;
12828           gc = &gcan->gcs[n] ;
12829           det = covariance_determinant(gc, gca->ninputs) ;
12830           if ((check_var && det <= 0) || gc->ntraining == 0)
12831             continue ;
12832           dist = sqrt(SQR(x-x0)+SQR(y-y0)+SQR(z-z0)) ;
12833           if (dist < min_dist)
12834           {
12835             gc_min = gc ;
12836             min_dist = dist ;
12837           }
12838         }
12839       }
12840     }
12841   }
12842   return(gc_min) ;
12843 }
12844 
12845 static int
12846 gcaCheck(GCA *gca)
12847 {
12848   int x, y, z, ret = NO_ERROR, n, r, c, v ;
12849   GCA_NODE *gcan ;
12850   GC1D     *gc ;
12851 
12852   for (x = 0 ; x < gca->node_width ; x++)
12853   {
12854     for (y = 0 ; y < gca->node_height ; y++)
12855     {
12856       for (z = 0 ; z < gca->node_depth ; z++)
12857       {
12858         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
12859           DiagBreak() ;
12860         gcan = &gca->nodes[x][y][z] ;
12861         for (n = 0 ; n < gcan->nlabels ; n++)
12862         {
12863           gc = &gcan->gcs[n] ;
12864           for (v = r = 0 ; r < gca->ninputs ; r++)
12865           {
12866             for (c = r ; c < gca->ninputs ; c++, v++)
12867               if (!finite(gc->means[r]) || !finite(gc->covars[v]))
12868               {
12869                 ret = ERROR_BADPARM ;
12870                 DiagBreak() ;
12871               }
12872           }
12873         }
12874       }
12875     }
12876   }
12877   return(ret) ;
12878 }
12879 int
12880 GCAcomputeVoxelLikelihoods(GCA *gca,
12881                            MRI *mri_in,
12882                            int x, int y, int z,
12883                            TRANSFORM *transform,
12884                            int *labels, double *likelihoods)
12885 {
12886   GCA_NODE  *gcan ;
12887   int       xn, yn, zn, n ;
12888   float     vals[MAX_GCA_INPUTS] ;
12889 
12890   if (!GCAsourceVoxelToNode(gca, mri_in, transform, x, y, z, &xn, &yn, &zn))
12891   {
12892     load_vals(mri_in, x, y, z, vals, gca->ninputs) ;
12893     gcan = &gca->nodes[xn][yn][zn] ;
12894     for (n = 0 ; n < gcan->nlabels ; n++)
12895     {
12896       labels[n] = gcan->labels[n] ;
12897       likelihoods[n] =
12898         GCAcomputeConditionalDensity(&gcan->gcs[n],vals,
12899                                      gca->ninputs, labels[n]);
12900     }
12901     return(gcan->nlabels) ;
12902   }
12903   else
12904     return 0;
12905 }
12906 
12907 int
12908 GCAmaxLikelihoodLabel(GCA_NODE *gcan,
12909                       float *vals, int ninputs, float *plikelihood)
12910 {
12911   double p, max_p ;
12912   int    n, best_label ;
12913 
12914   if (gcan->nlabels == 0)
12915     return(ERROR_BADPARM) ;
12916 
12917   best_label = gcan->labels[0] ;
12918   max_p = GCAcomputeConditionalDensity(&gcan->gcs[0],vals,
12919                                        ninputs, gcan->labels[0]) ;
12920 
12921   for (n = 1 ; n < gcan->nlabels ; n++)
12922   {
12923     p = GCAcomputeConditionalDensity(&gcan->gcs[n],vals,
12924                                      ninputs, gcan->labels[n]) ;
12925     if (p >= max_p)
12926     {
12927       max_p = p ;
12928       best_label = gcan->labels[n] ;
12929     }
12930   }
12931   if (plikelihood)
12932     *plikelihood = max_p ;
12933   return(best_label) ;
12934 }
12935 double
12936 GCAcomputeConditionalDensity(GC1D *gc, float *vals, int ninputs, int label)
12937 {
12938   double  p, dist ;
12939 
12940   /* compute 1-d Mahalanobis distance */
12941 #if 0
12942   if (label == Unknown)  /* uniform distribution */
12943   {
12944     p = 1.0/256.0f ;
12945   }
12946   else   /* Gaussian distribution */
12947 #endif
12948   {
12949     dist = GCAmahDist(gc, vals, ninputs) ;
12950     p = (1.0 / (pow(2*M_PI,ninputs/2.0)*sqrt(covariance_determinant
12951                 (gc, ninputs)))) *
12952         exp(-0.5*dist) ;
12953   }
12954   return(p) ;
12955 }
12956 double
12957 GCAcomputeNormalizedConditionalDensity(GCA *gca,
12958                                        int xp, int yp, int zp,
12959                                        float *vals, int label)
12960 {
12961   GCA_PRIOR  *gcap ;
12962   GC1D       *gc ;
12963   int        n ;
12964   double      p, total, plabel ;
12965 
12966   gcap = &gca->priors[xp][yp][zp] ;
12967   if (gcap==NULL)
12968     return(1.0);
12969   if (gcap->nlabels <= 1)
12970     return(1.0) ;
12971 
12972   for (plabel = total = 0.0, n = 0 ; n < gcap->nlabels ; n++)
12973   {
12974     gc = GCAfindPriorGC(gca, xp, yp, zp, gcap->labels[n]) ;
12975     if (!gc)
12976       continue ;
12977     p = GCAcomputeConditionalDensity(gc,vals,gca->ninputs,gcap->labels[n]);
12978     if (gcap->labels[n] == label)
12979       plabel = p ;
12980     total += p ;
12981   }
12982 
12983   if (!FZERO(total))
12984     plabel /= total ;
12985   return(plabel) ;
12986 }
12987 
12988 static double
12989 gcaComputeLogDensity(GC1D *gc, float *vals, int ninputs,
12990                      float prior, int label)
12991 {
12992   double log_p ;
12993 
12994   log_p = GCAcomputeConditionalLogDensity(gc, vals, ninputs, label) ;
12995   log_p += log(prior) ;
12996   return(log_p) ;
12997 }
12998 
12999 double
13000 GCAcomputeConditionalLogDensity(GC1D *gc, float *vals, int ninputs, int label)
13001 {
13002   double  log_p, det ;
13003 
13004 
13005   /* compute 1-d Mahalanobis distance */
13006 #if 0
13007   if (label == Unknown)  /* uniform distribution */
13008   {
13009     log_p = log(1.0/256.0f) ;
13010   }
13011   else   /* Gaussian distribution */
13012 #endif
13013   {
13014     det = covariance_determinant(gc, ninputs) ;
13015     log_p = -log(sqrt(det)) - .5*GCAmahDist(gc, vals, ninputs) ;
13016   }
13017   return(log_p) ;
13018 }
13019 
13020 GCA_SAMPLE *
13021 GCAfindAllSamples(GCA *gca, int *pnsamples, int *exclude_list,
13022                   int unknown_nbr_spacing)
13023 {
13024   GCA_SAMPLE *gcas ;
13025   GCA_PRIOR  *gcap ;
13026   GC1D       *gc ;
13027   int        x, y, z, width, height, depth, n, label, i,
13028   max_n, max_label, nsamples, r, c, v ;
13029   float      max_p, prior ;
13030   int        badcount=0;
13031 
13032   // going through gca->prior volume
13033   width = gca->prior_width ;
13034   height = gca->prior_height ;
13035   depth = gca->prior_depth ;
13036 
13037 
13038   /////////////////////////////////////////////////////////////////////////
13039   // just because of C, you have to repeat the loop twice :-(.....
13040   // first to find the size needed, second time it gets the info
13041   ////////////////////////////////////////////////////////////////////////
13042   /* find the # of places in the atlas that the highest prior class is
13043      other than unknown.
13044   */
13045   //////////// first loop of finding counts //////////////////////////////
13046   for (nsamples = x = 0 ; x < width ; x++)
13047   {
13048     for (y = 0 ; y < height ; y++)
13049     {
13050       for (z = 0 ; z < depth ; z++)
13051       {
13052         gcap = &gca->priors[x][y][z] ;
13053         if (gcap==NULL)
13054           continue;
13055         max_p = 0 ;
13056         max_n = -1 ;
13057         max_label = 0 ;
13058         // if no label, ignore
13059         if (gcap->nlabels == 0)
13060           continue ;
13061 
13062         //////////////// debug code /////////////////////////////////
13063         if (x*gca->prior_spacing == Gx && y*gca->prior_spacing == Gy &&
13064             z*gca->prior_spacing == Gz)
13065           DiagBreak() ;
13066         /////////////////////////////////////////////////////////////
13067 
13068         // go through the labels to find the max value
13069         // for prior probablity
13070         // and its label
13071         for (n = 0 ; n < gcap->nlabels ; n++)
13072         {
13073           label = gcap->labels[n] ;
13074           prior = gcap->priors[n] ;
13075           if (prior >= max_p)
13076           {
13077             max_n = n ;
13078             max_p = prior ;
13079             max_label = gcap->labels[n] ;
13080           }
13081         }
13082         // if this label is in the exclude list, continue
13083         if (exclude_list && exclude_list[max_label] > 0)
13084           continue ;
13085         // if the label is unknown and no +/-1
13086         // neighbor has different label, continue
13087         if (IS_UNKNOWN(max_label) &&
13088             (different_nbr_max_labels(gca, x, y, z,
13089                                       unknown_nbr_spacing, 0) == 0))
13090           continue ;
13091 
13092         nsamples++ ;
13093       }
13094     }
13095   }
13096   ///////////////////////////////////////////////////////////////////////
13097 
13098 
13099   // allocate nsamples worth GCA_SAMPLE
13100   // samples are non-unknowns and unknown with neighbor not unknown
13101   gcas = calloc(nsamples, sizeof(GCA_SAMPLE )) ;
13102 
13103   badcount = 0;
13104   // get the values for gcas
13105   // repeat the same thing again so that we can add info
13106   ////////////////// second loop of adding info ////////////////////////
13107   for (i = x = 0 ; x < width ; x++)
13108   {
13109     for (y = 0 ; y < height ; y++)
13110     {
13111       for (z = 0 ; z < depth ; z++)
13112       {
13113         gcap = &gca->priors[x][y][z] ;
13114         if (gcap==NULL)
13115           continue;
13116         max_p = 0 ;
13117         max_n = -1 ;
13118         max_label = 0 ;
13119         // no label, ignore
13120         if (gcap->nlabels == 0)
13121           continue ;
13122 
13123         for (n = 0 ; n < gcap->nlabels ; n++)
13124         {
13125           label = gcap->labels[n] ;
13126           prior = gcap->priors[n] ;
13127           if (prior >= max_p)
13128           {
13129             max_n = n ;
13130             max_p = prior ;
13131             max_label = gcap->labels[n] ;
13132           }
13133         }
13134         if (exclude_list && exclude_list[max_label] > 0)
13135           continue ;
13136         if (IS_UNKNOWN(max_label) &&
13137             (different_nbr_max_labels(gca, x, y, z,
13138                                       unknown_nbr_spacing, 0) == 0))
13139           continue ;
13140 
13141         // store prior coordinates
13142         gcas[i].xp = x ;
13143         gcas[i].yp = y ;
13144         gcas[i].zp = z ;
13145         //////////////////////////////////////
13146         // store talarached coordinate
13147         // talarached and prior has the same direction cosines
13148         // thus prior->talarached is only the scale difference
13149         // Note that we pick only one point in prior_spacing, though.
13150         gcas[i].x = x*gca->prior_spacing/gca->xsize ;
13151         gcas[i].y = y*gca->prior_spacing/gca->ysize ;
13152         gcas[i].z = z*gca->prior_spacing/gca->zsize ;
13153         //////////////////////////////////////
13154         gcas[i].label = max_label ;
13155         gcas[i].prior = max_p ;
13156         gcas[i].means = (float *)calloc(gca->ninputs, sizeof(float)) ;
13157         gcas[i].covars =
13158           (float *)calloc((gca->ninputs*(gca->ninputs+1))/2,
13159                           sizeof(float)) ;
13160         if (!gcas[i].means || !gcas[i].covars)
13161           ErrorExit(ERROR_NOMEMORY,
13162                     "GCAfindAllSamples: could not allocate mean "
13163                     "(%d) and covariance (%d) matrices",
13164                     gca->ninputs, gca->ninputs*(gca->ninputs+1)/2) ;
13165         gc = GCAfindPriorGC(gca, x, y, z, max_label) ;
13166         if (gc) // found
13167         {
13168           for (v = r = 0 ; r < gca->ninputs ; r++)
13169           {
13170             gcas[i].means[r] = gc->means[r] ;
13171             for (c = r ; c < gca->ninputs ; c++, v++)
13172               gcas[i].covars[v] = gc->covars[v] ;
13173           }
13174         }
13175         else // not found
13176         {
13177           badcount++;
13178           for (v = r = 0 ; r < gca->ninputs ; r++)
13179           {
13180             gcas[i].means[r] = 0.0 ;
13181             for (c = r ; c < gca->ninputs ; c++, v++)
13182             {
13183               if (c == r)
13184                 gcas[i].covars[v] = 1.0 ;
13185               else
13186                 gcas[i].covars[v] = 0.0 ;
13187             }
13188           }
13189         }
13190         gcas[i].log_p = 0 ; // initialize
13191         i++ ;
13192       }
13193     }
13194   }
13195   if (badcount > 0)
13196   {
13197     fprintf(stdout, "**************************************\n");
13198     fprintf(stdout, "those with gc cannot be found = %d\n", badcount);
13199     fprintf(stdout, "**************************************\n");
13200   }
13201   *pnsamples = nsamples ;
13202   return(gcas) ;
13203 }
13204 int
13205 GCAcomputeMAPlabelAtLocation(GCA *gca, int xp, int yp, int zp, float *vals,
13206                              int *pmax_n, float *plog_p)
13207 {
13208   GCA_PRIOR  *gcap ;
13209   GC1D       *gc ;
13210   int        n, max_n, max_label ;
13211   float      log_p, max_log_p ;
13212 
13213   gcap = &gca->priors[xp][yp][zp] ;
13214   if (gcap==NULL)
13215     return (Unknown);
13216   if (gcap->nlabels == 0)
13217   {
13218     if (plog_p)
13219       *plog_p = 0.0 ;
13220     if (pmax_n)
13221       *pmax_n = -1 ;
13222     return(Unknown) ;
13223   }
13224 
13225   // start from label[0]
13226   max_label = gcap->labels[0] ;
13227   max_n = 0 ;
13228   gc = GCAfindPriorGC(gca, xp, yp, zp, gcap->labels[0]) ;
13229   if (gc)
13230     max_log_p = gcaComputeLogDensity(gc, vals,
13231                                      gca->ninputs,
13232                                      gcap->priors[0],
13233                                      max_label) ;
13234   else
13235     max_log_p = -100000 ;
13236   // go through all the labels here
13237   for (n = 1 ; n < gcap->nlabels ; n++)
13238   {
13239     gc = GCAfindPriorGC(gca, xp, yp, zp, gcap->labels[n]) ;
13240     if (!gc)
13241       continue ;
13242     // calculate log_p
13243     log_p = gcaComputeLogDensity(gc,vals,
13244                                  gca->ninputs,
13245                                  gcap->labels[n],
13246                                  gcap->priors[n]);
13247     if (log_p > max_log_p)
13248     {
13249       max_log_p = log_p ;
13250       max_n = n ;
13251       max_label = gcap->labels[n] ;
13252     }
13253   }
13254 
13255   if (plog_p)
13256     *plog_p = max_log_p ;
13257   if (pmax_n)
13258     *pmax_n = max_n ;
13259   return(max_label) ;// return most probable label
13260 }
13261 int
13262 GCAcomputeMLElabelAtLocation(GCA *gca, int xp, int yp, int zp, float *vals,
13263                              int *pmax_n, float *plog_p)
13264 {
13265   GCA_PRIOR  *gcap ;
13266   GC1D       *gc ;
13267   int        n, max_n, max_label ;
13268   float      log_p, max_log_p ;
13269 
13270   gcap = &gca->priors[xp][yp][zp] ;
13271   if (gcap == NULL || gcap->nlabels <= 0)
13272     return(Unknown);
13273   if (gcap->nlabels == 0)
13274   {
13275     if (plog_p)
13276       *plog_p = 0.0 ;
13277     if (pmax_n)
13278       *pmax_n = -1 ;
13279     return(Unknown) ;
13280   }
13281 
13282   max_label = gcap->labels[0] ;
13283   max_n = 0 ;
13284   gc = GCAfindPriorGC(gca, xp, yp, zp, gcap->labels[0]) ;
13285   if (gc)
13286     max_log_p = GCAcomputeConditionalLogDensity(gc, vals,
13287                 gca->ninputs, max_label) ;
13288   else
13289     max_log_p = -100000 ;
13290   for (n = 1 ; n < gcap->nlabels ; n++)
13291   {
13292     gc = GCAfindPriorGC(gca, xp, yp, zp, gcap->labels[n]) ;
13293     if (!gc)
13294       continue ;
13295     log_p = GCAcomputeConditionalLogDensity(gc,vals,gca->ninputs,
13296                                             gcap->labels[n]);
13297     if (log_p > max_log_p)
13298     {
13299       max_log_p = log_p ;
13300       max_n = n ;
13301       max_label = gcap->labels[n] ;
13302     }
13303   }
13304 
13305   if (plog_p)
13306     *plog_p = max_log_p ;
13307   if (pmax_n)
13308     *pmax_n = max_n ;
13309   return(max_label) ;
13310 }
13311 GC1D *
13312 alloc_gcs(int nlabels, int flags, int ninputs)
13313 {
13314   GC1D  *gcs ;
13315   int   i ;
13316 
13317   gcs = (GC1D *)calloc(nlabels, sizeof(GC1D)) ;
13318   if (gcs == NULL)
13319     ErrorExit(ERROR_NOMEMORY, "alloc_gcs(%d, %x): could not allocated %d gcs",
13320               nlabels, flags, nlabels) ;
13321   for (i = 0 ; i < nlabels ; i++)
13322   {
13323     gcs[i].means = (float *)calloc(ninputs, sizeof(float)) ;
13324     gcs[i].covars = (float *)calloc((ninputs*(ninputs+1))/2, sizeof(float)) ;
13325     if (!gcs[i].means || !gcs[i].covars)
13326       ErrorExit(ERROR_NOMEMORY, "could not allocate mean (%d) "
13327                 "and covariance (%d) matrices",
13328                 ninputs, ninputs*(ninputs+1)/2) ;
13329   }
13330   if (flags & GCA_NO_MRF)
13331     return(gcs) ;
13332 
13333   for (i = 0 ; i < nlabels ; i++)
13334   {
13335     gcs[i].nlabels = (short *)calloc(GIBBS_NEIGHBORHOOD, sizeof(short)) ;
13336     gcs[i].labels =
13337       (unsigned short **)calloc(GIBBS_NEIGHBORHOOD, sizeof(unsigned short *)) ;
13338     gcs[i].label_priors =
13339       (float **)calloc(GIBBS_NEIGHBORHOOD, sizeof(float *)) ;
13340     if (!gcs[i].nlabels || !gcs[i].labels || !gcs[i].label_priors)
13341       ErrorExit(ERROR_NOMEMORY,
13342                 "alloc_gcs(%d, %x): could not allocated %d gcs(%d)",
13343                 nlabels, flags, nlabels, i) ;
13344   }
13345   return(gcs) ;
13346 }
13347 
13348 int
13349 free_gcs(GC1D *gcs, int nlabels, int ninputs)
13350 {
13351   int   i, j ;
13352 
13353   for (i = 0 ; i < nlabels ; i++)
13354   {
13355     if (gcs[i].means)
13356       free(gcs[i].means) ;
13357     if (gcs[i].covars)
13358       free(gcs[i].covars) ;
13359     if (gcs[i].nlabels)  /* gibbs stuff allocated */
13360     {
13361       for (j = 0 ; j < GIBBS_NEIGHBORHOOD ; j++)
13362       {
13363         if (gcs[i].labels[j])
13364           free(gcs[i].labels[j]) ;
13365         if (gcs[i].label_priors[j])
13366           free(gcs[i].label_priors[j]) ;
13367       }
13368       free(gcs[i].nlabels) ;
13369       free(gcs[i].labels) ;
13370       free(gcs[i].label_priors) ;
13371     }
13372   }
13373 
13374   free(gcs) ;
13375   return(NO_ERROR) ;
13376 }
13377 
13378 int
13379 copy_gcs(int nlabels, GC1D *gcs_src, GC1D *gcs_dst, int ninputs)
13380 {
13381   int   i, j, k, r, c,v ;
13382 
13383   for (i = 0 ; i < nlabels ; i++)
13384   {
13385     for (v = r = 0 ; r < ninputs ; r++)
13386     {
13387       gcs_dst[i].means[r] = gcs_src[i].means[r] ;
13388       for (c = r ; c < ninputs ; c++, v++)
13389         gcs_dst[i].covars[v] = gcs_src[i].covars[v] ;
13390     }
13391     gcs_dst[i].ntraining = gcs_src[i].ntraining ;
13392     if (gcs_dst[i].nlabels == NULL)   /* NO_MRF flag must be set */
13393       continue ;
13394     for (j = 0 ; j < GIBBS_NEIGHBORHOOD ; j++)
13395     {
13396       gcs_dst[i].nlabels[j] = gcs_src[i].nlabels[j] ;
13397       if (!gcs_dst[i].label_priors[j])
13398       {
13399         gcs_dst[i].label_priors[j] =
13400           (float *)calloc(gcs_src[i].nlabels[j],sizeof(float)) ;
13401         gcs_dst[i].labels[j] =
13402           (unsigned short *)calloc(gcs_src[i].nlabels[j],
13403                                   sizeof(unsigned short)) ;
13404         if (!gcs_dst[i].label_priors[j] || !gcs_dst[i].labels[j])
13405           ErrorExit(ERROR_NOMEMORY,
13406                     "copy_gcs(%d): i=%d, j=%d, could not gibbs\n",
13407                     nlabels, i, j) ;
13408       }
13409       for (k = 0 ; k < gcs_src[i].nlabels[j] ; k++)
13410       {
13411         gcs_dst[i].label_priors[j][k] = gcs_src[i].label_priors[j][k] ;
13412         gcs_dst[i].labels[j][k] = gcs_src[i].labels[j][k] ;
13413       }
13414     }
13415   }
13416   return(NO_ERROR) ;
13417 }
13418 
13419 int
13420 GCAfreeGibbs(GCA *gca)
13421 {
13422   int       x, y, z,n, i ;
13423   GCA_NODE  *gcan ;
13424   GC1D      *gc ;
13425 
13426   if (gca->flags & GCA_NO_MRF)
13427     return(NO_ERROR) ;  /* already done */
13428 
13429   for (x = 0 ; x < gca->node_width ; x++)
13430   {
13431     for (y = 0 ; y < gca->node_height ; y++)
13432     {
13433       for (z = 0 ; z < gca->node_depth ; z++)
13434       {
13435         gcan = &gca->nodes[x][y][z] ;
13436         for (n = 0 ; n < gcan->nlabels ; n++)
13437         {
13438           gc = &gcan->gcs[n] ;
13439           for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
13440           {
13441             free(gc->label_priors[i]) ;
13442             free(gc->labels[i]) ;
13443             gc->label_priors[i] = NULL ;
13444             gc->labels[i] = NULL ;
13445           }
13446           free(gc->nlabels) ;
13447           free(gc->labels) ;
13448           free(gc->label_priors) ;
13449           gc->nlabels = NULL ;
13450           gc->labels = NULL ;
13451           gc->label_priors = NULL ;
13452         }
13453       }
13454     }
13455   }
13456   gca->flags |= GCA_NO_MRF ;
13457   return(NO_ERROR) ;
13458 }
13459 
13460 int
13461 GCAcomputeSampleCoords(GCA *gca, MRI *mri, GCA_SAMPLE *gcas,
13462                        int nsamples,TRANSFORM *transform)
13463 {
13464   int    n, x, y, z ;
13465 
13466   TransformInvert(transform, mri) ;
13467   if (transform->type == LINEAR_VOX_TO_VOX)
13468   {
13469     LTA *lta;
13470     lta = (LTA *) transform->xform;
13471     fprintf(stdout, "INFO: compute sample coordinates transform\n");
13472     MatrixPrint(stdout, lta->xforms[0].m_L);
13473   }
13474   fprintf(stdout, "INFO: transform used\n");
13475 
13476   for (n = 0 ; n < nsamples ; n++)
13477   {
13478     if (gcas[n].label == Gdiag_no)
13479       DiagBreak() ;
13480     if (!GCApriorToSourceVoxel(gca, mri, transform,
13481                                gcas[n].xp, gcas[n].yp, gcas[n].zp,
13482                                &x, &y, &z))
13483     {
13484       gcas[n].x = x ;
13485       gcas[n].y = y ;
13486       gcas[n].z = z ;
13487       if (DIAG_VERBOSE_ON && Gdiag & DIAG_SHOW)
13488         printf("label %d: (%d, %d, %d) <-- (%d, %d, %d)\n",
13489                gcas[n].label,gcas[n].xp,gcas[n].yp,gcas[n].zp, x, y, z) ;
13490     }
13491   }
13492   return(NO_ERROR) ;
13493 }
13494 
13495 static HISTOGRAM *
13496 gcaHistogramSamples(GCA *gca, GCA_SAMPLE *gcas, MRI *mri,
13497                     TRANSFORM *transform, int nsamples,
13498                     HISTOGRAM *histo, int frame)
13499 {
13500   int    i ;
13501   double mean, var ;
13502   Real   val ;
13503   float  fmin, fmax ;
13504 
13505   if (!histo)
13506   {
13507     MRIvalRangeFrame(mri, &fmin, &fmax, frame) ;
13508     histo = HISTOalloc(nint(fmax-fmin+1)) ;
13509   }
13510   else
13511     HISTOclear(histo, histo) ;
13512 
13513   for (mean = var = 0.0, i = 0 ; i < nsamples ; i++)
13514   {
13515     MRIsampleVolumeFrame(mri, gcas[i].x,gcas[i].y,gcas[i].z, frame, &val) ;
13516     histo->counts[(int)val]++ ;
13517     mean += val ;
13518     var += (val*val) ;
13519   }
13520 
13521   mean /= (double)nsamples ;
13522   var = var / (double)nsamples - mean*mean ;
13523   return(histo) ;
13524 }
13525 int
13526 GCArenormalizeFromAtlas(GCA *gca, GCA *gca_template)
13527 {
13528   int   xs, ys, zs, xt, yt, zt, ns, label, v ;
13529   float scale ;
13530   GCA_NODE *gcan ;
13531   GC1D      *gc, *gct ;
13532 
13533   scale = (float)gca_template->node_width / (float)gca->node_width ;
13534 
13535   for (xs = 0 ; xs < gca->node_width ; xs++)
13536   {
13537     xt = (int)(scale*xs) ;
13538     for (ys = 0 ; ys < gca->node_width ; ys++)
13539     {
13540       yt = (int)(scale*ys) ;
13541       for (zs = 0 ; zs < gca->node_width ; zs++)
13542       {
13543         zt = (int)(scale*zs) ;
13544         if (xs == Ggca_x && ys == Ggca_y && zs == Ggca_z)
13545           DiagBreak() ;
13546         if (xt == Ggca_x && yt == Ggca_y && zt == Ggca_z)
13547           DiagBreak() ;
13548         gcan = &gca->nodes[xs][ys][zs] ;
13549         for (ns = 0 ; ns < gcan->nlabels ; ns++)
13550         {
13551           label = gcan->labels[ns] ;
13552           gc = &gcan->gcs[ns] ;
13553           gct = GCAfindGC(gca_template, xt, yt, zt, label) ;
13554           if (gct == NULL)
13555             continue ;    /* label not in template GCA */
13556           for (v = 0 ; v < gca->ninputs ; v++)
13557             gc->means[v] = gct->means[v] ;
13558         }
13559       }
13560     }
13561   }
13562   return(NO_ERROR) ;
13563 }
13564 
13565 
13566 void
13567 load_vals(MRI *mri_inputs, float x, float y, float z, float *vals, int ninputs)
13568 {
13569   int  n ;
13570   Real val ;
13571 
13572   // go through all inputs and get values from inputs
13573   for (n = 0 ; n < ninputs ; n++)
13574   {
13575     // trilinear value at float x, y, z
13576     MRIsampleVolumeFrame(mri_inputs, x, y, z, n, &val) ;
13577     vals[n] = val ;
13578   }
13579 }
13580 
13581 double
13582 GCAmahDist(GC1D *gc, float *vals, int ninputs)
13583 {
13584   static VECTOR *v_means = NULL, *v_vals = NULL ;
13585   static MATRIX *m_cov = NULL, *m_cov_inv ;
13586   int    i ;
13587   double dsq ;
13588 
13589   if (ninputs == 1)
13590   {
13591     float  v ;
13592     v = vals[0] - gc->means[0] ;
13593     dsq = v*v / gc->covars[0] ;
13594     return(dsq) ;
13595   }
13596 
13597   if (v_vals && ninputs != v_vals->rows)
13598     VectorFree(&v_vals) ;
13599   if (v_means && ninputs != v_means->rows)
13600     VectorFree(&v_means) ;
13601   if (m_cov && (ninputs != m_cov->rows || ninputs != m_cov->cols))
13602   {
13603     MatrixFree(&m_cov) ;
13604     MatrixFree(&m_cov_inv) ;
13605   }
13606   v_means = load_mean_vector(gc, v_means, ninputs) ;
13607   m_cov = load_covariance_matrix(gc, m_cov, ninputs) ;
13608   if (v_vals == NULL)
13609     v_vals = VectorClone(v_means) ;
13610   for (i = 0 ; i < ninputs ; i++)
13611     VECTOR_ELT(v_vals, i+1) = vals[i] ;
13612 
13613   VectorSubtract(v_means, v_vals, v_vals) ;  /* v_vals now has mean removed */
13614   m_cov_inv = MatrixInverse(m_cov, m_cov_inv) ;
13615   if (!m_cov_inv)
13616     ErrorExit(ERROR_BADPARM, "singular covariance matrix!") ;
13617   MatrixSVDInverse(m_cov, m_cov_inv) ;
13618 
13619   MatrixMultiply(m_cov_inv, v_vals, v_means) ;
13620   /* v_means is now inverse(cov) * v_vals */
13621   dsq = VectorDot(v_vals, v_means) ;
13622 
13623   return(dsq);
13624 }
13625 double
13626 GCAmahDistIdentityCovariance(GC1D *gc, float *vals, int ninputs)
13627 {
13628   static VECTOR *v_means = NULL, *v_vals = NULL ;
13629   int    i ;
13630   double dsq ;
13631 
13632   if (v_vals && ninputs != v_vals->rows)
13633     VectorFree(&v_vals) ;
13634   if (v_means && ninputs != v_means->rows)
13635     VectorFree(&v_means) ;
13636   v_means = load_mean_vector(gc, v_means, ninputs) ;
13637   if (v_vals == NULL)
13638     v_vals = VectorClone(v_means) ;
13639   for (i = 0 ; i < ninputs ; i++)
13640     VECTOR_ELT(v_vals, i+1) = vals[i] ;
13641 
13642   VectorSubtract(v_means, v_vals, v_vals) ;  /* v_vals now has mean removed */
13643   dsq = VectorDot(v_vals, v_vals) ;
13644 
13645   return(dsq);
13646 }
13647 
13648 double
13649 GCAcomputePosteriorDensity(GCA_PRIOR *gcap, GCA_NODE *gcan,
13650                            int n, float *vals, int ninputs)
13651 {
13652   GC1D *gc ;
13653   double p ;
13654 
13655   gc = &gcan->gcs[n] ;
13656 
13657   p = GCAcomputeConditionalDensity(gc, vals, ninputs, gcan->labels[n]) ;
13658   p *= getPrior(gcap, gcan->labels[n]) ;
13659   return(p) ;
13660 }
13661 
13662 VECTOR *
13663 load_mean_vector(GC1D *gc, VECTOR *v_means, int ninputs)
13664 {
13665   int n ;
13666 
13667   if (v_means == NULL)
13668     v_means = VectorAlloc(ninputs, MATRIX_REAL) ;
13669 
13670   for (n = 0 ; n < ninputs ; n++)
13671     VECTOR_ELT(v_means, n+1) = gc->means[n] ;
13672 
13673   return(v_means) ;
13674 }
13675 
13676 MATRIX *
13677 load_covariance_matrix(GC1D *gc, MATRIX *m_cov, int ninputs)
13678 {
13679   int n, m, i ;
13680 
13681   if (m_cov == NULL)
13682     m_cov = MatrixAlloc(ninputs, ninputs, MATRIX_REAL) ;
13683 
13684   for (i = n = 0 ; n < ninputs ; n++)
13685     for (m = n ; m < ninputs ; m++, i++)
13686     {
13687       *MATRIX_RELT(m_cov, n+1, m+1) = gc->covars[i] ;
13688       if (m != n)
13689         *MATRIX_RELT(m_cov, m+1, n+1) = gc->covars[i] ;
13690     }
13691 
13692   return(m_cov) ;
13693 }
13694 
13695 int
13696 set_mean_vector(GC1D *gc, VECTOR *v_means, int ninputs)
13697 {
13698   int n ;
13699 
13700   for (n = 0 ; n < ninputs ; n++)
13701     gc->means[n] = VECTOR_ELT(v_means, n+1) ;
13702 
13703   return(NO_ERROR) ;
13704 }
13705 
13706 int
13707 set_covariance_matrix(GC1D *gc, MATRIX *m_cov, int ninputs)
13708 {
13709   int n, m, i ;
13710 
13711   for (i = n = 0 ; n < ninputs ; n++)
13712     for (m = n ; m < ninputs ; m++, i++)
13713     {
13714       gc->covars[i] = *MATRIX_RELT(m_cov, n+1, m+1) ;
13715       if (m != n)
13716         gc->covars[i] = *MATRIX_RELT(m_cov, m+1, n+1) ;
13717     }
13718 
13719   return(NO_ERROR) ;
13720 }
13721 
13722 MATRIX *
13723 load_inverse_covariance_matrix(GC1D *gc, MATRIX *m_inv_cov, int ninputs)
13724 {
13725   static MATRIX *m_cov = NULL ;
13726 
13727   if (m_cov && (m_cov->rows != ninputs || m_cov->cols != ninputs))
13728     MatrixFree(&m_cov) ;
13729   m_cov = load_covariance_matrix(gc, m_cov, ninputs) ;
13730   m_inv_cov = MatrixInverse(m_cov, m_inv_cov) ;
13731 #if 0
13732   if (m_inv_cov == NULL)
13733     ErrorPrintf(ERROR_BADPARM,
13734                 "load_inverse_covariance_matrix: "
13735                 "singular covariance matrix!") ;
13736 #endif
13737   return(m_inv_cov) ;
13738 }
13739 
13740 double
13741 covariance_determinant(GC1D *gc, int ninputs)
13742 {
13743   double det ;
13744   static MATRIX *m_cov = NULL ;
13745 
13746   if (ninputs == 1)
13747     return(gc->covars[0]) ;
13748   if (m_cov && (m_cov->rows != ninputs || m_cov->cols != ninputs))
13749     MatrixFree(&m_cov) ;
13750   m_cov = load_covariance_matrix(gc, m_cov, ninputs) ;
13751   det = MatrixDeterminant(m_cov) ;
13752 #if 0
13753   if (det <= 0)
13754     det = 0.001 ;
13755 #endif
13756   return(det) ;
13757 }
13758 
13759 static double
13760 gcaComputeSampleLogDensity(GCA_SAMPLE *gcas, float *vals, int ninputs)
13761 {
13762   double log_p ;
13763 
13764   log_p = gcaComputeSampleConditionalLogDensity(gcas, vals,
13765           ninputs, gcas->label) ;
13766   log_p += log(gcas->prior) ;
13767   return(log_p) ;
13768 }
13769 
13770 static double
13771 gcaComputeSampleConditionalLogDensity(GCA_SAMPLE *gcas,
13772                                       float *vals,
13773                                       int ninputs, int label)
13774 {
13775   double  log_p, det ;
13776 
13777 
13778 #if 0
13779   if (label == Unknown)  /* uniform distribution */
13780   {
13781     log_p = log(1.0/256.0f) ;
13782   }
13783   else   /* Gaussian distribution */
13784 #endif
13785   {
13786     det = sample_covariance_determinant(gcas, ninputs) ;
13787     log_p = -log(sqrt(det)) - .5*GCAsampleMahDist(gcas, vals, ninputs) ;
13788   }
13789   return(log_p) ;
13790 }
13791 static VECTOR *
13792 load_sample_mean_vector(GCA_SAMPLE *gcas, VECTOR *v_means, int ninputs)
13793 {
13794   int n ;
13795 
13796   if (v_means == NULL)
13797     v_means = VectorAlloc(ninputs, MATRIX_REAL) ;
13798 
13799   for (n = 0 ; n < ninputs ; n++)
13800     VECTOR_ELT(v_means, n+1) = gcas->means[n] ;
13801 
13802   return(v_means) ;
13803 }
13804 static MATRIX *
13805 load_sample_covariance_matrix(GCA_SAMPLE *gcas, MATRIX *m_cov, int ninputs)
13806 {
13807   int n, m, i ;
13808 
13809   if (m_cov == NULL)
13810     m_cov = MatrixAlloc(ninputs, ninputs, MATRIX_REAL) ;
13811 
13812   for (i = n = 0 ; n < ninputs ; n++)
13813     for (m = n ; m < ninputs ; m++, i++)
13814     {
13815       *MATRIX_RELT(m_cov, n+1, m+1) = gcas->covars[i] ;
13816     }
13817 
13818   return(m_cov) ;
13819 }
13820 
13821 static double
13822 sample_covariance_determinant(GCA_SAMPLE *gcas, int ninputs)
13823 {
13824   double det ;
13825   static MATRIX *m_cov = NULL ;
13826 
13827   if (ninputs == 1)
13828     return(gcas->covars[0]) ;
13829   if (m_cov && (m_cov->rows != ninputs || m_cov->cols != ninputs))
13830     MatrixFree(&m_cov) ;
13831 
13832   m_cov = load_sample_covariance_matrix(gcas, m_cov, ninputs) ;
13833   det = MatrixDeterminant(m_cov) ;
13834   return(det) ;
13835 }
13836 double
13837 GCAsampleMahDist(GCA_SAMPLE *gcas, float *vals, int ninputs)
13838 {
13839   static VECTOR *v_means = NULL, *v_vals = NULL ;
13840   static MATRIX *m_cov = NULL, *m_cov_inv ;
13841   int    i ;
13842   double dsq ;
13843 
13844   if (ninputs == 1)
13845   {
13846     float  v ;
13847     v = vals[0] - gcas->means[0] ;
13848     dsq = v*v / gcas->covars[0] ;
13849     return(dsq) ;
13850   }
13851 
13852   if (v_vals && ninputs != v_vals->rows)
13853     VectorFree(&v_vals) ;
13854   if (v_means && ninputs != v_means->rows)
13855     VectorFree(&v_means) ;
13856   if (m_cov && (ninputs != m_cov->rows || ninputs != m_cov->cols))
13857   {
13858     MatrixFree(&m_cov) ;
13859     MatrixFree(&m_cov_inv) ;
13860   }
13861 
13862   v_means = load_sample_mean_vector(gcas, v_means, ninputs) ;
13863   m_cov = load_sample_covariance_matrix(gcas, m_cov, ninputs) ;
13864 
13865   if (v_vals == NULL)
13866     v_vals = VectorClone(v_means) ;
13867   for (i = 0 ; i < ninputs ; i++)
13868     VECTOR_ELT(v_vals, i+1) = vals[i] ;
13869 
13870   VectorSubtract(v_means, v_vals, v_vals) ;  /* v_vals now has mean removed */
13871   m_cov_inv = MatrixInverse(m_cov, m_cov_inv) ;
13872   if (!m_cov_inv)
13873     ErrorExit(ERROR_BADPARM, "singular covariance matrix!") ;
13874 
13875   MatrixMultiply(m_cov_inv, v_vals, v_means) ;
13876   /* v_means is now inverse(cov) * v_vals */
13877   dsq = VectorDot(v_vals, v_means) ;
13878 
13879   return(dsq);
13880 }
13881 #if 0
13882 static double
13883 gcaComputeSampleConditionalDensity(GCA_SAMPLE *gcas,
13884                                    float *vals, int ninputs, int label)
13885 {
13886   double  p, dist ;
13887 
13888   /* compute 1-d Mahalanobis distance */
13889 #if 0
13890   if (label == Unknown)  /* uniform distribution */
13891   {
13892     p = 1.0/256.0f ;
13893   }
13894   else   /* Gaussian distribution */
13895 #endif
13896   {
13897     dist = GCAsampleMahDist(gcas, vals, ninputs) ;
13898     p = 1 / sqrt(sample_covariance_determinant(gcas, ninputs)) * exp(-dist) ;
13899   }
13900   return(p) ;
13901 }
13902 #endif
13903 int
13904 GCAlabelExists(GCA *gca, MRI *mri, TRANSFORM *transform,
13905                int x, int y, int z, int label)
13906 {
13907 #if 0
13908   int  xn, yn, zn ;
13909 
13910   if (!GCAsourceVoxelToNode(gca, mri, transform, x, y, z, &xn, &yn, &zn))
13911   {
13912     if (GCAfindGC(gca, xn, yn, zn, label) == NULL)
13913       return(0) ;
13914     return(1) ;
13915   }
13916   else
13917     return 0;
13918 #else
13919   return(GCAisPossible(gca, mri, label, transform, x, y, z,0)) ;
13920 #endif
13921 }
13922 
13923 GC1D *
13924 GCAfindSourceGC(GCA *gca, MRI *mri, TRANSFORM *transform,
13925                 int x, int y, int z, int label)
13926 {
13927   int  xn, yn, zn ;
13928   GC1D *gc=NULL ;
13929 
13930   if (!GCAsourceVoxelToNode(gca, mri, transform, x, y, z, &xn, &yn, &zn))
13931   {
13932     gc = GCAfindGC(gca, xn, yn, zn, label) ;
13933   }
13934   return(gc) ;
13935 }
13936 int
13937 GCAfreeSamples(GCA_SAMPLE **pgcas, int nsamples)
13938 {
13939   GCA_SAMPLE *gcas ;
13940   int         i ;
13941 
13942   gcas = *pgcas ;
13943   *pgcas = NULL ;
13944 
13945   if (gcas == NULL)
13946     return(NO_ERROR) ;
13947 
13948   for (i = 0 ; i < nsamples ; i++)
13949   {
13950     if (gcas[i].means)
13951       free(gcas[i].means) ;
13952     if (gcas[i].covars)
13953       free(gcas[i].covars) ;
13954   }
13955   free(gcas) ;
13956   return(NO_ERROR) ;
13957 }
13958 int
13959 GCAnormalizePD(GCA *gca, MRI *mri_inputs, TRANSFORM *transform)
13960 {
13961   double     mri_PD  = 0.0, gca_PD = 0.0 ;
13962   int        n, x, y, z, brain_node, nvals, label ;
13963   GCA_PRIOR  *gcap ;
13964   GC1D       *gc ;
13965   Real      val ;
13966 
13967   if (mri_inputs->nframes != 2 || gca->ninputs != 2)
13968     ErrorReturn(ERROR_BADPARM,
13969                 (ERROR_BADPARM,
13970                  "GCAnormalizePD: invalid input size (%d) or gca size (%d)",
13971                  mri_inputs->nframes, gca->ninputs)) ;
13972 
13973   for (nvals = x = 0 ;  x < mri_inputs->width ; x++)
13974   {
13975     for (y = 0 ; y < mri_inputs->height ; y++)
13976     {
13977       for (z = 0 ; z < mri_inputs->depth ; z++)
13978       {
13979         gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
13980         if (gcap == NULL || gcap->nlabels <= 0)
13981           continue;
13982         for (label = brain_node = 0, n = 0 ; \
13983              !brain_node && n < gcap->nlabels ; n++)
13984           if (IS_WM(gcap->labels[n]) && gcap->priors[n] > 0.5)
13985           {
13986             brain_node = 1 ;
13987             label = gcap->labels[n] ;
13988           }
13989         if (!brain_node)
13990           continue ;   /* no valid data here */
13991         gc = GCAfindSourceGC(gca, mri_inputs, transform,
13992                              x, y, z, label) ;
13993         if (gc)
13994         {
13995           MRIsampleVolumeFrameType(mri_inputs, x, y, z, 1,
13996                                    SAMPLE_NEAREST, &val) ;
13997           nvals++ ;
13998           mri_PD += val ;
13999           gca_PD += gc->means[1] ;
14000         }
14001       }
14002     }
14003   }
14004   mri_PD /= (double)nvals ;
14005   gca_PD /= (double)nvals ;
14006   printf("mean PD in volume %2.1f, mean GCA PD %2.1f - scaling by %2.3f\n",
14007          mri_PD, gca_PD, gca_PD / mri_PD) ;
14008   MRIscalarMulFrame(mri_inputs, mri_inputs, gca_PD / mri_PD, 1) ;
14009 
14010   return(NO_ERROR) ;
14011 }
14012 GCA *
14013 GCAcreateWeightedFlashGCAfromParameterGCA(GCA *gca_T1PD,
14014     double *TR, double *fa, double *TE,
14015     int nflash, double *wts,
14016     double lambda)
14017 {
14018   GCA        *gca_flash ;
14019   GCA_PRIOR  *gcap_src, *gcap_dst ;
14020   GCA_NODE   *gcan_src, *gcan_dst ;
14021   GC1D       *gc_src, *gc_dst ;
14022   MATRIX     *m_jacobian, *m_cov_src = NULL, *m_cov_dst = NULL, \
14023                                        *m_jacobian_T = NULL, *m_tmp = NULL ;
14024   VECTOR     *v_wts, *v_wts_T ;
14025   int        n, x, y, z, i, j, v, label_count = 0 ;
14026   double     T1, PD, label_means[MAX_GCA_INPUTS] ;
14027 
14028   if (gca_T1PD->ninputs != 2)
14029     ErrorExit(ERROR_BADPARM,
14030               "GCAcreateWeightedFlashGCAfromParameterGCA: "
14031               "input gca must be T1/PD (ninputs=%d, should be 2",
14032               gca_T1PD->ninputs) ;
14033   gca_flash = GCAalloc(nflash, gca_T1PD->prior_spacing, gca_T1PD->node_spacing,
14034                        gca_T1PD->node_width*gca_T1PD->node_spacing,
14035                        gca_T1PD->node_height*gca_T1PD->node_spacing,
14036                        gca_T1PD->node_depth*gca_T1PD->node_spacing,
14037                        GCA_NO_FLAGS) ;
14038 
14039   m_jacobian =
14040     MatrixAlloc(gca_flash->ninputs, gca_T1PD->ninputs, MATRIX_REAL) ;
14041   v_wts = VectorAlloc(nflash, MATRIX_REAL) ;
14042   for (i = 1 ; i <= nflash ; i++)
14043     VECTOR_ELT(v_wts,i) = wts[i-1] ;
14044   v_wts_T = VectorTranspose(v_wts, NULL) ;
14045 
14046   /* first copy over priors */
14047   for (x = 0 ; x < gca_flash->prior_width ; x++)
14048   {
14049     for (y = 0 ; y < gca_flash->prior_height ; y++)
14050     {
14051       for (z = 0 ; z < gca_flash->prior_depth ; z++)
14052       {
14053         gcap_src = &gca_T1PD->priors[x][y][z] ;
14054         if (gcap_src==NULL)
14055           continue;
14056         gcap_dst = &gca_flash->priors[x][y][z] ;
14057         if (gcap_dst==NULL)
14058           continue;
14059         gcap_dst->nlabels = gcap_src->nlabels ;
14060         if (gcap_dst==NULL)
14061           continue;
14062         if (gcap_src->nlabels > gcap_dst->max_labels)
14063         {
14064           free(gcap_dst->priors) ;
14065           free(gcap_dst->labels) ;
14066 
14067           gcap_dst->labels =
14068             (unsigned short *)calloc(gcap_src->nlabels,
14069                                     sizeof(unsigned short)) ;
14070           if (!gcap_dst->labels)
14071             ErrorExit(ERROR_NOMEMORY,
14072                       "GCAcreateWeightedFlashGCAfromParameterGCA:"
14073                       " couldn't allocate %d labels",
14074                       gcap_src->nlabels) ;
14075 
14076           gcap_dst->priors =
14077             (float *)calloc(gcap_src->nlabels, sizeof(float)) ;
14078           if (!gcap_dst->priors)
14079             ErrorExit(ERROR_NOMEMORY,
14080                       "GCAcreateWeightedFlashGCAfromParameterGCA:"
14081                       " couldn't allocate %d priors",
14082                       gcap_src->nlabels) ;
14083           gcap_dst->max_labels = gcap_dst->nlabels ;
14084         }
14085         gcap_dst->total_training = gcap_src->total_training ;
14086         for (n = 0 ; n < gcap_src->nlabels ; n++)
14087         {
14088           gcap_dst->labels[n] = gcap_src->labels[n] ;
14089           gcap_dst->priors[n] = gcap_src->priors[n] ;
14090         }
14091       }
14092     }
14093   }
14094 
14095   /* now copy over classifiers and Markov stuff, using Jacobian to */
14096   /* map to new image space */
14097   for (x = 0 ; x < gca_flash->node_width ; x++)
14098   {
14099     for (y = 0 ; y < gca_flash->node_height ; y++)
14100     {
14101       for (z = 0 ; z < gca_flash->node_depth ; z++)
14102       {
14103         if (x == Gx && y == Gy && z == Gz)
14104           DiagBreak()  ;
14105         gcan_src = &gca_T1PD->nodes[x][y][z] ;
14106         gcan_dst = &gca_flash->nodes[x][y][z] ;
14107         gcan_dst->nlabels = gcan_src->nlabels ;
14108         gcan_dst->total_training = gcan_src->total_training ;
14109         if (gcan_src->nlabels > gcan_dst->max_labels)
14110         {
14111           free(gcan_dst->labels) ;
14112           free_gcs(gcan_dst->gcs,
14113                    gcan_dst->max_labels,
14114                    gca_flash->ninputs) ;
14115 
14116           gcan_dst->labels =
14117             (unsigned short *)calloc(gcan_src->nlabels,
14118                                     sizeof(unsigned short)) ;
14119           if (!gcan_dst->labels)
14120             ErrorExit(ERROR_NOMEMORY,
14121                       "GCAcreateWeightedFlashGCAfromParameterGCA:"
14122                       " couldn't allocate %d labels",
14123                       gcan_src->nlabels) ;
14124 
14125           gcan_dst->gcs = alloc_gcs(gcan_src->nlabels,
14126                                     GCA_NO_FLAGS, nflash) ;
14127           gcan_dst->max_labels = gcan_dst->nlabels ;
14128         }
14129         for (n = 0 ; n < gcan_src->nlabels ; n++)
14130         {
14131           gcan_dst->labels[n] = gcan_src->labels[n] ;
14132           gc_src = &gcan_src->gcs[n] ;
14133           gc_dst = &gcan_dst->gcs[n] ;
14134           gc_dst->ntraining = gc_src->ntraining ;
14135           gc_dst->n_just_priors = gc_src->n_just_priors ;
14136           gc_dst->regularized = gc_src->regularized ;
14137           for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
14138           {
14139             gc_dst->nlabels[i] = gc_src->nlabels[i] ;
14140             gc_dst->label_priors[i] =
14141               (float *)calloc(gc_src->nlabels[i],sizeof(float));
14142             if (!gc_dst->label_priors[i])
14143               ErrorExit(ERROR_NOMEMORY,
14144                         "GCAcreateWeightedFlashGCAfromParameterGCA: "
14145                         "to %d",gc_src->nlabels[i]);
14146             gc_dst->labels[i] =
14147               (unsigned short *)calloc(gc_src->nlabels[i], \
14148                                       sizeof(unsigned short)) ;
14149             if (!gc_dst->labels)
14150               ErrorExit(ERROR_NOMEMORY,
14151                         "GCAcreateWeightedFlashGCAfromParameterGCA:"
14152                         " to %d",gc_src->nlabels[i]);
14153             for (j = 0 ; j < gc_src->nlabels[i] ; j++)
14154             {
14155               gc_dst->label_priors[i][j]
14156               = gc_src->label_priors[i][j] ;
14157               gc_dst->labels[i][j]
14158               = gc_src->labels[i][j] ;
14159             }
14160           }
14161 
14162           /* now map intensity and covariance info over */
14163           T1 = gc_src->means[0] ;
14164           PD = gc_src->means[1] ;
14165           if (Ggca_label == gcan_dst->labels[n])
14166             label_count++ ;
14167           for (i = 0 ; i < gca_flash->ninputs ; i++)
14168           {
14169             gc_dst->means[i] =
14170               FLASHforwardModel(T1, PD, TR[i], fa[i], TE[i]) ;
14171             if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14172                 (Ggca_label < 0 ||
14173                  Ggca_label == gcan_src->labels[n]))
14174               printf("gcan(%d, %d, %d) %s: image[%d] "
14175                      "(fa=%2.1f) predicted mean "
14176                      "(%2.1f,%2.1f) --> %2.1f\n",
14177                      x, y, z,
14178                      cma_label_to_name(gcan_dst->labels[n]),
14179                      i, DEGREES(fa[i]),
14180                      T1, PD, gc_dst->means[i]) ;
14181             *MATRIX_RELT(m_jacobian, i+1, 1) =
14182               dFlash_dT1(T1, PD, TR[i], fa[i], TE[i]) ;
14183             *MATRIX_RELT(m_jacobian, i+1, 2) =
14184               dFlash_dPD(T1, PD, TR[i], fa[i], TE[i]) ;
14185             if (gcan_dst->labels[n] == Ggca_label)
14186             {
14187               label_means[i] += gc_dst->means[i] ;
14188             }
14189           }
14190 #define MIN_T1 50
14191           if (T1 < MIN_T1)
14192           {
14193             gc_dst->regularized = 1 ;
14194             m_cov_dst = MatrixIdentity(gca_flash->ninputs,
14195                                        m_cov_dst) ;
14196           }
14197           else
14198           {
14199             m_cov_src =
14200               load_covariance_matrix(gc_src, m_cov_src,
14201                                      gca_T1PD->ninputs) ;
14202             m_jacobian_T = MatrixTranspose(m_jacobian,
14203                                            m_jacobian_T) ;
14204             m_tmp = MatrixMultiply(m_cov_src, m_jacobian_T, m_tmp) ;
14205             m_cov_dst = MatrixMultiply(m_jacobian,
14206                                        m_tmp, m_cov_dst) ;
14207           }
14208           for (v = i = 0 ; i < gca_flash->ninputs ; i++)
14209           {
14210             for (j = i ; j < gca_flash->ninputs ; j++, v++)
14211               gc_dst->covars[v] = *MATRIX_RELT(m_cov_dst, i+1, j+1) ;
14212           }
14213           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14214               (Ggca_label < 0 || Ggca_label == gcan_src->labels[n]))
14215           {
14216             printf("predicted covariance matrix:\n") ;
14217             MatrixPrint(stdout, m_cov_dst)  ;
14218           }
14219         }
14220       }
14221     }
14222   }
14223 
14224   if (Ggca_label >= 0)
14225   {
14226     printf("label %s (%d): means = ",
14227            cma_label_to_name(Ggca_label), Ggca_label) ;
14228     for (i = 0 ; i < gca_flash->ninputs ; i++)
14229     {
14230       label_means[i] /= (double)label_count ;
14231       printf("%2.1f ", label_means[i]) ;
14232     }
14233     printf("\n") ;
14234   }
14235 
14236   /* check and fix singular covariance matrixces */
14237   GCAregularizeCovarianceMatrices(gca_flash, lambda) ;
14238   GCAfixSingularCovarianceMatrices(gca_flash) ;
14239   MatrixFree(&m_jacobian) ;
14240   MatrixFree(&m_cov_src) ;
14241   MatrixFree(&m_cov_dst) ;
14242   MatrixFree(&m_jacobian_T) ;
14243   MatrixFree(&m_tmp) ;
14244   VectorFree(&v_wts) ;
14245   VectorFree(&v_wts_T) ;
14246 
14247   gca_flash->type = GCA_FLASH;
14248   GCAcopyDCToGCA(gca_T1PD, gca_flash) ;
14249 
14250   return(gca_flash) ;
14251 }
14252 GCA *
14253 GCAcreateFlashGCAfromParameterGCA(GCA *gca_T1PD,
14254                                   double *TR, double *fa, double *TE,
14255                                   int nflash, double lambda)
14256 {
14257   GCA        *gca_flash ;
14258   GCA_PRIOR  *gcap_src, *gcap_dst ;
14259   GCA_NODE   *gcan_src, *gcan_dst ;
14260   GC1D       *gc_src, *gc_dst ;
14261   MATRIX     *m_jacobian, *m_cov_src = NULL, *m_cov_dst = NULL, \
14262                                        *m_jacobian_T = NULL, *m_tmp = NULL ;
14263   int        n, x, y, z, i, j, v, label_count = 0 ;
14264   double     T1, PD, label_means[MAX_GCA_INPUTS] ;
14265 
14266   if (gca_T1PD->ninputs != 2)
14267     ErrorExit(ERROR_BADPARM,
14268               "GCAcreateFlashGCAfromParameterGCA: "
14269               "input gca must be T1/PD (ninputs=%d, should be 2",
14270               gca_T1PD->ninputs) ;
14271   // gca_flash will have gca->ninputs = nflash
14272   gca_flash = GCAalloc(nflash, gca_T1PD->prior_spacing, gca_T1PD->node_spacing,
14273                        gca_T1PD->node_width*gca_T1PD->node_spacing,
14274                        gca_T1PD->node_height*gca_T1PD->node_spacing,
14275                        gca_T1PD->node_depth*gca_T1PD->node_spacing,
14276                        GCA_NO_FLAGS) ;
14277 
14278   m_jacobian = MatrixAlloc(gca_flash->ninputs,
14279                            gca_T1PD->ninputs, MATRIX_REAL) ;
14280 
14281   /* first copy over priors */
14282   for (x = 0 ; x < gca_flash->prior_width ; x++)
14283   {
14284     for (y = 0 ; y < gca_flash->prior_height ; y++)
14285     {
14286       for (z = 0 ; z < gca_flash->prior_depth ; z++)
14287       {
14288         gcap_src = &gca_T1PD->priors[x][y][z] ;
14289         if (gcap_src == NULL)
14290           continue;
14291         gcap_dst = &gca_flash->priors[x][y][z] ;
14292         if (gcap_dst == NULL)
14293           continue;
14294         gcap_dst->nlabels = gcap_src->nlabels ;
14295         if (gcap_src->nlabels > gcap_dst->max_labels)
14296         {
14297           free(gcap_dst->priors) ;
14298           free(gcap_dst->labels) ;
14299 
14300           gcap_dst->labels =
14301             (unsigned short *)calloc(gcap_src->nlabels,
14302                                     sizeof(unsigned short)) ;
14303           if (!gcap_dst->labels)
14304             ErrorExit(ERROR_NOMEMORY,
14305                       "GCAcreateFlashGCAfromParameterGCA: "
14306                       "couldn't allocate %d labels",
14307                       gcap_src->nlabels) ;
14308 
14309           gcap_dst->priors =
14310             (float *)calloc(gcap_src->nlabels, sizeof(float)) ;
14311           if (!gcap_dst->priors)
14312             ErrorExit(ERROR_NOMEMORY,
14313                       "GCAcreateFlashGCAfromParameterGCA: "
14314                       "couldn't allocate %d priors",
14315                       gcap_src->nlabels) ;
14316           gcap_dst->max_labels = gcap_dst->nlabels ;
14317         }
14318         gcap_dst->total_training = gcap_src->total_training ;
14319         for (n = 0 ; n < gcap_src->nlabels ; n++)
14320         {
14321           gcap_dst->labels[n] = gcap_src->labels[n] ;
14322           gcap_dst->priors[n] = gcap_src->priors[n] ;
14323         }
14324       }
14325     }
14326   }
14327 
14328   /* now copy over classifiers and Markov stuff, */
14329   /* using Jacobian to map to new image space */
14330   for (x = 0 ; x < gca_flash->node_width ; x++)
14331   {
14332     for (y = 0 ; y < gca_flash->node_height ; y++)
14333     {
14334       for (z = 0 ; z < gca_flash->node_depth ; z++)
14335       {
14336         if (x == Gx && y == Gy && z == Gz)
14337           DiagBreak()  ;
14338         gcan_src = &gca_T1PD->nodes[x][y][z] ;
14339         gcan_dst = &gca_flash->nodes[x][y][z] ;
14340         gcan_dst->nlabels = gcan_src->nlabels ;
14341         gcan_dst->total_training = gcan_src->total_training ;
14342         if (gcan_src->nlabels > gcan_dst->max_labels)
14343         {
14344           free(gcan_dst->labels) ;
14345           free_gcs(gcan_dst->gcs,
14346                    gcan_dst->max_labels,
14347                    gca_flash->ninputs) ;
14348 
14349           gcan_dst->labels =
14350             (unsigned short *)calloc(gcan_src->nlabels,
14351                                     sizeof(unsigned short)) ;
14352           if (!gcan_dst->labels)
14353             ErrorExit(ERROR_NOMEMORY,
14354                       "GCAcreateFlashGCAfromParameterGCA: "
14355                       "couldn't allocate %d labels",
14356                       gcan_src->nlabels) ;
14357 
14358           gcan_dst->gcs = alloc_gcs(gcan_src->nlabels,
14359                                     GCA_NO_FLAGS, nflash) ;
14360           gcan_dst->max_labels = gcan_dst->nlabels ;
14361         }
14362         for (n = 0 ; n < gcan_src->nlabels ; n++)
14363         {
14364           gcan_dst->labels[n] = gcan_src->labels[n] ;
14365           gc_src = &gcan_src->gcs[n] ;
14366           gc_dst = &gcan_dst->gcs[n] ;
14367           gc_dst->ntraining = gc_src->ntraining ;
14368           gc_dst->n_just_priors = gc_src->n_just_priors ;
14369           for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
14370           {
14371             gc_dst->nlabels[i] = gc_src->nlabels[i] ;
14372             gc_dst->label_priors[i] =
14373               (float *)calloc(gc_src->nlabels[i],sizeof(float));
14374             if (!gc_dst->label_priors[i])
14375               ErrorExit(ERROR_NOMEMORY,
14376                         "GCAcreateFlashGCAfromParameterGCA: to %d",
14377                         gc_src->nlabels[i]);
14378             gc_dst->labels[i] =
14379               (unsigned short *)calloc(gc_src->nlabels[i], \
14380                                       sizeof(unsigned short)) ;
14381             if (!gc_dst->labels)
14382               ErrorExit(ERROR_NOMEMORY,
14383                         "GCAcreateFlashGCAfromParameterGCA: to %d",
14384                         gc_src->nlabels[i]);
14385             for (j = 0 ; j < gc_src->nlabels[i] ; j++)
14386             {
14387               gc_dst->label_priors[i][j]
14388               = gc_src->label_priors[i][j] ;
14389               gc_dst->labels[i][j]
14390               = gc_src->labels[i][j] ;
14391             }
14392           }
14393 
14394           /* now map intensity and covariance info over */
14395           T1 = gc_src->means[0] ;
14396           PD = gc_src->means[1] ;
14397           if (T1 < 0)
14398           {
14399             printf
14400             ("WARN: ******************************************\n");
14401             printf
14402             ("WARN: (%d, %d, %d) has T1 = %f < 0 and PD = %f\n",
14403              x, y, z, T1, PD);
14404             printf("WARN: nlabels = %d\n", gcan_src->nlabels);
14405             for (i=0;i < gcan_src->nlabels; ++i)
14406               printf
14407               ("WARN: %d: label = %d\n", i, gcan_src->labels[i]);
14408             printf("WARN: make T1 = 10 msec\n");
14409             printf
14410             ("WARN: ******************************************\n");
14411           }
14412           T1 = MAX(T1,10) ;
14413           PD = MAX(PD, 0) ;
14414           if (Ggca_label == gcan_dst->labels[n])
14415             label_count++ ;
14416           for (i = 0 ; i < gca_flash->ninputs ; i++)
14417           {
14418             gc_dst->means[i] =
14419               FLASHforwardModel(T1, PD, TR[i], fa[i], TE[i]) ;
14420             if (x == Gx && y == Gy && z == Gz &&
14421                 (Ggca_label < 0
14422                  || Ggca_label == gcan_src->labels[n]))
14423               printf("gcan(%d, %d, %d) %s: image[%d] "
14424                      "(fa=%2.1f) predicted mean "
14425                      "(%2.1f,%2.1f) --> %2.1f\n",
14426                      x, y, z,
14427                      cma_label_to_name(gcan_dst->labels[n]),
14428                      i, DEGREES(fa[i]),
14429                      T1, PD, gc_dst->means[i]) ;
14430             *MATRIX_RELT(m_jacobian, i+1, 1) =
14431               dFlash_dT1(T1, PD, TR[i], fa[i], TE[i]) ;
14432             *MATRIX_RELT(m_jacobian, i+1, 2) =
14433               dFlash_dPD(T1, PD, TR[i], fa[i], TE[i]) ;
14434             if (gcan_dst->labels[n] == Ggca_label)
14435             {
14436               label_means[i] += gc_dst->means[i] ;
14437             }
14438           }
14439 #define MIN_T1 50
14440           if (T1 < MIN_T1)
14441             m_cov_dst = MatrixIdentity(gca_flash->ninputs, m_cov_dst) ;
14442           else
14443           {
14444             m_cov_src =
14445               load_covariance_matrix(gc_src, m_cov_src,
14446                                      gca_T1PD->ninputs) ;
14447             m_jacobian_T = MatrixTranspose(m_jacobian,m_jacobian_T) ;
14448             m_tmp = MatrixMultiply(m_cov_src, m_jacobian_T, m_tmp) ;
14449             m_cov_dst = MatrixMultiply(m_jacobian,
14450                                        m_tmp,
14451                                        m_cov_dst) ;
14452           }
14453           for (v = i = 0 ; i < gca_flash->ninputs ; i++)
14454           {
14455             for (j = i ; j < gca_flash->ninputs ; j++, v++)
14456               gc_dst->covars[v] = *MATRIX_RELT(m_cov_dst, i+1, j+1) ;
14457           }
14458           if (x == Gx && y == Gy && z == Gz &&
14459               (Ggca_label < 0 || Ggca_label == gcan_src->labels[n]))
14460           {
14461             printf("predicted covariance matrix:\n") ;
14462             MatrixPrint(stdout, m_cov_dst)  ;
14463           }
14464         }
14465       }
14466     }
14467   }
14468 
14469   if (Ggca_label >= 0)
14470   {
14471     printf("label %s (%d): means = ",
14472            cma_label_to_name(Ggca_label), Ggca_label) ;
14473     for (i = 0 ; i < gca_flash->ninputs ; i++)
14474     {
14475       label_means[i] /= (double)label_count ;
14476       printf("%2.1f ", label_means[i]) ;
14477     }
14478     printf("\n") ;
14479   }
14480 
14481   /* check and fix singular covariance matrixces */
14482   GCAregularizeCovarianceMatrices(gca_flash, lambda) ;
14483   GCAfixSingularCovarianceMatrices(gca_flash) ;
14484   MatrixFree(&m_jacobian) ;
14485   MatrixFree(&m_cov_src) ;
14486   MatrixFree(&m_cov_dst) ;
14487   MatrixFree(&m_jacobian_T) ;
14488   MatrixFree(&m_tmp) ;
14489 
14490   gca_flash->type = GCA_FLASH;
14491   GCAcopyDCToGCA(gca_T1PD, gca_flash) ;
14492 
14493   return(gca_flash) ;
14494 }
14495 
14496 int
14497 GCAfixSingularCovarianceMatrices(GCA *gca)
14498 {
14499   int       x, y, z, fixed = 0, i, r, c, n, num, nparams, regularized = 0 ;
14500 GCA_NODE  *gcan ;
14501 GC1D      *gc ;
14502 double    det, vars[MAX_GCA_INPUTS], min_det ;
14503   MATRIX    *m_cov_inv, *m_cov = NULL ;
14504 
14505   nparams = (gca->ninputs * (gca->ninputs+1))/2 + gca->ninputs ;
14506   /* covariance matrix and means */
14507 
14508   memset(vars, 0, sizeof(vars)) ;
14509 
14510     if (gca->total_training <= 1 && gca->prior_spacing <=1 && 
14511             gca->node_spacing <=1)  // degenerate case - can't estimate vars
14512     {
14513         for (num = 0, x = 0 ; x < gca->node_width ; x++)
14514         {
14515             for (y = 0 ; y < gca->node_height ; y++)
14516             {
14517                 for (z = 0 ; z < gca->node_depth ; z++)
14518                 {
14519                     if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
14520                         DiagBreak() ;
14521                     gcan = &gca->nodes[x][y][z] ;
14522                     for (n = 0 ; n < gcan->nlabels ; n++)
14523                     {
14524                         if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14525                                 (Ggca_label == gcan->labels[n] || Ggca_label < 0))
14526                             DiagBreak() ;
14527                         gc = &gcan->gcs[n] ;
14528                         for (r = 0 ; r < gca->ninputs ; r++)
14529                             vars[r] += SQR((gc->means[r]*0.1)) ;
14530                         num++ ;
14531                     }
14532                 }
14533             }
14534         }
14535     }
14536     else
14537     {
14538         for (num = 0, x = 0 ; x < gca->node_width ; x++)
14539         {
14540             for (y = 0 ; y < gca->node_height ; y++)
14541             {
14542                 for (z = 0 ; z < gca->node_depth ; z++)
14543                 {
14544                     if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
14545                         DiagBreak() ;
14546                     gcan = &gca->nodes[x][y][z] ;
14547                     for (n = 0 ; n < gcan->nlabels ; n++)
14548                     {
14549                         if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14550                                 (Ggca_label == gcan->labels[n] || Ggca_label < 0))
14551                             DiagBreak() ;
14552                         gc = &gcan->gcs[n] ;
14553                         det = covariance_determinant(gc, gca->ninputs) ;
14554                         if ((gc->ntraining == 0 && det > 1) ||
14555                                 (gc->ntraining*gca->ninputs > 2.5*nparams))
14556                             /* enough to estimate parameters */
14557                         {
14558                             m_cov = load_covariance_matrix(gc, m_cov, gca->ninputs) ;
14559                             for (r = 0 ; r < gca->ninputs ; r++)
14560                             {
14561                                 vars[r] += *MATRIX_RELT(m_cov,r+1, r+1) ;
14562                             }
14563                             num++ ;
14564                         }
14565                     }
14566                 }
14567             }
14568         }
14569     }
14570   if (m_cov)
14571     MatrixFree(&m_cov) ;
14572   if (num >= 1)
14573   {
14574     printf("average std = ") ;
14575     for (min_det = 1.0, r = 0 ; r < gca->ninputs ; r++)
14576     {
14577       vars[r] /= (float)num ;
14578       printf("%2.1f ", sqrt(vars[r])) ;
14579       min_det *= vars[r] ;
14580     }
14581     min_det = min_det / pow(10.0, gca->ninputs) ;
14582     printf("  using min determinant for regularization = %2.1f\n", min_det) ;
14583   }
14584   else
14585     min_det = MIN_DET ;
14586 
14587   for (regularized = fixed = x = 0 ; x < gca->node_width ; x++)
14588     {
14589       for (y = 0 ; y < gca->node_height ; y++)
14590       {
14591         for (z = 0 ; z < gca->node_depth ; z++)
14592         {
14593           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
14594             DiagBreak() ;
14595           gcan = &gca->nodes[x][y][z] ;
14596           for (n = 0 ; n < gcan->nlabels ; n++)
14597           {
14598             if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14599                 (Ggca_label == gcan->labels[n] || Ggca_label < 0))
14600               DiagBreak() ;
14601             gc = &gcan->gcs[n] ;
14602             det = covariance_determinant(gc, gca->ninputs) ;
14603             m_cov_inv = load_inverse_covariance_matrix(gc,
14604                         NULL,
14605                         gca->ninputs) ;
14606 
14607             if (det <= 0 || m_cov_inv == NULL)
14608             {
14609               fixed ++ ;
14610                             gc->regularized = 1 ;
14611                             for (i = r = 0 ; r < gca->ninputs ; r++)
14612                             {
14613                                 for (c = r ; c < gca->ninputs ; c++, i++)
14614                                 {
14615                                     if (r == c)
14616                                         gc->covars[i] += vars[r] ;
14617                                     /* mean of other variances at
14618                                          this location */
14619                                 }
14620                                 if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14621                                         (Ggca_label == gcan->labels[n] || Ggca_label < 0))
14622                                 {
14623                                     MATRIX *m ;
14624                                     printf("fixing singular covariance matrix for %s "
14625                                                  "@ (%d, %d, %d):\n",
14626                                                  cma_label_to_name(gcan->labels[n]),
14627                                                  x, y, z) ;
14628                                     m = load_covariance_matrix(gc, NULL, gca->ninputs) ;
14629                                     MatrixPrint(stdout, m) ;
14630                                     MatrixFree(&m) ;
14631                                 }
14632                             }
14633                         }
14634             else   /* not singular - check if it is ill-conditioned */
14635             {
14636               if (gc->regularized == 0)
14637                 DiagBreak() ;
14638               if ((gc->ntraining*gca->ninputs
14639                    < 2*nparams && det < 0.1)
14640                   || (det < min_det))
14641               {
14642                 gc->regularized = 1 ;
14643                 regularized++ ;
14644                 for (i = r = 0 ; r < gca->ninputs ; r++)
14645                 {
14646                   for (c = r ; c < gca->ninputs ; c++, i++)
14647                   {
14648                     if (r == c)
14649                       gc->covars[i] += vars[r] ;
14650                     /* mean of overall variance
14651                        in this image */
14652                   }
14653                 }
14654                 if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14655                     (Ggca_label == gcan->labels[n]
14656                      || Ggca_label < 0))
14657                 {
14658                   MATRIX *m ;
14659                   printf("fixing ill-conditioned covariance "
14660                          "matrix for %s @ (%d, %d, %d):\n",
14661                          cma_label_to_name(gcan->labels[n]),
14662                          x, y, z) ;
14663                   m = load_covariance_matrix(gc,
14664                                              NULL, gca->ninputs) ;
14665                   MatrixPrint(stdout, m) ;
14666                   MatrixFree(&m) ;
14667                 }
14668               }
14669             }
14670 
14671             if (m_cov_inv)
14672               MatrixFree(&m_cov_inv) ;
14673             det = covariance_determinant(gc, gca->ninputs) ;
14674             m_cov_inv = load_inverse_covariance_matrix(gc,
14675                         NULL,
14676                         gca->ninputs) ;
14677             if (det <= min_det || m_cov_inv == NULL)
14678             {
14679               printf("warning: regularization of node (%d, %d, %d) "
14680                      "label %s failed\n",
14681                      x, y, z, cma_label_to_name(gcan->labels[n])) ;
14682               DiagBreak() ;
14683 
14684             }
14685             if (m_cov_inv)
14686               MatrixFree(&m_cov_inv) ;
14687           }
14688         }
14689       }
14690     }
14691 
14692   printf("%d singular and %d ill-conditioned covariance"
14693          " matrices regularized\n",
14694          fixed , regularized) ;
14695   return(NO_ERROR) ;
14696 }
14697 int
14698 GCAregularizeCovarianceMatrices(GCA *gca, double lambda)
14699 {
14700   int       x, y, z, r, n, num, nparams ;
14701   GCA_NODE  *gcan ;
14702   GC1D      *gc ;
14703   double    det, vars[MAX_GCA_INPUTS], min_det ;
14704   MATRIX    *m_cov = NULL ;
14705 
14706   nparams = (gca->ninputs * (gca->ninputs+1))/2 + gca->ninputs ;
14707   /* covariance matrix and means */
14708 
14709   memset(vars, 0, sizeof(vars)) ;
14710 
14711   for (num = 0, x = 0 ; x < gca->node_width ; x++)
14712   {
14713     for (y = 0 ; y < gca->node_height ; y++)
14714     {
14715       for (z = 0 ; z < gca->node_depth ; z++)
14716       {
14717         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
14718           DiagBreak() ;
14719         gcan = &gca->nodes[x][y][z] ;
14720         for (n = 0 ; n < gcan->nlabels ; n++)
14721         {
14722           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14723               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
14724             DiagBreak() ;
14725           gc = &gcan->gcs[n] ;
14726           det = covariance_determinant(gc, gca->ninputs) ;
14727           if ((gc->ntraining == 0 && det > 1) ||
14728               (gc->ntraining*gca->ninputs > 2.5*nparams))
14729             /* enough to estimate parameters */
14730           {
14731             m_cov = load_covariance_matrix(gc, m_cov, gca->ninputs) ;
14732             for (r = 0 ; r < gca->ninputs ; r++)
14733             {
14734               vars[r] += *MATRIX_RELT(m_cov,r+1, r+1) ;
14735             }
14736             num++ ;
14737           }
14738         }
14739       }
14740     }
14741   }
14742 
14743   if (num >= 1)
14744   {
14745     printf("average std = ") ;
14746     for (min_det = 1.0, r = 0 ; r < gca->ninputs ; r++)
14747     {
14748       vars[r] /= (float)num ;
14749       printf("%2.1f ", sqrt(vars[r])) ;
14750       min_det *= vars[r] ;
14751     }
14752     min_det = min_det / pow(10.0, gca->ninputs) ;
14753     printf("  using min determinant for regularization = %2.1f\n", min_det) ;
14754   }
14755   else
14756     min_det = MIN_DET ;
14757 
14758   /* discard all previous stuff and just regularize by adding a */
14759   /* fixed constant independent of variance */
14760   for ( r = 0 ; r < gca->ninputs ; r++)
14761     vars[r] = lambda ;
14762 
14763   for (x = 0 ; x < gca->node_width ; x++)
14764   {
14765     for (y = 0 ; y < gca->node_height ; y++)
14766     {
14767       for (z = 0 ; z < gca->node_depth ; z++)
14768       {
14769         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
14770           DiagBreak() ;
14771         gcan = &gca->nodes[x][y][z] ;
14772         for (n = 0 ; n < gcan->nlabels ; n++)
14773         {
14774           int r, c, v ;
14775           MATRIX *m ;
14776 
14777           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14778               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
14779             DiagBreak() ;
14780           gc = &gcan->gcs[n] ;
14781 
14782 
14783           m = load_covariance_matrix(gc, NULL, gca->ninputs) ;
14784           for (r = v = 0 ; r < gca->ninputs ; r++)
14785             for (c = r ; c < gca->ninputs ; c++, v++)
14786             {
14787               if (r == c)
14788                 gc->covars[v] += vars[r] ;
14789             }
14790           MatrixFree(&m) ;
14791           m = load_covariance_matrix(gc, NULL, gca->ninputs) ;
14792           v = 0 ;
14793         }
14794       }
14795     }
14796   }
14797 
14798   return(NO_ERROR) ;
14799 }
14800 int
14801 GCAsetFlashParameters(GCA *gca, double *TRs, double *FAs, double *TEs)
14802 {
14803   int n ;
14804 
14805   printf("setting GCA flash parameters to:\n") ;
14806   for (n = 0 ; n < gca->ninputs ; n++)
14807   {
14808     gca->TRs[n] = TRs[n] ;
14809     gca->FAs[n] = FAs[n] ;
14810     gca->TEs[n] = TEs[n] ;
14811     printf("TR=%2.1f msec, FA=%2.1f deg, TE=%2.1f msec\n",
14812            TRs[n], DEGREES(FAs[n]), TEs[n]) ;
14813   }
14814   gca->type=GCA_FLASH; // mark gca type
14815   return(NO_ERROR) ;
14816 }
14817 
14818 GCA *
14819 GCAcreateFlashGCAfromFlashGCA(GCA *gca_flash_src,
14820                               double *TR, double *fa,
14821                               double *TE, int nflash)
14822 {
14823   GCA        *gca_flash_dst ;
14824   GCA_PRIOR  *gcap_src, *gcap_dst ;
14825   GCA_NODE   *gcan_src, *gcan_dst ;
14826   GC1D       *gc_src, *gc_dst ;
14827   MATRIX     *m_jac_dst, *m_jac_src, *m_cov_src,
14828   *m_cov_dst, *m_pinv_src, *m_cov_T1PD ;
14829   int        n, x, y, z, i, j, v, label_count = 0 ;
14830   double     T1, PD, label_means[MAX_GCA_INPUTS] ;
14831 
14832   m_cov_T1PD = m_cov_dst = m_pinv_src = m_cov_src = NULL ;
14833   FlashBuildLookupTables(gca_flash_src->ninputs,
14834                          gca_flash_src->TRs,
14835                          gca_flash_src->FAs,
14836                          gca_flash_src->TEs) ;
14837 
14838   gca_flash_dst =
14839     GCAalloc(nflash, gca_flash_src->prior_spacing, gca_flash_src->node_spacing,
14840              gca_flash_src->node_width*gca_flash_src->node_spacing,
14841              gca_flash_src->node_height*gca_flash_src->node_spacing,
14842              gca_flash_src->node_depth*gca_flash_src->node_spacing,
14843              GCA_NO_FLAGS) ;
14844 
14845   for (n = 0 ; n < nflash ; n++)
14846   {
14847     gca_flash_dst->TRs[n] = TR[n] ;
14848     gca_flash_dst->FAs[n] = fa[n] ;
14849     gca_flash_dst->TEs[n] = TE[n] ;
14850   }
14851 
14852   m_jac_src = MatrixAlloc(gca_flash_src->ninputs, 2, MATRIX_REAL) ;
14853   /* T1/PD --> src jacobian */
14854   m_jac_dst = MatrixAlloc(gca_flash_dst->ninputs, 2, MATRIX_REAL) ;
14855   /* T1/PD --> dst jacobian */
14856 
14857   /* first copy over priors */
14858   for (x = 0 ; x < gca_flash_dst->prior_width ; x++)
14859   {
14860     for (y = 0 ; y < gca_flash_dst->prior_height ; y++)
14861     {
14862       for (z = 0 ; z < gca_flash_dst->prior_depth ; z++)
14863       {
14864         gcap_src = &gca_flash_src->priors[x][y][z] ;
14865         if (gcap_src == NULL)
14866           continue;
14867         gcap_dst = &gca_flash_dst->priors[x][y][z] ;
14868         if (gcap_dst == NULL)
14869           continue;
14870         gcap_dst->nlabels = gcap_src->nlabels ;
14871         if (gcap_src->nlabels > gcap_dst->max_labels)
14872         {
14873           free(gcap_dst->priors) ;
14874           free(gcap_dst->labels) ;
14875 
14876           gcap_dst->labels =
14877             (unsigned short *)calloc(gcap_src->nlabels,
14878                                     sizeof(unsigned short)) ;
14879           if (!gcap_dst->labels)
14880             ErrorExit(ERROR_NOMEMORY,
14881                       "GCAcreateFlashGCAfromFlashGCA: "
14882                       "couldn't allocate %d labels",
14883                       gcap_src->nlabels) ;
14884 
14885           gcap_dst->priors =
14886             (float *)calloc(gcap_src->nlabels, sizeof(float)) ;
14887           if (!gcap_dst->priors)
14888             ErrorExit(ERROR_NOMEMORY,
14889                       "GCAcreateFlashGCAfromFlashGCA: "
14890                       "couldn't allocate %d priors",
14891                       gcap_src->nlabels) ;
14892           gcap_dst->max_labels = gcap_dst->nlabels ;
14893         }
14894         gcap_dst->total_training = gcap_src->total_training ;
14895         for (n = 0 ; n < gcap_src->nlabels ; n++)
14896         {
14897           gcap_dst->labels[n] = gcap_src->labels[n] ;
14898           gcap_dst->priors[n] = gcap_src->priors[n] ;
14899         }
14900       }
14901     }
14902   }
14903 
14904   /* now copy over classifiers and Markov stuff, */
14905   /* using Jacobian to map to new image space */
14906   for (x = 0 ; x < gca_flash_dst->node_width ; x++)
14907   {
14908     for (y = 0 ; y < gca_flash_dst->node_height ; y++)
14909     {
14910       for (z = 0 ; z < gca_flash_dst->node_depth ; z++)
14911       {
14912         if (x == Gx && y == Gy && z == Gz)
14913           DiagBreak()  ;
14914         gcan_src = &gca_flash_src->nodes[x][y][z] ;
14915         gcan_dst = &gca_flash_dst->nodes[x][y][z] ;
14916         gcan_dst->nlabels = gcan_src->nlabels ;
14917         gcan_dst->total_training = gcan_src->total_training ;
14918         if (gcan_src->nlabels > gcan_dst->max_labels)
14919         {
14920           free(gcan_dst->labels) ;
14921           for (n = 0 ; n < gcan_dst->max_labels ; n++)
14922           {
14923             gc_dst = &gcan_dst->gcs[n] ;
14924             for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
14925             {
14926               if (gc_dst->label_priors[i])
14927                 free(gc_dst->label_priors[i]) ;
14928               if (gc_dst->labels[i])
14929                 free(gc_dst->labels[i]) ;
14930             }
14931             if (gc_dst->nlabels)
14932               free(gc_dst->nlabels) ;
14933             if (gc_dst->labels)
14934               free(gc_dst->labels) ;
14935             if (gc_dst->label_priors)
14936               free(gc_dst->label_priors) ;
14937           }
14938 
14939           gcan_dst->labels =
14940             (unsigned short *)calloc(gcan_src->nlabels,
14941                                     sizeof(unsigned short)) ;
14942           if (!gcan_dst->labels)
14943             ErrorExit(ERROR_NOMEMORY, "GCAcreateFlashGCAfromFlashGCA: "
14944                       "couldn't allocate %d labels",
14945                       gcan_src->nlabels) ;
14946 
14947           gcan_dst->gcs = alloc_gcs(gcan_src->nlabels,
14948                                     GCA_NO_FLAGS, nflash) ;
14949         }
14950         for (n = 0 ; n < gcan_src->nlabels ; n++)
14951         {
14952           gcan_dst->labels[n] = gcan_src->labels[n] ;
14953           gc_src = &gcan_src->gcs[n] ;
14954           gc_dst = &gcan_dst->gcs[n] ;
14955           gc_dst->ntraining = gc_src->ntraining ;
14956           gc_dst->n_just_priors = gc_src->n_just_priors ;
14957           for (i = 0 ; i < GIBBS_NEIGHBORS ; i++)
14958           {
14959             gc_dst->nlabels[i] = gc_src->nlabels[i] ;
14960             gc_dst->label_priors[i] =
14961               (float *)calloc(gc_src->nlabels[i],sizeof(float));
14962             if (!gc_dst->label_priors[i])
14963               ErrorExit(ERROR_NOMEMORY,
14964                         "GCAcreateFlashGCAfromFlashGCA: to %d",
14965                         gc_src->nlabels[i]);
14966             gc_dst->labels[i] =
14967               (unsigned short *)calloc(gc_src->nlabels[i],
14968                                       sizeof(unsigned short)) ;
14969             if (!gc_dst->labels)
14970               ErrorExit(ERROR_NOMEMORY,
14971                         "GCAcreateFlashGCAfromFlashGCA: to %d",
14972                         gc_src->nlabels[i]);
14973             for (j = 0 ; j < gc_src->nlabels[i] ; j++)
14974             {
14975               gc_dst->label_priors[i][j]
14976               = gc_src->label_priors[i][j] ;
14977               gc_dst->labels[i][j]
14978               = gc_src->labels[i][j] ;
14979             }
14980           }
14981 
14982           /* now map intensity and covariance info over */
14983           compute_T1_PD(gca_flash_src->ninputs,
14984                         gc_src->means,
14985                         gca_flash_src->TRs,
14986                         gca_flash_src->FAs,
14987                         gca_flash_src->TEs,
14988                         &T1, &PD) ;
14989           T1 = MAX(T1,10) ;
14990           PD = MAX(PD,0) ;
14991           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
14992               (Ggca_label < 0 || Ggca_label == gcan_src->labels[n]))
14993           {
14994             int j ;
14995             printf("gcan(%d, %d, %d) %s: means=[",
14996                    x, y, z, cma_label_to_name(gcan_src->labels[n])) ;
14997             for (j = 0 ; j < gca_flash_src->ninputs ; j++)
14998               printf(" %2.1f", gc_src->means[j]) ;
14999             printf("] T1/PD=%2.1f/%2.1f\n", T1, PD) ;
15000           }
15001           if (Ggca_label == gcan_dst->labels[n])
15002             label_count++ ;
15003           for (i = 0 ; i < gca_flash_dst->ninputs ; i++)
15004           {
15005             gc_dst->means[i] =
15006               FLASHforwardModel(T1, PD, TR[i], fa[i], TE[i]) ;
15007             if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
15008                 (Ggca_label < 0
15009                  || Ggca_label == gcan_src->labels[n]))
15010               printf("gcan(%d, %d, %d) %s: image[%d] "
15011                      "(fa=%2.1f) predicted mean "
15012                      "(%2.1f,%2.1f) --> %2.1f\n",
15013                      x, y, z,
15014                      cma_label_to_name(gcan_dst->labels[n]),
15015                      i, DEGREES(fa[i]),
15016                      T1, PD, gc_dst->means[i]) ;
15017             *MATRIX_RELT(m_jac_dst, i+1, 1) =
15018               dFlash_dT1(T1, PD, gca_flash_dst->TRs[i],
15019                          gca_flash_dst->FAs[i],
15020                          gca_flash_dst->TEs[i]) ;
15021             *MATRIX_RELT(m_jac_dst, i+1, 2) =
15022               dFlash_dPD(T1, PD, gca_flash_dst->TRs[i],
15023                          gca_flash_dst->FAs[i],
15024                          gca_flash_dst->TEs[i]) ;
15025 
15026             //  *MATRIX_RELT(m_jac_src, i+1, 1) =
15027             //  dFlash_dT1(T1, PD, gca_flash_src->TRs[i],
15028             // gca_flash_src->FAs[i], gca_flash_src->TEs[i]) ;
15029             //  *MATRIX_RELT(m_jac_src, i+1, 2) =
15030             //  dFlash_dPD(T1, PD, gca_flash_src->TRs[i],
15031             //gca_flash_src->FAs[i], gca_flash_src->TEs[i]) ;
15032             if (gcan_dst->labels[n] == Ggca_label)
15033             {
15034               label_means[i] += gc_dst->means[i] ;
15035             }
15036           }
15037           //this allows src and dst have different ninputs
15038           for (i = 0 ; i < gca_flash_src->ninputs ; i++)
15039           {
15040             *MATRIX_RELT(m_jac_src, i+1, 1) =
15041               dFlash_dT1(T1, PD, gca_flash_src->TRs[i],
15042                          gca_flash_src->FAs[i],
15043                          gca_flash_src->TEs[i]) ;
15044             *MATRIX_RELT(m_jac_src, i+1, 2) =
15045               dFlash_dPD(T1, PD, gca_flash_src->TRs[i],
15046                          gca_flash_src->FAs[i],
15047                          gca_flash_src->TEs[i]) ;
15048           }
15049 
15050 #define MIN_T1 50
15051           if (x == Gx && y == Gy && z == Gz)
15052             DiagBreak()  ;
15053           if (T1 < MIN_T1)
15054             m_cov_dst = MatrixIdentity(gca_flash_dst->ninputs,
15055                                        m_cov_dst) ;
15056           else
15057           {
15058             m_cov_src =
15059               load_covariance_matrix(gc_src, m_cov_src,
15060                                      gca_flash_src->ninputs) ;
15061             m_pinv_src = MatrixPseudoInverse(m_jac_src, m_pinv_src) ;
15062             m_cov_T1PD =
15063               MatrixSimilarityTransform(m_cov_src,
15064                                         m_pinv_src,
15065                                         m_cov_T1PD) ;
15066             m_cov_dst = MatrixSimilarityTransform(m_cov_T1PD,
15067                                                   m_jac_dst,
15068                                                   m_cov_dst) ;
15069           }
15070           for (v = i = 0 ; i < gca_flash_dst->ninputs ; i++)
15071           {
15072             for (j = i ; j < gca_flash_dst->ninputs ; j++, v++)
15073               gc_dst->covars[v] = *MATRIX_RELT(m_cov_dst, i+1, j+1) ;
15074           }
15075           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
15076               (Ggca_label < 0 || Ggca_label == gcan_src->labels[n]))
15077           {
15078             printf("predicted covariance matrix:\n") ;
15079             MatrixPrint(stdout, m_cov_dst)  ;
15080           }
15081         }
15082       }
15083     }
15084   }
15085 
15086   if (Ggca_label >= 0)
15087   {
15088     printf("label %s (%d): means = ",
15089            cma_label_to_name(Ggca_label), Ggca_label) ;
15090     for (i = 0 ; i < gca_flash_dst->ninputs ; i++)
15091     {
15092       label_means[i] /= (double)label_count ;
15093       printf("%2.1f ", label_means[i]) ;
15094     }
15095     printf("\n") ;
15096   }
15097 
15098   /* check and fix singular covariance matrixces */
15099   GCAfixSingularCovarianceMatrices(gca_flash_dst) ;
15100   MatrixFree(&m_jac_dst) ;
15101   MatrixFree(&m_jac_src) ;
15102   if (m_cov_src)
15103     MatrixFree(&m_cov_src) ;
15104   MatrixFree(&m_cov_dst) ;
15105   if (m_pinv_src)
15106     MatrixFree(&m_pinv_src) ;
15107   if (m_cov_T1PD)
15108     MatrixFree(&m_cov_T1PD) ;
15109 
15110   gca_flash_dst->type = GCA_FLASH;
15111   GCAcopyDCToGCA(gca_flash_src, gca_flash_dst) ;
15112   return(gca_flash_dst) ;
15113 }
15114 
15115 int
15116 GCAnormalizeMeans(GCA *gca, float target)
15117 {
15118   int       x, y, z, frame, n ;
15119   double    norm ;
15120   Real      val ;
15121   GCA_NODE  *gcan ;
15122   GC1D      *gc ;
15123 
15124   for (x = 0 ; x < gca->node_width ; x++)
15125   {
15126     for (y = 0 ; y < gca->node_height ; y++)
15127     {
15128       for (z = 0 ; z < gca->node_depth ; z++)
15129       {
15130         gcan = &gca->nodes[x][y][z] ;
15131         for (n = 0 ; n < gcan->nlabels ; n++)
15132         {
15133           gc = &gcan->gcs[n] ;
15134           for (frame = 0, norm = 0 ; frame < gca->ninputs ; frame++)
15135           {
15136             val = gc->means[frame] ;
15137             norm += (val*val) ;
15138           }
15139           norm = sqrt(norm) / target ;
15140           if (FZERO(norm))
15141             norm = 1 ;
15142           for (frame = 0 ; frame < gca->ninputs ; frame++)
15143             gc->means[frame] /= norm ;
15144         }
15145       }
15146     }
15147   }
15148 
15149   return(NO_ERROR) ;
15150 }
15151 int
15152 GCAregularizeCovariance(GCA *gca, float regularize)
15153 {
15154   int       x, y, z, i, r, c, n, num, nparams ;
15155   GCA_NODE  *gcan ;
15156   GC1D      *gc ;
15157   double    det, vars[MAX_GCA_INPUTS] ;
15158   MATRIX    *m_cov = NULL ;
15159 
15160   nparams = (gca->ninputs * (gca->ninputs+1))/2 + gca->ninputs ;
15161   /* covariance matrix and means */
15162   memset(vars, 0, sizeof(vars)) ;
15163   for (num = 0, x = 0 ; x < gca->node_width ; x++)
15164   {
15165     for (y = 0 ; y < gca->node_height ; y++)
15166     {
15167       for (z = 0 ; z < gca->node_depth ; z++)
15168       {
15169         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
15170           DiagBreak() ;
15171         gcan = &gca->nodes[x][y][z] ;
15172         for (n = 0 ; n < gcan->nlabels ; n++)
15173         {
15174           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
15175               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
15176             DiagBreak() ;
15177           gc = &gcan->gcs[n] ;
15178           det = covariance_determinant(gc, gca->ninputs) ;
15179           if ((gc->ntraining == 0 && det > 1) ||
15180               (gc->ntraining*gca->ninputs > 2.5*nparams))
15181             /* enough to estimate parameters */
15182           {
15183             m_cov = load_covariance_matrix(gc, m_cov, gca->ninputs) ;
15184             for (r = 0 ; r < gca->ninputs ; r++)
15185             {
15186               vars[r] += *MATRIX_RELT(m_cov,r+1, r+1) ;
15187             }
15188             num++ ;
15189           }
15190         }
15191       }
15192     }
15193   }
15194   if (m_cov)
15195     MatrixFree(&m_cov) ;
15196   if (num >= 1)
15197   {
15198     for (r = 0 ; r < gca->ninputs ; r++)
15199     {
15200       vars[r] /= (float)num ;
15201       printf("average std[%d] = %2.1f\n", r, sqrt(vars[r])) ;
15202     }
15203   }
15204   for (x = 0 ; x < gca->node_width ; x++)
15205   {
15206     for (y = 0 ; y < gca->node_height ; y++)
15207     {
15208       for (z = 0 ; z < gca->node_depth ; z++)
15209       {
15210         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
15211           DiagBreak() ;
15212         gcan = &gca->nodes[x][y][z] ;
15213         for (n = 0 ; n < gcan->nlabels ; n++)
15214         {
15215           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
15216               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
15217             DiagBreak() ;
15218           gc = &gcan->gcs[n] ;
15219           for (i = r = 0 ; r < gca->ninputs ; r++)
15220           {
15221             for (c = r ; c < gca->ninputs ; c++, i++)
15222             {
15223               gc->covars[i] = (1-regularize)*gc->covars[i] ;
15224               if (r == c)
15225                 gc->covars[i] += regularize*vars[r] ;
15226             }
15227           }
15228           if (x == Ggca_x && y == Ggca_y && z == Ggca_z &&
15229               (Ggca_label == gcan->labels[n] || Ggca_label < 0))
15230           {
15231             MATRIX *m ;
15232             printf("regularizing covariance matrix "
15233                    "for %s @ (%d, %d, %d):\n",
15234                    cma_label_to_name(gcan->labels[n]), x, y, z) ;
15235             m = load_covariance_matrix(gc, NULL, gca->ninputs) ;
15236             MatrixPrint(stdout, m) ;
15237             MatrixFree(&m) ;
15238           }
15239         }
15240       }
15241     }
15242   }
15243   return(NO_ERROR) ;
15244 }
15245 
15246 MATRIX  *
15247 GCAlabelCovariance(GCA *gca, int label, MATRIX *m_total)
15248 {
15249   int       xn, yn, zn, n ;
15250   GCA_NODE  *gcan ;
15251   GC1D      *gc ;
15252   double    wt ;
15253   float     prior ;
15254   MATRIX    *m_cov = NULL ;
15255 
15256   /* compute overall white matter mean to use as anchor for rescaling */
15257   for (wt = 0.0, zn = 0 ; zn < gca->node_depth ; zn++)
15258   {
15259     for (yn = 0 ; yn < gca->node_height ; yn++)
15260     {
15261       for (xn = 0 ; xn < gca->node_width ; xn++)
15262       {
15263         gcan = &gca->nodes[xn][yn][zn] ;
15264         for (n = 0 ; n < gcan->nlabels ; n++)
15265         {
15266           /* find index in lookup table for this label */
15267           if (gcan->labels[n] != label)
15268             continue ;
15269           gc = &gcan->gcs[n] ;
15270           prior = get_node_prior(gca, label, xn, yn, zn);
15271           if (prior != 0)
15272           {
15273             wt += prior ;
15274             m_cov = load_covariance_matrix(gc, m_cov, gca->ninputs) ;
15275             MatrixScalarMul(m_cov, prior, m_cov) ;
15276             if (m_total == NULL)
15277               m_total = MatrixCopy(m_cov, NULL) ;
15278             else
15279               MatrixAdd(m_cov, m_total, m_total) ;
15280           }
15281         }
15282       }
15283     }
15284   }
15285 
15286   if (m_total == NULL)
15287     return(NULL) ;
15288 
15289   if (FZERO(wt))
15290     wt = 1 ;
15291   MatrixScalarMul(m_total, 1/wt, m_total) ;
15292   MatrixFree(&m_cov) ;
15293   return(m_total) ;
15294 }
15295 
15296 int
15297 GCAlabelMeanFromImage(GCA *gca, TRANSFORM *transform,
15298                       MRI *mri, int label, float *means)
15299 {
15300   int       xn, yn, zn, n, r, xv, yv, zv ;
15301   GCA_NODE  *gcan ;
15302   GC1D      *gc ;
15303   double    wt, val ;
15304   float     prior ;
15305   double MIN_MEAN_PRIOR = 0.5 ;
15306 
15307   /* compute overall white matter mean to use as anchor for rescaling */
15308   memset(means, 0, gca->ninputs*sizeof(float)) ;
15309   for (wt = 0.0, zn = 0 ; zn < gca->node_depth ; zn++)
15310   {
15311     for (yn = 0 ; yn < gca->node_height ; yn++)
15312     {
15313       for (xn = 0 ; xn < gca->node_width ; xn++)
15314       {
15315         gcan = &gca->nodes[xn][yn][zn] ;
15316         if (GCAnodeToSourceVoxel(gca, mri, transform,
15317                                  xn, yn, zn, &xv, &yv, &zv)==NO_ERROR)
15318         {
15319           for (n = 0 ; n < gcan->nlabels ; n++)
15320           {
15321             /* find index in lookup table for this label */
15322             if (gcan->labels[n] != label)
15323               continue ;
15324             gc = &gcan->gcs[n] ;
15325             prior = get_node_prior(gca, label, xn, yn, zn) ;
15326             if (prior < MIN_MEAN_PRIOR)
15327               continue ;
15328             wt += prior ;
15329             for (r = 0 ; r < gca->ninputs ; r++)
15330             {
15331               MRIsampleVolumeFrame(mri, xv, yv, zv, r, &val) ;
15332               means[r] += val*prior ;
15333               if (!finite(gc->means[r]))
15334                 DiagBreak() ;
15335             }
15336           }
15337         }
15338       }
15339     }
15340   }
15341   for (r = 0 ; r < gca->ninputs ; r++)
15342     means[r] /= wt ;
15343   return(NO_ERROR) ;
15344 }
15345 
15346 
15347 /* don't try to estimate cortex directly - too hard to
15348    get alignment. We'll estimate it from other gm classes
15349    but how about just use initial linear registration?
15350 */
15351 #if 1
15352 static int align_labels[] =
15353   {
15354     Right_Pallidum,
15355     Left_Pallidum,
15356     Right_Lateral_Ventricle,
15357     Left_Lateral_Ventricle,
15358     Right_Hippocampus,
15359     Left_Hippocampus,
15360     Right_Cerebral_White_Matter,
15361     Left_Cerebral_White_Matter,
15362     Left_Cerebral_Cortex,
15363     Right_Cerebral_Cortex,
15364 #if 0
15365     Left_Inf_Lat_Vent,
15366     Right_Inf_Lat_Vent,
15367 #endif
15368     Right_Caudate,
15369     Left_Caudate,
15370     Left_Cerebellum_Cortex,
15371     Right_Cerebellum_Cortex,
15372     Left_Cerebellum_White_Matter,
15373     Right_Cerebellum_White_Matter,
15374     Left_Amygdala,
15375     Right_Amygdala,
15376     Left_Thalamus_Proper,
15377     Right_Thalamus_Proper,
15378     Left_Putamen,
15379     Right_Putamen,
15380     Brain_Stem,
15381     Right_VentralDC,
15382     Left_VentralDC,
15383     Third_Ventricle,
15384     Fourth_Ventricle
15385   } ;
15386 #else
15387 static int align_labels[] =
15388   {
15389     Right_Cerebellum_White_Matter,
15390   } ;
15391 #endif
15392 
15393 
15394 #define NALIGN_LABELS (sizeof(align_labels) / sizeof(align_labels[0]))
15395 #define BORDER_SIZE 2
15396 #define WM_BORDER_SIZE 5
15397 
15398 static int gm_labels[] =
15399   {
15400     Left_Hippocampus,
15401     Right_Hippocampus,
15402     Left_Amygdala,
15403     Right_Amygdala,
15404     //    Left_Caudate,
15405     //    Right_Caudate,
15406     Left_Cerebral_Cortex,
15407     Right_Cerebral_Cortex
15408     //          Left_Putamen,
15409     //  Right_Putamen
15410   } ;
15411 
15412 #define NGM_LABELS (sizeof(gm_labels) / sizeof(gm_labels[0]))
15413 
15414 static int wm_labels[] =
15415   {
15416     Left_Cerebral_White_Matter,
15417     Right_Cerebral_White_Matter
15418   } ;
15419 #define NWM_LABELS (sizeof(wm_labels) / sizeof(wm_labels[0]))
15420 
15421 
15422 static int csf_labels[] =
15423   {
15424     Left_Lateral_Ventricle,
15425     Right_Lateral_Ventricle,
15426     Third_Ventricle,
15427     Fourth_Ventricle
15428   } ;
15429 
15430 #define NCSF_LABELS (sizeof(csf_labels) / sizeof(csf_labels[0]))
15431 
15432 #if 0 //This is Bruce's version
15433 int
15434 GCAmapRenormalizeWithAlignment(GCA *gca,
15435                                MRI *mri,
15436                                TRANSFORM *transform,
15437                                FILE *logfp,
15438                                char *base_name,
15439                                LTA **plta)
15440 {
15441   HISTOGRAM *h_mri, *h_gca ;
15442   int       l, nbins, i, x, y, z, xn, yn, zn, num, frame, \
15443   bin, j, n, computed[MAX_CMA_LABELS], b, label, k,
15444   border = BORDER_SIZE, peak ;
15445   float     fmin, fmax, label_scales[MAX_CMA_LABELS], scale_factor, overlap,
15446   mean_gm_scale, mean_wm_scale, mean_csf_scale,
15447   label_offsets[MAX_CMA_LABELS], mean_wm_offset, \
15448   mean_csf_offset, mean_gm_offset ;
15449   Real      val/*, scale*/ ;
15450   GCA_NODE  *gcan ;
15451   GC1D      *gc ;
15452   MRI       *mri_seg = NULL, *mri_aligned, *mri_labels = NULL ;
15453   char      fname[STRLEN] ;
15454   MATRIX    *m_L, *m_by_label[MAX_CMA_LABELS] ;
15455   LTA       *lta ;
15456 
15457   printf("renormalizing by structure alignment....\n") ;
15458   if (plta)
15459     lta = *plta ;
15460   else
15461     lta = NULL ;
15462   for (frame = 0 ; frame < mri->nframes ; frame++)
15463   {
15464     for (l = 0 ; l < MAX_CMA_LABELS ; l++)
15465     {
15466       if (l == Gdiag_no)
15467         DiagBreak() ;
15468       label_scales[l] = 1.0 ;
15469       label_offsets[l] = 0.0 ;
15470       computed[l] = 0 ;
15471       m_by_label[l] = NULL ;  // not estimated yet
15472     }
15473 
15474     printf("renormalizing input #%d\n", frame) ;
15475     MRIvalRangeFrame(mri, &fmin, &fmax, frame) ;
15476     nbins = 256 ;
15477     h_mri = HISTOalloc(nbins) ;
15478     for (j = 0 ; j < NALIGN_LABELS ; j++)
15479     {
15480       l = align_labels[j] ;
15481       if (l == Gdiag_no)
15482         DiagBreak() ;
15483 
15484       mri_seg = MRIclone(mri, mri_seg) ;
15485       mri_labels = MRIclone(mri, mri_labels) ;
15486 
15487       /* include 2 voxel border to get context around structure.
15488          e.g. hippo is made easier to find by wm inferior and ventricle
15489          posterior.
15490       */
15491       if (IS_HIPPO(l) || IS_AMYGDALA(l))
15492         border = BORDER_SIZE+1 ;  // need more context for hippo
15493       else
15494         border = BORDER_SIZE ;
15495       GCAbuildMostLikelyVolumeForStructure
15496       (gca, mri_seg, l, border, transform,mri_labels) ;
15497       for (x = 0 ; x < mri_labels->width ; x++)
15498       {
15499         for (y = 0 ; y < mri_labels->height ; y++)
15500         {
15501           for (z = 0 ; z < mri_labels->depth ; z++)
15502           {
15503             if (x == Gx && y == Gy && z == Gz)
15504               DiagBreak() ;
15505             label = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ;
15506             if (computed[label] == 0)
15507               continue ;
15508             val = MRIgetVoxVal(mri_seg, x, y, z, frame) ;
15509             val = val * label_scales[label] + label_offsets[label] ;
15510             MRIsetVoxVal(mri_seg, x, y, z, frame, val) ;
15511           }
15512         }
15513       }
15514 
15515       /* ventricle at the posterior part of hippo frequently
15516          makes local minima
15517          in alignment energy functional - remove them.
15518       */
15519 #if 1
15520       if (l == Left_Hippocampus || l == Right_Hippocampus)
15521       {
15522         for (x = 0 ; x < mri_labels->width ; x++)
15523         {
15524           for (y = 0 ; y < mri_labels->height ; y++)
15525           {
15526             for (z = 0 ; z < mri_labels->depth ; z++)
15527             {
15528               if (x == Gx && y == Gy && z == Gz)
15529                 DiagBreak() ;
15530               label = MRIgetVoxVal(mri_labels, x, y, z, 0) ;
15531               if (IS_LAT_VENT(label) || IS_INF_LAT_VENT(label))
15532                 MRIsetVoxVal(mri_seg, x, y, z, frame, 0) ;
15533             }
15534           }
15535         }
15536       }
15537 #endif
15538       if (l == Left_Cerebral_White_Matter ||
15539           l == Right_Cerebral_White_Matter)
15540       {
15541         MRI *mri_tmp, *mri_border ;
15542 
15543         // create a volume that is the wm eroded
15544         // 3 times, plus the border voxels
15545         mri_tmp = MRIclone(mri_seg, NULL) ;
15546         GCAbuildMostLikelyVolumeForStructure
15547         (gca, mri_tmp, l, 0, transform, NULL) ;
15548         mri_border = MRIsubtract(mri_seg, mri_tmp, NULL) ;
15549         // just outside
15550 
15551         // erode just the interior 3 times to get to high prob regions
15552         MRIerode(mri_tmp, mri_tmp) ;
15553         MRIerode(mri_tmp, mri_tmp) ;
15554         MRIerode(mri_tmp, mri_tmp) ;
15555         MRIadd(mri_tmp, mri_border, mri_seg) ;  // border + interior
15556         MRIfree(&mri_tmp) ;
15557         MRIfree(&mri_border) ;
15558       }
15559 
15560       if (Gdiag & DIAG_WRITE)
15561       {
15562         sprintf(fname, "%s_label%d.mgz", base_name, l) ;
15563         MRIwrite(mri_seg, fname) ;
15564       }
15565       if (transform->type != MORPH_3D_TYPE)
15566       {
15567         if (lta)   // try to find a previously computed one
15568         {
15569           for (n = 0 ; n < lta->num_xforms ; n++)
15570             if (lta->xforms[n].label == l)
15571               break ;
15572           if (n >= lta->num_xforms)
15573             n = -1 ;  // indicate no xform found
15574         }
15575         else   // no transform specified by caller
15576           n = -1 ;
15577         if (n < 0)  // no transform - compute one
15578         {
15579           double det ;
15580           float  evalues[4] ;
15581           MATRIX *m_evectors ;
15582 
15583           printf("aligning %s...\n", cma_label_to_name(l)) ;
15584           fflush(stdout);
15585           m_L = MRIgetVoxelToVoxelXform(mri_seg, mri) ;
15586           MRIpowellAlignImages
15587           (mri_seg, mri,  m_L, &scale_factor, NULL) ;
15588           det = MatrixDeterminant(m_L) ;
15589           m_evectors = MatrixEigenSystem(m_L, evalues, NULL) ;
15590           printf("eigen values (%2.2f, %2.2f, %2.2f, %2.2f), "
15591                  "vectors:\n",
15592                  evalues[0], evalues[1], evalues[2], evalues[3]) ;
15593           MatrixPrint(stdout, m_evectors) ;
15594           MatrixFree(&m_evectors) ;
15595           if (det < 0.1 || det > 4 ||
15596               scale_factor > 3 || scale_factor<0.3 || evalues[3] < 0.2)
15597           {
15598             printf("invalid transform detected "
15599                    "(det=%2.4f, iscale=%2.4f\n",
15600                    det, scale_factor) ;
15601             MatrixFree(&m_L) ;
15602             m_L = MRIgetVoxelToVoxelXform(mri_seg, mri) ;
15603 
15604           }
15605         }
15606         else   // use previously computed transform
15607           m_L = MatrixCopy(lta->xforms[n].m_L, NULL) ;
15608 
15609         if (l == Gdiag_no)
15610           DiagBreak() ;
15611 
15612         if (Gdiag & DIAG_WRITE)
15613         {
15614           sprintf(fname, "%s_label%d_after.mgz", base_name, l) ;
15615           mri_aligned = MRIlinearTransform(mri_seg, NULL, m_L) ;
15616           MRIwrite(mri_aligned, fname) ;
15617           MRIfree(&mri_aligned) ;
15618         }
15619 
15620         if (l == Left_Cerebral_White_Matter ||
15621             l == Right_Cerebral_White_Matter)
15622         {
15623           // wm so big it's hard to localize with a linear xform
15624           GCAbuildMostLikelyVolumeForStructure
15625           (gca, mri_seg, l, 0, transform, NULL) ;
15626           MRIerode(mri_seg, mri_seg) ;
15627           MRIerode(mri_seg, mri_seg) ;
15628         }
15629         else
15630         {
15631           /* put ventricles back in for erosion to remove
15632              (otherwise a bunch of hippo
15633              gets removed */
15634           if (l == Left_Hippocampus || l == Right_Hippocampus)
15635           {
15636             for (x = 0 ; x < mri_labels->width ; x++)
15637             {
15638               for (y = 0 ; y < mri_labels->height ; y++)
15639               {
15640                 for (z = 0 ; z < mri_labels->depth ; z++)
15641                 {
15642                   if (x == Gx && y == Gy && z == Gz)
15643                     DiagBreak() ;
15644                   label =
15645                     MRIgetVoxVal(mri_labels, x, y, z, 0) ;
15646                   if (IS_LAT_VENT(label) ||
15647                       IS_INF_LAT_VENT(label))
15648                     MRIsetVoxVal
15649                     (mri_seg, x, y, z, frame, 128) ;
15650                 }
15651               }
15652             }
15653           }
15654           for (b = 0 ; b < border ; b++)
15655             MRIerode(mri_seg, mri_seg) ; // get rid of outside border
15656           MRIerode(mri_seg, mri_seg) ; // get rid of inside border
15657         }
15658 
15659         mri_aligned = MRIlinearTransform(mri_seg, NULL, m_L) ;
15660       }
15661       else  // 3d morph already done - don't bother aligning
15662       {
15663         m_L = NULL ;
15664         if (l == Left_Cerebral_White_Matter ||
15665             l == Right_Cerebral_White_Matter)
15666         {
15667           // wm so big it's hard to localize with a linear xform
15668           GCAbuildMostLikelyVolumeForStructure
15669           (gca, mri_seg, l, 0, transform, NULL) ;
15670           MRIerode(mri_seg, mri_seg) ;
15671         }
15672         else
15673         {
15674           /* put ventricles back in for erosion
15675              to remove (otherwise a bunch of hippo
15676              gets removed */
15677           if (l == Left_Hippocampus || l == Right_Hippocampus)
15678           {
15679             for (x = 0 ; x < mri_labels->width ; x++)
15680             {
15681               for (y = 0 ; y < mri_labels->height ; y++)
15682               {
15683                 for (z = 0 ; z < mri_labels->depth ; z++)
15684                 {
15685                   if (x == Gx && y == Gy && z == Gz)
15686                     DiagBreak() ;
15687                   label =
15688                     MRIgetVoxVal(mri_labels, x, y, z, 0) ;
15689                   if (IS_LAT_VENT(label) ||
15690                       IS_INF_LAT_VENT(label))
15691                     MRIsetVoxVal
15692                     (mri_seg, x, y, z, frame, 128) ;
15693                 }
15694               }
15695             }
15696           }
15697           for (b = 0 ; b < border ; b++)
15698             MRIerode(mri_seg, mri_seg) ; // get rid of outside border
15699         }
15700         mri_aligned = MRIerode(mri_seg, NULL) ;
15701         // get rid of inside border
15702       }
15703 
15704       MRIbinarize(mri_aligned, mri_aligned, 1, 0, 128) ;
15705       if (Gdiag & DIAG_WRITE)
15706       {
15707         sprintf(fname, "%s_label%d_eroded.mgz", base_name, l) ;
15708         MRIwrite(mri_aligned, fname) ;
15709       }
15710       if (l == Gdiag_no)
15711         DiagBreak() ;
15712       HISTOclear(h_mri, h_mri) ;
15713       h_mri->bin_size = (fmax-fmin)/255.0 ;
15714       if (h_mri->bin_size < 1 &&
15715           (mri->type == MRI_UCHAR || mri->type == MRI_SHORT))
15716         h_mri->bin_size = 1 ;
15717       for (i = 0 ; i < nbins ; i++)
15718         h_mri->bins[i] = (i+1)*h_mri->bin_size ;
15719 
15720       for (num = x = 0 ; x < mri_aligned->width ; x++)
15721       {
15722         for (y = 0 ; y < mri_aligned->height ; y++)
15723         {
15724           for (z = 0 ; z < mri_aligned->depth ; z++)
15725           {
15726             if (x == Gx && y == Gy && z == Gz)
15727               DiagBreak() ;
15728             MRIsampleVolumeFrame(mri_aligned, x, y, z, frame, &val) ;
15729             if (DZERO(val))  // not in this structure
15730               continue ;
15731             MRIsampleVolumeFrame(mri, x, y, z, frame, &val) ;
15732 
15733             if (FZERO(val))  // skull stripped
15734               continue ;
15735             bin = nint((val - fmin)/h_mri->bin_size) ;
15736             if (bin >= h_mri->nbins)
15737               bin = h_mri->nbins-1 ;
15738             else if (bin < 0)
15739               bin = 0 ;
15740 
15741             h_mri->counts[bin]++ ;
15742             num++ ;
15743           }
15744         }
15745       }
15746       MRIfree(&mri_aligned) ;
15747       peak = HISTOfindHighestPeakInRegion(h_mri, 0, h_mri->nbins) ;
15748       HISTOfillHoles(h_mri) ;
15749       HISTOmakePDF(h_mri, h_mri) ;
15750       printf("peak = %2.5f (%d)\n", h_mri->counts[peak], peak) ;
15751       if ((num <= 50) ||
15752           ((transform->type != MORPH_3D_TYPE) &&
15753            (h_mri->counts[peak] < 0.05)))
15754       {
15755         if (h_mri->counts[peak] < .05)
15756           printf("uniform distribution in %s MR - "
15757                  "rejecting arbitrary fit\n",
15758                  cma_label_to_name(l)) ;
15759         if (m_L)
15760           MatrixFree(&m_L) ;
15761         continue ;
15762       }
15763       if (m_L)
15764       {
15765         if (plta)
15766           m_by_label[l] = m_L ;  // store if for assembling an LTA later
15767         else
15768           MatrixFree(&m_L) ;
15769       }
15770       h_gca = gcaGetLabelHistogram(gca, l, 0) ;
15771       HISTOmakePDF(h_gca, h_gca) ;
15772 
15773       {
15774         sprintf(fname, "%s_label%d_mri.plt", base_name, l) ;
15775         HISTOplot(h_mri, fname) ;
15776         sprintf(fname, "%s_label%d_gca.plt", base_name, l) ;
15777         HISTOplot(h_gca, fname) ;
15778         DiagBreak() ;
15779       }
15780       overlap = HISTOthreshSum(h_mri, h_gca, .025) ;
15781       if (overlap > 0.01)
15782       {
15783         //                        if (l == Gdiag_no)
15784         HISTOfindLinearFit(h_gca, h_mri, .025, 10, -75, 75,
15785                            &label_scales[l],
15786                            &label_offsets[l]) ;
15787         computed[l] = 1 ;
15788         printf("%s (%d): linear fit = %2.2f x + %2.1f "
15789                "(%d voxels, overlap=%2.3f)\n",
15790                cma_label_to_name(l), l,
15791                label_scales[l], label_offsets[l], num,overlap);
15792         if (logfp)
15793         {
15794           fprintf(logfp, "%s (%d): linear fit = %2.2f x + "
15795                   "%2.1f (%d voxels)\n",
15796                   cma_label_to_name(l), l,
15797                   label_scales[l], label_offsets[l],
15798                   num);
15799           fflush(logfp) ;
15800         }
15801         {
15802           HISTOlinearScale(h_gca, h_gca,
15803                            label_scales[l], label_offsets[l]) ;
15804           sprintf(fname, "%s_label%d_gca_scaled.plt", base_name, l) ;
15805           HISTOplot(h_gca, fname) ;
15806         }
15807       }
15808       else
15809       {
15810         printf("insufficient overlap %2.4f in "
15811                "%s histograms - rejecting\n",
15812                overlap, cma_label_to_name(l)) ;
15813       }
15814 
15815       if (l == Gdiag_no)
15816         DiagBreak() ;
15817       if (l >100)
15818         break ;
15819     }
15820     HISTOfree(&h_gca) ;
15821     HISTOfree(&h_mri) ;
15822 
15823     if (DIAG_VERBOSE_ON)
15824     {
15825       FILE *fp ;
15826       float scale, offset ;
15827       fp = fopen("norm_offset.plt", "r") ;
15828       for (l = 0 ; l < MAX_CMA_LABELS ; l++)
15829       {
15830         fscanf(fp, "%d %f %f", &l, &scale, &offset) ;
15831         label_scales[l] = scale ;
15832         label_offsets[l] = offset ;
15833         computed[l] = 1 ;
15834       }
15835       fclose(fp) ;
15836     }
15837     num = 0 ;
15838     mean_gm_scale = 0 ;
15839     mean_gm_offset = 0 ;
15840     fprintf(stdout, "not using caudate to estimate GM means\n") ;
15841     for (k = 0 ; k < NGM_LABELS ; k++)
15842     {
15843       label = gm_labels[k] ;
15844       if (computed[label])
15845       {
15846         mean_gm_scale += label_scales[label] ;
15847         mean_gm_offset += label_offsets[label] ;
15848         num++ ;
15849       }
15850     }
15851     if (num == 0)
15852     {
15853       mean_gm_scale = 1 ;
15854       mean_gm_offset = 0 ;
15855     }
15856     else
15857     {
15858       mean_gm_scale /= (float)num ;
15859       mean_gm_offset /= (float)num ;
15860     }
15861 
15862     num = 0 ;
15863     mean_wm_scale = 0 ;
15864     mean_wm_offset = 0 ;
15865     for (k = 0 ; k < NWM_LABELS ; k++)
15866     {
15867       label = wm_labels[k] ;
15868       if (computed[label])
15869       {
15870         mean_wm_scale += label_scales[label] ;
15871         mean_wm_offset += label_offsets[label] ;
15872         num++ ;
15873       }
15874     }
15875     if (num == 0)
15876     {
15877       mean_wm_scale = 1 ;
15878       mean_wm_offset = 0 ;
15879     }
15880     else
15881     {
15882       mean_wm_scale /= (float)num ;
15883       mean_wm_offset /= (float)num ;
15884     }
15885 
15886     num = 0 ;
15887     mean_csf_scale = 0 ;
15888     mean_csf_offset = 0 ;
15889     for (k = 0 ; k < NCSF_LABELS ; k++)
15890     {
15891       label = csf_labels[k] ;
15892       if (computed[label])
15893       {
15894         mean_csf_scale += label_scales[label] ;
15895         mean_csf_offset += label_offsets[label] ;
15896         num++ ;
15897       }
15898     }
15899     if (num == 0)
15900     {
15901       mean_csf_scale = 1 ;
15902       mean_csf_offset = 0 ;
15903     }
15904     else
15905     {
15906       mean_csf_scale /= (float)num ;
15907       mean_csf_offset /= (float)num ;
15908     }
15909 
15910     printf("estimating mean gm scale to be %2.2f x + %2.1f\n",
15911            mean_gm_scale, mean_gm_offset) ;
15912     printf("estimating mean wm scale to be %2.2f x + %2.1f\n",
15913            mean_wm_scale, mean_wm_offset) ;
15914     printf("estimating mean csf scale to be %2.2f x + %2.1f\n",
15915            mean_csf_scale, mean_csf_offset) ;
15916 
15917     // assume that cortical gm goes as wm
15918     if (computed[Left_Cerebral_Cortex] == 0 &&
15919         computed[Left_Cerebral_White_Matter] != 0)
15920     {
15921       if (m_by_label[Left_Cerebral_White_Matter])
15922         m_by_label[Left_Cerebral_Cortex] =
15923           MatrixCopy(m_by_label[Left_Cerebral_White_Matter], NULL) ;
15924       label_scales[Left_Cerebral_Cortex] = mean_gm_scale ;
15925       label_offsets[Left_Cerebral_Cortex] = mean_gm_offset ;
15926       computed[Left_Cerebral_Cortex] = 1;
15927     }
15928     if (computed[Right_Cerebral_Cortex] == 0 &&
15929         computed[Right_Cerebral_White_Matter] != 0)
15930     {
15931       if (m_by_label[Right_Cerebral_White_Matter])
15932         m_by_label[Right_Cerebral_Cortex] =
15933           MatrixCopy(m_by_label[Right_Cerebral_White_Matter], NULL) ;
15934       label_scales[Right_Cerebral_Cortex] = mean_gm_scale ;
15935       label_offsets[Right_Cerebral_Cortex] = mean_gm_offset ;
15936       computed[Right_Cerebral_Cortex] = 1;
15937     }
15938 
15939     // lock some labels scaling to others that have been estimated
15940     if (computed[Left_Caudate])
15941     {
15942       label_offsets[Left_Accumbens_area] = label_offsets[Left_Caudate] ;
15943       label_scales[Left_Accumbens_area] = label_scales[Left_Caudate] ;
15944       computed[Left_Accumbens_area] = 1;
15945     }
15946     if (computed[Right_Caudate])
15947     {
15948       label_offsets[Right_Accumbens_area] = label_offsets[Right_Caudate] ;
15949       label_scales[Right_Accumbens_area] = label_scales[Right_Caudate] ;
15950       computed[Right_Accumbens_area] = 1;
15951     }
15952     if (computed[Left_Inf_Lat_Vent] == 0 && computed[Left_Hippocampus] != 0)
15953     {
15954       label_scales[Left_Inf_Lat_Vent] = label_scales[Left_Hippocampus] ;
15955       label_offsets[Left_Inf_Lat_Vent] = label_offsets[Left_Hippocampus] ;
15956       computed[Left_Inf_Lat_Vent] = 1 ;
15957     }
15958     if (computed[Right_Inf_Lat_Vent] == 0 &&
15959         computed[Right_Hippocampus] != 0)
15960     {
15961       label_scales[Right_Inf_Lat_Vent] = label_scales[Right_Hippocampus] ;
15962       label_offsets[Right_Inf_Lat_Vent] =
15963         label_offsets[Right_Hippocampus] ;
15964       computed[Right_Inf_Lat_Vent] = 1 ;
15965     }
15966 
15967     label_scales[CSF] = mean_csf_scale ;
15968     label_scales[Fifth_Ventricle] = mean_csf_scale ;
15969     label_offsets[CSF] = mean_csf_offset ;
15970     label_offsets[Fifth_Ventricle] = mean_csf_offset ;
15971     computed[CSF] = computed[Fifth_Ventricle] = 1 ;
15972 
15973 
15974     if (logfp)
15975     {
15976       for (l = 0 ; l < MAX_CMA_LABELS ; l++)
15977         if (computed[l] != 0)
15978           fprintf(logfp, "label %s: scaling by %2.2f  + %2.1f\n",
15979                   cma_label_to_name(l),
15980                   label_scales[l], label_offsets[l]) ;
15981       fflush(logfp) ;
15982     }
15983     if (DIAG_VERBOSE_ON)
15984     {
15985       FILE *fp ;
15986       fp = fopen("norm_offset.plt", "w") ;
15987       for (l = 0 ; l < MAX_CMA_LABELS ; l++)
15988         if (computed[l] != 0)
15989           fprintf(fp, "%d %f %f\n", l, label_scales[l], label_offsets[l]) ;
15990       fclose(fp) ;
15991     }
15992 
15993     gcaCheck(gca) ;
15994     for (xn = 0 ; xn < gca->node_width ; xn++)
15995     {
15996       double     means_before[MAX_GCA_LABELS], \
15997       means_after[MAX_GCA_LABELS], scales[MAX_GCA_LABELS];
15998 #if 1
15999       double     delta_i, delta_j ;
16000       int        xp, yp, zp ;
16001 #endif
16002       int        labels[MAX_GCA_LABELS], niter ;
16003       LABEL_PROB ranks_before[MAX_GCA_LABELS], \
16004       ranks_after[MAX_GCA_LABELS] ;
16005 
16006       for (yn = 0 ; yn < gca->node_height ; yn++)
16007       {
16008         for (zn = 0 ; zn < gca->node_depth ; zn++)
16009         {
16010           if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
16011             DiagBreak() ;
16012           gcan = &gca->nodes[xn][yn][zn] ;
16013           if (gcan->nlabels <= 0)
16014             continue ;
16015 
16016           for (i = 0 ; i < gcan->nlabels ; i++)
16017           {
16018             gc = &gcan->gcs[i] ;
16019             l = gcan->labels[i] ;
16020             labels[i] = l ;
16021             scales[i] = label_scales[l] ;
16022             means_before[i] = gc->means[frame] ;
16023             ranks_before[i].label = l ;
16024             ranks_before[i].prob = means_before[i] ;
16025             ranks_before[i].index = i ;
16026           }
16027           qsort(ranks_before, gcan->nlabels,
16028                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
16029           niter = 0 ;
16030           for (i = 0 ; i < gcan->nlabels ; i++)
16031           {
16032             gc = &gcan->gcs[i] ;
16033             l = gcan->labels[i] ;
16034             means_after[i] =
16035               means_before[i]*label_scales[l] + label_offsets[l] ;
16036             if (means_after[i] < 0)
16037               means_after[i] = 0 ;
16038             ranks_after[i].label = l ;
16039             ranks_after[i].prob = means_after[i] ;
16040             ranks_after[i].index = i ;
16041           }
16042           qsort(ranks_after, gcan->nlabels,
16043                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
16044           for (i = 0 ; i < gcan->nlabels ; i++)
16045           {
16046 #if 1
16047             if (ranks_before[i].label != ranks_after[i].label)
16048             {
16049               double    pi, pj, lambda ;
16050               int       j, ind_j, ind_i ;
16051               GCA_PRIOR *gcap;
16052 
16053               /* two have swapped position - put them */
16054               /* back in the right order */
16055               for (j = 0 ; j < gcan->nlabels ; j++)
16056                 if (ranks_after[j].label == ranks_before[i].label)
16057                   break ;
16058               if (j >= gcan->nlabels)
16059               {
16060                 DiagBreak() ;
16061                 continue ;
16062               }
16063               gcaNodeToPrior(gca, xn, yn, zn, &xp, &yp, &zp) ;
16064               gcap = &gca->priors[xp][yp][zp] ;
16065               pi = getPrior(gcap, ranks_after[i].label) ;
16066               pj = getPrior(gcap, ranks_after[j].label) ;
16067               if (FZERO(pi) && FZERO(pj))
16068                 break ;   // both labels will never happen
16069               lambda = pi / (pi + pj) ;
16070               ind_j = ranks_after[j].index ;
16071               ind_i = ranks_after[i].index ;
16072               delta_j =
16073                 (means_after[ind_j] - means_after[ind_i]) *
16074                 lambda ;
16075               delta_i =
16076                 (means_after[ind_i] - means_after[ind_j]) *
16077                 (1-lambda) ;
16078 
16079               if ((fabs(delta_j) < 1) && (fabs(delta_i) < 1))
16080               {
16081                 // this will move one mean to the
16082                 // other side of the other
16083                 if ((fabs(delta_j) > fabs(delta_i)) &&
16084                     !FZERO(delta_j))
16085                   delta_j /= fabs(delta_j) ;  // make it +-1
16086                 else if (!FZERO(delta_i))
16087                   delta_i /= fabs(delta_i) ;  // make it +-1
16088               }
16089               if (!finite(delta_i) || !finite(delta_j))
16090               {
16091                 DiagBreak() ;
16092                 break ;
16093               }
16094               ranks_after[j].prob =
16095                 means_after[ind_j] = means_after[ind_j] - delta_j ;
16096               ranks_after[i].prob =
16097                 means_after[ind_i] = means_after[ind_i] - delta_i ;
16098               if ((xn == Gx && yn == Gy && zn == Gz) &&
16099                   (ranks_after[i].label == gcan->labels[i] ||
16100                    ranks_after[j].label == gcan->labels[j] ||
16101                    Ggca_label < 0))
16102               {
16103                 printf("ordering of labels %s and %s changed, "
16104                        "modifying means by %2.0f (%2.1f) "
16105                        "and %2.0f (%2.1f)\n",
16106                        cma_label_to_name(ranks_after[i].label),
16107                        cma_label_to_name(ranks_after[j].label),
16108                        means_after[i], delta_i,
16109                        means_after[j], delta_i) ;
16110               }
16111 
16112               qsort(ranks_after, gcan->nlabels,
16113                     sizeof(LABEL_PROB),
16114                     compare_sort_probabilities) ;
16115               i = -1 ;   /* start loop over */
16116               if (niter++ > 9)
16117               {
16118                 DiagBreak() ;
16119                 break ;
16120               }
16121               continue ;
16122             }
16123 #endif
16124           }
16125 
16126           for (i = 0 ; i < gcan->nlabels ; i++)
16127           {
16128             if (FZERO(label_scales[gcan->labels[i]]))
16129               continue ;
16130             gc = &gcan->gcs[i] ;
16131             if ((xn == Gx && yn == Gy && zn == Gz) &&
16132                 (Ggca_label == gcan->labels[i] || Ggca_label < 0))
16133             {
16134               printf("scaling gc for label %s at "
16135                      "(%d, %d, %d) from %2.1f to %2.1f\n",
16136                      cma_label_to_name(gcan->labels[i]),
16137                      xn, yn, zn,
16138                      means_before[i], means_after[i]) ;
16139               DiagBreak() ;
16140             }
16141             gc->means[frame] = means_after[i] ;
16142             check_finite("after rescaling", gc->means[frame]) ;
16143           }
16144         }
16145       }
16146     }
16147     gcaCheck(gca) ;
16148   }
16149 
16150   if (plta)  // return linear transform array to caller
16151   {
16152     int i ;
16153 
16154     // count # of xforms
16155     for (i = l = 0 ; l < MAX_CMA_LABELS ; l++)
16156     {
16157       if (m_by_label[l] != NULL)
16158         i++ ;
16159     }
16160 
16161     if (i > 0)  // should always be true
16162     {
16163       *plta = lta = LTAalloc(i, mri) ;
16164       for (i = l = 0 ; l < MAX_CMA_LABELS ; l++)
16165       {
16166         if (m_by_label[l] != NULL)
16167         {
16168           MatrixCopy(m_by_label[l], lta->xforms[i].m_L) ;
16169           MatrixFree(&m_by_label[l]) ;
16170           lta->xforms[i].label = l ;
16171           i++ ;
16172         }
16173       }
16174     }
16175   }
16176 
16177   if (mri_seg)
16178     MRIfree(&mri_seg) ;
16179   return(NO_ERROR) ;
16180 }
16181 #endif
16182 
16183 static int lh_labels[] =
16184   {
16185     Left_Cerebral_White_Matter,
16186     Left_Hippocampus,
16187     Left_Cerebral_Cortex,
16188     Left_Lateral_Ventricle,
16189     Left_Caudate,
16190     Left_Cerebellum_Cortex,
16191     Left_Cerebellum_White_Matter,
16192     Left_Amygdala,
16193     Left_Thalamus_Proper,
16194     Left_Putamen,
16195     Left_Pallidum,
16196     Left_VentralDC,
16197   } ;
16198 static int rh_labels[] =
16199   {
16200     Right_Cerebral_White_Matter,
16201     Right_Hippocampus,
16202     Right_Cerebral_Cortex,
16203     Right_Lateral_Ventricle,
16204     Right_Caudate,
16205     Right_Cerebellum_Cortex,
16206     Right_Cerebellum_White_Matter,
16207     Right_Amygdala,
16208     Right_Thalamus_Proper,
16209     Right_Putamen,
16210     Right_Pallidum,
16211     Right_VentralDC,
16212   } ;
16213 
16214 #define NHEMI_LABELS (sizeof(rh_labels) / sizeof(rh_labels[0]))
16215 int
16216 GCAmapRenormalizeWithAlignment(GCA *gca,
16217                                MRI *mri,
16218                                TRANSFORM *transform,
16219                                FILE *logfp,
16220                                char *base_name,
16221                                LTA **plta,
16222                                int handle_expanded_ventricles)
16223 {
16224   HISTOGRAM *h_mri, *h_gca ;
16225   int       l, nbins, i, x, y, z, xn, yn, zn, num, frame, \
16226   bin, j, n, computed[MAX_CMA_LABELS], b, label, k,
16227   border = BORDER_SIZE, gca_peak, mri_peak ;
16228   float     fmin, fmax, label_scales[MAX_CMA_LABELS], overlap,
16229   mean_gm_scale, mean_wm_scale, mean_csf_scale, label_peaks[MAX_CMA_LABELS],
16230   label_offsets[MAX_CMA_LABELS], \
16231   mean_wm_offset, mean_csf_offset, mean_gm_offset,
16232   lower_thresh, upper_thresh ;
16233   Real      val/*, scale*/ ;
16234   GCA_NODE  *gcan ;
16235   GC1D      *gc ;
16236   MRI       *mri_seg = NULL, *mri_aligned, *mri_labels = NULL ;
16237   char      fname[STRLEN] ;
16238   MATRIX    *m_L, *m_by_label[MAX_CMA_LABELS] ;
16239   LTA       *lta ;
16240 
16241   double    det = -1 ;
16242   float peak_threshold = 0.03;
16243   float overlap_threshold = 0.001;
16244   int equiv_class[MAX_CMA_LABELS];
16245 
16246   if (transform->type == MORPH_3D_TYPE)
16247   {
16248     peak_threshold = 0.01;
16249     overlap_threshold = -1.0; //at mri_ca_label stage;
16250     // trust the registration more
16251   }
16252 
16253   set_equilavent_classes(equiv_class);
16254 
16255   printf("renormalizing by structure alignment....\n") ;
16256   if (plta)
16257     lta = *plta ;
16258   else
16259     lta = NULL ;
16260   for (frame = 0 ; frame < mri->nframes ; frame++)
16261   {
16262     for (l = 0 ; l < MAX_CMA_LABELS ; l++)
16263     {
16264       if (l == Gdiag_no)
16265         DiagBreak() ;
16266       label_scales[l] = 1.0 ;
16267       label_offsets[l] = 0.0 ;
16268       computed[l] = 0 ;
16269       m_by_label[l] = NULL ;  // not estimated yet
16270     }
16271 
16272     printf("renormalizing input #%d\n", frame) ;
16273     MRIvalRangeFrame(mri, &fmin, &fmax, frame) ;
16274     nbins = 256 ;
16275     h_mri = HISTOalloc(nbins) ;
16276     for (j = 0 ; j < NALIGN_LABELS ; j++)
16277     {
16278       l = align_labels[j] ;
16279       if (l == Gdiag_no)
16280         DiagBreak() ;
16281 
16282 
16283       mri_seg = MRIclone(mri, mri_seg) ;
16284       mri_labels = MRIclone(mri, mri_labels) ;
16285 
16286       /* include 2 voxel border to get context around structure.
16287         e.g. hippo is made easier to find by wm inferior and ventricle
16288         posterior.
16289       */
16290       if (transform->type != MORPH_3D_TYPE)
16291       {
16292         if (IS_HIPPO(l) ||
16293             IS_AMYGDALA(l) ||
16294             IS_CAUDATE(l) ||
16295             IS_PUTAMEN(l) ||
16296             IS_PALLIDUM(l))
16297           border = BORDER_SIZE+1 ;  // need more context for hippo
16298         else if (IS_GM(l))
16299           border = 0;
16300         else if (IS_WHITE_CLASS(l))
16301           border = WM_BORDER_SIZE ;
16302         else
16303           border = BORDER_SIZE ;
16304         GCAbuildMostLikelyVolumeForStructure
16305           (gca, mri_seg, l, border, transform,mri_labels) ;
16306         for (x = 0 ; x < mri_labels->width ; x++)
16307         {
16308           for (y = 0 ; y < mri_labels->height ; y++)
16309           {
16310             for (z = 0 ; z < mri_labels->depth ; z++)
16311             {
16312               if (x == Gx && y == Gy && z == Gz)
16313                 DiagBreak() ;
16314               label = MRIgetVoxVal(mri_labels, x, y, z, 0) ;
16315               if (computed[label] == 0)
16316                 continue ;
16317               val = MRIgetVoxVal(mri_seg, x, y, z, frame) ;
16318               val = val * label_scales[label] +
16319                     label_offsets[label] ;
16320               MRIsetVoxVal(mri_seg, x, y, z, frame, val) ;
16321             }
16322           }
16323         }
16324 
16325         /* ventricle at the posterior part of hippo
16326           frequently makes local minima
16327           in alignment energy functional - remove them.
16328         */
16329         if (l == Left_Hippocampus || l == Right_Hippocampus)
16330         {
16331           for (x = 0 ; x < mri_labels->width ; x++)
16332           {
16333             for (y = 0 ; y < mri_labels->height ; y++)
16334             {
16335               for (z = 0 ; z < mri_labels->depth ; z++)
16336               {
16337                 if (x == Gx && y == Gy && z == Gz)
16338                   DiagBreak() ;
16339                 label = MRIgetVoxVal(mri_labels, x, y, z, 0) ;
16340                 if (IS_LAT_VENT(label) || IS_INF_LAT_VENT(label))
16341                   MRIsetVoxVal(mri_seg, x, y, z, frame, 0) ;
16342               }
16343             }
16344           }
16345         }
16346         if (l == Left_Cerebral_White_Matter ||
16347             l == Right_Cerebral_White_Matter)
16348         {
16349           MRI *mri_tmp, *mri_border ;
16350 
16351           // create a volume that is the wm eroded 3 times,
16352           // plus the border voxels
16353           mri_tmp = MRIclone(mri_seg, NULL) ;
16354           GCAbuildMostLikelyVolumeForStructure
16355             (gca, mri_tmp, l, BORDER_SIZE, transform, NULL) ;
16356           mri_border = MRIsubtract(mri_seg, mri_tmp, NULL) ;
16357           // just outside
16358 
16359           // erode just the interior 4 times to get to high prob regions
16360           MRIerode(mri_tmp, mri_tmp) ;
16361           MRIerode(mri_tmp, mri_tmp) ;
16362           MRIerode(mri_tmp, mri_tmp) ;
16363           MRIerode(mri_tmp, mri_tmp) ;
16364           MRIerode(mri_tmp, mri_tmp) ;
16365           MRIerode(mri_tmp, mri_tmp) ; // two more to remove border
16366           MRIadd(mri_tmp, mri_border, mri_seg) ;  // border + interior
16367           MRIfree(&mri_tmp) ;
16368           MRIfree(&mri_border) ;
16369         }
16370 
16371         if (Gdiag & DIAG_WRITE)
16372         {
16373           sprintf(fname, "%s_label%d.mgz", base_name, l) ;
16374           MRIwrite(mri_seg, fname) ;
16375         }
16376 
16377         if (lta)   // try to find a previously computed one
16378         {
16379           for (n = 0 ; n < lta->num_xforms ; n++)
16380             if (lta->xforms[n].label == l)
16381               break ;
16382           if (n >= lta->num_xforms)
16383             n = -1 ;  // indicate no xform found
16384         }
16385         else   // no transform specified by caller
16386           n = -1 ;
16387         if (n < 0)  // no transform - compute one
16388         {
16389           // float  evalues[4] ;
16390           // MATRIX *m_evectors ;
16391 
16392           printf("aligning %s...\n", cma_label_to_name(l)) ;
16393           m_L = MRIgetVoxelToVoxelXform(mri_seg, mri) ;
16394           if (! IS_GM(l))
16395           { // will use alignment of WM for GM
16396             //  MRIpowellAlignImages(mri_seg, mri,
16397             // m_L, &scale_factor, NULL) ;
16398             if ((l == Left_Lateral_Ventricle ||
16399                  l == Right_Lateral_Ventricle) &&
16400                 (transform->type != MORPH_3D_TYPE) &&
16401                 (handle_expanded_ventricles == 1))
16402             {
16403               char label_base_name[STRLEN] ;
16404               sprintf(label_base_name, "%s_label%d", base_name, l) ;
16405               initialize_ventricle_alignment
16406                 (mri_seg, mri, m_L, label_base_name) ;
16407             }
16408             MRIfaridAlignImages(mri_seg, mri,  m_L) ;
16409           }
16410           else
16411           {
16412             // assume that cortical gm goes as wm
16413             if ((l == Left_Cerebral_Cortex) &&
16414                 computed[Left_Cerebral_White_Matter] != 0)
16415             {
16416               if (m_by_label[Left_Cerebral_White_Matter])
16417                 m_L =
16418                   MatrixCopy(m_by_label[Left_Cerebral_White_Matter], m_L) ;
16419             }
16420             if ( (l == Right_Cerebral_Cortex) &&
16421                  computed[Right_Cerebral_White_Matter] != 0)
16422             {
16423               if (m_by_label[Right_Cerebral_White_Matter])
16424                 m_L =
16425                   MatrixCopy(m_by_label[Right_Cerebral_White_Matter], m_L) ;
16426             }
16427           }
16428 
16429           det = MatrixDeterminant(m_L) ;
16430           if (det > 4 && det < 8 &&
16431               (l == Left_Lateral_Ventricle || l == Right_Lateral_Ventricle))
16432             det = 1 ;  // allow large determinants for the ventricles
16433 
16434 #if 0
16435           // for non-ventricular structures make sure that
16436           // there isn't too much shape deformation
16437           if (l != Left_Lateral_Ventricle && l != Right_Lateral_Ventricle)
16438           {
16439             float evalues[4], cond ;
16440             MATRIX *m ;
16441 
16442             m = MatrixCopyRegion(m_L, NULL, 1, 1, 3, 3, 1, 1) ;
16443             cond = MatrixSVDEigenValues(m, evalues) ;
16444             MatrixFree(&m) ;
16445 
16446             if (evalues[0]/evalues[2] > 2)
16447             {
16448               printf("extreme anistropy detected in transform "
16449                      "(%2.2f=%2.2f/%2.2f)\n", 
16450                      evalues[0]/evalues[2], evalues[0], evalues[2]) ;
16451               det = -1 ;
16452             }
16453           }
16454 #endif
16455 
16456           printf("det = %2.3f, M=\n", det) ;
16457           MatrixPrint(stdout, m_L) ;
16458           if (det < 0.25 || det > 4)
16459           {
16460             printf("invalid transform detected (det=%2.4f) \n",det) ;
16461             det = -1 ;  // mark it as invalid for later
16462             MatrixFree(&m_L) ;
16463             m_L = MRIgetVoxelToVoxelXform(mri_seg, mri) ;
16464           }
16465         }
16466         else   // use previously computed transform
16467           m_L = MatrixCopy(lta->xforms[n].m_L, NULL) ;
16468 
16469         if (l == Gdiag_no)
16470           DiagBreak() ;
16471 
16472         if (Gdiag & DIAG_WRITE)
16473         {
16474           sprintf(fname, "%s_label%d_after.mgz", base_name, l) ;
16475           mri_aligned = MRIlinearTransform(mri_seg, NULL, m_L) ;
16476           MRIwrite(mri_aligned, fname) ;
16477           MRIfree(&mri_aligned) ;
16478         }
16479 
16480         if (l == Left_Cerebral_White_Matter ||
16481             l == Right_Cerebral_White_Matter)
16482         {
16483           // wm so big it's hard to localize with a linear xform
16484           GCAbuildMostLikelyVolumeForStructure
16485           (gca, mri_seg, l, 0, transform, NULL) ;
16486           MRIerode(mri_seg, mri_seg) ;
16487           MRIerode(mri_seg, mri_seg) ;
16488         }
16489         else
16490         {
16491           /* put ventricles back in for erosion to remove
16492             (otherwise a bunch of hippo
16493             gets removed */
16494           if (l == Left_Hippocampus || l == Right_Hippocampus)
16495           {
16496             for (x = 0 ; x < mri_labels->width ; x++)
16497             {
16498               for (y = 0 ; y < mri_labels->height ; y++)
16499               {
16500                 for (z = 0 ; z < mri_labels->depth ; z++)
16501                 {
16502                   if (x == Gx && y == Gy && z == Gz)
16503                     DiagBreak() ;
16504                   label = MRIgetVoxVal(mri_labels, x, y, z, 0) ;
16505                   if (IS_LAT_VENT(label) ||
16506                       IS_INF_LAT_VENT(label))
16507                     MRIsetVoxVal(mri_seg, x, y, z, frame, 128) ;
16508                 }
16509               }
16510             }
16511           }
16512           for (b = 0 ; b < border ; b++)
16513             MRIerode(mri_seg, mri_seg) ; // get rid of outside border
16514           MRIerode(mri_seg, mri_seg) ; // get rid of inside border
16515         }
16516 
16517         mri_aligned = MRIlinearTransform(mri_seg, NULL, m_L) ;
16518       }
16519       else  // 3d morph already done - don't bother aligning
16520       {
16521         m_L = NULL ;
16522         if (l == Left_Cerebral_White_Matter ||
16523             l == Right_Cerebral_White_Matter)
16524         {
16525           // wm so big it's hard to localize with a linear xform
16526           GCAbuildMostLikelyVolumeForStructure
16527           (gca, mri_seg, l, 0, transform, NULL) ;
16528           MRIerode(mri_seg, mri_seg) ;
16529         }
16530         else
16531         {
16532           GCAbuildMostLikelyVolumeForStructure
16533           (gca, mri_seg, l, 0, transform, NULL) ;
16534         }
16535         mri_aligned = MRIerode(mri_seg, NULL);
16536       }
16537 
16538       MRIbinarize(mri_aligned, mri_aligned, 1, 0, 128) ;
16539       if (Gdiag & DIAG_WRITE)
16540       {
16541         sprintf(fname, "%s_label%d_eroded.mgz", base_name, l) ;
16542         MRIwrite(mri_aligned, fname) ;
16543       }
16544       if (l == Gdiag_no)
16545         DiagBreak() ;
16546       HISTOclear(h_mri, h_mri) ;
16547       h_mri->bin_size = (fmax-fmin)/255.0 ;
16548       if (h_mri->bin_size < 1 &&
16549           (mri->type == MRI_UCHAR || mri->type == MRI_SHORT))
16550         h_mri->bin_size = 1 ;
16551       for (i = 0 ; i < nbins ; i++)
16552         h_mri->bins[i] = (i+1)*h_mri->bin_size ;
16553 
16554       for (num = x = 0 ; x < mri_aligned->width ; x++)
16555       {
16556         for (y = 0 ; y < mri_aligned->height ; y++)
16557         {
16558           for (z = 0 ; z < mri_aligned->depth ; z++)
16559           {
16560             if (x == Gx && y == Gy && z == Gz)
16561               DiagBreak() ;
16562             MRIsampleVolumeFrame(mri_aligned, x, y, z, frame, &val) ;
16563             if (DZERO(val))  // not in this structure
16564               continue ;
16565             MRIsampleVolumeFrame(mri, x, y, z, frame, &val) ;
16566 
16567             if (FZERO(val))  // skull stripped
16568               continue ;
16569             bin = nint((val - fmin)/h_mri->bin_size) ;
16570             if (bin >= h_mri->nbins)
16571               bin = h_mri->nbins-1 ;
16572             else if (bin < 0)
16573               bin = 0 ;
16574 
16575             h_mri->counts[bin]++ ;
16576             num++ ;
16577           }
16578         }
16579       }
16580       MRIfree(&mri_aligned) ;
16581 
16582       h_gca = gcaGetLabelHistogram(gca, l, 0) ;
16583       gca_peak = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
16584       HISTOmakePDF(h_gca, h_gca) ;
16585       if (gca_peak >= 0)
16586         printf("gca peak = %2.5f (%2.0f)\n", 
16587                h_gca->counts[gca_peak], h_gca->bins[gca_peak]) ;
16588       label_peaks[l] = h_gca->bins[gca_peak] ;
16589       fflush(stdout);
16590 
16591       mri_peak = HISTOfindHighestPeakInRegion(h_mri, 0, h_mri->nbins) ;
16592       HISTOfillHoles(h_mri) ;
16593       HISTOmakePDF(h_mri, h_mri) ;
16594       if (mri_peak >= 0)
16595         printf("mri peak = %2.5f (%2.0f)\n", 
16596                h_mri->counts[mri_peak], h_mri->bins[mri_peak]) ;
16597       fflush(stdout);
16598 
16599       if (IS_CSF(l) && h_mri->bins[mri_peak] > 55)
16600       {
16601         printf("CSF peak too bright - rejecting\n") ;
16602         continue ;
16603       }
16604       if (h_mri->counts[mri_peak] < peak_threshold || num <= 50)
16605         /* not enough to reliably estimate density */
16606       {
16607         if (h_mri->counts[mri_peak] < peak_threshold)
16608           printf("uniform distribution in MR - "
16609                  "rejecting arbitrary fit\n") ;
16610         if (m_L)
16611           MatrixFree(&m_L) ;
16612         continue ;
16613       }
16614       if (m_L)
16615       {
16616         if (plta && (!IS_GM(l))) //GM will be copied from WM later
16617           m_by_label[l] = m_L ;  // store if for assembling an LTA later
16618         else
16619           MatrixFree(&m_L) ;
16620       }
16621 
16622       if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
16623       {
16624         sprintf(fname, "%s_label%d_mri.plt", base_name, l) ;
16625         HISTOplot(h_mri, fname) ;
16626         sprintf(fname, "%s_label%d_gca.plt", base_name, l) ;
16627         HISTOplot(h_gca, fname) ;
16628         DiagBreak() ;
16629       }
16630       overlap = HISTOthreshSum(h_mri, h_gca, .025) ;
16631 
16632       //if (overlap > 0.01)
16633       //      if (overlap > 0.001)
16634       if (IS_LAT_VENT(l) || overlap > overlap_threshold)
16635       {
16636         //                        if (l == Gdiag_no)
16637         //  HISTOfindLinearFit(h_gca, h_mri, .025, 10, -75, 75,
16638         // &label_scales[l],  &label_offsets[l]) ;
16639         //              HISTOfindLinearFit(h_gca, h_mri, .025,
16640         // 4, -125, 125, &label_scales[l], &label_offsets[l]) ;
16641         HISTOfindLinearFit(h_gca, h_mri, .025, 4, 0, 0,
16642                            &label_scales[l], &label_offsets[l]) ;
16643 
16644         val = h_gca->bins[gca_peak]*label_scales[l]+label_offsets[l] ;
16645         switch (l)
16646         {
16647         case Brain_Stem:
16648         case Left_VentralDC:
16649         case Right_VentralDC:
16650           lower_thresh = 80 ;
16651           upper_thresh = 110 ;
16652           break ;
16653         case Left_Caudate:
16654         case Right_Caudate:
16655           lower_thresh = 50 ;
16656           upper_thresh = 100 ;
16657           break ;
16658         case Left_Cerebral_Cortex:
16659         case Right_Cerebral_Cortex:
16660           lower_thresh = 40 ;
16661           upper_thresh = 95 ;
16662           break ;
16663         case Left_Pallidum:
16664         case Right_Pallidum:
16665           lower_thresh = 75 ;
16666           upper_thresh = 135 ;
16667           break ;
16668         case Left_Thalamus_Proper:
16669         case Right_Thalamus_Proper:
16670           lower_thresh = 75 ;
16671           upper_thresh = 120 ;
16672           break ;
16673         case Left_Cerebral_White_Matter:
16674         case Right_Cerebral_White_Matter:
16675           lower_thresh = 90 ;
16676           upper_thresh = 130 ;
16677           break ;
16678         case Left_Putamen:
16679         case Right_Putamen:
16680           lower_thresh = 60 ;
16681           upper_thresh = 100 ;
16682           break ;
16683         case Left_Lateral_Ventricle:
16684         case Right_Lateral_Ventricle:
16685         case Third_Ventricle:
16686         case Fourth_Ventricle:
16687         case CSF:
16688           lower_thresh = 0 ;
16689           upper_thresh = 40 ;
16690           break ;
16691         case Left_Inf_Lat_Vent:
16692         case Right_Inf_Lat_Vent:
16693           lower_thresh = 0 ;
16694           upper_thresh = 65 ;
16695           break ;
16696         default:
16697           lower_thresh = 0 ;
16698           upper_thresh = 256 ;
16699           break ;
16700         }
16701         if ((val < lower_thresh || 
16702              val > upper_thresh) ||
16703             (h_mri->bins[mri_peak] < lower_thresh || 
16704              h_mri->bins[mri_peak] > upper_thresh))
16705         {
16706           //          if (transform->type != MORPH_3D_TYPE)
16707           {
16708             printf("unreasonable value (%2.1f/%2.1f), "
16709                    "not in range [%2.0f, %2.0f] - rejecting\n",
16710                    val, h_mri->bins[mri_peak], lower_thresh, upper_thresh) ;
16711             label_scales[l] = 1.0 ;
16712             label_offsets[l] = 1.0 ;
16713             continue ;
16714           }
16715         }
16716 
16717         // only allow certain labels to be used for initializing the 3d morph
16718         // (which is what happens when computed[l] = 2)
16719         computed[l] = (det > 0) ? 2 : 1 ;
16720         printf("%s (%d): linear fit = %2.2f x + %2.1f "
16721                "(%d voxels, overlap=%2.3f)\n",
16722                cma_label_to_name(l), l,
16723                label_scales[l], label_offsets[l], num,overlap);
16724 
16725         //note that the following range need be changed
16726         // if both scale and offset are allowed' 1/1.5 = 0.67
16727         if (IS_LAT_VENT(l))
16728         {
16729           if (label_scales[l] < 0.4) label_scales[l] = 0.4;
16730           else if (label_scales[l] > 1.5) label_scales[l] = 1.5;
16731         }
16732         if ((label_scales[l] < 0.67 ||
16733              (label_scales[l] > 1.5)) && !IS_LAT_VENT(l))
16734         {
16735           /*
16736            if(IS_CSF(l)){
16737            if(label_scales[l] < 0.67) label_scales[l] = 0.67;
16738            else if(label_scales[l] > 1.5) label_scales[l] = 1.5;
16739            } else
16740           */
16741           {
16742             //scaling is unreliable, ignore it
16743             computed[l] = 0 ;
16744             m_by_label[l] = NULL;
16745           }
16746         }
16747         label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16748 
16749         if (logfp)
16750         {
16751           fprintf(logfp, "%s (%d): linear fit = %2.2f x + "
16752                   "%2.1f (%d voxels, peak = %2.0f), gca=%2.1f\n",
16753                   cma_label_to_name(l), l,
16754                   label_scales[l], label_offsets[l],
16755                   num, val, label_peaks[l]);
16756           fflush(logfp) ;
16757         }
16758         fprintf(stdout, "%s (%d): linear fit = %2.2f x + "
16759                 "%2.1f (%d voxels, peak = %2.0f), gca=%2.1f\n",
16760                 cma_label_to_name(l), l,
16761                 label_scales[l], label_offsets[l],
16762                 num, val, label_peaks[l]);
16763         fflush(stdout) ;
16764         {
16765           HISTOlinearScale(h_gca, h_gca,
16766                            label_scales[l], label_offsets[l]) ;
16767           if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
16768           {
16769             sprintf(fname, "%s_label%d_gca_scaled.plt", base_name, l) ;
16770             HISTOplot(h_gca, fname) ;
16771           }
16772         }
16773       }
16774       else
16775       {
16776         printf("overlap = %g, overlap_threshold = %g\n",
16777                overlap, overlap_threshold);
16778         printf("insufficient overlap %2.4f in histograms - rejecting\n",
16779                overlap) ;
16780       }
16781 
16782       if (l == Gdiag_no)
16783         DiagBreak() ;
16784       if (l >100)
16785         break ;
16786     }
16787     HISTOfree(&h_gca) ;
16788     HISTOfree(&h_mri) ;
16789 
16790     // make sure non-computed labels don't scale
16791     for (l = 0 ; l < MAX_CMA_LABELS ; l++)
16792     {
16793       if (computed[l] == 0)
16794       {
16795         label_scales[l] = 1.0 ;
16796         label_offsets[l] = 0.0 ;
16797         h_gca = gcaGetLabelHistogram(gca, l, 0) ;
16798         gca_peak = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
16799         HISTOmakePDF(h_gca, h_gca) ;
16800         if (gca_peak >= 0)
16801           printf("gca peak %s = %2.5f (%2.0f)\n", 
16802                  cma_label_to_name(l), 
16803                  h_gca->counts[gca_peak], 
16804                  h_gca->bins[gca_peak]) ;
16805         label_peaks[l] = h_gca->bins[gca_peak] ;
16806         fflush(stdout);
16807       }
16808     }
16809 
16810     if (DIAG_VERBOSE_ON)
16811     {
16812       FILE *fp ;
16813       float scale, offset ;
16814       fp = fopen("norm_offset.plt", "r") ;
16815       if (fp != NULL)
16816       {
16817         for (l = 0 ; l < MAX_CMA_LABELS ; l++)
16818         {
16819           fscanf(fp, "%d %f %f", &l, &scale, &offset) ;
16820           label_scales[l] = scale ;
16821           label_offsets[l] = offset ;
16822           computed[l] = 1 ;
16823         }
16824         fclose(fp) ;
16825       }
16826     }
16827     fprintf(stdout, "not using caudate to estimate GM means\n") ;
16828     for (k = 0 ; k < NHEMI_LABELS ; k++)
16829     {
16830       int lhl, rhl ;
16831       if (computed[lh_labels[k]] && !computed[rh_labels[k]])
16832       {
16833         lhl = lh_labels[k] ;
16834         rhl = rh_labels[k] ;
16835         label_scales[rhl] = label_scales[lhl] ;
16836         label_offsets[rhl] = label_offsets[lhl] ;
16837         label_peaks[rhl] = label_peaks[lhl] ;
16838         computed[rhl] = 1;
16839         fprintf(stdout, "setting label %s based on %s = %2.2f x + %2.0f\n",
16840                 cma_label_to_name(lhl), cma_label_to_name(rhl),
16841                 label_scales[rhl], label_offsets[rhl]) ;
16842       }
16843       else if (computed[rh_labels[k]] && !computed[lh_labels[k]])
16844       {
16845         lhl = lh_labels[k] ;
16846         rhl = rh_labels[k] ;
16847         label_scales[lhl] = label_scales[rhl] ;
16848         label_offsets[lhl] = label_offsets[rhl] ;
16849         label_peaks[lhl] = label_peaks[rhl] ;
16850         computed[lhl] = 1;
16851         fprintf(stdout, "setting label %s based on %s = %2.2f x + %2.0f\n",
16852                 cma_label_to_name(rhl), cma_label_to_name(lhl),
16853                 label_scales[lhl], label_offsets[lhl]) ;
16854       }
16855     }
16856 
16857     num = 0 ;
16858     mean_gm_scale = 0 ;
16859     mean_gm_offset = 0 ;
16860     for (k = 0 ; k < NGM_LABELS ; k++)
16861     {
16862       label = gm_labels[k] ;
16863       if (computed[label])
16864       {
16865         mean_gm_scale += label_scales[label] ;
16866         mean_gm_offset += label_offsets[label] ;
16867         num++ ;
16868       }
16869     }
16870     if (num == 0)
16871     {
16872       mean_gm_scale = 1 ;
16873       mean_gm_offset = 0 ;
16874     }
16875     else
16876     {
16877       mean_gm_scale /= (float)num ;
16878       mean_gm_offset /= (float)num ;
16879     }
16880 
16881     num = 0 ;
16882     mean_wm_scale = 0 ;
16883     mean_wm_offset = 0 ;
16884     for (k = 0 ; k < NWM_LABELS ; k++)
16885     {
16886       label = wm_labels[k] ;
16887       if (computed[label])
16888       {
16889         mean_wm_scale += label_scales[label] ;
16890         mean_wm_offset += label_offsets[label] ;
16891         num++ ;
16892       }
16893     }
16894     if (num == 0)
16895     {
16896       mean_wm_scale = 1 ;
16897       mean_wm_offset = 0 ;
16898     }
16899     else
16900     {
16901       mean_wm_scale /= (float)num ;
16902       mean_wm_offset /= (float)num ;
16903     }
16904 
16905     num = 0 ;
16906     mean_csf_scale = 0 ;
16907     mean_csf_offset = 0 ;
16908     for (k = 0 ; k < NCSF_LABELS ; k++)
16909     {
16910       label = csf_labels[k] ;
16911       if (computed[label])
16912       {
16913         mean_csf_scale += label_scales[label] ;
16914         mean_csf_offset += label_offsets[label] ;
16915         num++ ;
16916       }
16917     }
16918     if (num == 0)
16919     {
16920       mean_csf_scale = 1 ;
16921       mean_csf_offset = 0 ;
16922     }
16923     else
16924     {
16925       mean_csf_scale /= (float)num ;
16926       mean_csf_offset /= (float)num ;
16927     }
16928 
16929     printf("estimating mean gm scale to be %2.2f x + %2.1f\n",
16930            mean_gm_scale, mean_gm_offset) ;
16931     printf("estimating mean wm scale to be %2.2f x + %2.1f\n",
16932            mean_wm_scale, mean_wm_offset) ;
16933     printf("estimating mean csf scale to be %2.2f x + %2.1f\n",
16934            mean_csf_scale, mean_csf_offset) ;
16935 
16936     // assume that cortical gm goes as wm
16937     if (computed[Left_Cerebral_Cortex] == 0 &&
16938         computed[Left_Cerebral_White_Matter] != 0)
16939     {
16940       if (m_by_label[Left_Cerebral_White_Matter])
16941         m_by_label[Left_Cerebral_Cortex] =
16942           MatrixCopy(m_by_label[Left_Cerebral_White_Matter], NULL) ;
16943       label_scales[Left_Cerebral_Cortex] = mean_gm_scale ;
16944       label_offsets[Left_Cerebral_Cortex] = mean_gm_offset ;
16945       computed[Left_Cerebral_Cortex] = 1;
16946       l = Left_Cerebral_Cortex ;
16947       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16948     }
16949     if (computed[Left_Cerebellum_Cortex] == 0)
16950     {
16951       label_scales[Left_Cerebellum_Cortex] = mean_gm_scale ;
16952       label_offsets[Left_Cerebellum_Cortex] = mean_gm_offset ;
16953       computed[Left_Cerebellum_Cortex] = 1;
16954       l = Left_Cerebellum_Cortex ;
16955       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16956       printf("setting left cbm cortex = %2.2f x + %2.2f\n",
16957              mean_gm_scale, mean_gm_offset) ;
16958     }
16959     if (computed[Right_Cerebellum_Cortex] == 0)
16960     {
16961       label_scales[Right_Cerebellum_Cortex] = mean_gm_scale ;
16962       label_offsets[Right_Cerebellum_Cortex] = mean_gm_offset ;
16963       computed[Right_Cerebellum_Cortex] = 1;
16964       l = Right_Cerebellum_Cortex ;
16965       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16966       printf("setting right cbm cortex = %2.2f x + %2.2f\n",
16967              mean_gm_scale, mean_gm_offset) ;
16968     }
16969     if (computed[Right_Cerebral_Cortex] == 0 &&
16970         computed[Right_Cerebral_White_Matter] != 0)
16971     {
16972       if (m_by_label[Right_Cerebral_White_Matter])
16973         m_by_label[Right_Cerebral_Cortex] =
16974           MatrixCopy(m_by_label[Right_Cerebral_White_Matter], NULL) ;
16975       label_scales[Right_Cerebral_Cortex] = mean_gm_scale ;
16976       label_offsets[Right_Cerebral_Cortex] = mean_gm_offset ;
16977       l = Right_Cerebral_Cortex ;
16978       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16979       computed[Right_Cerebral_Cortex] = 1;
16980     }
16981 
16982     // lock some labels scaling to others that have been estimated
16983     if (computed[Left_Caudate])
16984     {
16985       label_offsets[Left_Accumbens_area] = label_offsets[Left_Caudate] ;
16986       label_scales[Left_Accumbens_area] = label_scales[Left_Caudate] ;
16987       l = Left_Accumbens_area ;
16988       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16989       computed[Left_Accumbens_area] = 1;
16990     }
16991     if (computed[Right_Caudate])
16992     {
16993       label_offsets[Right_Accumbens_area] = label_offsets[Right_Caudate] ;
16994       label_scales[Right_Accumbens_area] = label_scales[Right_Caudate] ;
16995       l = Right_Accumbens_area ;
16996       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
16997       computed[Right_Accumbens_area] = 1;
16998     }
16999     if (computed[Left_Inf_Lat_Vent] == 0 && computed[Left_Hippocampus] != 0)
17000     {
17001       label_scales[Left_Inf_Lat_Vent] = label_scales[Left_Hippocampus] ;
17002       label_offsets[Left_Inf_Lat_Vent] = label_offsets[Left_Hippocampus] ;
17003       l = Left_Inf_Lat_Vent ;
17004       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
17005       computed[Left_Inf_Lat_Vent] = 1 ;
17006     }
17007     if (computed[Right_Inf_Lat_Vent] == 0 &&
17008         computed[Right_Hippocampus] != 0)
17009     {
17010       label_scales[Right_Inf_Lat_Vent] = label_scales[Right_Hippocampus] ;
17011       label_offsets[Right_Inf_Lat_Vent] =
17012         label_offsets[Right_Hippocampus] ;
17013       l = Right_Inf_Lat_Vent ;
17014       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
17015       computed[Right_Inf_Lat_Vent] = 1 ;
17016     }
17017 
17018     label_scales[CSF] = mean_csf_scale ;
17019     label_scales[Fifth_Ventricle] = mean_csf_scale ;
17020     label_offsets[CSF] = mean_csf_offset ;
17021     label_offsets[Fifth_Ventricle] = mean_csf_offset ;
17022     computed[CSF] = computed[Fifth_Ventricle] = 1 ;
17023     l = CSF ;
17024     label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
17025     l = Fifth_Ventricle ;
17026     label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
17027 
17028     //set the scale and offset for the rest; added by xhan
17029     for (l = 0 ; l < MAX_CMA_LABELS ; l++)
17030     {
17031       if (l == Gdiag_no)
17032         DiagBreak() ;
17033       if (computed[l] > 0)
17034         continue;
17035       if (equiv_class[l] == 1)
17036       {
17037         label_scales[l] = mean_csf_scale;
17038         label_offsets[l] = mean_csf_offset;
17039         computed[l] = 1 ;
17040       }
17041       else if (equiv_class[l] == 2)
17042       {
17043         label_scales[l] = mean_wm_scale;
17044         label_offsets[l] = mean_wm_offset;
17045         computed[l] = 1 ;
17046       }
17047       else if (equiv_class[l] == 3)
17048       {
17049         label_scales[l] = mean_gm_scale;
17050         label_offsets[l] = mean_gm_offset;
17051         computed[l] = 1 ;
17052       }
17053       label_peaks[l] = label_peaks[l] * label_scales[l] + label_offsets[l];
17054     }
17055 
17056     // make sure labels are self-consistent
17057     for (l = 0 ; l < MAX_CMA_LABELS ; l++)
17058     {
17059       double peak, scale ;
17060       switch (l)
17061       {
17062       case Left_Pallidum:
17063       case Right_Pallidum:
17064 #if 1
17065         if ((label_peaks[l] >= .95*label_peaks[Left_Cerebral_White_Matter]) ||
17066             (label_peaks[l] >= .95*label_peaks[Right_Cerebral_White_Matter]))
17067         {
17068           // don't let pallidum be as bright as wm
17069           peak = 0.95 *
17070                  (label_peaks[Left_Cerebral_White_Matter] +
17071                   label_peaks[Right_Cerebral_White_Matter])/2 ;
17072           scale = peak / label_peaks[l] ;
17073           printf("%s too bright - rescaling by %2.3f "
17074                  "(from %2.3f) to %2.1f (was %2.1f)\n",
17075                  cma_label_to_name(l),
17076                  scale, label_scales[l], peak, label_peaks[l]) ;
17077           label_scales[l] = scale ;
17078           label_peaks[l] = peak ;
17079         }
17080 #endif
17081         break ;
17082       case Left_Putamen:
17083       case Right_Putamen:
17084         if ((label_peaks[l] >= .9*label_peaks[Left_Cerebral_White_Matter]) ||
17085             (label_peaks[l] >= .9*label_peaks[Right_Cerebral_White_Matter]))
17086         {
17087           // don't let putamen be as bright as wm
17088           peak = 0.9 *
17089                  (label_peaks[Left_Cerebral_White_Matter] +
17090                   label_peaks[Right_Cerebral_White_Matter])/2 ;
17091           scale = peak / label_peaks[l] ;
17092           printf("%s too bright - rescaling by %2.3f "
17093                  "(from %2.3f) to %2.1f (was %2.1f)\n",
17094                  cma_label_to_name(l),
17095                  scale, label_scales[l], peak, label_peaks[l]) ;
17096           label_scales[l] = scale ;
17097           label_peaks[l] = peak ;
17098         }
17099         break ;
17100       }
17101     }
17102 
17103     // now use precomputed eigenstructure of intensity 
17104     // volumes to adjust corrections
17105 #if 0
17106     {
17107 #define NUM_EIG 5
17108       MATRIX *m_eig ;
17109       VECTOR *v_dot, *v_obs, *v_obs_estimated, *v_dot_T ;
17110       int     r, c, c2, num_eig = NUM_EIG ;
17111 
17112       m_eig = MatrixAlloc(NUM_INT_EIG_LABELS, num_eig, MATRIX_REAL) ;
17113       v_obs = RVectorAlloc(NUM_INT_EIG_LABELS, MATRIX_REAL) ;
17114       for (r = 0 ; r < NUM_INT_EIG_LABELS ; r++)
17115       {
17116         for (c2 = 1, c = NUM_INT_EIG_LABELS-num_eig ; 
17117              c < NUM_INT_EIG_LABELS ; 
17118              c++, c2++)
17119         {
17120           *MATRIX_RELT(m_eig, r+1, c2) = intensity_eig_vectors[r][c] ;
17121         }
17122       }
17123 
17124       for (r = 1 ; r <= NUM_INT_EIG_LABELS ; r++)
17125       {
17126         RVECTOR_ELT(v_obs, r) = 
17127           label_peaks[intensity_eig_labels[r-1]] - intensity_means[r-1] ;
17128       }
17129       v_dot = MatrixMultiply(v_obs, m_eig, NULL) ;
17130       v_dot_T = VectorTranspose(v_dot, NULL) ;
17131       v_obs_estimated = MatrixMultiply(m_eig, v_dot_T, NULL) ;
17132       for (c = 1 ; c <= NUM_INT_EIG_LABELS ; c++)
17133       {
17134         float old_peak, new_peak ;
17135         l = intensity_eig_labels[c-1] ;
17136         old_peak = label_peaks[l] ;
17137         new_peak = intensity_means[c-1] + VECTOR_ELT(v_obs_estimated,c) ;
17138         printf("EIG %s = changing peak from %2.0f to %2.0f, "
17139                "scale from %2.3f to %2.3f\n",
17140                cma_label_to_name(l), old_peak, new_peak, 
17141                label_scales[l], label_scales[l]*new_peak/old_peak) ;
17142         if (logfp)
17143           fprintf(logfp, "EIG %s = changing peak from %2.0f to %2.0f, "
17144                   "scale from %2.3f to %2.3f\n",
17145                   cma_label_to_name(l), old_peak, new_peak, 
17146                   label_scales[l], label_scales[l]*new_peak/old_peak) ;
17147         label_scales[l] *= (new_peak/old_peak) ;
17148         label_peaks[l] = new_peak ;
17149       }
17150 
17151       MatrixFree(&m_eig) ;
17152       VectorFree(&v_dot) ;
17153       VectorFree(&v_obs) ;
17154       VectorFree(&v_obs_estimated) ;
17155       VectorFree(&v_dot_T) ;
17156     }
17157 #endif
17158 
17159     if (logfp)
17160     {
17161       for (l = 0 ; l < MAX_CMA_LABELS ; l++)
17162         if (computed[l] != 0)
17163           fprintf(logfp, "label %s: scaling by %2.2f  + %2.1f to %2.0f\n",
17164                   cma_label_to_name(l),
17165                   label_scales[l], label_offsets[l], label_peaks[l]) ;
17166       fflush(logfp) ;
17167     }
17168     if (DIAG_VERBOSE_ON)
17169     {
17170       FILE *fp ;
17171       fp = fopen("norm_offset.plt", "w") ;
17172       for (l = 0 ; l < MAX_CMA_LABELS ; l++)
17173         if (computed[l] != 0)
17174           fprintf(fp, "%d %f %f\n", l, label_scales[l], label_offsets[l]) ;
17175       fclose(fp) ;
17176     }
17177 
17178 
17179     gcaCheck(gca) ;
17180     for (xn = 0 ; xn < gca->node_width ; xn++)
17181     {
17182       double     means_before[MAX_GCA_LABELS], \
17183       means_after[MAX_GCA_LABELS], scales[MAX_GCA_LABELS];
17184 #if 1
17185       double     delta_i, delta_j ;
17186       int        xp, yp, zp ;
17187 #endif
17188       int        labels[MAX_GCA_LABELS], niter ;
17189       LABEL_PROB ranks_before[MAX_GCA_LABELS], \
17190       ranks_after[MAX_GCA_LABELS] ;
17191 
17192       for (yn = 0 ; yn < gca->node_height ; yn++)
17193       {
17194         for (zn = 0 ; zn < gca->node_depth ; zn++)
17195         {
17196           if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
17197             DiagBreak() ;
17198           gcan = &gca->nodes[xn][yn][zn] ;
17199           if (gcan->nlabels <= 0)
17200             continue ;
17201 
17202           for (i = 0 ; i < gcan->nlabels ; i++)
17203           {
17204             gc = &gcan->gcs[i] ;
17205             l = gcan->labels[i] ;
17206             labels[i] = l ;
17207             scales[i] = label_scales[l] ;
17208             means_before[i] = gc->means[frame] ;
17209             ranks_before[i].label = l ;
17210             ranks_before[i].prob = means_before[i] ;
17211             ranks_before[i].index = i ;
17212           }
17213           qsort(ranks_before, gcan->nlabels,
17214                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
17215           niter = 0 ;
17216           for (i = 0 ; i < gcan->nlabels ; i++)
17217           {
17218             gc = &gcan->gcs[i] ;
17219             l = gcan->labels[i] ;
17220             means_after[i] =
17221               means_before[i]*label_scales[l] + label_offsets[l] ;
17222             if (means_after[i] < 0)
17223               means_after[i] = 0 ;
17224             ranks_after[i].label = l ;
17225             ranks_after[i].prob = means_after[i] ;
17226             ranks_after[i].index = i ;
17227           }
17228           qsort(ranks_after, gcan->nlabels,
17229                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
17230           for (i = 0 ; i < gcan->nlabels ; i++)
17231           {
17232 #if 1
17233             if (ranks_before[i].label != ranks_after[i].label)
17234             {
17235               double    pi, pj, lambda ;
17236               int       j, ind_j, ind_i ;
17237               GCA_PRIOR *gcap;
17238 
17239               /* two have swapped position - put them */
17240               /* back in the right order */
17241               for (j = 0 ; j < gcan->nlabels ; j++)
17242                 if (ranks_after[j].label == ranks_before[i].label)
17243                   break ;
17244               if (j >= gcan->nlabels)
17245               {
17246                 DiagBreak() ;
17247                 continue ;
17248               }
17249               gcaNodeToPrior(gca, xn, yn, zn, &xp, &yp, &zp) ;
17250               gcap = &gca->priors[xp][yp][zp] ;
17251               pi = getPrior(gcap, ranks_after[i].label) ;
17252               pj = getPrior(gcap, ranks_after[j].label) ;
17253               if (FZERO(pi) && FZERO(pj))
17254                 break ;   // both labels will never happen
17255               lambda = pi / (pi + pj) ;
17256               ind_j = ranks_after[j].index ;
17257               ind_i = ranks_after[i].index ;
17258               delta_j = (means_after[ind_j] -
17259                          means_after[ind_i]) * lambda ;
17260               delta_i = (means_after[ind_i] -
17261                          means_after[ind_j]) * (1-lambda) ;
17262 
17263               if ((fabs(delta_j) < 1) && (fabs(delta_i) < 1))
17264               {
17265                 // this will move one mean to the
17266                 // other side of the other
17267                 if ((fabs(delta_j) > fabs(delta_i)) &&
17268                     !FZERO(delta_j))
17269                   delta_j /= fabs(delta_j) ;  // make it +-1
17270                 else if (!FZERO(delta_i))
17271                   delta_i /= fabs(delta_i) ;  // make it +-1
17272               }
17273               if (!finite(delta_i) || !finite(delta_j))
17274               {
17275                 DiagBreak() ;
17276                 break ;
17277               }
17278               ranks_after[j].prob =
17279                 means_after[ind_j] = means_after[ind_j] - delta_j ;
17280               ranks_after[i].prob =
17281                 means_after[ind_i] = means_after[ind_i] - delta_i ;
17282               if ((xn == Gx && yn == Gy && zn == Gz) &&
17283                   (ranks_after[i].label == gcan->labels[i] ||
17284                    ranks_after[j].label == gcan->labels[j] ||
17285                    Ggca_label < 0))
17286               {
17287                 printf("ordering of labels %s and %s changed, "
17288                        "modifying means by %2.0f (%2.1f) "
17289                        "and %2.0f (%2.1f)\n",
17290                        cma_label_to_name(ranks_after[i].label),
17291                        cma_label_to_name(ranks_after[j].label),
17292                        means_after[i], delta_i,
17293                        means_after[j], delta_i) ;
17294               }
17295 
17296               qsort(ranks_after, gcan->nlabels,
17297                     sizeof(LABEL_PROB),
17298                     compare_sort_probabilities) ;
17299               i = -1 ;   /* start loop over */
17300               if (niter++ > 9)
17301               {
17302                 DiagBreak() ;
17303                 break ;
17304               }
17305               continue ;
17306             }
17307 #endif
17308           }
17309 
17310           for (i = 0 ; i < gcan->nlabels ; i++)
17311           {
17312             if (FZERO(label_scales[gcan->labels[i]]))
17313               continue ;
17314             gc = &gcan->gcs[i] ;
17315             if ((xn == Gx && yn == Gy && zn == Gz) &&
17316                 (Ggca_label == gcan->labels[i] || Ggca_label < 0))
17317             {
17318               printf("scaling gc for label %s at "
17319                      "(%d, %d, %d) from %2.1f to %2.1f\n",
17320                      cma_label_to_name(gcan->labels[i]),
17321                      xn, yn, zn,
17322                      means_before[i], means_after[i]) ;
17323               DiagBreak() ;
17324             }
17325             gc->means[frame] = means_after[i] ;
17326             check_finite("after rescaling", gc->means[frame]) ;
17327           }
17328         }
17329       }
17330     }
17331     gcaCheck(gca) ;
17332   }
17333 
17334   if (plta)  // return linear transform array to caller
17335   {
17336     int i ;
17337 
17338     // count # of xforms
17339     for (i = l = 0 ; l < MAX_CMA_LABELS ; l++)
17340     {
17341       if (m_by_label[l] != NULL && computed[l] == 2)
17342         i++ ;
17343     }
17344 
17345     if (i > 0)  // should always be true
17346     {
17347       *plta = lta = LTAalloc(i, mri) ;
17348       for (i = l = 0 ; l < MAX_CMA_LABELS ; l++)
17349       {
17350         if (m_by_label[l] != NULL && computed[l] == 2)
17351         {
17352           MatrixCopy(m_by_label[l], lta->xforms[i].m_L) ;
17353           MatrixFree(&m_by_label[l]) ;
17354           lta->xforms[i].label = l ;
17355           i++ ;
17356         }
17357       }
17358     }
17359     printf("%d transforms computed\n", i) ;
17360   }
17361 
17362   if (mri_seg)
17363     MRIfree(&mri_seg) ;
17364   return(NO_ERROR) ;
17365 }
17366 
17367 
17368 static float pthresh = 0.5 ;
17369 int
17370 GCAmapRenormalize(GCA *gca, MRI *mri, TRANSFORM *transform)
17371 {
17372   HISTOGRAM *h, *hsmooth ;
17373   int       l, xp, yp, zp, nbins, i, x, y, z,
17374   xn, yn, zn, num, frame, bin ;
17375   float     fmin, fmax, prior, label_scales[MAX_CMA_LABELS],
17376   label_modes[MAX_CMA_LABELS],
17377   modes[MAX_GCA_INPUTS],std, peak, smooth_peak ;
17378   Real      val/*, scale*/ ;
17379   GCA_PRIOR *gcap ;
17380   GCA_NODE  *gcan ;
17381   GC1D      *gc ;
17382   MATRIX    *m_cov ;
17383   MRI       *mri_fsamples = NULL ;   // diag volume
17384 
17385   /* for each class, build a histogram of values
17386      (weighted by priors) to determine
17387      p(I|u,c) p(c).
17388   */
17389 
17390 
17391 #if 0
17392   if (gca->ninputs > 1)
17393     ErrorReturn(ERROR_UNSUPPORTED,
17394                 (ERROR_UNSUPPORTED,
17395                  "GCAmapRenormalize: not implemented for ninputs > 1")) ;
17396 #endif
17397 
17398   for (frame = 0 ; frame < mri->nframes ; frame++)
17399   {
17400     printf("renormalizing input #%d\n", frame) ;
17401     MRIvalRangeFrame(mri, &fmin, &fmax, frame) ;
17402     nbins = 256 ;
17403     h = HISTOalloc(nbins) ;
17404 
17405     hsmooth = HISTOcopy(h, NULL) ;
17406     for (l = 0 ; l <= MAX_CMA_LABELS ; l++)  /* don't do Unknown class */
17407     {
17408       label_scales[l] = 1 ;  /* mark it as unusable */
17409       GCAlabelMode(gca, l, modes) ;
17410       m_cov = GCAlabelCovariance(gca, l, NULL) ;
17411       if (m_cov == NULL)
17412         continue ;
17413       std = 4*sqrt(*MATRIX_RELT(m_cov, frame+1,frame+1)) ;
17414       MatrixFree(&m_cov) ;
17415       label_modes[l] = modes[frame] ;
17416       if (IS_UNKNOWN(l) || IS_INF_LAT_VENT(l))
17417         continue ;
17418 
17419       printf("%s (%d): mode = %2.2f +- %2.1f\n",
17420              cma_label_to_name(l), l, label_modes[l], std) ;
17421       if (l == Gdiag_no)
17422       {
17423         mri_fsamples = MRIclone(mri, NULL) ;
17424         DiagBreak() ;
17425       }
17426       if (FZERO(label_modes[l]))
17427         continue ;
17428       HISTOclear(h, h) ;
17429       h->bin_size = (fmax-fmin)/255.0 ;
17430       if (h->bin_size < 1 && (mri->type == MRI_UCHAR
17431                               || mri->type == MRI_SHORT))
17432         h->bin_size = 1 ;
17433       for (i = 0 ; i < nbins ; i++)
17434         h->bins[i] = (i+1)*h->bin_size ;
17435 
17436       for (num = xp = 0 ; xp < gca->prior_width ; xp++)
17437       {
17438         for (yp = 0 ; yp < gca->prior_height ; yp++)
17439         {
17440           for (zp = 0 ; zp < gca->prior_depth ; zp++)
17441           {
17442             if (xp == Gxp && yp == Gyp && zp == Gzp)
17443               DiagBreak() ;
17444             gcap = &gca->priors[xp][yp][zp] ;
17445             if (gcap==NULL)
17446               continue;
17447             prior = getPrior(gcap, l) ;
17448             if (prior < pthresh)
17449               continue ;
17450             if (!GCApriorToSourceVoxel(gca, mri,
17451                                        transform,
17452                                        xp, yp, zp,
17453                                        &x, &y, &z))
17454             {
17455               MRIsampleVolumeFrame(mri, x, y, z, frame, &val) ;
17456               if (FZERO(val))  // skull stripped
17457                 continue ;
17458               bin = nint((val - fmin)/h->bin_size) ;
17459               if (bin >= h->nbins)
17460                 bin = h->nbins-1 ;
17461               else if (bin < 0)
17462                 bin = 0 ;
17463 
17464               h->counts[bin] += prior ;
17465               num++ ;
17466               if (mri_fsamples != NULL)
17467                 MRIsetVoxVal(mri_fsamples, x, y, z, 0, 128) ;
17468             }
17469           }
17470         }
17471       }
17472       if (num <= 50)  /* not enough to reliably estimate density */
17473         continue ;
17474       HISTOfillHoles(h) ;
17475       if (l == Gdiag_no)
17476       {
17477         HISTOplot(h, "h.plt") ;
17478         if (mri_fsamples && (Gdiag & DIAG_WRITE))
17479         {
17480           char fname[STRLEN] ;
17481           sprintf(fname, "fsamples%d.mgz", l) ;
17482           printf("writing fsamples for class %s to %s\n",
17483                  cma_label_to_name(l), fname) ;
17484           MRIwrite(mri_fsamples, fname) ;
17485           MRIfree(&mri_fsamples) ;
17486         }
17487         DiagBreak() ;
17488       }
17489       HISTOsmooth(h, hsmooth, 1) ;
17490       if (l == Gdiag_no)
17491       {
17492         HISTOplot(hsmooth, "hs.plt") ;
17493       }
17494       peak = h->bins[HISTOfindHighestPeakInRegion(h, 0, h->nbins)] ;
17495       smooth_peak =
17496         hsmooth->bins[HISTOfindHighestPeakInRegion(hsmooth,
17497                       0, hsmooth->nbins)] ;
17498 
17499       label_scales[l] = (float)smooth_peak / label_modes[l] ;
17500       printf("%s (%d): peak at %2.2f, smooth at %2.2f (%d voxels), "
17501              "scaling by %2.2f\n",
17502              cma_label_to_name(l), l, peak, smooth_peak, num,
17503              label_scales[l]) ;
17504       bin = nint((modes[frame] - fmin)/hsmooth->bin_size) ;
17505 #ifdef WSIZE
17506 #undef WSIZE
17507 #endif
17508 #define WSIZE 11
17509 #define WHALF ((WSIZE-1)/2)
17510       bin = HISTOfindCurrentPeak(hsmooth, bin, WSIZE, .2) ;
17511       smooth_peak = hsmooth->bins[bin] ;
17512       if (bin < 0 || smooth_peak <= 0)
17513         continue ;
17514       if (num < 200 && hsmooth->counts[bin] < 5)
17515         /* not very much data - check more */
17516       {
17517         int other_bin ;
17518         other_bin = HISTOfindPreviousPeak(hsmooth, bin, WHALF) ;
17519         if (other_bin >= 0)
17520         {
17521           if ((hsmooth->counts[other_bin] / hsmooth->counts[bin])
17522               > 0.9)
17523           {
17524             printf("!!!!!!!!!additional peak detected "
17525                    "at %2.1f (was %2.1f) - unreliable estimate...\n",
17526                    hsmooth->bins[other_bin], hsmooth->bins[bin]) ;
17527             label_scales[l] = 1.0 ;
17528             continue ;
17529           }
17530         }
17531         other_bin = HISTOfindNextPeak(hsmooth, bin, WHALF) ;
17532         if (other_bin >= 0)
17533         {
17534           if (hsmooth->counts[other_bin] / hsmooth->counts[bin] > 0.9)
17535           {
17536             printf("!!!!!!!!!additional peak detected "
17537                    "at %2.1f (was %2.1f) - unreliable estimate...\n",
17538                    hsmooth->bins[other_bin], hsmooth->bins[bin]) ;
17539             label_scales[l] = 1.0 ;
17540             continue ;
17541           }
17542         }
17543       }
17544       label_scales[l] = (float)smooth_peak / label_modes[l] ;
17545       if ((label_scales[l] < 0.5 || label_scales[l] > 1.5) &&
17546           !IS_LAT_VENT(l))
17547       {
17548         printf("!!!!!!! rejecting excessive scaling %2.2f\n",
17549                label_scales[l]) ;
17550         label_scales[l] = 1.0 ;
17551       }
17552       printf("%s (%d): AFTER PRIOR: peak at %2.2f, smooth "
17553              "at %2.2f (%d voxels), scaling by %2.2f\n",
17554              cma_label_to_name(l), l, peak, smooth_peak, num,
17555              label_scales[l]) ;
17556 
17557       if (l == Gdiag_no)
17558         DiagBreak() ;
17559       if (l >100)
17560         break ;
17561     }
17562 
17563     l = Left_Inf_Lat_Vent ;
17564     label_scales[Left_Inf_Lat_Vent] =
17565       (.25+.75*label_scales[Left_Lateral_Ventricle]);
17566     printf("%s (%d): scaling by %2.2f = %2.1f "
17567            "(based on %2.2f for lateral ventricle)\n",
17568            cma_label_to_name(l), l, label_scales[Left_Inf_Lat_Vent],
17569            label_modes[Left_Inf_Lat_Vent]*label_scales[Left_Inf_Lat_Vent],
17570            label_scales[Left_Lateral_Ventricle]) ;
17571     l = Right_Inf_Lat_Vent ;
17572     label_scales[Right_Inf_Lat_Vent] =
17573       (.25+.75*label_scales[Right_Lateral_Ventricle]) ;
17574     printf("%s (%d): scaling by %2.2f = %2.1f "
17575            "(based on %2.2f for lateral ventricle)\n",
17576            cma_label_to_name(l), l, label_scales[Right_Inf_Lat_Vent],
17577            label_modes[Right_Inf_Lat_Vent]*label_scales[Right_Inf_Lat_Vent],
17578            label_scales[Right_Lateral_Ventricle]) ;
17579 
17580 
17581     for (xn = 0 ; xn < gca->node_width ; xn++)
17582     {
17583       double     means_before[MAX_GCA_LABELS], \
17584       means_after[MAX_GCA_LABELS], scales[MAX_GCA_LABELS] ;
17585       int        labels[MAX_GCA_LABELS], niter ;
17586       LABEL_PROB ranks_before[MAX_GCA_LABELS], \
17587       ranks_after[MAX_GCA_LABELS] ;
17588 
17589       for (yn = 0 ; yn < gca->node_height ; yn++)
17590       {
17591         for (zn = 0 ; zn < gca->node_depth ; zn++)
17592         {
17593           if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
17594             DiagBreak() ;
17595           gcan = &gca->nodes[xn][yn][zn] ;
17596           if (gcan->nlabels <= 0)
17597             continue ;
17598 
17599           for (i = 0 ; i < gcan->nlabels ; i++)
17600           {
17601             gc = &gcan->gcs[i] ;
17602             l = gcan->labels[i] ;
17603             labels[i] = l ;
17604             scales[i] = label_scales[l] ;
17605             means_before[i] = gc->means[frame] ;
17606             ranks_before[i].label = l ;
17607             ranks_before[i].prob = means_before[i] ;
17608             ranks_before[i].index = i ;
17609           }
17610           qsort(ranks_before, gcan->nlabels,
17611                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
17612           niter = 0 ;
17613           for (i = 0 ; i < gcan->nlabels ; i++)
17614           {
17615             gc = &gcan->gcs[i] ;
17616             l = gcan->labels[i] ;
17617             means_after[i] = means_before[i]*scales[i] ;
17618             ranks_after[i].label = l ;
17619             ranks_after[i].prob = means_after[i] ;
17620             ranks_after[i].index = i ;
17621           }
17622           qsort(ranks_after, gcan->nlabels,
17623                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
17624           for (i = 0 ; i < gcan->nlabels ; i++)
17625           {
17626             if (ranks_before[i].label != ranks_after[i].label)
17627             {
17628 #if 1
17629               double    pi, pj, lambda, delta_i, delta_j ;
17630               int       j, ind_j, ind_i ;
17631               GCA_PRIOR *gcap;
17632 
17633               /* two have swapped position - put them */
17634               /* back in the right order */
17635               for (j = 0 ; j < gcan->nlabels ; j++)
17636                 if (ranks_after[j].label == ranks_before[i].label)
17637                   break ;
17638               if (j >= gcan->nlabels)
17639               {
17640                 DiagBreak() ;
17641                 continue ;
17642               }
17643               gcaNodeToPrior(gca, xn, yn, zn, &xp, &yp, &zp) ;
17644               gcap = &gca->priors[xp][yp][zp] ;
17645               pi = getPrior(gcap, ranks_after[i].label) ;
17646               pj = getPrior(gcap, ranks_after[j].label) ;
17647               if (FZERO(pi) && FZERO(pj))
17648                 break ;   // both labels will never happen
17649               lambda = pi / (pi + pj) ;
17650               ind_j = ranks_after[j].index ;
17651               ind_i = ranks_after[i].index ;
17652               delta_j =
17653                 (means_after[ind_j] - means_after[ind_i]) *
17654                 lambda ;
17655               delta_i = (means_after[ind_i] - means_after[ind_j]) *
17656                         (1-lambda) ;
17657 
17658               if ((fabs(delta_j) < 1) && (fabs(delta_i) < 1))
17659               {
17660                 // this will move one mean to the
17661                 // other side of the other
17662                 if ((fabs(delta_j) > fabs(delta_i)) &&
17663                     !FZERO(delta_j))
17664                   delta_j /= fabs(delta_j) ;  // make it +-1
17665                 else if (!FZERO(delta_i))
17666                   delta_i /= fabs(delta_i) ;  // make it +-1
17667               }
17668               if (!finite(delta_i) || !finite(delta_j))
17669               {
17670                 DiagBreak() ;
17671                 break ;
17672               }
17673               ranks_after[j].prob =
17674                 means_after[ind_j] = means_after[ind_j] - delta_j ;
17675               ranks_after[i].prob =
17676                 means_after[ind_i] = means_after[ind_i] - delta_i ;
17677               if ((xn == Gx && yn == Gy && zn == Gz) &&
17678                   (ranks_after[i].label == gcan->labels[i] ||
17679                    ranks_after[j].label == gcan->labels[j] ||
17680                    Ggca_label < 0))
17681               {
17682                 printf("ordering of labels %s and %s changed, "
17683                        "modifying means by %2.0f (%2.1f) "
17684                        "and %2.0f (%2.1f)\n",
17685                        cma_label_to_name(ranks_after[i].label),
17686                        cma_label_to_name(ranks_after[j].label),
17687                        means_after[i], delta_i,
17688                        means_after[j], delta_i) ;
17689               }
17690 
17691 #else
17692               double diff, avg ;
17693               int    j ;
17694 
17695               /* two have swapped position - put them */
17696               /* back in the right order */
17697               for (j = 0 ; j < gcan->nlabels ; j++)
17698                 if (ranks_after[j].label == ranks_before[i].label)
17699                   break ;
17700               diff = means_before[ranks_after[i].index] -
17701                      means_before[ranks_before[i].index];
17702               avg = (means_after[ranks_after[i].index] +
17703                      means_after[ranks_before[i].index]) / 2 ;
17704               ranks_after[i].prob =
17705                 means_after[ranks_after[i].index] =
17706                   avg+diff/4 ;
17707               ranks_after[j].prob =
17708                 means_after[ranks_after[j].index] =
17709                   avg-diff/4 ;
17710 #endif
17711               qsort(ranks_after, gcan->nlabels,
17712                     sizeof(LABEL_PROB),
17713                     compare_sort_probabilities) ;
17714               i = -1 ;   /* start loop over */
17715               if (niter++ > 9)
17716               {
17717                 DiagBreak() ;
17718                 break ;
17719               }
17720               continue ;
17721             }
17722           }
17723 
17724           for (i = 0 ; i < gcan->nlabels ; i++)
17725           {
17726             if (FZERO(label_scales[gcan->labels[i]]))
17727               continue ;
17728             gc = &gcan->gcs[i] ;
17729             if ((xn == Ggca_x && yn == Ggca_y && zn == Ggca_z) &&
17730                 (Ggca_label == gcan->labels[i] || Ggca_label < 0))
17731             {
17732               printf("scaling gc for label %s at "
17733                      "(%d, %d, %d) from %2.1f to %2.1f\n",
17734                      cma_label_to_name(gcan->labels[i]),
17735                      xn, yn, zn,
17736                      means_before[i], means_after[i]) ;
17737               DiagBreak() ;
17738             }
17739             gc->means[frame] = means_after[i] ;
17740           }
17741         }
17742       }
17743     }
17744   }
17745 
17746   return(NO_ERROR) ;
17747 }
17748 
17749 
17750 
17751 int
17752 GCAmapRenormalizeByClass(GCA *gca, MRI *mri, TRANSFORM *transform)
17753 {
17754   HISTOGRAM *h, *hsmooth ;
17755   int       l, nbins, i, x, y, z, max_p_label,
17756   xn, yn, zn, num, frame, bin, n, label, c, max_label ;
17757   float     fmin, fmax, prior, label_scales[MAX_CMA_LABELS],
17758   class_modes[NTISSUE_CLASSES], class_scales[NTISSUE_CLASSES],
17759   modes[MAX_GCA_INPUTS], peak, smooth_peak ;
17760   Real      val ;
17761   float     vals[MAX_GCA_INPUTS] ;
17762   GCA_PRIOR *gcap ;
17763   GCA_NODE  *gcan ;
17764   GC1D      *gc ;
17765   double    p, max_p ;
17766 
17767   /* for each class, build a histogram of values
17768      (weighted by priors) to determine
17769      p(I|u,c) p(c).
17770   */
17771 
17772   max_label = GCAmaxLabel(gca) ;
17773 
17774 #if 0
17775   if (gca->ninputs > 1)
17776     ErrorReturn(ERROR_UNSUPPORTED,
17777                 (ERROR_UNSUPPORTED,
17778                  "GCAmapRenormalize: not implemented for ninputs > 1")) ;
17779 #endif
17780 
17781   for (frame = 0 ; frame < mri->nframes ; frame++)
17782   {
17783     printf("renormalizing input #%d\n", frame) ;
17784     MRIvalRangeFrame(mri, &fmin, &fmax, frame) ;
17785     nbins = 256 ;
17786     h = HISTOalloc(nbins) ;
17787 
17788     hsmooth = HISTOcopy(h, NULL) ;
17789     for (c = 0 ;  c < NTISSUE_CLASSES ; c++)  /* don't do Unknown class */
17790     {
17791       class_scales[c] = 1 ;  /* mark it as unusable */
17792       GCAclassMode(gca, c, modes) ;
17793       class_modes[c] = modes[frame] ;
17794       printf("%s (%d): mode = %2.2f\n",
17795              c == CSF_CLASS ? "CSF" : c == GM_CLASS ? "GM" : "WM",
17796              c, class_modes[c]) ;
17797       if (c == Gdiag_no)
17798         DiagBreak() ;
17799       if (FZERO(class_modes[c]))
17800         continue ;
17801       HISTOclear(h, h) ;
17802       h->bin_size = (fmax-fmin)/255.0 ;
17803       if (h->bin_size < 1 && (mri->type == MRI_UCHAR
17804                               || mri->type == MRI_SHORT))
17805         h->bin_size = 1 ;
17806       for (i = 0 ; i < nbins ; i++)
17807         h->bins[i] = (i+1)*h->bin_size ;
17808 
17809       for (num = x = 0 ; x < mri->width ; x++)
17810       {
17811         for (y = 0 ; y < mri->height ; y++)
17812         {
17813           for (z = 0 ; z < mri->depth ; z++)
17814           {
17815             if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
17816               DiagBreak() ;
17817             if (GCAsourceVoxelToNode(gca, mri,
17818                                      transform, x, y, z,
17819                                      &xn, &yn, &zn) != NO_ERROR)
17820               continue ;
17821             gcan = &gca->nodes[xn][yn][zn] ;
17822             gcap = getGCAP(gca, mri, transform, x, y, z) ;
17823             if (gcap==NULL || gcan == NULL)
17824               continue;
17825             if (gcan->nlabels == 1 && IS_UNKNOWN(gcan->labels[0]))
17826               continue ;
17827             load_vals(mri, x, y, z, vals, gca->ninputs);
17828             val = vals[frame] ;
17829             if (FZERO(val))  // skull stripped
17830               continue ;
17831 
17832 
17833             // find class with highest posterior likilihood
17834             max_p = GCAcomputePosteriorDensity
17835                     (gcap, gcan, 0, vals, gca->ninputs) ;
17836             max_p_label = gcan->labels[0] ;
17837 
17838             for (n = 1 ; n < gcan->nlabels ; n++)
17839             {
17840               label = gcan->labels[n] ;
17841 
17842               p = GCAcomputePosteriorDensity(gcap, gcan, n, vals,
17843                                              gca->ninputs) ;
17844               if (p > max_p)
17845               {
17846                 max_p = p ;
17847                 max_p_label = gcan->labels[n] ;
17848               }
17849             }
17850 
17851             if (IS_CLASS(max_p_label,c) == 0)
17852               // a label in a different class
17853               continue ;
17854             prior = getPrior(gcap, max_p_label) ;
17855             if (prior < pthresh)
17856               continue ;
17857 
17858             bin = nint((val - fmin)/h->bin_size) ;
17859             if (bin >= h->nbins)
17860               bin = h->nbins-1 ;
17861             else if (bin < 0)
17862               bin = 0 ;
17863 
17864             h->counts[bin] += prior ;
17865             num++ ;
17866           }
17867         }
17868       }
17869       if (num <= 50)  /* not enough to reliably estimate density */
17870         continue ;
17871       HISTOfillHoles(h) ;
17872       if (c == Gdiag_no)
17873       {
17874         HISTOplot(h, "h.plt") ;
17875         DiagBreak() ;
17876       }
17877       HISTOsmooth(h, hsmooth, 1) ;
17878       if (c == Gdiag_no)
17879       {
17880         HISTOplot(hsmooth, "hs.plt") ;
17881       }
17882       peak = h->bins[HISTOfindHighestPeakInRegion(h, 0, h->nbins)] ;
17883       smooth_peak =
17884         hsmooth->bins[HISTOfindHighestPeakInRegion(hsmooth,
17885                       0, hsmooth->nbins)] ;
17886 
17887       class_scales[c] = (float)smooth_peak / class_modes[c] ;
17888       printf("%s (%d): peak at %2.2f, smooth at %2.2f (%d voxels), "
17889              "scaling by %2.2f\n",
17890              c == CSF_CLASS ? "CSF" : c == GM_CLASS ? "GM" : "WM",
17891              c, peak, smooth_peak, num, class_scales[c]) ;
17892 #if 0
17893       bin = nint((modes[frame] - fmin)/hsmooth->bin_size) ;
17894 #ifdef WSIZE
17895 #undef WSIZE
17896 #endif
17897 #define WSIZE 11
17898 #define WHALF ((WSIZE-1)/2)
17899       bin = HISTOfindCurrentPeak(hsmooth, bin, WSIZE, .2) ;
17900       smooth_peak = hsmooth->bins[bin] ;
17901       if (bin < 0 || smooth_peak <= 0)
17902         continue ;
17903       if (num < 200 && hsmooth->counts[bin] < 5)
17904         /* not very much data - check more */
17905       {
17906         int other_bin ;
17907         other_bin = HISTOfindPreviousPeak(hsmooth, bin, WHALF) ;
17908         if (other_bin >= 0)
17909         {
17910           if ((hsmooth->counts[other_bin] / hsmooth->counts[bin])
17911               > 0.9)
17912           {
17913             printf("!!!!!!!!!additional peak detected "
17914                    "at %2.1f (was %2.1f) - unreliable estimate...\n",
17915                    hsmooth->bins[other_bin], hsmooth->bins[bin]) ;
17916             class_scales[c] = 1.0 ;
17917             continue ;
17918           }
17919         }
17920         other_bin = HISTOfindNextPeak(hsmooth, bin, WHALF) ;
17921         if (other_bin >= 0)
17922         {
17923           if (hsmooth->counts[other_bin] / hsmooth->counts[bin] > 0.9)
17924           {
17925             printf("!!!!!!!!!additional peak detected "
17926                    "at %2.1f (was %2.1f) - unreliable estimate...\n",
17927                    hsmooth->bins[other_bin], hsmooth->bins[bin]) ;
17928             class_scales[c] = 1.0 ;
17929             continue ;
17930           }
17931         }
17932       }
17933       class_scales[c] = (float)smooth_peak / class_modes[c] ;
17934       printf("%s (%d): AFTER PRIOR: peak at %2.2f, smooth "
17935              "at %2.2f (%d voxels), scaling by %2.2f\n",
17936              c == CSF_CLASS ? "CSF" : c == GM_CLASS ? "GM" : "WM",
17937              c, peak, smooth_peak, num,
17938              class_scales[c]) ;
17939 #endif
17940       if (c == Gdiag_no)
17941         DiagBreak() ;
17942     }
17943 
17944     for (l = 0 ; l <= max_label ; l++)
17945     {
17946       GCAlabelMode(gca, l, modes) ;
17947       if (FZERO(modes[frame]))  // no real data
17948       {
17949         label_scales[l] = 1.0 ;
17950         continue ;
17951       }
17952 
17953       // computed from manually labeled images
17954       //(gray matter coef, wm is 1-l)
17955 #define L_THALAMUS  0.6
17956 #define L_PALLIDUM  0.6
17957 #define L_PUTAMEN   0.8
17958 #define L_VENTRALDC 0.2      // mostly white
17959 
17960       if (IS_GRAY_CLASS(l))
17961         label_scales[l] = class_scales[GM_CLASS] ;
17962       else if (IS_CSF_CLASS(l))
17963         label_scales[l] = class_scales[CSF_CLASS] ;
17964       else if (IS_WHITE_CLASS(l))
17965         label_scales[l] = class_scales[WM_CLASS] ;
17966       else
17967         switch (l)
17968         {
17969         case Right_VentralDC:
17970         case Left_VentralDC:
17971           label_scales[l] =
17972             L_VENTRALDC*class_scales[GM_CLASS] +
17973             (1-L_VENTRALDC)*class_scales[WM_CLASS];
17974           break ;
17975         case Left_Thalamus:
17976         case Right_Thalamus:
17977         case Left_Thalamus_Proper:
17978         case Right_Thalamus_Proper:
17979           //      GCAlabelMean(gca, Left_Thalamus, means) ;
17980           //      GCAlabelMean(gca, Right_Thalamus, rmeans) ;
17981           //      means[frame] = (means[frame] + rmeans[frame]) / 2 ;
17982           label_scales[l] =
17983             L_THALAMUS*class_scales[GM_CLASS] +
17984             (1-L_THALAMUS)*class_scales[WM_CLASS];
17985           break ;
17986         case Left_Pallidum:
17987         case Right_Pallidum:
17988           label_scales[l] =
17989             L_PALLIDUM*class_scales[GM_CLASS] +
17990             (1-L_PALLIDUM)*class_scales[WM_CLASS];
17991           break ;
17992         case Left_Putamen:
17993         case Right_Putamen:
17994           label_scales[l] =
17995             (L_PUTAMEN)*class_scales[GM_CLASS] +
17996             (1-L_PUTAMEN)*class_scales[WM_CLASS];
17997           break ;
17998         case Left_Inf_Lat_Vent:  // just CSF
17999         case Right_Inf_Lat_Vent:
18000           label_scales[l] = class_scales[CSF_CLASS] ;
18001           break ;
18002         case Left_Hippocampus:   // just GM
18003         case Right_Hippocampus:
18004         case Left_Amygdala:
18005         case Right_Amygdala:
18006         case Left_Accumbens_area:
18007         case Right_Accumbens_area:
18008         case Left_Cerebellum_Cortex:
18009         case Left_Cerebellum_Exterior:
18010         case Right_Cerebellum_Cortex:
18011         case Right_Cerebellum_Exterior:
18012         case Right_Cerebral_Exterior:
18013         case Left_Cerebral_Exterior:
18014           label_scales[l] = class_scales[GM_CLASS] ;
18015           break ;
18016         case Right_Cerebellum_White_Matter:  // just WM
18017         case Left_Cerebellum_White_Matter:
18018         case Brain_Stem:
18019           label_scales[l] = class_scales[WM_CLASS] ;
18020           break ;
18021         default:
18022           label_scales[l] = 1.0 ;
18023         }
18024       printf("%s (%d): scaling by %2.2f = %2.1f (was %2.1f)\n",
18025              cma_label_to_name(l), l,
18026              label_scales[l], modes[frame]*label_scales[l], modes[frame]) ;
18027 
18028     }
18029 
18030     for (xn = 0 ; xn < gca->node_width ; xn++)
18031     {
18032       double     means_before[MAX_GCA_LABELS], \
18033       means_after[MAX_GCA_LABELS], scales[MAX_GCA_LABELS] ;
18034       int        labels[MAX_GCA_LABELS], niter ;
18035       LABEL_PROB ranks_before[MAX_GCA_LABELS], \
18036       ranks_after[MAX_GCA_LABELS] ;
18037 
18038       for (yn = 0 ; yn < gca->node_height ; yn++)
18039       {
18040         for (zn = 0 ; zn < gca->node_depth ; zn++)
18041         {
18042           if (xn == Ggca_x && yn == Ggca_y && zn == Ggca_z)
18043             DiagBreak() ;
18044           gcan = &gca->nodes[xn][yn][zn] ;
18045           if (gcan->nlabels <= 0)
18046             continue ;
18047 
18048           for (i = 0 ; i < gcan->nlabels ; i++)
18049           {
18050             gc = &gcan->gcs[i] ;
18051             l = gcan->labels[i] ;
18052             labels[i] = l ;
18053             scales[i] = label_scales[l] ;
18054             means_before[i] = gc->means[frame] ;
18055             ranks_before[i].label = l ;
18056             ranks_before[i].prob = means_before[i] ;
18057             ranks_before[i].index = i ;
18058           }
18059           qsort(ranks_before, gcan->nlabels,
18060                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
18061           niter = 0 ;
18062           for (i = 0 ; i < gcan->nlabels ; i++)
18063           {
18064             gc = &gcan->gcs[i] ;
18065             l = gcan->labels[i] ;
18066             means_after[i] = means_before[i]*scales[i] ;
18067             ranks_after[i].label = l ;
18068             ranks_after[i].prob = means_after[i] ;
18069             ranks_after[i].index = i ;
18070           }
18071           qsort(ranks_after, gcan->nlabels,
18072                 sizeof(LABEL_PROB), compare_sort_probabilities) ;
18073           for (i = 0 ; i < gcan->nlabels ; i++)
18074           {
18075             if (ranks_before[i].label != ranks_after[i].label)
18076             {
18077               double diff, avg ;
18078               int    j ;
18079 
18080               /* two have swapped position - put them */
18081               /* back in the right order */
18082               for (j = 0 ; j < gcan->nlabels ; j++)
18083                 if (ranks_after[j].label == ranks_before[i].label)
18084                   break ;
18085               diff = means_before[ranks_after[i].index] -
18086                      means_before[ranks_before[i].index];
18087               avg = (means_after[ranks_after[i].index] +
18088                      means_after[ranks_before[i].index]) / 2 ;
18089               ranks_after[i].prob =
18090                 means_after[ranks_after[i].index] =
18091                   avg+diff/4 ;
18092               ranks_after[j].prob =
18093                 means_after[ranks_after[j].index] =
18094                   avg-diff/4 ;
18095               qsort(ranks_after, gcan->nlabels,
18096                     sizeof(LABEL_PROB),
18097                     compare_sort_probabilities) ;
18098               i = -1 ;   /* start loop over */
18099               if (niter++ > 9)
18100               {
18101                 DiagBreak() ;
18102                 break ;
18103               }
18104               continue ;
18105             }
18106           }
18107 
18108           for (i = 0 ; i < gcan->nlabels ; i++)
18109           {
18110             if (FZERO(label_scales[gcan->labels[i]]))
18111               continue ;
18112             gc = &gcan->gcs[i] ;
18113             if ((xn == Ggca_x && yn == Ggca_y && zn == Ggca_z) &&
18114                 (Ggca_label == gcan->labels[i] || Ggca_label < 0))
18115             {
18116               printf("scaling gc for label %s at "
18117                      "(%d, %d, %d) from %2.1f to %2.1f\n",
18118                      cma_label_to_name(gcan->labels[i]),
18119                      xn, yn, zn,
18120                      means_before[i], means_after[i]) ;
18121               DiagBreak() ;
18122             }
18123             gc->means[frame] = means_after[i] ;
18124           }
18125         }
18126       }
18127     }
18128   }
18129 
18130   return(NO_ERROR) ;
18131 }
18132 
18133 
18134 
18135 #define NLABELS 4
18136 
18137 static int labels[NLABELS] =
18138   {
18139     Dura, Bone, SC_FAT_MUSCLE, CSF_SA
18140   } ;
18141 MRI *
18142 GCArelabelNonbrain(GCA *gca,
18143                    MRI *mri_inputs,
18144                    MRI *mri_src,
18145                    MRI *mri_dst,
18146                    TRANSFORM *transform)
18147 {
18148   int       x, y, z, xn, yn, zn, width, height, depth, label,
18149   i, total_changed = 0, n, nchanged ;
18150   int      max_i = 0;
18151   GC1D      *gcs[NLABELS] ;
18152   double    pvals[NLABELS], max_p ;
18153   GCA_NODE  *gcan ;
18154   float     vals[MAX_GCA_INPUTS],
18155   means[NLABELS][MAX_GCA_INPUTS],
18156   vars[NLABELS][MAX_GCA_INPUTS], dist ;
18157   MRI       *mri_tmp ;
18158 
18159   if (mri_src != mri_dst)
18160     mri_dst = MRIcopy(mri_src, mri_dst) ;
18161 
18162   mri_tmp = MRIcopy(mri_dst, NULL) ;
18163 
18164   width = mri_src->width ;
18165   height = mri_src->height ;
18166   depth = mri_src->depth ;
18167 
18168   for (i = 0 ; i < NLABELS ; i++)
18169     GCAcomputeLabelStats(gca, labels[i], vars[i], means[i]) ;
18170 
18171   /* replace Epidermis with SC_FAT */
18172   for (x = 0 ; x < width ; x++)
18173   {
18174     for (y = 0 ; y < height ; y++)
18175     {
18176       for (z = 0 ; z < depth ; z++)
18177       {
18178         label = nint(MRIgetVoxVal(mri_src, x, y, z, 0)) ;
18179         if (label == Epidermis)
18180           label = SC_FAT_MUSCLE ;
18181         if (label == Cranium)
18182           label = Bone ;
18183         MRIsetVoxVal(mri_src, x, y, z, 0, label) ;
18184         MRIsetVoxVal(mri_tmp, x, y, z, 0, label) ;
18185       }
18186     }
18187   }
18188 
18189   do
18190   {
18191     nchanged = 0 ;
18192     for (x = 0 ; x < width ; x++)
18193     {
18194       for (y = 0 ; y < height ; y++)
18195       {
18196         for (z = 0 ; z < depth ; z++)
18197         {
18198           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18199             DiagBreak() ;
18200 
18201           label = nint(MRIgetVoxVal(mri_tmp, x, y, z, 0)) ;
18202 
18203           if (label == SC_FAT_MUSCLE)
18204             /* check to see whether at borders of skull */
18205           {
18206             if (MRIneighborsInWindow(mri_src, x, y, z, 3, Unknown)
18207                 > 1)
18208               continue ;
18209           }
18210 
18211           if (label != Dura &&
18212               label != Bone &&
18213               label != SC_FAT_MUSCLE &&
18214               label != CSF_SA)
18215             continue ;
18216           if (MRIneighborsInWindow(mri_src, x, y, z, 3, label) >= 24)
18217             continue ;   /* in the body of the label - ignore */
18218           if (MRIneighborsInWindow(mri_src, x, y, z, 5, label) >= 100)
18219             continue ;   /* in the body of the label - ignore */
18220           load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
18221           if (!GCAsourceVoxelToNode(gca, mri_inputs, transform,
18222                                     x, y, z, &xn, &yn, &zn))
18223           {
18224             gcan = &gca->nodes[xn][yn][zn] ;
18225             max_i = -1 ;
18226             max_p = -1 ;
18227             for (i = 0 ; i < NLABELS ; i++)
18228             {
18229               gcs[i] = GCAfindGC(gca, xn, yn, zn, labels[i]) ;
18230               if (gcs[i] == NULL)
18231                 gcs[i]
18232                 = findGCInWindow(gca, xn, yn, zn, labels[i], 3) ;
18233               if (gcs[i] == NULL)
18234               {
18235                 DiagBreak() ;
18236                 continue ;
18237               }
18238               for (dist = 0, n = 0 ; n < gca->ninputs ; n++)
18239                 dist += SQR(vals[n]-means[i][n]) ;
18240               pvals[i] = exp(-dist) ;
18241               if (pvals[i] >= max_p)
18242               {
18243                 max_p = pvals[i] ;
18244                 max_i = i ;
18245               }
18246             }
18247           }
18248           ///////////////
18249           if ((labels[max_i] == Dura) &&
18250               (MRIneighborsInWindow(mri_tmp, x, y, z, 5, Bone)+
18251                MRIneighborsInWindow(mri_tmp, x, y, z, 5,
18252                                     SC_FAT_MUSCLE)>=120))
18253             continue ;
18254           if (labels[max_i] != label && ((x == Ggca_x && y ==
18255                                           Ggca_y && z == Ggca_z)))
18256           {
18257             printf("GCArelabelNonbrain: changing label at "
18258                    "(%d, %d, %d) from %s (%d) to %s (%d)\n",
18259                    x, y, z, cma_label_to_name(label), label,
18260                    cma_label_to_name(labels[max_i]), labels[max_i]) ;
18261           }
18262           MRIsetVoxVal(mri_tmp, x, y, z, 0, labels[max_i]) ;
18263           if (labels[max_i] != label)
18264             nchanged++ ;
18265         }
18266       }
18267     }
18268     total_changed += nchanged ;
18269     break ;
18270   }
18271   while (nchanged > 0) ;
18272 
18273   /* look for dura between bone and skin -
18274      it is partial volumed of these two */
18275   do
18276   {
18277     nchanged = 0 ;
18278     for (x = 0 ; x < width ; x++)
18279     {
18280       for (y = 0 ; y < height ; y++)
18281       {
18282         for (z = 0 ; z < depth ; z++)
18283         {
18284           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18285             DiagBreak() ;
18286 
18287           label = MRIgetVoxVal(mri_tmp, x, y, z, 0) ;
18288 
18289           if (label != Dura)
18290             continue ;
18291           if (((MRIneighborsInWindow(mri_tmp, x, y, z, 3, Bone) < 7) ||
18292                (MRIneighborsInWindow(mri_tmp, x, y, z, 3,
18293                                      SC_FAT_MUSCLE) < 7)) &&
18294               ((MRIneighborsInWindow(mri_tmp, x, y, z, 5,
18295                                      Bone) < 30) ||
18296                (MRIneighborsInWindow(mri_tmp, x, y, z, 5,
18297                                      SC_FAT_MUSCLE) < 30)))
18298             continue ;
18299           load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
18300           if (!GCAsourceVoxelToNode(gca, mri_inputs,
18301                                     transform, x, y, z, &xn, &yn, &zn))
18302           {
18303             gcan = &gca->nodes[xn][yn][zn] ;
18304             max_i = -1 ;
18305             max_p = -1 ;
18306             for (i = 0 ; i < NLABELS ; i++)
18307             {
18308               if (labels[i] != SC_FAT_MUSCLE && labels[i] != Bone)
18309                 continue ;
18310               gcs[i] = GCAfindGC(gca, xn, yn, zn, labels[i]) ;
18311               if (gcs[i] == NULL)
18312                 gcs[i] = findGCInWindow(gca, xn, yn, zn,
18313                                         labels[i], 3) ;
18314               if (gcs[i] == NULL)
18315               {
18316                 DiagBreak() ;
18317                 continue ;
18318               }
18319               for (dist = 0, n = 0 ; n < gca->ninputs ; n++)
18320                 dist += SQR(vals[n]-means[i][n]) ;
18321               pvals[i] = exp(-dist) ;
18322               if (pvals[i] >= max_p)
18323               {
18324                 max_p = pvals[i] ;
18325                 max_i = i ;
18326               }
18327             }
18328           }
18329           /////////////////////////
18330           if (labels[max_i] != label &&
18331               ((x == Ggca_x && y == Ggca_y && z == Ggca_z)))
18332           {
18333             printf("GCArelabelNonbrain: changing label at "
18334                    "(%d, %d, %d) from %s (%d) to %s (%d)\n",
18335                    x, y, z, cma_label_to_name(label), label,
18336                    cma_label_to_name(labels[max_i]), labels[max_i]) ;
18337           }
18338           MRIsetVoxVal(mri_tmp, x, y, z, 0, labels[max_i]) ;
18339           if (labels[max_i] != label)
18340             nchanged++ ;
18341         }
18342       }
18343     }
18344     total_changed += nchanged ;
18345     printf("%d voxels labeled dura changed to bone or skin...\n", nchanged) ;
18346     if (nchanged < 10)
18347       break ;
18348   }
18349   while (nchanged > 0) ;
18350 
18351   /* change dura and cortex labels that are
18352      in the middle of tons of SC_FAT to SC_FAT */
18353   do
18354   {
18355     nchanged = 0 ;
18356     for (x = 0 ; x < width ; x++)
18357     {
18358       for (y = 0 ; y < height ; y++)
18359       {
18360         for (z = 0 ; z < depth ; z++)
18361         {
18362           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18363             DiagBreak() ;
18364 
18365           label = nint(MRIgetVoxVal(mri_tmp, x, y, z, 0)) ;
18366 
18367           if (label != Dura && !IS_CORTEX(label))
18368             continue ;
18369           if (MRIneighborsInWindow(mri_tmp, x, y, z,
18370                                    5, SC_FAT_MUSCLE) < 100)
18371             continue ;
18372           label = SC_FAT_MUSCLE ;
18373           if ((label != nint(MRIgetVoxVal(mri_tmp, x, y, z, 0))) &&
18374               ((x == Ggca_x && y == Ggca_y && z == Ggca_z)))
18375           {
18376             printf("GCArelabelNonbrain: changing label at "
18377                    "(%d, %d, %d) from %s (%d) to %s (%d)\n",
18378                    x, y, z,
18379                    cma_label_to_name(nint(MRIgetVoxVal(mri_tmp,x,y,z,0))),
18380                    nint(MRIgetVoxVal(mri_tmp,x,y,z,0)),
18381                    cma_label_to_name(label), label) ;
18382           }
18383           if (label != nint(MRIgetVoxVal(mri_tmp, x, y, z, 0)))
18384             nchanged++ ;
18385           MRIsetVoxVal(mri_tmp, x, y, z, 0, label) ;
18386         }
18387       }
18388     }
18389     total_changed += nchanged ;
18390     printf("%d voxels labeled dura and/or cortex changed to skin...\n",
18391            nchanged) ;
18392     if (nchanged < 10)
18393       break ;
18394   }
18395   while (nchanged > 0) ;
18396 
18397   MRIcopy(mri_tmp, mri_dst) ;
18398   MRIfree(&mri_tmp) ;
18399 
18400   printf("%d voxels changed in MRIrelabelNonbrain\n", total_changed) ;
18401   return(mri_dst) ;
18402 }
18403 
18404 
18405 
18406 int
18407 GCAreplaceLabels(GCA *gca, int in_label, int out_label)
18408 {
18409   int       x, y, z, n ;
18410   GCA_NODE  *gcan ;
18411   GCA_PRIOR *gcap ;
18412 
18413   for (x = 0 ; x < gca->node_width ; x++)
18414   {
18415     for (y = 0 ; y < gca->node_height ; y++)
18416     {
18417       for (z = 0 ; z < gca->node_depth ; z++)
18418       {
18419         gcan = &gca->nodes[x][y][z] ;
18420         for (n = 0 ; n < gcan->nlabels ; n++)
18421           if (gcan->labels[n] == in_label)
18422             gcan->labels[n] = out_label ;
18423       }
18424     }
18425   }
18426 
18427   for (x = 0 ; x < gca->prior_width ; x++)
18428   {
18429     for (y = 0 ; y < gca->prior_height ; y++)
18430     {
18431       for (z = 0 ; z < gca->prior_depth ; z++)
18432       {
18433         gcap = &gca->priors[x][y][z] ;
18434         if (gcap==NULL)
18435           continue;
18436         for (n = 0 ; n < gcap->nlabels ; n++)
18437           if (gcap->labels[n] == in_label)
18438             gcap->labels[n] = out_label ;
18439       }
18440     }
18441   }
18442 
18443   return(NO_ERROR) ;
18444 }
18445 
18446 
18447 int
18448 GCAreplaceRightWithLeft(GCA *gca)
18449 {
18450   GCAreplaceLabels(gca, Right_Cerebral_Exterior, Left_Cerebral_Exterior) ;
18451   GCAreplaceLabels(gca, Right_Cerebral_White_Matter,
18452                    Left_Cerebral_White_Matter) ;
18453   GCAreplaceLabels(gca, Right_Cerebral_Cortex, Left_Cerebral_Cortex) ;
18454   GCAreplaceLabels(gca, Right_Lateral_Ventricle, Left_Lateral_Ventricle) ;
18455   GCAreplaceLabels(gca, Right_Inf_Lat_Vent, Left_Inf_Lat_Vent) ;
18456   GCAreplaceLabels(gca, Right_Cerebellum_Exterior, Left_Cerebellum_Exterior) ;
18457   GCAreplaceLabels(gca, Right_Cerebellum_White_Matter,
18458                    Left_Cerebellum_White_Matter) ;
18459   GCAreplaceLabels(gca, Right_Cerebellum_Cortex, Left_Cerebellum_Cortex) ;
18460   GCAreplaceLabels(gca, Right_Thalamus, Left_Thalamus) ;
18461   GCAreplaceLabels(gca, Right_Thalamus_Proper, Left_Thalamus_Proper) ;
18462   GCAreplaceLabels(gca, Right_Caudate, Left_Caudate) ;
18463   GCAreplaceLabels(gca, Right_Putamen, Left_Putamen) ;
18464   GCAreplaceLabels(gca, Right_Pallidum, Left_Pallidum) ;
18465   GCAreplaceLabels(gca, Right_Hippocampus, Left_Hippocampus) ;
18466   GCAreplaceLabels(gca, Right_Amygdala, Left_Amygdala) ;
18467   GCAreplaceLabels(gca, Right_Insula, Left_Insula) ;
18468   GCAreplaceLabels(gca, Right_Operculum, Left_Operculum) ;
18469   GCAreplaceLabels(gca, Right_Lesion, Left_Lesion) ;
18470   GCAreplaceLabels(gca, Right_Accumbens_area, Left_Accumbens_area) ;
18471   GCAreplaceLabels(gca, Right_Substancia_Nigra, Left_Substancia_Nigra) ;
18472   GCAreplaceLabels(gca, Right_VentralDC, Left_VentralDC) ;
18473   GCAreplaceLabels(gca, Right_undetermined, Left_undetermined) ;
18474   return(NO_ERROR) ;
18475 }
18476 
18477 
18478 
18479 GCA_NODE *
18480 GCAbuildRegionalGCAN(GCA *gca, int xn, int yn, int zn, int wsize)
18481 {
18482   GCA_NODE *gcan, *gcan_nbr ;
18483   GCA_PRIOR *gcap ;
18484   int      n, xi, yi, zi, xk, yk, zk, nlabels = 0, whalf,
18485       xp, yp, zp, label, total_training[MAX_CMA_LABELS+1],
18486       used[MAX_CMA_LABELS+1] ;
18487   float    label_priors[MAX_CMA_LABEL+1], p ;
18488   MATRIX   *m_cov[MAX_CMA_LABEL+1], *m_tmp = NULL ;
18489   VECTOR   *v_means[MAX_CMA_LABEL+1], *v_tmp = NULL ;
18490 
18491   gcan = calloc(1, sizeof(GCA_NODE)) ;
18492 
18493   memset(label_priors, 0, sizeof(label_priors)) ;
18494   memset(total_training, 0, sizeof(total_training)) ;
18495   memset(used, 0, sizeof(used)) ;
18496   nlabels = 0 ;
18497   whalf = (wsize-1)/2 ;
18498   for (xk = -whalf ; xk <= whalf ; xk++)
18499   {
18500     xi = xn + xk ;
18501     if (xi < 0 || xi >= gca->node_width)
18502       continue ;
18503     for (yk = -whalf ; yk <= whalf ; yk++)
18504     {
18505       yi = yn + yk ;
18506       if (yi < 0 || yi >= gca->node_height)
18507         continue ;
18508       for (zk = -whalf ; zk <= whalf ; zk++)
18509       {
18510         zi = zn + zk ;
18511         if (zi < 0 || zi >= gca->node_depth)
18512           continue ;
18513         gcan_nbr = &gca->nodes[xi][yi][zi] ;
18514         if (gcaNodeToPrior(gca, xi, yi, zi, &xp, &yp, &zp) != NO_ERROR)
18515           continue ;
18516         gcap = &gca->priors[xp][yp][zp] ;
18517         for (n = 0 ; n < gcan_nbr->nlabels ; n++)
18518         {
18519           label = gcan_nbr->labels[n] ;
18520           if (used[label] == 0)  /* first time for this label */
18521           {
18522             used[label] = 1 ;
18523             m_cov[label] =
18524               load_covariance_matrix(&gcan_nbr->gcs[n],
18525                                      NULL, gca->ninputs) ;
18526             v_means[label] =
18527               load_mean_vector(&gcan_nbr->gcs[n],
18528                                NULL, gca->ninputs) ;
18529             MatrixClear(m_cov[label]) ;
18530             MatrixClear(v_means[label]) ;
18531             nlabels++ ;
18532           }
18533           total_training[label] += gcan_nbr->gcs[n].ntraining ;
18534           p = getPrior(gcap, label) ;
18535           label_priors[label] += p ;
18536 
18537           m_tmp =
18538             load_covariance_matrix(&gcan_nbr->gcs[n],
18539                                    m_tmp, gca->ninputs) ;
18540           MatrixScalarMul(m_tmp, p, m_tmp) ;
18541           MatrixAdd(m_tmp, m_cov[label], m_cov[label]) ;
18542 
18543           v_tmp = load_mean_vector(&gcan_nbr->gcs[n],
18544                                    v_tmp, gca->ninputs) ;
18545           MatrixScalarMul(v_tmp, p, v_tmp) ;
18546           MatrixAdd(v_tmp, v_means[label], v_means[label]) ;
18547         }
18548         gcan->total_training += gcan_nbr->total_training ;
18549       }
18550     }
18551   }
18552 
18553   gcan->nlabels = gcan->max_labels = nlabels ;
18554   gcan->gcs = alloc_gcs(nlabels, GCA_NO_MRF, gca->ninputs) ;
18555   gcan->labels = (unsigned short *)calloc(nlabels, sizeof(unsigned short)) ;
18556 
18557   for (nlabels = 0, n = 0 ; n <= MAX_CMA_LABELS ; n++)
18558   {
18559     if (used[n] > 0)
18560     {
18561       gcan->labels[nlabels] = n ;
18562       MatrixScalarMul(m_cov[n], 1.0/label_priors[n], m_cov[n]) ;
18563       MatrixScalarMul(v_means[n], 1.0/label_priors[n], v_means[n]) ;
18564       set_mean_vector(&gcan->gcs[nlabels], v_means[n], gca->ninputs) ;
18565       set_covariance_matrix(&gcan->gcs[nlabels], m_cov[n], gca->ninputs) ;
18566       MatrixFree(&m_cov[n]) ;
18567       VectorFree(&v_means[n]) ;
18568       gcan->gcs[nlabels].ntraining = total_training[n] ;
18569       nlabels++ ;
18570     }
18571   }
18572 
18573   MatrixFree(&m_tmp) ;
18574   VectorFree(&v_tmp) ;
18575   return(gcan) ;
18576 }
18577 
18578 
18579 int
18580 GCAfreeRegionalGCAN(GCA_NODE **pgcan)
18581 {
18582   GCA_NODE *gcan ;
18583 
18584   gcan = *pgcan ;
18585   *pgcan = NULL ;
18586   free_gcs(gcan->gcs, GCA_NO_MRF, gcan->nlabels) ;
18587   free(gcan->labels) ;
18588   free(gcan) ;
18589   return(NO_ERROR) ;
18590 }
18591 
18592 
18593 
18594 GCA *GCAcompactify(GCA *gca)
18595 {
18596   int width, height, depth;
18597   GCA_PRIOR *gcap = 0;
18598   GCA_NODE  *gcan = 0;
18599   float *old_priors;
18600   unsigned short *old_labels;
18601   GC1D *old_gcs;
18602   int n, nmax;
18603   int i,j, k;
18604   double byteSaved = 0.;
18605 
18606   width = gca->prior_width;
18607   height = gca->prior_height;
18608   depth = gca->prior_depth;
18609 
18610   for (k = 0; k < depth; ++k)
18611     for (j= 0; j < height; ++j)
18612       for (i=0; i < width; ++i)
18613       {
18614         gcap = &gca->priors[i][j][k];
18615         // typedef struct
18616         // {
18617         //   short nlabels ;
18618         //   short max_labels ;        modify
18619         //   unsigned short  *labels ;  modify
18620         //   float *priors ;           modify
18621         //   int   total_training ;
18622         // } GCA_PRIOR ;
18623         //
18624         if (gcap)
18625         {
18626           n= gcap->nlabels;
18627           nmax = gcap->max_labels;
18628           if (n < nmax)
18629           {
18630             // printf("prior has more than needed (%d,%d,%d)
18631             // nlabels=%d, max_labels=%d\n", i,j,k, n, nmax);
18632             old_priors = gcap->priors;
18633             old_labels = gcap->labels;
18634             gcap->priors = (float *) calloc(n, sizeof(float));
18635             if (!gcap->priors)
18636               ErrorExit(ERROR_NOMEMORY,
18637                         "GCANupdatePriors: couldn't expand priors to %d",
18638                         gcap->max_labels) ;
18639             gcap->labels =
18640               (unsigned short *)calloc(n, sizeof(unsigned short)) ;
18641             if (!gcap->labels)
18642               ErrorExit(ERROR_NOMEMORY,
18643                         "GCANupdatePriors: couldn't expand labels to %d",
18644                         gcap->max_labels) ;
18645             /* copy the old ones over */
18646             memmove(gcap->priors, old_priors, n*sizeof(float)) ;
18647             memmove(gcap->labels, old_labels, n*sizeof(unsigned short)) ;
18648 
18649             /* free the old ones */
18650             free(old_priors) ;
18651             free(old_labels) ;
18652             gcap->max_labels = gcap->nlabels;
18653 
18654             byteSaved += (sizeof(float)+sizeof(unsigned short))*(nmax-n);
18655           }
18656         }
18657       }
18658 
18659   width = gca->node_width;
18660   height = gca->node_height;
18661   depth = gca->node_depth;
18662   for (k = 0; k < depth; ++k)
18663     for (j= 0; j < height; ++j)
18664       for (i=0; i < width; ++i)
18665       {
18666         gcan = &gca->nodes[i][j][k];
18667         if (gcan)
18668         {
18669           n= gcan->nlabels;
18670           nmax = gcan->max_labels;
18671           if (n < nmax)
18672           {
18673             // printf("node has more than needed (%d,%d,%d) "
18674             // "nlabels=%d, max_labels=%d\n", i,j,k, n, nmax);
18675             // typedef struct
18676             // {
18677             // int  nlabels ;
18678             // int  max_labels ;         modify
18679             // unsigned short *labels ;   modify
18680             // GC1D *gcs ;               modify
18681             // int  total_training ;
18682             /* total # of times this node was was accessed */
18683             // } GCA_NODE ;
18684             old_labels = gcan->labels;
18685             old_gcs = gcan->gcs;
18686             // only allocate what is needed
18687             gcan->gcs = alloc_gcs(n, gca->flags, gca->ninputs) ;
18688             if (!gcan->gcs)
18689               ErrorExit(ERROR_NOMEMORY,
18690                         "GCANupdateNode: couldn't expand gcs to %d",
18691                         gcan->max_labels) ;
18692             // only allocate what is needed
18693             gcan->labels =
18694               (unsigned short *)calloc(n, sizeof(unsigned short)) ;
18695             if (!gcan->labels)
18696               ErrorExit(ERROR_NOMEMORY,
18697                         "GCANupdateNode: couldn't expand labels to %d",
18698                         gcan->max_labels) ;
18699             copy_gcs(n, old_gcs, gcan->gcs, gca->ninputs);
18700             memmove(gcan->labels, old_labels, n*sizeof(unsigned short)) ;
18701 
18702             /* free the old ones */
18703             free(old_gcs) ;
18704             free(old_labels) ;
18705             gcan->max_labels = n;
18706             byteSaved += (sizeof(float)+sizeof(unsigned short))*(nmax-n);
18707           }
18708         }
18709       }
18710 
18711   if (DIAG_VERBOSE_ON)
18712     printf("GCAcompactify reduced the memory use by %.f bytes.\n", byteSaved);
18713 
18714   return gca;
18715 }
18716 
18717 
18718 MRI *
18719 GCAreplaceImpossibleLabels(MRI *mri_inputs, GCA *gca,
18720                            MRI *mri_in_labels, MRI *mri_out_labels,
18721                            TRANSFORM *transform)
18722 {
18723   int       x, y, z, width, height, depth, label,
18724   xn, yn, zn, n, found, nchanged ;
18725   GCA_NODE  *gcan ;
18726   GCA_PRIOR *gcap ;
18727   float      max_p, p, vals[MAX_GCA_INPUTS] ;
18728 
18729   mri_out_labels = MRIcopy(mri_in_labels, mri_out_labels) ;
18730 
18731   width = mri_inputs->width ;
18732   height = mri_inputs->height;
18733   depth = mri_inputs->depth ;
18734   for (nchanged = x = 0 ; x < width ; x++)
18735   {
18736     for (y = 0 ; y < height ; y++)
18737     {
18738       for (z = 0 ; z < depth ; z++)
18739       {
18740         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18741           DiagBreak() ;
18742         label = nint(MRIgetVoxVal(mri_out_labels, x, y, z,0)) ;
18743         if (!GCAsourceVoxelToNode(gca, mri_inputs,
18744                                   transform, x, y, z, &xn, &yn, &zn))
18745         {
18746           gcan = &gca->nodes[xn][yn][zn] ;
18747           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
18748           if (gcap==NULL)
18749             continue;
18750           for (found = n = 0 ; n < gcap->nlabels ; n++)
18751           {
18752             if (gcap->labels[n] == label)
18753             {
18754               found = 1 ;
18755               break ;
18756             }
18757           }
18758           if (found)
18759             continue ;
18760           load_vals(mri_inputs, x, y, z, vals, gca->ninputs);
18761           nchanged++ ;
18762           max_p =
18763             GCAcomputePosteriorDensity(gcap, gcan, 0,
18764                                        vals, gca->ninputs) ;
18765           label = gcap->labels[0] ;
18766           for (n = 1 ; n < gcap->nlabels ; n++)
18767           {
18768             p = GCAcomputePosteriorDensity(gcap, gcan, n,
18769                                            vals, gca->ninputs) ;
18770             if (p >= max_p)
18771             {
18772               max_p = p ;
18773               label = gcap->labels[n] ;
18774             }
18775           }
18776           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18777             printf("changing label at (%d, %d, %d) from %s (%d) to %s (%d)\n",
18778                    x, y, z,
18779                    cma_label_to_name(nint(MRIgetVoxVal(mri_out_labels,x,y,z,0))),
18780                    nint(MRIgetVoxVal(mri_out_labels,x,y,z,0)),
18781                    cma_label_to_name(label), label) ;
18782           MRIsetVoxVal(mri_out_labels, x, y, z, 0, label) ;
18783         }
18784       }
18785     }
18786   }
18787 
18788   printf("%d impossible labels replaced...\n", nchanged) ;
18789   return(mri_out_labels) ;
18790 }
18791 
18792 
18793 
18794 double
18795 compute_partial_volume_log_posterior(GCA *gca,
18796                                      GCA_NODE *gcan,
18797                                      GCA_PRIOR *gcap,
18798                                      float *vals, int l1, int l2)
18799 {
18800   GC1D *gc1, *gc2 ;
18801   int  i ;
18802   double p1, p2, p, alpha, u, v, p_alpha, dist ;
18803 
18804   gc1 = gc2 = NULL ;
18805   for (i = 0 ; i < gcan->nlabels ; i++)
18806   {
18807     if (gcan->labels[i] == l1)
18808       gc1 = &gcan->gcs[i] ;
18809     else if (gcan->labels[i] == l2)
18810       gc2 = &gcan->gcs[i] ;
18811   }
18812   if (gc1 == NULL || gc2 == NULL)
18813     return(VERY_UNLIKELY) ;
18814 
18815   p1 = p2 = 0 ;
18816   for (i = 0 ; i < gcap->nlabels ; i++)
18817   {
18818     if (gcap->labels[i] == l1)
18819       p1 = gcap->priors[i] ;
18820     else if (gcap->labels[i] == l2)
18821       p2 = gcap->priors[i] ;
18822 
18823   }
18824 
18825 #define D_ALPHA 0.01
18826   for (p = alpha = 0.0 ; alpha <= 1.0 ; alpha += D_ALPHA)
18827   {
18828     u = alpha*gc1->means[0] + (1-alpha)*gc2->means[0] ;
18829     v = alpha*gc1->covars[0] + (1-alpha)*gc2->covars[0] ;
18830     dist = SQR(u-vals[0]) / v ;
18831     p_alpha = 1.0 / sqrt(v) * exp(-0.5*dist) *
18832               pow(p1,alpha)*pow(p2,1-alpha) ;
18833     p += (p_alpha*D_ALPHA) ;
18834   }
18835   return(log(p)) ;
18836 }
18837 
18838 
18839 static int
18840 gcaRelabelSegment(GCA *gca, TRANSFORM *transform, MRI *mri_inputs,
18841                   MRI *mri_dst, MRI_SEGMENT *mseg)
18842 {
18843   int         i, n, x, y, z, labels[MAX_CMA_LABEL+1],
18844   label, max_label, old_label, debug = 0 ;
18845   double      max_ll, new_ll ;
18846   GCA_PRIOR   *gcap ;
18847 
18848   memset(labels, 0, sizeof(labels)) ;
18849 
18850   /* build a list of all possible labels that could occur within this segment,
18851      and also compute current log likelihood */
18852   for (max_ll = 0.0, old_label = max_label = i = 0 ; i < mseg->nvoxels ; i++)
18853   {
18854     x = mseg->voxels[i].x ;
18855     y = mseg->voxels[i].y ;
18856     z = mseg->voxels[i].z ;
18857     if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18858       debug = 1 ;
18859     max_ll += gcaNbhdGibbsLogLikelihood(gca, mri_dst, mri_inputs,
18860                                         x, y, z, transform, PRIOR_FACTOR) ;
18861 
18862     if (i == 0)
18863       old_label = max_label =
18864                     MRIgetVoxVal(mri_dst, x, y, z, 0) ; // current label
18865     gcap = getGCAP(gca, mri_dst, transform, x, y, z) ;
18866     for (n = 0 ; n < gcap->nlabels ; n++)
18867       labels[gcap->labels[n]]++ ;
18868     /* count # of possible labels in segment */
18869   }
18870 
18871   for (label = 0 ; label <= MAX_CMA_LABEL ; label++)
18872   {
18873     if (labels[label] <= 0)  /* not possible in this nbhd */
18874       continue ;
18875 
18876     /* change all labels to the new one */
18877     for (i = 0 ; i < mseg->nvoxels ; i++)
18878     {
18879       x = mseg->voxels[i].x ;
18880       y = mseg->voxels[i].y ;
18881       z = mseg->voxels[i].z ;
18882       MRIsetVoxVal(mri_dst, x, y, z, 0, label) ;
18883     }
18884     for (new_ll = 0.0, i = 0 ; i < mseg->nvoxels ; i++)
18885     {
18886       x = mseg->voxels[i].x ;
18887       y = mseg->voxels[i].y ;
18888       z = mseg->voxels[i].z ;
18889       new_ll += gcaNbhdGibbsLogLikelihood(gca, mri_dst, mri_inputs,
18890                                           x, y, z, transform,
18891                                           PRIOR_FACTOR) ;
18892     }
18893     if (new_ll > max_ll)
18894     {
18895       max_label = label ;
18896       max_ll = new_ll ;
18897     }
18898   }
18899   if ((old_label != max_label) && (debug || getenv("DEBUG_MRM")))
18900     printf("changing segment at (%2.0f, %2.0f, %2.0f) "
18901            "from %s (%d) to %s (%d)\n",
18902            mseg->cx, mseg->cy, mseg->cz,
18903            cma_label_to_name(old_label), old_label,
18904            cma_label_to_name(max_label), max_label) ;
18905   for (i = 0 ; i < mseg->nvoxels ; i++)
18906   {
18907     x = mseg->voxels[i].x ;
18908     y = mseg->voxels[i].y ;
18909     z = mseg->voxels[i].z ;
18910     MRIsetVoxVal(mri_dst, x, y, z, 0, max_label) ;
18911   }
18912   return(old_label != max_label) ;
18913 }
18914 
18915 
18916 
18917 MRI *
18918 GCAmarkImpossible(GCA *gca,
18919                   MRI *mri_labeled,
18920                   MRI *mri_dst,
18921                   TRANSFORM *transform)
18922 {
18923   int   x, y, z, label ;
18924 
18925   if (mri_dst == NULL)
18926     mri_dst = MRIclone(mri_labeled, NULL) ;
18927   for (x = 0 ; x < mri_labeled->width ; x++)
18928   {
18929     for (y = 0 ; y < mri_labeled->height ; y++)
18930     {
18931       for (z = 0 ; z < mri_labeled->depth ; z++)
18932       {
18933         label = MRIgetVoxVal(mri_labeled, x, y, z, 0) ;
18934         if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
18935           DiagBreak() ;
18936         if (GCAisPossible(gca, mri_labeled,
18937                           label, transform, x, y, z,1) ==0)
18938         {
18939           MRIsetVoxVal(mri_dst, x, y, z, 0, 1) ;
18940         }
18941       }
18942     }
18943   }
18944   return(mri_dst) ;
18945 }
18946 
18947 
18948 int
18949 GCAmaxLabel(GCA *gca)
18950 {
18951   int       x, y, z, max_label, n ;
18952   GCA_PRIOR *gcap ;
18953 
18954   max_label = 0 ;
18955   for (x = 0 ; x < gca->prior_width ; x++)
18956   {
18957     for (y = 0 ; y < gca->prior_height ; y++)
18958     {
18959       for (z = 0 ; z < gca->prior_depth ; z++)
18960       {
18961         gcap = &gca->priors[x][y][z] ;
18962         for (n = 0 ; n < gcap->nlabels ; n++)
18963         {
18964           if (gcap->labels[n] > max_label)
18965             max_label = gcap->labels[n] ;
18966         }
18967       }
18968     }
18969   }
18970   return(max_label) ;
18971 }
18972 
18973 
18974 MRI *
18975 GCAbuildMostLikelyVolumeForStructure(GCA *gca, MRI *mri, int label, int border,
18976                                      TRANSFORM *transform, MRI *mri_labels)
18977 {
18978   int              x,  y, z, xn, yn, zn, width, depth, height, 
18979     n, xp, yp, zp, r ;
18980   GCA_NODE         *gcan ;
18981   GCA_PRIOR        *gcap ;
18982   double           max_prior ;
18983   int              max_label ;
18984   GC1D             *gc_max ;
18985   MRI              *mri_tmp ;
18986   MRI_SEGMENTATION *mriseg ;
18987 
18988   if (!mri)
18989   {
18990     mri = MRIallocSequence(gca->prior_width, gca->prior_height,
18991                            gca->prior_depth, MRI_FLOAT, gca->ninputs) ;
18992     // hey create gca volume and thus copies gca prior values
18993     mri->xsize = gca->xsize*gca->prior_spacing;
18994     mri->ysize = gca->ysize*gca->prior_spacing;
18995     mri->zsize = gca->zsize*gca->prior_spacing;
18996   }
18997   // most likely volume should agree with direction cosines
18998   //  GCAcopyDCToMRI(gca, mri);
18999 
19000   if (mri->nframes != gca->ninputs)
19001     ErrorExit(ERROR_BADPARM, "GCAbuildMostLikelyVolume: mri->frames "
19002               "(%d) does not match gca->ninputs (%d)",
19003               mri->nframes, gca->ninputs) ;
19004 
19005 
19006   // mri is prior if mri = NULL
19007   width = mri->width ;
19008   depth = mri->depth ;
19009   height = mri->height ;
19010   for (z = 0 ; z < depth ; z++)
19011   {
19012     for (y = 0 ; y < height ; y++)
19013     {
19014       for (x = 0 ; x < width ; x++)
19015       {
19016         if (x == Gx && y == Gy && z == Gz)
19017           DiagBreak() ;
19018         // get node value
19019         if (GCAsourceVoxelToNode
19020             (gca, mri, transform, x, y, z, &xn, &yn, &zn) == NO_ERROR)
19021         {
19022           // get prior value
19023           if (GCAsourceVoxelToPrior(gca, mri, transform, x, y, z,
19024                                     &xp, &yp, &zp) == NO_ERROR)
19025           {
19026             gcan = &gca->nodes[xn][yn][zn] ;
19027             gcap = &gca->priors[xp][yp][zp] ;
19028             if (gcap==NULL || gcap->nlabels <= 0)
19029               continue;
19030             // initialize
19031             max_prior = gcap->priors[0] ;
19032             max_label = gcap->labels[0] ;
19033             gc_max = NULL ;
19034             // prior labels
19035             for (n = 1 ; n < gcap->nlabels ; n++)
19036             {
19037               if (gcap->priors[n] >= max_prior)
19038               {
19039                 max_prior = gcap->priors[n] ;
19040                 max_label = gcap->labels[n] ;
19041               }
19042             }
19043             if (max_label != label)
19044             {
19045               if (mri_labels)
19046                 MRIsetVoxVal(mri_labels, x, y, z, 0, 0) ;
19047               for (r = 0 ; r < gca->ninputs ; r++)
19048               {
19049                 MRIsetVoxVal(mri, x, y, z, r, 0) ;
19050               }
19051               continue ;
19052             }
19053             // get max_prior, max_label
19054             // go through node labels
19055             for (n = 0 ; n < gcan->nlabels ; n++)
19056             {
19057               if (gcan->labels[n] == max_label)
19058                 gc_max = &gcan->gcs[n] ;
19059             }
19060 
19061             if (!gc_max)
19062               continue ;
19063             if (mri_labels)
19064               MRIsetVoxVal(mri_labels, x, y, z, 0, label) ;
19065             for (r = 0 ; r < gca->ninputs ; r++)
19066             {
19067               MRIsetVoxVal(mri, x, y, z, r, gc_max->means[r]) ;
19068             }
19069           }
19070           else
19071           {
19072             for (r = 0 ; r < gca->ninputs ; r++)
19073             {
19074               MRIsetVoxVal(mri, x, y, z, r, 0) ;
19075             }
19076           }
19077         }
19078         else
19079         {
19080           for (r = 0 ; r < gca->ninputs ; r++)
19081           {
19082             MRIsetVoxVal(mri, x, y, z, r, 0) ;
19083           }
19084         }
19085       }
19086     }
19087   }
19088 
19089   mriseg = MRIsegment(mri, 1.0, 255.0) ;
19090   if (!mriseg)
19091   {
19092     ErrorPrintf(Gerror,"GCAmostLikelyVolumeForStructure: "
19093                 "label %s segmentation failed", cma_label_to_name(label)) ;
19094   }
19095   else if (mriseg->nsegments > 1)  // use largest segment
19096   {
19097 #if 0
19098     MRI *mri_tmp ;
19099     int index ;
19100 
19101     index = MRIsegmentMax(mriseg) ;
19102 
19103     printf("%d segments detected for structure, using largest (%d vox)\n",
19104            mriseg->nsegments, mriseg->segments[index].nvoxels) ;
19105     if (mri_labels)
19106     {
19107       mri_tmp = MRIsegmentToImage(mri_labels, NULL, mriseg, index) ;
19108       MRIcopy(mri_tmp, mri_labels) ;
19109       MRIfree(&mri_tmp) ;
19110     }
19111     mri_tmp = MRIsegmentToImage(mri, NULL, mriseg, index) ;
19112     MRIcopy(mri_tmp, mri) ;
19113     MRIfree(&mri_tmp) ;
19114 #endif
19115   }
19116   MRIsegmentFree(&mriseg) ;
19117 
19118   // add voxels from labels on the border of this stuct
19119   if (border > 0)
19120   {
19121     mri_tmp = MRIcopy(mri, NULL) ;
19122 
19123     for (z = 0 ; z < depth ; z++)
19124     {
19125       for (y = 0 ; y < height ; y++)
19126       {
19127         for (x = 0 ; x < width ; x++)
19128         {
19129           if (x == Gx && y == Gy && z == Gz)
19130             DiagBreak() ;
19131           if (MRIgetVoxVal(mri, x, y, z, 0) > 0)
19132             continue ;  // already filled in
19133 
19134           if (MRIareNonzeroInNbhd(mri, (2*border)+1, x, y, z) == 0)
19135             continue ;
19136 
19137           // get node value
19138           if (GCAsourceVoxelToNode
19139               (gca, mri, transform,
19140                x, y, z, &xn, &yn, &zn) == NO_ERROR)
19141           {
19142             // get prior value
19143             if (GCAsourceVoxelToPrior(gca, mri, transform, x, y, z,
19144                                       &xp, &yp, &zp) == NO_ERROR)
19145             {
19146               gcan = &gca->nodes[xn][yn][zn] ;
19147               gcap = &gca->priors[xp][yp][zp] ;
19148               if (gcap==NULL || gcap->nlabels <= 0)
19149                 continue;
19150               // initialize
19151               max_prior = gcap->priors[0] ;
19152               max_label = gcap->labels[0] ;
19153               gc_max = NULL ;
19154               // prior labels
19155               for (n = 1 ; n < gcap->nlabels ; n++)
19156               {
19157                 if (gcap->priors[n] >= max_prior)
19158                 {
19159                   max_prior = gcap->priors[n] ;
19160                   max_label = gcap->labels[n] ;
19161                 }
19162               }
19163               // get max_prior, max_label
19164               // go through node labels
19165               for (n = 0 ; n < gcan->nlabels ; n++)
19166               {
19167                 if (gcan->labels[n] == max_label)
19168                   gc_max = &gcan->gcs[n] ;
19169               }
19170 
19171               if (!gc_max || max_prior < .25)
19172                 continue ;
19173               if (mri_labels)
19174                 MRIsetVoxVal(mri_labels, x, y, z, 0, max_label) ;
19175               for (r = 0 ; r < gca->ninputs ; r++)
19176               {
19177                 MRIsetVoxVal
19178                 (mri_tmp, x, y, z, r, gc_max->means[r]) ;
19179               }
19180             }
19181           }
19182         }
19183       }
19184     }
19185 
19186     MRIcopy(mri_tmp, mri) ;
19187     MRIfree(&mri_tmp) ;
19188   }
19189   return(mri) ;
19190 }
19191 
19192 
19193 #if 0
19194 static float
19195 gcaFindCerebellarScaleFactor(GCA *gca,
19196                              HISTOGRAM *h_mri,
19197                              int label, FILE *logfp)
19198 {
19199   HISTOGRAM *h_gca ;
19200   int       xn, yn, zn, n, r ;
19201   GCA_NODE  *gcan ;
19202   GC1D      *gc ;
19203   float     prior ;
19204   int       b, gca_peak1, gca_peak2, mri_peak1, mri_peak2 ;
19205   float     scale, mri_val1, mri_val2, gca_val1, gca_val2 ;
19206 
19207   // build histogram of this label
19208   h_gca = HISTOalloc(256) ;
19209   for (b = 0 ; b < h_gca->nbins ; b++)
19210     h_gca->bins[b] = b ;
19211   for (zn = 0 ; zn < gca->node_depth ; zn++)
19212   {
19213     for (yn = 0 ; yn < gca->node_height ; yn++)
19214     {
19215       for (xn = 0 ; xn < gca->node_width ; xn++)
19216       {
19217         gcan = &gca->nodes[xn][yn][zn] ;
19218         for (n = 0 ; n < gcan->nlabels ; n++)
19219         {
19220           /* find index in lookup table for this label */
19221           if (gcan->labels[n] != label)
19222             continue ;
19223           gc = &gcan->gcs[n] ;
19224           prior = get_node_prior(gca, label, xn, yn, zn) ;
19225           if (prior != 0)
19226           {
19227             for (r = 0 ; r < gca->ninputs ; r++)
19228             {
19229               b = nint(gc->means[r]) ;
19230               h_gca->counts[b] += prior ;
19231               if (!finite(gc->means[r]))
19232                 DiagBreak() ;
19233             }
19234           }
19235         }
19236       }
19237     }
19238   }
19239 
19240   gca_peak1 = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
19241   for (b = gca_peak1-2 ; b <= gca_peak1+2 ; b++)
19242     h_gca->counts[b] = 0 ;
19243   gca_peak2 = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
19244   if (gca_peak1 < gca_peak2)
19245   {
19246     int p ;
19247     p = gca_peak1 ;
19248     gca_peak1 = gca_peak2 ;
19249     gca_peak2 = p ;
19250   }
19251 
19252   mri_peak1 = HISTOfindHighestPeakInRegion(h_mri, 0, h_mri->nbins) ;
19253   for (b = mri_peak1-2 ; b <= mri_peak1+2 ; b++)
19254     h_mri->counts[b] = 0 ;
19255   mri_peak2 = HISTOfindHighestPeakInRegion(h_mri, 0, h_mri->nbins) ;
19256   if (mri_peak1 < mri_peak2)
19257   {
19258     int p ;
19259     p = mri_peak1 ;
19260     mri_peak1 = mri_peak2 ;
19261     mri_peak2 = p ;
19262   }
19263 
19264   gca_val1 = h_gca->bins[gca_peak1] ;
19265   gca_val2 = h_gca->bins[gca_peak2] ;
19266 
19267   mri_val1 = h_mri->bins[mri_peak1] ;
19268   mri_val2 = h_mri->bins[mri_peak2] ;
19269 
19270   scale = (mri_val1/gca_val1 + mri_val2/gca_val2)/2 ;
19271 
19272   if (Gdiag & DIAG_SHOW)
19273     printf("%s (%d): peaks at %2.2f, %2.2f (%2.1f, %2.1f) "
19274            "scaling by %2.2f\n",
19275            cma_label_to_name(label), label, mri_val1, mri_val2,
19276            gca_val1, gca_val2, scale) ;
19277   if (logfp)
19278   {
19279     fprintf(logfp, "%s (%d): peaks at %2.2f, %2.2f (%2.1f, %2.1f) "
19280             "scaling by %2.2f\n",
19281             cma_label_to_name(label), label, mri_val1, mri_val2,
19282             gca_val1, gca_val2, scale) ;
19283     fflush(logfp) ;
19284   }
19285 
19286   return(scale) ;
19287 }
19288 
19289 
19290 static HISTOGRAM *
19291 gcaComputeHistogramNormalization(GCA *gca, HISTOGRAM *h_mri, int label)
19292 {
19293   HISTOGRAM *h_gca, *h_gca_eq, *h_mri_eq, *h_norm ;
19294 
19295   h_gca = gcaGetLabelHistogram(gca, label, 0) ;
19296   h_norm = HISTOcomposeInvert(h_gca, h_mri, NULL) ;
19297   HISTOfree(&h_gca) ;
19298   return(h_eq) ;
19299 }
19300 
19301 #endif
19302 static HISTOGRAM *
19303 gcaGetLabelHistogram(GCA *gca, int label, int frame)
19304 {
19305   HISTOGRAM *h_gca ;
19306   int       xn, yn, zn, n ;
19307   GCA_NODE  *gcan ;
19308   GC1D      *gc ;
19309   float     prior ;
19310   int       b ;
19311 
19312 
19313   // build histogram of this label
19314   h_gca = HISTOalloc(256) ;
19315   for (b = 0 ; b < h_gca->nbins ; b++)
19316     h_gca->bins[b] = b ;
19317   for (zn = 0 ; zn < gca->node_depth ; zn++)
19318   {
19319     for (yn = 0 ; yn < gca->node_height ; yn++)
19320     {
19321       for (xn = 0 ; xn < gca->node_width ; xn++)
19322       {
19323         gcan = &gca->nodes[xn][yn][zn] ;
19324         for (n = 0 ; n < gcan->nlabels ; n++)
19325         {
19326           /* find index in lookup table for this label */
19327           if (gcan->labels[n] != label)
19328             continue ;
19329           gc = &gcan->gcs[n] ;
19330           prior = get_node_prior(gca, label, xn, yn, zn) ;
19331           if (prior != 0)
19332           {
19333             //  for (r = 0 ; r < gca->ninputs ; r++)
19334             {
19335               b = nint(gc->means[frame]) ;
19336               if (b < 0 || b >= h_gca->nbins)
19337               {
19338                 DiagBreak() ;
19339                 if (b < 0)
19340                   b = 0 ;
19341                 if (b >= h_gca->nbins)
19342                   b = h_gca->nbins - 1 ;
19343               }
19344               h_gca->counts[b] += prior ;
19345               if (!finite(gc->means[frame]))
19346                 DiagBreak() ;
19347             }
19348           }
19349         }
19350       }
19351     }
19352   }
19353   return(h_gca) ;
19354 }
19355 
19356 
19357 #if INTERP_PRIOR
19358 static float
19359 gcaComputePrior(GCA *gca, MRI *mri, TRANSFORM *transform,
19360                 int x0, int y0, int z0, int label)
19361 {
19362   Real  x, y, z, xmd, ymd, zmd, xpd, ypd, zpd, prior ;
19363   int   xm, ym, zm, xp, yp, zp ;
19364   GCA_PRIOR *gcap ;
19365   float  total_prior  ;
19366 
19367   if (x0 == Ggca_x && y0 == Ggca_y && z0 == Ggca_z)
19368     DiagBreak() ;
19369 
19370   gcaSourceVoxelToPriorReal(gca, mri, transform, x0, y0, z0, &x, &y, &z);
19371   xm = MAX((int)x, 0) ;
19372   xp = MIN(gca->prior_width-1, xm+1) ;
19373   ym = MAX((int)y, 0) ;
19374   yp = MIN(gca->prior_height-1, ym+1) ;
19375   zm = MAX((int)z, 0) ;
19376   zp = MIN(gca->prior_depth-1, zm+1) ;
19377 
19378   xmd = x - (float)xm ;
19379   ymd = y - (float)ym ;
19380   zmd = z - (float)zm ;
19381   xpd = (1.0f - xmd) ;
19382   ypd = (1.0f - ymd) ;
19383   zpd = (1.0f - zmd) ;
19384 
19385   gcap = &gca->priors[xp][yp][zp] ;
19386   prior  = getPrior(gcap, label) ;
19387   total_prior = prior*xpd*ypd*zpd ;
19388 
19389   gcap = &gca->priors[xp][yp][zm] ;
19390   prior  = getPrior(gcap, label) ;
19391   total_prior += prior*xpd*ypd*zmd ;
19392 
19393   gcap = &gca->priors[xp][ym][zp] ;
19394   prior  = getPrior(gcap, label) ;
19395   total_prior += prior*xpd*ymd*zpd ;
19396 
19397   gcap = &gca->priors[xp][ym][zm] ;
19398   prior  = getPrior(gcap, label) ;
19399   total_prior += prior*xpd*ymd*zmd ;
19400 
19401   gcap = &gca->priors[xm][yp][zp] ;
19402   prior  = getPrior(gcap, label) ;
19403   total_prior += prior*xmd*ypd*zpd ;
19404 
19405   gcap = &gca->priors[xm][yp][zm] ;
19406   prior  = getPrior(gcap, label) ;
19407   total_prior += prior*xmd*ypd*zmd ;
19408 
19409   gcap = &gca->priors[xm][ym][zp] ;
19410   prior  = getPrior(gcap, label) ;
19411   total_prior += prior*xmd*ymd*zpd ;
19412 
19413   gcap = &gca->priors[xm][ym][zm] ;
19414   prior  = getPrior(gcap, label) ;
19415   total_prior += prior*xmd*ymd*zmd ;
19416 
19417   return(total_prior) ;
19418 }
19419 
19420 #endif
19421 
19422 
19423 
19424 static void  set_equilavent_classes(int *equivalent_classes)
19425 {
19426   int i;
19427 
19428   for (i=0; i < MAX_CMA_LABELS; i++)
19429   {
19430     equivalent_classes[i] = i;
19431   }
19432 
19433   //CSF 1, GM 3, WM 2
19434   equivalent_classes[0] = 0;
19435   equivalent_classes[1] = 1;
19436   equivalent_classes[2] = 2;
19437   equivalent_classes[3] = 3;
19438   equivalent_classes[4] = 1;
19439   equivalent_classes[5] = 1;
19440   equivalent_classes[6] = 0;
19441   equivalent_classes[7] = 2;
19442   equivalent_classes[8] = 3;
19443   equivalent_classes[9] = 3;
19444   equivalent_classes[10] = 3;
19445   equivalent_classes[11] = 3;
19446   equivalent_classes[12] = 3;
19447   equivalent_classes[13] = 3;
19448   equivalent_classes[14] = 1;
19449   equivalent_classes[15] = 1;
19450   equivalent_classes[16] = 2; //this is brain stem, really WM??
19451   equivalent_classes[17] = 3;
19452   equivalent_classes[18] = 3;
19453   equivalent_classes[19] = 0; //Left_Insula
19454   equivalent_classes[20] = 0; //Left_Operculum
19455   equivalent_classes[21] = 0; //Line_1
19456   equivalent_classes[22] = 0; //Line_2
19457   equivalent_classes[23] = 0; //Line_3
19458   equivalent_classes[24] = 1; //CSF
19459   equivalent_classes[25] = 0; //Left_lesion
19460   equivalent_classes[26] = 3; //left_accumbens_area
19461   equivalent_classes[27] = 0; //Left_Substancia_Nigra
19462   equivalent_classes[28] = 0; //Left_VentralDC;
19463   equivalent_classes[29] = 0; //left_undetermined
19464   equivalent_classes[30] = 0; // Left_vessel
19465   equivalent_classes[31] = 0; //left_choroid_plexus
19466   equivalent_classes[32] = 0; //lEFT_f3ORB
19467   equivalent_classes[33] = 0; //Left_lOg
19468   equivalent_classes[34] = 0; //Left_aOg
19469   equivalent_classes[35] = 0; // Left_mOg
19470   equivalent_classes[36] = 0; //Left_pOg
19471   equivalent_classes[37] = 0; //Left_Stellate
19472   equivalent_classes[38] = 0; //Left_Porg
19473   equivalent_classes[39] = 0; //Left_Aorg
19474   equivalent_classes[40] = equivalent_classes[1];
19475   equivalent_classes[41] = equivalent_classes[2];
19476   equivalent_classes[42] = equivalent_classes[3];
19477   equivalent_classes[43] =equivalent_classes[4];
19478   equivalent_classes[44] =equivalent_classes[5];
19479   equivalent_classes[45] =equivalent_classes[6];
19480   equivalent_classes[46] =equivalent_classes[7];
19481   equivalent_classes[47] =equivalent_classes[8];
19482   equivalent_classes[48] =equivalent_classes[9];
19483   equivalent_classes[49] =equivalent_classes[10];
19484   equivalent_classes[50] =equivalent_classes[11];
19485   equivalent_classes[51] =equivalent_classes[12];
19486   equivalent_classes[52] =equivalent_classes[13];
19487   equivalent_classes[53] =equivalent_classes[17];
19488   equivalent_classes[54] =equivalent_classes[18];
19489   equivalent_classes[55] =equivalent_classes[19];
19490   equivalent_classes[56] =equivalent_classes[20];
19491   equivalent_classes[57] =equivalent_classes[25];
19492   equivalent_classes[58] =equivalent_classes[26];
19493   equivalent_classes[59] =equivalent_classes[27];
19494   equivalent_classes[60] =equivalent_classes[28];
19495   equivalent_classes[61] =equivalent_classes[29];
19496   equivalent_classes[62] =equivalent_classes[30];
19497   equivalent_classes[63] =equivalent_classes[31]; //choroid_plexus
19498   equivalent_classes[64] =equivalent_classes[32];
19499   equivalent_classes[65] =equivalent_classes[33];
19500   equivalent_classes[66] =equivalent_classes[34];
19501   equivalent_classes[67] =equivalent_classes[35];
19502   equivalent_classes[68] =equivalent_classes[36];
19503   equivalent_classes[69] =equivalent_classes[37];
19504   equivalent_classes[70] =equivalent_classes[38];
19505   equivalent_classes[71] =equivalent_classes[39];
19506   equivalent_classes[72] =1;
19507   equivalent_classes[73] =0; // Left_Interior
19508   equivalent_classes[74] =equivalent_classes[73];
19509   equivalent_classes[75] = 1;
19510   equivalent_classes[76] =equivalent_classes[75];
19511   equivalent_classes[77] = 2;
19512   equivalent_classes[78] = 2;
19513   equivalent_classes[79] =equivalent_classes[78];
19514   equivalent_classes[80] = 2;
19515   equivalent_classes[81] = 2;
19516   equivalent_classes[82] =equivalent_classes[81];
19517   equivalent_classes[83] = 0;
19518   equivalent_classes[84] =equivalent_classes[83];
19519   equivalent_classes[186] = 2;
19520   equivalent_classes[187] =equivalent_classes[186];
19521 
19522   return;
19523 }
19524 
19525 
19526 MRI *GCAbuildMostLikelyLabelVolume(GCA *gca)
19527 {
19528   /* this function creates a label volume and will be used to register
19529      a subject's manual label to it, as a way to get linear registration
19530      from the subject to the gca for gca training */
19531   int       x,  y, z, xn, yn, zn, width, depth, height, n, xp, yp, zp;
19532   GCA_NODE  *gcan ;
19533   GCA_PRIOR *gcap ;
19534   MRI *mri;
19535   double    max_prior ;
19536   int       max_label ;
19537 
19538   // most likely label volume should agree with direction cosines
19539   mri = MRIalloc(gca->width, gca->height, gca->depth, MRI_SHORT);
19540 
19541     mri->xsize = gca->xsize;
19542     mri->ysize = gca->ysize;
19543     mri->zsize = gca->zsize;
19544   GCAcopyDCToMRI(gca, mri);
19545 
19546   width = mri->width ; depth = mri->depth ;height = mri->height ;
19547   for (z = 0 ; z < depth ; z++)
19548   {
19549     for (y = 0 ; y < height ; y++)
19550     {
19551       for (x = 0 ; x < width ; x++)
19552       {
19553         if (x == Gx && y == Gy && z == Gz)
19554           DiagBreak() ;
19555         // get node value
19556         if (GCAvoxelToNode(gca, mri, x, y, z, &xn, &yn, &zn) == NO_ERROR)
19557         {
19558           // get prior value
19559           if (GCAvoxelToPrior(gca, mri, x, y, z,
19560                               &xp, &yp, &zp) == NO_ERROR)
19561           {
19562             gcan = &gca->nodes[xn][yn][zn] ;
19563             gcap = &gca->priors[xp][yp][zp] ;
19564             if (gcap==NULL || gcap->nlabels <= 0)
19565               continue;
19566             // initialize
19567             max_prior = gcap->priors[0] ;
19568             max_label = gcap->labels[0] ;
19569             // prior labels
19570             for (n = 1 ; n < gcap->nlabels ; n++)
19571             {
19572               if (gcap->priors[n] >= max_prior)
19573               {
19574                 max_prior = gcap->priors[n] ;
19575                 max_label = gcap->labels[n] ;
19576               }
19577             }
19578             MRIsetVoxVal(mri, x, y, z, 0, max_label) ;
19579           }
19580           else
19581           {
19582             MRIsetVoxVal(mri, x, y, z, 0, 0) ;
19583           }
19584         }
19585         else
19586         {
19587           MRIsetVoxVal(mri, x, y, z, 0, 0) ;
19588 
19589         }
19590       }
19591     }
19592   }
19593 
19594   return(mri) ;
19595 }
19596 
19597 
19598 
19599 int
19600 GCAcomputeLabelMeansAndCovariances
19601 (GCA *gca, int target_label, MATRIX **p_mcov, VECTOR **p_vmeans)
19602 {
19603   int      x, y, z, n, r ;
19604   double   var, dof, total_dof ;
19605   GC1D     *gc ;
19606   GCA_NODE *gcan ;
19607   float fval;
19608   MATRIX *m_cov=NULL, *m_cov_total ;
19609   VECTOR *v_means ;
19610 
19611   m_cov_total = MatrixAlloc(gca->ninputs, gca->ninputs, MATRIX_REAL) ;
19612   v_means = VectorAlloc(gca->ninputs, MATRIX_REAL) ;
19613 
19614   var = total_dof = 0.0 ;
19615   for (x = 0 ; x < gca->node_width ; x++)
19616   {
19617     for (y = 0 ; y < gca->node_height ; y++)
19618     {
19619       for (z = 0 ; z < gca->node_depth ; z++)
19620       {
19621         gcan = &gca->nodes[x][y][z] ;
19622 
19623         for (n = 0 ; n < gcan->nlabels ; n++)
19624         {
19625           if (gcan->labels[n] == target_label)
19626           {
19627             gc = &gcan->gcs[n] ;
19628             fval = get_node_prior(gca, target_label, x,y,z);
19629             if (fval != 0)
19630             {
19631               dof =
19632                 get_node_prior(gca, target_label, x, y, z) \
19633                 * gcan->total_training ;
19634               for (r = 0 ; r < gca->ninputs ; r++)
19635                 VECTOR_ELT(v_means, r+1) += dof*gc->means[r] ;
19636               m_cov = load_covariance_matrix
19637                       (gc, m_cov, gca->ninputs) ;
19638               MatrixScalarMul(m_cov, dof, m_cov) ;
19639               MatrixAdd(m_cov, m_cov_total, m_cov_total) ;
19640               total_dof += dof ;
19641             }
19642           }
19643         }
19644       }
19645     }
19646   }
19647 
19648   if (total_dof > 0.0)
19649   {
19650     MatrixScalarMul(m_cov_total, 1/(double)total_dof, m_cov_total) ;
19651     VectorScalarMul(v_means, 1/(double)total_dof, v_means) ;
19652   }
19653 
19654   *p_mcov = m_cov_total ;
19655   *p_vmeans = v_means ;
19656   MatrixFree(&m_cov) ;
19657   return(NO_ERROR) ;
19658 }
19659 #ifdef WSIZE
19660 #undef WSIZE
19661 #endif
19662 #ifdef WHALF
19663 #undef WHALF
19664 #endif
19665 
19666 #define WSIZE  5
19667 #define WHALF  ((WSIZE-1)/2)
19668 static double
19669 compute_conditional_density(MATRIX *m_inv_cov, VECTOR *v_means, VECTOR *v_vals)
19670 {
19671   double  p, dist, det ;
19672   int     ninputs ;
19673 
19674   ninputs = m_inv_cov->rows ;
19675 
19676   det = MatrixDeterminant(m_inv_cov) ;
19677   dist = MatrixMahalanobisDistance(v_means, m_inv_cov, v_vals) ;
19678   p = (1.0 / (pow(2*M_PI,ninputs/2.0)*sqrt(1.0/det))) * exp(-0.5*dist) ;
19679   return(p) ;
19680 }
19681 
19682 
19683 static int
19684 load_val_vector(VECTOR *v_means, MRI *mri_inputs, int x, int y, int z)
19685 {
19686   int  n ;
19687 
19688   for (n = 0 ; n < mri_inputs->nframes ; n++)
19689     VECTOR_ELT(v_means, n+1) = MRIgetVoxVal(mri_inputs, x, y, z, n) ;
19690   return(NO_ERROR) ;
19691 }
19692 
19693 
19694 MRI *
19695 GCAlabelWMandWMSAs(GCA *gca,
19696                    MRI *mri_inputs,
19697                    MRI *mri_src_labels,
19698                    MRI *mri_dst_labels,
19699                    TRANSFORM *transform)
19700 {
19701   int    h, wm_label, wmsa_label, x, y, z, label, nwm, nwmsa, nunknown, ngm,
19702   ncaudate, caudate_label, gm_label, n, found, i;
19703   MATRIX *m_cov_wm, *m_cov_wmsa, *m_inv_cov_wmsa, *m_inv_cov_wm, *m_I,
19704   *m_cov_un, *m_inv_cov_un;
19705   VECTOR *v_mean_wm, *v_mean_wmsa, *v_vals, *v_dif_label, *v_dif_wmsa,
19706   *v_mean_caudate, *v_mean_un ;
19707   double pwm, pwmsa, wmsa_dist, wm_dist, wm_mdist, wmsa_mdist ;
19708   GCA_PRIOR *gcap ;
19709   MRI       *mri_tmp = NULL ;
19710 
19711   mri_dst_labels = MRIcopy(mri_src_labels, mri_dst_labels) ;
19712 
19713   v_vals = VectorAlloc(mri_inputs->nframes, MATRIX_REAL) ;
19714   v_dif_label = VectorAlloc(mri_inputs->nframes, MATRIX_REAL) ;
19715   v_dif_wmsa = VectorAlloc(mri_inputs->nframes, MATRIX_REAL) ;
19716   m_I = MatrixIdentity(mri_inputs->nframes, NULL) ;
19717   for (h = 0 ; h <= 1 ; h++)
19718   {
19719     if (h == 0) // lh
19720     {
19721       wm_label = Left_Cerebral_White_Matter ;
19722       wmsa_label = Left_WM_hypointensities ;
19723       caudate_label = Left_Caudate ;
19724       gm_label = Left_Cerebral_Cortex ;
19725     }
19726     else
19727     {
19728       wm_label = Right_Cerebral_White_Matter ;
19729       wmsa_label = Right_WM_hypointensities ;
19730       caudate_label = Right_Caudate ;
19731       gm_label = Right_Cerebral_Cortex ;
19732     }
19733 
19734     GCAcomputeLabelMeansAndCovariances
19735     (gca, Unknown, &m_cov_un, &v_mean_un) ;
19736     GCAcomputeLabelMeansAndCovariances
19737     (gca, wm_label, &m_cov_wm, &v_mean_wm) ;
19738     GCAcomputeLabelMeansAndCovariances
19739     (gca, caudate_label, &m_cov_wm, &v_mean_caudate) ;
19740     GCAcomputeLabelMeansAndCovariances
19741     (gca, wmsa_label, &m_cov_wmsa, &v_mean_wmsa) ;
19742     m_inv_cov_wm = MatrixInverse(m_cov_wm, NULL) ;
19743     if (m_inv_cov_wm == NULL)
19744       ErrorExit(ERROR_BADPARM,
19745                 "%s: could not compute inverse covariance for %s (%d)",
19746                 Progname, cma_label_to_name(wm_label), wm_label) ;
19747     m_inv_cov_un = MatrixInverse(m_cov_un, NULL) ;
19748     if (m_inv_cov_un == NULL)
19749       ErrorExit(ERROR_BADPARM,
19750                 "%s: could not compute inverse covariance for %s (%d)",
19751                 Progname, cma_label_to_name(Unknown), Unknown) ;
19752     m_inv_cov_wmsa = MatrixInverse(m_cov_wmsa, NULL) ;
19753     if (m_inv_cov_wmsa == NULL)
19754       ErrorExit(ERROR_BADPARM,
19755                 "%s: could not compute inverse covariance for %s (%d)",
19756                 Progname, cma_label_to_name(wmsa_label), wmsa_label) ;
19757 
19758     // do max likelihood reclassification of possible wmsa voxels
19759     // if they are in a nbhd with likely labels
19760     for (x = 0 ; x < mri_inputs->width ; x++)
19761     {
19762       for (y = 0 ; y < mri_inputs->height ; y++)
19763       {
19764         for (z = 0 ; z < mri_inputs->depth ; z++)
19765         {
19766           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19767             DiagBreak() ;
19768           label = MRIgetVoxVal(mri_src_labels, x, y, z, 0) ;
19769           if (label != wm_label &&
19770               label != wmsa_label &&
19771               label != Unknown)
19772             continue ;
19773           // only process it if it's in the body of the wm
19774           nwm = MRIlabelsInNbhd
19775                 (mri_src_labels, x, y, z, WHALF, wm_label) ;
19776           nwmsa = MRIlabelsInNbhd
19777                   (mri_src_labels, x, y, z,WHALF, wmsa_label) ;
19778 
19779           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19780             printf("(%d, %d, %d) - %s (nbrs = %d + %d = %2.2f%%)\n",
19781                    x, y, z, cma_label_to_name(label),
19782                    nwm, nwmsa,
19783                    (double)(nwm+nwmsa)*100.0/(WSIZE*WSIZE*WSIZE));
19784           if (label == Unknown)
19785           {
19786             // only unknowns that are close to wm
19787             if (nwm+nwmsa < 0.5*WSIZE*WSIZE*WSIZE)
19788               continue ;
19789             nunknown = MRIlabelsInNbhd
19790                        (mri_src_labels, x, y, z,WHALF, Unknown) ;
19791             if (nwm+nwmsa+nunknown < 0.9*WSIZE*WSIZE*WSIZE)
19792               continue ;
19793           }
19794           else if (nwm+nwmsa < .9*WSIZE*WSIZE*WSIZE)
19795             // somewhat arbitrary - the bulk of the nbhd
19796             continue ;
19797 
19798           gcap = getGCAP(gca, mri_dst_labels, transform, x, y, z) ;
19799           for (found = n = 0 ; n < gcap->nlabels ; n++)
19800             if ((IS_WHITE_CLASS(gcap->labels[n]) &&
19801                  gcap->priors[n] > 0.1) ||
19802                 IS_HYPO(gcap->labels[n]))
19803               found = 1 ;
19804           if (found == 0)  // no chance of wm or wmsa here
19805             continue ;
19806 
19807           if (label == Unknown)
19808             DiagBreak() ;
19809           load_val_vector(v_vals, mri_inputs, x, y, z) ;
19810           pwm = compute_conditional_density
19811                 (m_inv_cov_wm, v_mean_wm, v_vals) ;
19812           pwmsa = compute_conditional_density
19813                   (m_inv_cov_wmsa, v_mean_wmsa, v_vals) ;
19814           if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19815             printf("         - pwm = %2.3e, pwmsa = %2.3e\n",
19816                    pwm, pwmsa) ;
19817           if (label == wm_label && pwmsa > pwm)
19818           {
19819             wm_dist = VectorDistance(v_mean_wm, v_vals) ;
19820             wmsa_dist = VectorDistance(v_mean_wmsa, v_vals) ;
19821             wm_mdist = MatrixMahalanobisDistance
19822                        (v_mean_wm, m_inv_cov_wm, v_vals) ;
19823             wmsa_mdist = MatrixMahalanobisDistance
19824                          (v_mean_wmsa, m_inv_cov_wmsa, v_vals) ;
19825             if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19826               printf("         - wm_dist = %2.0f, "
19827                      "wmsa_dist = %2.0f, mdists = (%2.0f, %2.0f)\n",
19828                      wm_dist, wmsa_dist, wm_mdist, wmsa_mdist) ;
19829             if ((wm_dist > wmsa_dist) && (wm_mdist > wmsa_mdist))
19830             {
19831               VectorSubtract(v_vals, v_mean_wm, v_dif_label) ;
19832               VectorSubtract(v_vals, v_mean_wmsa, v_dif_wmsa) ;
19833               if (
19834                 ((fabs(VECTOR_ELT(v_dif_wmsa,1)) <
19835                   fabs(VECTOR_ELT(v_dif_label,1))) &&
19836                  (fabs(VECTOR_ELT(v_dif_wmsa,2)) <
19837                   fabs(VECTOR_ELT(v_dif_label,2))) &&
19838                  (fabs(VECTOR_ELT(v_dif_wmsa,3)) <
19839                   fabs(VECTOR_ELT(v_dif_label,3)))) ||
19840                 ((2*wmsa_dist < wm_dist) &&
19841                  (2*wmsa_mdist < wm_mdist)))
19842               {
19843                 if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19844                   printf("changing label from %s to %s\n",
19845                          cma_label_to_name(label),
19846                          cma_label_to_name(wmsa_label)) ;
19847                 if (label == Unknown)
19848                   DiagBreak() ;
19849                 label = wmsa_label ;
19850               }
19851             }
19852           }
19853           MRIsetVoxVal(mri_dst_labels, x, y, z, 0, label) ;
19854         }
19855       }
19856     }
19857 
19858     // now do 3 iterations of region growing
19859     for (i = 0 ; i < 3 ; i++)
19860     {
19861       mri_tmp = MRIcopy(mri_dst_labels, mri_tmp) ;
19862       for (x = 0 ; x < mri_inputs->width ; x++)
19863       {
19864         for (y = 0 ; y < mri_inputs->height ; y++)
19865         {
19866           for (z = 0 ; z < mri_inputs->depth ; z++)
19867           {
19868             if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19869               DiagBreak() ;
19870             label = MRIgetVoxVal(mri_dst_labels, x, y, z, 0) ;
19871             if (label != wm_label &&
19872                 label != Unknown &&
19873                 label != caudate_label)
19874               continue ;
19875             load_val_vector(v_vals, mri_inputs, x, y, z) ;
19876             nwmsa = MRIlabelsInNbhd
19877                     (mri_dst_labels, x, y, z, 1, wmsa_label) ;
19878             if (nwmsa < 1)
19879               continue ;
19880             gcap = getGCAP(gca, mri_dst_labels, transform, x, y, z) ;
19881             for (found = n = 0 ; n < gcap->nlabels ; n++)
19882               if ((IS_WHITE_CLASS(gcap->labels[n]) &&
19883                    gcap->priors[n] > 0.1) ||
19884                   IS_HYPO(gcap->labels[n]))
19885                 found = 1 ;
19886             if (found == 0)  // no chance of wm or wmsa here
19887               continue ;
19888 
19889             // only process it if it's in the body of the wm
19890 #undef WSIZE
19891 #define WSIZE 5
19892 #define WHALF ((WSIZE-1)/2)
19893 
19894             nwm = MRIlabelsInNbhd
19895                   (mri_tmp, x, y, z, WHALF, wm_label) ;
19896             nwmsa = MRIlabelsInNbhd
19897                     (mri_tmp, x, y, z,WHALF, wmsa_label) ;
19898             nunknown = MRIlabelsInNbhd
19899                        (mri_tmp, x, y, z,WHALF, Unknown) ;
19900             ncaudate = MRIlabelsInNbhd
19901                        (mri_tmp, x, y, z,WHALF, caudate_label) ;
19902             ngm = MRIlabelsInNbhd
19903                   (mri_tmp, x, y, z,WHALF, gm_label) ;
19904 
19905             // took gm out for now
19906             if (ncaudate+nwm+nwmsa+nunknown <
19907                 .9*WSIZE*WSIZE*WSIZE)  /* somewhat arbitrary -
19908                                           the bulk of the nbhd */
19909               continue ;
19910             ngm = MRIlabelsInNbhd(mri_tmp, x, y, z,1, gm_label) ;
19911             if (ngm > 0)  // not if there are any gm nearest nbrs
19912               continue ;
19913 
19914             if (nwm + nwmsa == 0)
19915               continue ;
19916             wm_dist = VectorDistance(v_mean_wm, v_vals) ;
19917             wmsa_dist = VectorDistance(v_mean_wmsa, v_vals) ;
19918             VectorSubtract(v_vals, v_mean_wmsa, v_dif_wmsa) ;
19919             if (label == caudate_label)
19920             {
19921               VectorSubtract(v_vals, v_mean_caudate, v_dif_label) ;
19922               if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19923                 printf("         - wm_dist = %2.0f, "
19924                        "wmsa_dist = %2.0f\n",
19925                        wm_dist, wmsa_dist) ;
19926               if ((fabs(VECTOR_ELT(v_dif_wmsa,1)) <
19927                    fabs(VECTOR_ELT(v_dif_label,1))) &&
19928                   (fabs(VECTOR_ELT(v_dif_wmsa,2)) <
19929                    fabs(VECTOR_ELT(v_dif_label,2))) &&
19930                   (fabs(VECTOR_ELT(v_dif_wmsa,3)) <
19931                    fabs(VECTOR_ELT(v_dif_label,3))))
19932               {
19933                 if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19934                   printf("changing label from %s to %s\n",
19935                          cma_label_to_name(label),
19936                          cma_label_to_name(wmsa_label)) ;
19937                 label = wmsa_label ;
19938               }
19939             }
19940             else if (label == wm_label)
19941             {
19942               VectorSubtract(v_vals, v_mean_wm, v_dif_label) ;
19943               if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19944                 printf("         - wm_dist = %2.0f, "
19945                        "wmsa_dist = %2.0f\n",
19946                        wm_dist, wmsa_dist) ;
19947               if (((fabs(VECTOR_ELT(v_dif_wmsa,1)) <
19948                     fabs(VECTOR_ELT(v_dif_label,1))) &&
19949                    (fabs(VECTOR_ELT(v_dif_wmsa,2)) <
19950                     fabs(VECTOR_ELT(v_dif_label,2))) &&
19951                    (fabs(VECTOR_ELT(v_dif_wmsa,3)) <
19952                     fabs(VECTOR_ELT(v_dif_label,3)))) ||
19953                   (wmsa_dist*3 < wm_dist))
19954               {
19955                 if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19956                   printf("changing label from %s to %s\n",
19957                          cma_label_to_name(label),
19958                          cma_label_to_name(wmsa_label)) ;
19959                 if (label == Unknown)
19960                   DiagBreak() ;
19961                 label = wmsa_label ;
19962               }
19963             }
19964             else if (label == Unknown)
19965             {
19966               VectorSubtract(v_vals, v_mean_un, v_dif_label) ;
19967               if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19968                 printf("         - wm_dist = %2.0f, "
19969                        "wmsa_dist = %2.0f\n",
19970                        wm_dist, wmsa_dist) ;
19971               if ((fabs(VECTOR_ELT(v_dif_wmsa,1)) <
19972                    fabs(VECTOR_ELT(v_dif_label,1))) &&
19973                   (fabs(VECTOR_ELT(v_dif_wmsa,2)) <
19974                    fabs(VECTOR_ELT(v_dif_label,2))) &&
19975                   (fabs(VECTOR_ELT(v_dif_wmsa,3)) <
19976                    fabs(VECTOR_ELT(v_dif_label,3))))
19977               {
19978                 if (x == Ggca_x && y == Ggca_y && z == Ggca_z)
19979                   printf("changing label from %s to %s\n",
19980                          cma_label_to_name(label),
19981                          cma_label_to_name(wmsa_label)) ;
19982                 if (label == Unknown)
19983                   DiagBreak() ;
19984                 label = wmsa_label ;
19985               }
19986             }
19987             MRIsetVoxVal(mri_dst_labels, x, y, z, 0, label) ;
19988           }
19989         }
19990       }
19991     }
19992     MatrixFree(&m_cov_un) ;
19993     MatrixFree(&m_inv_cov_un) ;
19994     MatrixFree(&m_cov_wm) ;
19995     MatrixFree(&m_inv_cov_wm) ;
19996     MatrixFree(&m_cov_wmsa) ;
19997     MatrixFree(&m_inv_cov_wmsa) ;
19998     VectorFree(&v_mean_wm) ;
19999     VectorFree(&v_mean_wmsa) ;
20000     VectorFree(&v_mean_caudate) ;
20001     VectorFree(&v_mean_un) ;
20002   }
20003   VectorFree(&v_vals) ;
20004   VectorFree(&v_dif_label) ;
20005   VectorFree(&v_dif_wmsa) ;
20006   MRIfree(&mri_tmp) ;
20007   return(mri_dst_labels) ;
20008 }
20009 static int
20010 initialize_ventricle_alignment(MRI *mri_seg, 
20011                                MRI *mri, 
20012                                MATRIX *m_L, 
20013                                char *base_name)
20014 {
20015   printf("Handling expanded ventricles... "
20016          "(gca::initialize_ventricle_alignment)\n");
20017 
20018   MRIcomputeOptimalLinearXform(mri_seg, mri, m_L,
20019                                -RADIANS(10), RADIANS(10),
20020                                .9, 2,  // allow for ventriular expansion
20021                                -10, 10,
20022                                4, 3, 3, 3, base_name) ;
20023   return(NO_ERROR) ;
20024 }
20025 
20026 /*-------------------------------------------------------------------------
20027   GCAcolorTableCMA() - construct a color table from the unique entries
20028   in the GCA.  RGBs are random. Indices that are not represented have
20029   their entries in the ctab set to NULL.  Note that the names in cma.h
20030   do not match the names in FreeSurferLUT.txt exactly, so
20031   FreeSurferLUT.txt is loaded and the names are extracted rather than
20032   using those in cma.h.
20033   -------------------------------------------------------------------------*/
20034 COLOR_TABLE *GCAcolorTableCMA(GCA *gca)
20035 {
20036   int nl,n,c,r,s,nmax;
20037   int labelhitlist[1000]; // probably only need 256
20038   COLOR_TABLE *ct,*ct0;
20039   char ctabfile[2000];
20040 
20041   sprintf(ctabfile,"%s/FreeSurferColorLUT.txt",getenv("FREESURFER_HOME"));
20042   printf("GCAcolorTableCMA: using ctab %s\n",ctabfile);
20043   ct0 = CTABreadASCII(ctabfile);
20044   if (ct0 == NULL)
20045   {
20046     printf("ERROR: reading %s\n",ctabfile);
20047     exit(1);
20048   }
20049 
20050   // Init the hit
20051   for (n=0; n<1000; n++) labelhitlist[n]=0;
20052 
20053   // Go thru each node
20054   for (c=0; c < gca->node_width; c++)
20055   {
20056     for (r=0; r < gca->node_height; r++)
20057     {
20058       for (s=0; s < gca->node_depth; s++)
20059       {
20060         nl = gca->nodes[c][r][s].nlabels;
20061         // Go thru each label in the node
20062         for (n=0;n<nl;n++)
20063         {
20064           // Get the index (labels[n] is an index, not string)
20065           // Mark the index as represented
20066           labelhitlist[gca->nodes[c][r][s].labels[n]] = 1;
20067         } //n
20068       } //s
20069     } //r
20070   } //c
20071 
20072   // determine the maximum index
20073   nmax = 0;
20074   for (n=0; n<1000; n++) if (labelhitlist[n]) nmax=n;
20075 
20076   ct = CTABalloc(nmax+1);
20077   for (n=0; n<=nmax; n++)
20078   {
20079     if (labelhitlist[n])
20080     {
20081       // If this index is represented, then set up its
20082       // entry in the color table. The name is derived
20083       // from the CMA.
20084       ct->entries[n]->ri = nint(randomNumber(0, 255));
20085       ct->entries[n]->gi = nint(randomNumber(0, 255));
20086       ct->entries[n]->bi = nint(randomNumber(0, 255));
20087       ct->entries[n]->ai = 255;
20088       ct->entries[n]->rf = (float)ct->entries[n]->ri / 255.0;
20089       ct->entries[n]->gf = (float)ct->entries[n]->gi / 255.0;
20090       ct->entries[n]->bf = (float)ct->entries[n]->bi / 255.0;
20091       ct->entries[n]->af = (float)ct->entries[n]->ai / 255.0;
20092       // There is a mismatch between the names listed in
20093       // FreeSurferColorLUT.txt and the names in cma.h but the
20094       // indices are the same (I hope), so we need to
20095       // use the names from FreeSurferColorLUT.txt.
20096       sprintf(ct->entries[n]->name, "%s", ct0->entries[n]->name);
20097       // printf("%d %s %s\n", n,cma_label_to_name(n),ct->entries[n]->name);
20098     }
20099     else
20100     {
20101       // If this index is not represented, then free and NULL
20102       // its entry.
20103       free(ct->entries[n]);
20104       ct->entries[n] = NULL;
20105     }
20106   }
20107   CTABfree(&ct0);
20108   return(ct);
20109 }
20110 #if 1
20111 double
20112 GCAimageLogLikelihood(GCA *gca, MRI *mri_inputs, TRANSFORM *transform,
20113                       int penalize_zero_brain, MRI *mri_orig)
20114 {
20115   int        x, y, z, xn, yn, zn, label, xp, yp, zp, num,nz,nout, n ;
20116   GCA_PRIOR  *gcap ;
20117   GC1D       *gc ;
20118   double     total_log_p, log_p=0, prior, min_log_p ;
20119   float      vals[MAX_GCA_INPUTS], fmin, fmax ;
20120   MRI        *mri_ll ;
20121 
20122   if (DIAG_VERBOSE_ON)
20123     mri_ll = MRIalloc(mri_inputs->width, 
20124                       mri_inputs->height, 
20125                       mri_inputs->depth, 
20126                       MRI_FLOAT) ;
20127   else
20128     mri_ll = NULL ;
20129 
20130   if (Gx >= 0)
20131   {
20132     GCAsourceVoxelToPrior(gca, mri_inputs,
20133                           transform, Gx, Gy, Gz, &Gxp, &Gyp, &Gzp);
20134     GCApriorToSourceVoxel(gca, mri_inputs, transform, Gxp, Gyp, Gzp,&x,&y,&z);
20135   }
20136 
20137   fmin = 100000 ;
20138   fmax = -fmin ;
20139   for (min_log_p = 0, nz = nout = num = xp = 0 ; xp < gca->prior_width ; xp++)
20140   {
20141     for (yp = 0 ; yp < gca->prior_height ; yp++)
20142     {
20143       for (zp = 0 ; zp < gca->prior_depth ; zp++)
20144       {
20145         if (xp == Gxp && yp == Gyp && zp == Gzp)
20146           DiagBreak() ;
20147         gcap = &gca->priors[xp][yp][zp] ;
20148         if (gcap == NULL || gcap->nlabels == 0)
20149           continue ;
20150         min_log_p += gcap->total_training ;
20151         label = gcapGetMaxPriorLabel(gcap, &prior) ;
20152         if (IS_BRAIN(label) && !IS_CSF(label))
20153         {
20154           GCApriorToNode(gca, xp, yp, zp, &xn, &yn, &zn) ;
20155           gc = GCAfindGC(gca, xn, yn, zn, label) ;
20156           if (gc->means[0] > fmax)
20157             fmax = gc->means[0] ;
20158           if (gc->means[0] < fmin)
20159             fmin = gc->means[0] ;
20160         }
20161       }
20162     }
20163   }
20164   fprintf(stderr,"valid intensity range = [%2.0f, %2.0f]\n", fmin, fmax) ;
20165 
20166   min_log_p = log(0.01/min_log_p) ;
20167   if (min_log_p > -50)
20168     min_log_p = -50 ;  // to penalize enough (I know it's a hack)
20169   for (total_log_p = 0, nz = num = xp = 0 ; xp < gca->prior_width ; xp++)
20170   {
20171     for (yp = 0 ; yp < gca->prior_height ; yp++)
20172     {
20173       for (zp = 0 ; zp < gca->prior_depth ; zp++)
20174       {
20175         if (xp == Gxp && yp == Gyp && zp == Gzp)
20176           DiagBreak() ;
20177         gcap = &gca->priors[xp][yp][zp] ;
20178         if (gcap == NULL || gcap->nlabels == 0)
20179         {
20180           num++ ;
20181           nout++ ;
20182           total_log_p += min_log_p ;
20183           continue ;
20184         }
20185         if (GCApriorToSourceVoxel(gca, mri_inputs, transform,
20186                                   xp, yp, zp,&x,&y,&z) != NO_ERROR)
20187         {
20188           num++ ;
20189           nout++ ;
20190           total_log_p += min_log_p ;
20191           continue ;
20192         }
20193         if (x == Gx && y == Gy && z == Gz)
20194           DiagBreak() ;
20195         GCApriorToNode(gca, xp, yp, zp, &xn, &yn, &zn) ;
20196         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
20197         for (n = 0 ; n < gcap->nlabels ; n++)
20198         {
20199           label = gcap->labels[n] ;
20200           prior = gcap->priors[n] ;
20201           gc = GCAfindGC(gca, xn, yn, zn, label) ;
20202           if (gc == NULL)
20203           {
20204             num++ ;
20205             nout++ ;
20206             total_log_p += min_log_p ;
20207             continue ;
20208           }
20209           //        if (IS_BRAIN(label) == 0 || FZERO(prior))
20210           if (FZERO(prior))
20211             continue ;
20212           num++ ;
20213 
20214           log_p = gcaComputeLogDensity(gc, vals,gca->ninputs,prior, label);
20215           if (penalize_zero_brain && 
20216               FZERO(vals[0]) && 
20217               IS_BRAIN(label) && 
20218               !IS_CSF(label))
20219           {
20220             if (mri_orig)  // use unstripped volume to 
20221                            // see if this could have been brain
20222             {
20223               float      ovals[MAX_GCA_INPUTS] ;
20224               load_vals(mri_orig, x, y, z, ovals, gca->ninputs) ;
20225               if (ovals[0] >= fmin && 
20226                   ovals[0] <= fmax)  // could have been brain
20227               {
20228                 nz++ ;
20229                 log_p += min_log_p ;
20230               }
20231             }
20232             else
20233             {
20234               log_p += min_log_p ;
20235               nz++ ;
20236             }
20237           }
20238         }
20239         if (mri_ll)
20240           MRIsetVoxVal(mri_ll, x, y, z, 0, log_p) ;
20241         if (!finite(log_p))
20242           DiagBreak() ;
20243         total_log_p += log_p ;
20244       }
20245     }
20246   }
20247 
20248   if (mri_ll)
20249     MRIwrite(mri_ll, "ll.mgz") ;
20250 
20251   if (penalize_zero_brain)
20252     fprintf(stderr, "%d zero brain voxels\n", nz) ;
20253   return(total_log_p / (double)num) ;
20254 }
20255 #else
20256 double
20257 GCAimageLogLikelihood(GCA *gca, MRI *mri_inputs, TRANSFORM *transform)
20258 {
20259   int        x, y, z, width, height, depth, xn, yn, zn, n, label /*, found*/,
20260   xp, yp, zp ;
20261   GCA_NODE   *gcan ;
20262   GCA_PRIOR  *gcap ;
20263   GC1D       *gc ;
20264   double     total_log_p, log_p, min_log_p ;
20265   float      vals[MAX_GCA_INPUTS], min ;
20266 
20267   /* go through each voxel in the input volume and find the canonical
20268   voxel (and hence the classifier) to which it maps. Then update the
20269   classifiers statistics based on this voxel's intensity and label.
20270   */
20271   width = mri_inputs->width ;
20272   height = mri_inputs->height;
20273   depth = mri_inputs->depth ;
20274   min_log_p = 0 ;
20275   for (total_log_p = 0.0, x = 0 ; x < width ; x++)
20276   {
20277     for (y = 0 ; y < height ; y++)
20278     {
20279       for (z = 0 ; z < depth ; z++)
20280       {
20281         if (x == Gx && y == Gy && z == Gz)
20282           DiagBreak() ;
20283 
20284         load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ;
20285 
20286         /* find the node associated with this coordinate and classify */
20287         GCAsourceVoxelToNode(gca, mri_inputs,transform, x, y, z, &xn, &yn,&zn);
20288         if (xn < 0)
20289           xn = 0 ;
20290         else if (xn >= gca->node_width)
20291           xn = gca->node_width-1 ;
20292         if (yn < 0)
20293           yn = 0 ;
20294         else if (yn >= gca->node_height)
20295           yn = gca->node_height-1 ;
20296         if (zn < 0)
20297           zn = 0 ;
20298         else if (zn >= gca->node_depth)
20299           zn = gca->node_depth-1 ;
20300 
20301         gcan = &gca->nodes[xn][yn][zn] ;
20302         GCAsourceVoxelToPrior(gca, mri_inputs, transform, x, y, z,
20303                               &xp, &yp, &zp);
20304         if (xp < 0)
20305           xp = 0 ;
20306         else if (xp >= gca->prior_width)
20307           xp = gca->prior_width-1 ;
20308         if (yp < 0)
20309           yp = 0 ;
20310         else if (yp >= gca->prior_height)
20311           yp = gca->prior_height-1 ;
20312         if (zp < 0)
20313           zp = 0 ;
20314         else if (zp >= gca->prior_depth)
20315           zp = gca->prior_depth-1 ;
20316         gcap = &gca->priors[xp][yp][zp] ;
20317         if (gcap == NULL || gcan->nlabels == 1)
20318           label = gcan->labels[0] ;
20319         else
20320           label = gcaMaxPriorLabel(gca, mri_inputs, transform, x, y, z) ;
20321         for (n = 0 ; n < gcan->nlabels ; n++)
20322         {
20323           if (gcan->labels[n] == label)
20324             break ;
20325         }
20326         if (n < gcan->nlabels)
20327           gc = &gcan->gcs[n] ;
20328         else
20329           gc = findClosestValidGC(gca, xn, yn, zn, label, 0) ;
20330 
20331         log_p = gcaComputeLogDensity(gc, vals,gca->ninputs,
20332                                      getPrior(gcap, label),label) ;
20333         total_log_p += log_p ;
20334         if (log_p < min_log_p)
20335           min_log_p = log_p ;
20336         if (!check_finite("4", total_log_p))
20337         {
20338           DiagBreak() ;
20339           fprintf(stdout,
20340                   "total log p not finite at (%d, %d, %d)"
20341                   " n = %d,\n", x, y, z, n) ;
20342         }
20343       }
20344     }
20345   }
20346 #if 0
20347   for (x = 0 ; x < width ; x++)
20348   {
20349     for (y = 0 ; y < height ; y++)
20350     {
20351       for (z = 0 ; z < depth ; z++)
20352       {
20353         if (x == Gx && y == Gy && z == Gz)
20354           DiagBreak() ;
20355         found = 1 ;
20356         if (!GCAsourceVoxelToNode(gca, mri_inputs,
20357                                   transform, x, y, z, &xn, &yn, &zn))
20358         {
20359           gcan = &gca->nodes[xn][yn][zn] ;
20360           gcap = getGCAP(gca, mri_inputs, transform, x, y, z) ;
20361           if (gcap==NULL)
20362             found = 0 ;
20363           else
20364           {
20365             label = gcaMaxPriorLabel(gca, mri_inputs, transform, x, y, z) ;
20366             for (n = 0 ; n < gcan->nlabels ; n++)
20367             {
20368               if (gcan->labels[n] == label)
20369                 break ;
20370             }
20371             if (n >= gcan->nlabels)
20372               found = 0 ;
20373           }
20374         }
20375         else // outside fov
20376           found = 0 ;
20377         if (!found)
20378           total_log_p += min_log_p ; // penalize for non-found voxels
20379       }
20380     }
20381   }
20382 #endif
20383 
20384   total_log_p /= (double)(mri_inputs->width*
20385                           mri_inputs->height*
20386                           mri_inputs->depth);
20387   return(total_log_p) ;
20388 }
20389 #endif
20390 
20391 #if 0
20392 static int
20393 gcaMaxPriorLabel(GCA *gca, MRI *mri, TRANSFORM *transform, int x, int y, int z)
20394 {
20395   int        n, max_label ;
20396   GCA_PRIOR  *gcap ;
20397   float      maxp ;
20398 
20399   gcap = getGCAP(gca, mri, transform, x, y, z) ;
20400   if (gcap->nlabels == 0)
20401     return(0) ;
20402   maxp = gcap->priors[0] ;
20403   max_label = gcap->labels[0] ;
20404   for (n = 1 ; n < gcap->nlabels ; n++)
20405   {
20406     if (gcap->priors[n] > maxp)
20407     {
20408       maxp = gcap->priors[n] ;
20409       max_label = gcap->labels[n] ;
20410     }
20411   }
20412 
20413   return(max_label) ;
20414 }
20415 #endif
20416 #if 1
20417 static int entropy_labels[] =
20418   {
20419     Left_Cerebral_White_Matter,
20420     Left_Cerebral_Cortex,
20421     Left_Cerebellum_White_Matter,
20422     Left_Cerebellum_Cortex,
20423     Left_Amygdala,
20424     Left_Hippocampus,
20425     Left_Thalamus_Proper,
20426     Left_Pallidum,
20427     Left_Caudate,
20428     Left_Putamen,
20429     Left_Lateral_Ventricle,
20430     Left_Inf_Lat_Vent,
20431     Left_VentralDC,
20432     Brain_Stem,
20433     Third_Ventricle,
20434     Fourth_Ventricle,
20435   } ;
20436 
20437 static int contra_entropy_labels[] =
20438   {
20439     Right_Cerebral_White_Matter,
20440     Right_Cerebral_Cortex,
20441     Right_Cerebellum_White_Matter,
20442     Right_Cerebellum_Cortex,
20443     Right_Amygdala,
20444     Right_Hippocampus,
20445     Right_Thalamus_Proper,
20446     Right_Pallidum,
20447     Right_Caudate,
20448     Right_Putamen,
20449     Right_Lateral_Ventricle,
20450     Right_Inf_Lat_Vent,
20451     Right_VentralDC,
20452     Brain_Stem,
20453     Third_Ventricle,
20454     Fourth_Ventricle,
20455   } ;
20456 #else
20457 static int entropy_labels[] =
20458   {
20459     Right_Cerebral_White_Matter,
20460     Left_Cerebral_White_Matter,
20461     Left_Cerebral_Cortex,
20462     Right_Cerebral_Cortex,
20463     Left_Caudate,
20464     Right_Caudate
20465   } ;
20466 #endif
20467 #define NUM_ENTROPY_LABELS (sizeof(entropy_labels) / sizeof(entropy_labels[0]))
20468 #define NUM_CONTRA_LABELS (sizeof(contra_entropy_labels) / sizeof(contra_entropy_labels[0]))
20469 
20470 static int
20471 compute_ll_scale_change(GCA *gca, 
20472                         MRI *mri, 
20473                         MRI *mri_aseg, 
20474                         TRANSFORM *transform,
20475                         int *labels, int *contra_labels,
20476                         float *scales, int nlabels, float step_size)
20477 {
20478   float       dk[NUM_ENTROPY_LABELS] ;
20479   double      prior, plike, dist ;
20480   int         x, y, z, xn, yn, zn, l, num[NUM_ENTROPY_LABELS], ind ;
20481   GCA_PRIOR   *gcap ;
20482   GC1D        *gc ;
20483   float       vals[MAX_GCA_INPUTS] ;
20484   int         label_indices[MAX_CMA_LABEL+1], label ;
20485 
20486   memset(dk, 0, sizeof(dk)) ;
20487   memset(num, 0, sizeof(num)) ;
20488 
20489   for (l = 0 ; l <= MAX_CMA_LABEL ; l++)
20490     label_indices[l] = -1 ;
20491   for (l = 0 ; l < nlabels ; l++)
20492   {
20493     label_indices[labels[l]] = l ;
20494     label_indices[contra_labels[l]] = l ;
20495   }
20496 
20497   for (x = 0 ; x < mri->width ; x++)
20498   {
20499     for (y = 0 ; y < mri->height ; y++)
20500     {
20501       for (z = 0 ; z < mri->depth ; z++)
20502       {
20503         if (x == Gx && y == Gy && z == Gz)
20504           DiagBreak() ;
20505         load_vals(mri, x, y, z, vals, gca->ninputs) ;
20506         label = (int)MRIgetVoxVal(mri_aseg, x, y, z, 0) ;
20507         gcap = getGCAP(gca, mri, transform, x, y, z) ;
20508         ind = label_indices[label] ;
20509         if (gcap == NULL || gcap->nlabels <= 1 || ind < 0)
20510           continue ;
20511         if (MRIlabelsInNbhd
20512             (mri_aseg, x, y, z, 1, label) < 26)  // avoid border voxels
20513           continue ;
20514         if (!GCAsourceVoxelToNode(gca, mri, transform,x, y, z, &xn, &yn, &zn))
20515         {
20516           gc = GCAfindGC(gca, xn, yn, zn, label) ;
20517           if (gc == NULL)
20518             continue ;
20519           plike = GCAcomputeConditionalDensity(gc, vals, gca->ninputs, label) ;
20520           prior = getPrior(gcap, label) ;
20521 
20522           dist = vals[0]-(gc->means[0]*scales[ind]) ;
20523           if (FZERO(dist))
20524             continue ;
20525           num[ind]++ ;
20526           dk[ind] += plike * prior * dist / (fabs(dist)) ;
20527           if (!finite(dk[l]))
20528             DiagBreak() ;
20529         }
20530       }
20531     }
20532   }
20533   for (l = 0 ; l < nlabels ; l++)
20534     if (num[l] > 0)
20535     {
20536       if (!finite(dk[l]))
20537         DiagBreak() ;
20538       dk[l] /= num[l] ;
20539       scales[l] += step_size * dk[l] ;
20540     }
20541   return(NO_ERROR) ;
20542 }
20543 int
20544 GCArenormalizeWithEntropyMinimization(GCA *gca, 
20545                                       MRI *mri, 
20546                                       TRANSFORM *transform, 
20547                                       FILE *logfp)
20548 {
20549   float     scales[NUM_ENTROPY_LABELS], ll, last_ll, peaks[NUM_ENTROPY_LABELS],
20550     contra_peaks[NUM_CONTRA_LABELS], pct_change, 
20551     last_scales[NUM_ENTROPY_LABELS] ;
20552   int       i, done = 0, peak_bin ;
20553   HISTOGRAM *h_gca ;
20554   MRI       *mri_aseg ;
20555 
20556   for (i = 0 ; i < NUM_ENTROPY_LABELS ; i++)
20557   {
20558     scales[i] = 1.0 ;
20559     h_gca = gcaGetLabelHistogram(gca, entropy_labels[i], 0) ;
20560     peak_bin = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
20561     peaks[i] = h_gca->bins[peak_bin] ;
20562     HISTOfree(&h_gca) ;
20563 
20564     h_gca = gcaGetLabelHistogram(gca, contra_entropy_labels[i], 0) ;
20565     peak_bin = HISTOfindHighestPeakInRegion(h_gca, 0, h_gca->nbins) ;
20566     contra_peaks[i] = h_gca->bins[peak_bin] ;
20567     HISTOfree(&h_gca) ;
20568   }
20569 
20570   mri_aseg = GCAlabel(mri, gca, NULL, transform) ;
20571   if (Gdiag & DIAG_WRITE)
20572   {
20573     char fname[STRLEN] ;
20574     sprintf(fname, "seg%3.3d.mgz", 0) ;
20575     printf("writing current segmentation snapshot to %s\n", fname) ;
20576     MRIwrite(mri_aseg, fname) ;
20577   }
20578   last_ll = 
20579     ll = 
20580     GCAimagePosteriorLogProbability(gca, mri_aseg, mri, transform) ;
20581   printf("%3.3d: ll = %2.7f\n", 0, ll) ;
20582   i = 0 ;
20583   do
20584   {
20585     memmove(last_scales, scales, sizeof(scales)) ;
20586     compute_ll_scale_change(gca, mri, mri_aseg, 
20587                             transform, entropy_labels, 
20588                             contra_entropy_labels, 
20589                             scales, NUM_ENTROPY_LABELS,.1) ;
20590     gcaScale(gca, entropy_labels, contra_entropy_labels, 
20591              scales, NUM_ENTROPY_LABELS, 1);
20592     {
20593       int n ;
20594       for (n = 0 ; n < NUM_ENTROPY_LABELS ; n++)
20595         printf("scales[%s] = %2.3f, peak = %2.0f (rh=%2.0f)\n", 
20596                cma_label_to_name(entropy_labels[n]), scales[n],
20597                peaks[n]*scales[n], contra_peaks[n]*scales[n]) ;
20598     }
20599     ll = GCAimagePosteriorLogProbability(gca, mri_aseg, mri, transform) ;
20600     gcaScale(gca, entropy_labels, contra_entropy_labels, 
20601              scales, NUM_ENTROPY_LABELS, -1);
20602 
20603     pct_change = 100*(last_ll-ll) / last_ll ;
20604     if (pct_change < 0.01)
20605       done = 1 ;
20606     i++ ;
20607     printf("%3.3d: ll = %2.7f (%2.3f%%)\n", i, ll, pct_change) ;
20608     if (logfp)
20609       fprintf(logfp, "%3.3d: ll = %2.7f (%2.3f%%)\n", i, ll, pct_change) ;
20610     if (!((i+1)%1))
20611     {
20612       printf("recomputing MAP labels...\n") ;
20613       gcaScale(gca, entropy_labels, contra_entropy_labels, 
20614                scales, NUM_ENTROPY_LABELS, 1);
20615       GCAlabel(mri, gca, mri_aseg, transform) ;
20616       if (Gdiag & DIAG_WRITE && (!((i+1)%2)))
20617       {
20618         char fname[STRLEN] ;
20619         sprintf(fname, "seg%3.3d.mgz", i+1) ;
20620         printf("writing current segmentation snapshot to %s\n", fname) ;
20621         MRIwrite(mri_aseg, fname) ;
20622       }
20623       ll = GCAimagePosteriorLogProbability(gca, mri_aseg, mri, transform) ;
20624       gcaScale(gca, entropy_labels, contra_entropy_labels, 
20625                scales, NUM_ENTROPY_LABELS, -1);
20626     }
20627     if (last_ll < ll)
20628       memmove(scales, last_scales, sizeof(scales)) ;
20629 
20630     last_ll = ll ;
20631     if (i < 8)
20632       done = 0 ;
20633     if (logfp)
20634       fflush(logfp) ;
20635   }
20636   while (!done) ;
20637 
20638   for (i = 0 ; i < NUM_ENTROPY_LABELS ; i++)
20639   {
20640     printf("scaling %s by %2.3f from %2.0f to %2.0f (rh=%2.0f)\n", 
20641            cma_label_to_name(entropy_labels[i]), scales[i],
20642            peaks[i], peaks[i]*scales[i], contra_peaks[i]*scales[i]) ;
20643     if (logfp)
20644       fprintf(logfp, "scaling %s by %2.3f from %2.0f to %2.0f (rh=%2.0f)\n",
20645               cma_label_to_name(entropy_labels[i]), scales[i],
20646               peaks[i], peaks[i]*scales[i], contra_peaks[i]*scales[i]) ;
20647   }
20648   if (logfp)
20649     fflush(logfp) ;
20650   gcaScale(gca, entropy_labels, contra_entropy_labels, 
20651            scales, NUM_ENTROPY_LABELS, 1);
20652   return(NO_ERROR) ;
20653 }
20654 
20655 #if 0
20656 static double
20657 GCAcomputeScaledMeanEntropy(GCA *gca, 
20658                             MRI *mri, 
20659                             TRANSFORM *transform, 
20660                             int *labels, float *scales, int nlabels)
20661 {
20662   double      entropy, entropy_total, p[MAX_LABELS_PER_GCAN], 
20663     ptotal, max_prior, max_like, p_like ;
20664   int         x, y, z, c, xn, yn, zn, num, max_prior_c, max_like_c, l, i ;
20665   GCA_PRIOR   *gcap ;
20666   GC1D        *gc ;
20667   float      vals[MAX_GCA_INPUTS] ;
20668   int         label_indices[MAX_CMA_LABEL+1] ;
20669 
20670   for (l = 0 ; l <= MAX_CMA_LABEL ; l++)
20671     label_indices[l] = -1 ;
20672   for (l = 0 ; l < nlabels ; l++)
20673     label_indices[labels[l]] = l ;
20674 
20675   for (num = 0, entropy_total = 0.0, x = 0 ; x < mri->width ; x++)
20676   {
20677     for (y = 0 ; y < mri->height ; y++)
20678     {
20679       for (z = 0 ; z < mri->depth ; z++)
20680       {
20681         if (x == Gx && y == Gy && z == Gz)
20682           DiagBreak() ;
20683         load_vals(mri, x, y, z, vals, gca->ninputs) ;
20684         if (vals[0] < 40)
20685           continue ;  // skull stripped region
20686         gcap = getGCAP(gca, mri, transform, x, y, z) ;
20687         if (gcap == NULL || gcap->nlabels <= 1)
20688           continue ;
20689         if (!GCAsourceVoxelToNode(gca, mri, transform,x, y, z, &xn, &yn, &zn))
20690         {
20691           max_prior = max_like = 0 ;
20692           max_prior_c = max_like_c = 0 ;
20693           for (ptotal = 0, c = 0 ; c < gcap->nlabels ; c++)
20694           {
20695             gc = GCAfindGC(gca, xn, yn, zn, gcap->labels[c]) ;
20696             if (gc == NULL)
20697             {
20698               p[c] = 0 ;
20699               continue ;
20700             }
20701             if (label_indices[gcap->labels[c]] >= 0)  // scale up
20702             {
20703               for (i = 0 ; i < gca->ninputs ; i++)
20704                 gc->means[i] += scales[label_indices[gcap->labels[c]]] ;
20705             }
20706             p_like = GCAcomputeConditionalDensity(gc, 
20707                                                   vals, 
20708                                                   gca->ninputs, 
20709                                                   gcap->labels[c]) ;
20710             p[c] = gcap->priors[c]*p_like ;
20711             if (label_indices[gcap->labels[c]] >= 0)  // scale back down
20712             {
20713               for (i = 0 ; i < gca->ninputs ; i++)
20714                 gc->means[i] -= scales[label_indices[gcap->labels[c]]] ;
20715             }
20716             ptotal += p[c] ;
20717             if (gcap->priors[c] > max_prior)
20718             {
20719               max_prior = gcap->priors[c] ;
20720               max_prior_c = c ;
20721             }
20722             if (p_like > max_like)
20723             {
20724               max_like = p_like ;
20725               max_like_c = c ;
20726             }
20727           }
20728           if (FZERO(ptotal))
20729             continue ;
20730           for (entropy = 0.0, c = 0 ; c < gcap->nlabels ; c++)
20731           {
20732             p[c] /= ptotal ;
20733             if (DZERO(p[c]))
20734               continue ;
20735             //            if (c == max_prior_c && c == max_like_c)
20736             {
20737               if (label_indices[gcap->labels[c]] >= 0)
20738                 DiagBreak() ;
20739               entropy += p[c] * log(p[c]) ;
20740             }
20741           }
20742           num++ ;
20743           if (!finite(entropy))
20744             DiagBreak() ;
20745           entropy_total += entropy ;
20746         }
20747       }
20748     }
20749   }
20750 
20751   return(-entropy_total/num) ;
20752 }
20753 #endif
20754 double
20755 GCAcomputeMeanEntropy(GCA *gca, MRI *mri, TRANSFORM *transform)
20756 {
20757   double      entropy, entropy_total, p[MAX_LABELS_PER_GCAN], ptotal, max_p ;
20758   int         x, y, z, c, xn, yn, zn, num, max_c ;
20759   GCA_PRIOR   *gcap ;
20760   GC1D        *gc ;
20761   float      vals[MAX_GCA_INPUTS] ;
20762 
20763   num = 0 ;
20764   for (entropy_total = 0.0, x = 0 ; x < mri->width ; x++)
20765   {
20766     for (y = 0 ; y < mri->height ; y++)
20767     {
20768       for (z = 0 ; z < mri->depth ; z++)
20769       {
20770         if (x == Gx && y == Gy && z == Gz)
20771           DiagBreak() ;
20772         gcap = getGCAP(gca, mri, transform, x, y, z) ;
20773         if (gcap == NULL || gcap->nlabels <= 1)
20774           continue ;
20775         if (!GCAsourceVoxelToNode(gca, mri, transform,x, y, z, &xn, &yn, &zn))
20776         {
20777           load_vals(mri, x, y, z, vals, gca->ninputs) ;
20778           max_p = 0 ;
20779           max_c = 0 ;
20780           for (ptotal = 0, c = 0 ; c < gcap->nlabels ; c++)
20781           {
20782             gc = GCAfindGC(gca, xn, yn, zn, gcap->labels[c]) ;
20783             if (gc == NULL)
20784             {
20785               p[c] = 0 ;
20786               continue ;
20787             }
20788             p[c] = GCAcomputeConditionalDensity(gc, 
20789                                                 vals, 
20790                                                 gca->ninputs, 
20791                                                 gcap->labels[c]) ;
20792             ptotal += p[c] ;
20793             if (p[c] > max_p)
20794             {
20795               max_p = p[c] ;
20796               max_c = c ;
20797             }
20798           }
20799           if (FZERO(ptotal))
20800             continue ;
20801           for (entropy = 0.0, c = 0 ; c < gcap->nlabels ; c++)
20802           {
20803             p[c] /= ptotal ;
20804             if (DZERO(p[c]))
20805               continue ;
20806             entropy += p[c] * log(p[c]) ;
20807           }
20808           num++ ;
20809           if (!finite(entropy))
20810             DiagBreak() ;
20811           entropy_total += entropy ;
20812         }
20813       }
20814     }
20815   }
20816 
20817   return(-entropy_total/num) ;
20818 }
20819 static int
20820 gcaScale(GCA *gca, 
20821          int *labels, 
20822          int *contra_labels, 
20823          float *scales, 
20824          int nlabels, 
20825          int dir)
20826 {
20827   int         label_indices[MAX_CMA_LABEL+1], x, y, z, n, label, ind, i ;
20828   GC1D        *gc ;
20829   GCA_NODE    *gcan ;
20830   float       scale ;
20831 
20832 
20833   for (i = 0 ; i <= MAX_CMA_LABEL ; i++)
20834     label_indices[i] = -1 ;
20835   for (i = 0 ; i < nlabels ; i++)
20836   {
20837     label_indices[labels[i]] = i ;
20838     label_indices[contra_labels[i]] = i ;
20839   }
20840 
20841   for (x = 0 ; x < gca->node_width ; x++)
20842   {
20843     for (y = 0 ; y < gca->node_height ; y++)
20844     {
20845       for (z = 0 ; z < gca->node_depth ; z++)
20846       {
20847         gcan = &gca->nodes[x][y][z] ;
20848         for (n = 0 ; n < gcan->nlabels ; n++)
20849         {
20850           label = gcan->labels[n] ;
20851           ind = label_indices[label] ;
20852           if (ind < 0)
20853             continue ;
20854           scale = scales[ind] ;
20855           gc = &gcan->gcs[n] ;
20856           for (i = 0 ; i < gca->ninputs ; i++)
20857           {
20858             if (dir > 0)
20859               gc->means[i] *= scale ;
20860             else
20861               gc->means[i] /= scale ;
20862           }
20863         }
20864       }
20865     }
20866   }
20867   return(NO_ERROR) ;
20868 }
20869 
20870 static int
20871 gcapGetMaxPriorLabel(GCA_PRIOR *gcap, double *p_prior)
20872 {
20873   int n, best_label = 0 ;
20874   float max_p ;
20875 
20876   *p_prior = 0 ;
20877   if (gcap == NULL)
20878     return(0) ;
20879 
20880   max_p = -1 ;
20881   for (n = 0 ; n < gcap->nlabels ; n++)
20882   {
20883     if (gcap->priors[n] > max_p)
20884     {
20885       max_p = gcap->priors[n] ;
20886       best_label = gcap->labels[n] ;
20887     }
20888   }
20889   *p_prior = max_p ;
20890   return(best_label) ;
20891 }
20892 
20893 #if 0
20894 static int
20895 gcapBrainIsPossible(GCA_PRIOR *gcap)
20896 {
20897   int possible, n ;
20898 
20899   for (n = possible = 0 ; n < gcap->nlabels ; n++)
20900     if (IS_BRAIN(gcap->labels[n]))
20901     {
20902       possible = 1 ;
20903       break ;
20904     }
20905   return(possible) ;
20906 }
20907 #endif
20908 float
20909 GCAcomputeLabelPosterior(GCA *gca, TRANSFORM *transform, MRI *mri, float x, float y, float z, int label)
20910 {
20911   float    p, plabel, vals[MAX_GCA_INPUTS], ptotal ;
20912   GCA_PRIOR *gcap ;
20913   int       n, olabel ;
20914 
20915   load_vals(mri, x, y, z, vals, gca->ninputs) ;
20916   gcap = getGCAPfloat(gca, mri, transform, x, y, z) ;
20917   if (gcap == NULL)
20918     return(0.0) ;
20919 
20920   if (gcap->total_training > 0)
20921     plabel = .01 / gcap->total_training ;
20922   else
20923     plabel = 0.0 ;
20924   for (ptotal = 0.0, n = 0 ; n < gcap->nlabels ; n++)
20925   {
20926     olabel = gcap->labels[n] ;
20927     p = 
20928       GCAlabelProbability(mri, gca, transform, x, y, z, olabel)
20929       * gcap->priors[n];
20930     if (olabel == label)
20931       plabel = p ;
20932 
20933     ptotal += p ;
20934   }
20935 
20936   if (!FZERO(ptotal))
20937     plabel /= ptotal ;
20938   return(plabel) ;
20939 }
20940 
20941 float
20942 GCAcomputeLabelLikelihood(GCA *gca, TRANSFORM *transform, MRI *mri, float x, float y, float z, int label)
20943 {
20944   float    p, plabel, vals[MAX_GCA_INPUTS], ptotal ;
20945   GCA_PRIOR *gcap ;
20946   int       n, olabel, found = 0 ;
20947 
20948   gcap = getGCAPfloat(gca, mri, transform, x, y, z) ;
20949   if (gcap == NULL)
20950     return(0.0) ;
20951 
20952   if (gcap->total_training > 0)
20953     plabel = .01 / gcap->total_training ;
20954   else
20955     plabel = 0.0 ;
20956   for (ptotal = 0.0, n = 0 ; n < gcap->nlabels ; n++)
20957   {
20958     olabel = gcap->labels[n] ;
20959     p =  GCAlabelProbability(mri, gca, transform, x, y, z, olabel);
20960     if (olabel == label)
20961     {
20962       found = 1 ;
20963       plabel = p ;
20964     }
20965 
20966     ptotal += p ;
20967   }
20968 
20969   if (found == 0)
20970   {
20971     GC1D *gc ;
20972     int  xn, yn, zn ;
20973 
20974     if (!GCAsourceVoxelToNode(gca, mri, transform, x, y, z, &xn, &yn, &zn))
20975     {
20976       gc = findClosestValidGC(gca, xn, yn, zn, label, 0) ;
20977       if (gc == NULL)
20978         DiagBreak() ;
20979       else
20980       {
20981         load_vals(mri, x, y, z, vals, gca->ninputs) ;
20982         plabel = GCAcomputeConditionalDensity(gc, vals, gca->ninputs, label) ;
20983         ptotal += plabel ;
20984       }
20985     }
20986   }
20987 
20988   if (!FZERO(ptotal))
20989     plabel /= ptotal ;
20990   return(plabel) ;
20991 }
20992 

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.