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.- [get | view] (2009-01-26 22:35:31, 625.2 KB) [[attachment:gca.c]]
- [get | view] (2009-01-26 22:35:31, 19.3 KB) [[attachment:gca.h]]
- [get | view] (2009-01-26 22:35:31, 3.1 KB) [[attachment:load_gca.m]]
You are not allowed to attach a file to this page.