int main(int argc, char *argv[]) { char **av, fname[STRLEN], *out_fname, *subject_name, *cp ; int ac, nargs, i, n, noint = 0, options ; int msec, minutes, seconds, nsubjects, input ; struct timeb start ; GCA *gca ; MRI *mri_seg, *mri_tmp, *mri_inputs ; TRANSFORM *transform ; LTA *lta; GCA_BOUNDARY *gcab ; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; parms.use_gradient = 0 ; spacing = 8 ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_gcab_train.c,v 1.4 2011/03/16 20:23:33 fischl Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; // parse command line args ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } printf("reading gca from %s\n", argv[1]) ; gca = GCAread(argv[1]) ; if (!gca) exit(Gerror) ; if (!strlen(subjects_dir)) /* hasn't been set on command line */ { cp = getenv("SUBJECTS_DIR") ; if (!cp) ErrorExit(ERROR_BADPARM, "%s: SUBJECTS_DIR not defined in environment", Progname); strcpy(subjects_dir, cp) ; if (argc < 4) usage_exit(1) ; } // options parsed. subjects and gca name remaining out_fname = argv[argc-1] ; nsubjects = argc-3 ; for (options = i = 0 ; i < nsubjects ; i++) { if (argv[i+1][0] == '-') { nsubjects-- ; options++ ; } } printf("training on %d subject and writing results to %s\n", nsubjects, out_fname) ; n = 0 ; gcab = GCABalloc(gca, 8, 0, 30, 10, target_label); strcpy(gcab->gca_fname, argv[1]) ; // going through the subject one at a time for (nargs = i = 0 ; i < nsubjects+options ; i++) { subject_name = argv[i+2] ; ////////////////////////////////////////////////////////////// printf("***************************************" "************************************\n"); printf("processing subject %s, %d of %d...\n", subject_name,i+1-nargs, nsubjects); if (stricmp(subject_name, "-NOINT") == 0) { printf("not using intensity information for subsequent subjects...\n"); noint = 1 ; nargs++ ; continue ; } else if (stricmp(subject_name, "-INT") == 0) { printf("using intensity information for subsequent subjects...\n"); noint = 0 ; nargs++ ; continue ; } // reading this subject segmentation sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, seg_dir) ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) fprintf(stderr, "Reading segmentation from %s...\n", fname) ; mri_seg = MRIread(fname) ; if (!mri_seg) ErrorExit(ERROR_NOFILE, "%s: could not read segmentation file %s", Progname, fname) ; if ((mri_seg->type != MRI_UCHAR) && (mri_seg->type != MRI_FLOAT)) { ErrorExit (ERROR_NOFILE, "%s: segmentation file %s is not type UCHAR or FLOAT", Progname, fname) ; } if (binarize) { int j ; for (j = 0 ; j < 256 ; j++) { if (j == binarize_in) MRIreplaceValues(mri_seg, mri_seg, j, binarize_out) ; else MRIreplaceValues(mri_seg, mri_seg, j, 0) ; } } if (insert_fname) { MRI *mri_insert ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, insert_fname) ; mri_insert = MRIread(fname) ; if (mri_insert == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read volume from %s for insertion", Progname, insert_fname) ; MRIbinarize(mri_insert, mri_insert, 1, 0, insert_label) ; MRIcopyLabel(mri_insert, mri_seg, insert_label) ; MRIfree(&mri_insert) ; } replaceLabels(mri_seg) ; MRIeraseBorderPlanes(mri_seg, 1) ; for (input = 0 ; input < gca->ninputs ; input++) { //////////// set the gca type ////////////////////////////// // is this T1/PD training? // how can we allow flash data training ??????? // currently checks the TE, TR, FA to be the same for all inputs // thus we cannot allow flash data training. //////////////////////////////////////////////////////////// sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name,input_names[input]); if (DIAG_VERBOSE_ON) printf("reading co-registered input from %s...\n", fname) ; fprintf(stderr, " reading input %d: %s\n", input, fname); mri_tmp = MRIread(fname) ; if (!mri_tmp) ErrorExit (ERROR_NOFILE, "%s: could not read image from file %s", Progname, fname) ; // input check 1 if (getSliceDirection(mri_tmp) != MRI_CORONAL) { ErrorExit (ERROR_BADPARM, "%s: must be in coronal direction, but it is not\n", fname); } // input check 2 if (mri_tmp->xsize != 1 || mri_tmp->ysize != 1 || mri_tmp->zsize != 1) { ErrorExit (ERROR_BADPARM, "%s: must have 1mm voxel size, but have (%f, %f, %f)\n", fname, mri_tmp->xsize, mri_tmp->ysize, mri_tmp->ysize); } // input check 3 is removed. now we can handle c_(ras) != 0 case // input check 4 if (i == 0) { TRs[input] = mri_tmp->tr ; FAs[input] = mri_tmp->flip_angle ; TEs[input] = mri_tmp->te ; } else if (!FEQUAL(TRs[input],mri_tmp->tr) || !FEQUAL(FAs[input],mri_tmp->flip_angle) || !FEQUAL(TEs[input], mri_tmp->te)) ErrorExit (ERROR_BADPARM, "%s: subject %s input volume %s: sequence parameters " "(%2.1f, %2.1f, %2.1f)" "don't match other inputs (%2.1f, %2.1f, %2.1f)", Progname, subject_name, fname, mri_tmp->tr, DEGREES(mri_tmp->flip_angle), mri_tmp->te, TRs[input], DEGREES(FAs[input]), TEs[input]) ; // first time do the following if (input == 0) { int nframes = gca->ninputs ; /////////////////////////////////////////////////////////// mri_inputs = MRIallocSequence(mri_tmp->width, mri_tmp->height, mri_tmp->depth, mri_tmp->type, nframes) ; if (!mri_inputs) ErrorExit (ERROR_NOMEMORY, "%s: could not allocate input volume %dx%dx%dx%d", mri_tmp->width, mri_tmp->height, mri_tmp->depth,nframes) ; MRIcopyHeader(mri_tmp, mri_inputs) ; } // -mask option //////////////////////////////////////////// if (mask_fname) { MRI *mri_mask ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, mask_fname); printf("reading volume %s for masking...\n", fname) ; mri_mask = MRIread(fname) ; if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n", Progname, fname) ; MRImask(mri_tmp, mri_mask, mri_tmp, 0, 0) ; MRIfree(&mri_mask) ; } MRIcopyFrame(mri_tmp, mri_inputs, 0, input) ; MRIfree(&mri_tmp) ; }// end of inputs per subject ///////////////////////////////////////////////////////// // xform_name is given, then we can use the consistent c_(r,a,s) for gca ///////////////////////////////////////////////////////// if (xform_name) { // we read talairach.xfm which is a RAS-to-RAS sprintf(fname, "%s/%s/mri/transforms/%s", subjects_dir, subject_name, xform_name) ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) printf("INFO: reading transform file %s...\n", fname); if (!FileExists(fname)) { fprintf(stderr,"ERROR: cannot find transform file %s\n",fname); exit(1); } transform = TransformRead(fname); if (!transform) ErrorExit(ERROR_NOFILE, "%s: could not read transform from file %s", Progname, fname); modify_transform(transform, mri_inputs, gca); // Here we do 2 things // 1. modify gca direction cosines to // that of the transform destination (both linear and non-linear) // 2. if ras-to-ras transform, // then change it to vox-to-vox transform (linear case) // modify transform to store inverse also TransformInvert(transform, mri_inputs) ; // verify inverse lta = (LTA *) transform->xform; } else { GCAreinit(mri_inputs, gca); // just use the input value, since dst = src volume transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ; } //////////////////////////////////////////////////////////////////// // train gca //////////////////////////////////////////////////////////////////// // segmentation is seg volume // inputs is the volumes of all inputs // transform is for this subject // noint is whether to use intensity information or not GCABtrain(gcab, mri_inputs, mri_seg, transform, target_label) ; MRIfree(&mri_seg) ; MRIfree(&mri_inputs) ; TransformFree(&transform) ; } GCABcompleteTraining(gcab) ; if (smooth > 0) { printf("regularizing conditional densities with smooth=%2.2f\n", smooth) ; GCAregularizeConditionalDensities(gca, smooth) ; } if (navgs) { printf("applying mean filter %d times to conditional densities\n", navgs) ; GCAmeanFilterConditionalDensities(gca, navgs) ; } printf("writing trained GCAB to %s...\n", out_fname) ; if (GCABwrite(gcab, out_fname) != NO_ERROR) ErrorExit (ERROR_BADFILE, "%s: could not write gca to %s", Progname, out_fname) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRI *mri ; mri = GCAbuildMostLikelyVolume(gca, NULL) ; MRIwrite(mri, "m.mgz") ; MRIfree(&mri) ; } if (histo_fname) { FILE *fp ; int histo_counts[10000], xn, yn, zn, max_count ; GCA_NODE *gcan ; memset(histo_counts, 0, sizeof(histo_counts)) ; fp = fopen(histo_fname, "w") ; if (!fp) ErrorExit(ERROR_BADFILE, "%s: could not open histo file %s", Progname, histo_fname) ; max_count = 0 ; for (xn = 0 ; xn < gca->node_width; xn++) { for (yn = 0 ; yn < gca->node_height ; yn++) { for (zn = 0 ; zn < gca->node_depth ; zn++) { gcan = &gca->nodes[xn][yn][zn] ; if (gcan->nlabels < 1) continue ; if (gcan->nlabels == 1 && IS_UNKNOWN(gcan->labels[0])) continue ; histo_counts[gcan->nlabels]++ ; if (gcan->nlabels > max_count) max_count = gcan->nlabels ; } } } max_count = 20 ; for (xn = 1 ; xn < max_count ; xn++) fprintf(fp, "%d %d\n", xn, histo_counts[xn]) ; fclose(fp) ; } GCAfree(&gca) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("classifier array training took %d minutes" " and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
static RANDOM_FOREST * train_rforest(MRI *mri_inputs[MAX_SUBJECTS][MAX_TIMEPOINTS], MRI *mri_segs[MAX_SUBJECTS][MAX_TIMEPOINTS], TRANSFORM *transforms[MAX_SUBJECTS][MAX_TIMEPOINTS], int nsubjects, GCA *gca, RFA_PARMS *parms, float wm_thresh, int wmsa_whalf, int ntp) { RANDOM_FOREST *rf ; int nfeatures, x, y, z, ntraining, n, tvoxel_size, width, height, depth, xt, yt, zt ; double xatlas, yatlas, zatlas ; MRI *mri_in, *mri_seg, *mri_training_voxels, *mri_wmsa_possible ; TRANSFORM *transform ; double **training_data ; int *training_classes, i, label, tlabel, nwmsa, nfuture, nnot, correct, label_time1, label_time2; nwmsa = nnot = nfuture = 0 ; /* features are: t1 intensity (3 vols) 3 priors # of unknown voxels in the nbhd # of neighboring wmsa voxels at t1 */ nfeatures = parms->wsize*parms->wsize*parms->wsize*parms->nvols + 5 ; rf = RFalloc(parms->ntrees, nfeatures, NCLASSES, parms->max_depth, single_classifier_names, max_steps) ; if (rf == NULL) ErrorExit(ERROR_NOFILE, "%s: could not allocate random forest", Progname) ; rf->min_step_size = 1 ; tvoxel_size=1 ; width = (int)ceil((float)mri_segs[0][0]->width/tvoxel_size) ; height = (int)ceil((float)mri_segs[0][0]->height/tvoxel_size) ; depth = (int)ceil((float)mri_segs[0][0]->depth/tvoxel_size) ; mri_wmsa_possible = MRIalloc(width, height, depth, MRI_UCHAR) ; GCAcopyDCToMRI(gca, mri_wmsa_possible) ; mri_in = mri_inputs[0][0] ; mri_training_voxels = MRIallocSequence(mri_in->width,mri_in->height, mri_in->depth,MRI_UCHAR,nsubjects) ; #if 1 // update time 1 segmentation based on labels at time1 and time2 for (n = 0 ; n < nsubjects ; n++) { mri_seg = mri_segs[n][0] ; for (x = 0 ; x < mri_in->width ; x++) for (y = 0 ; y < mri_in->height ; y++) for (z = 0 ; z < mri_in->depth ; z++) { label_time1 = MRIgetVoxVal(mri_segs[n][0], x, y, z, 0) ; label_time2 = MRIgetVoxVal(mri_segs[n][1], x, y, z, 0) ; if (IS_WMSA(label_time1)) MRIsetVoxVal(mri_segs[n][0], x, y, z, 0, label_time1) ; else if (IS_WMSA(label_time2)) MRIsetVoxVal(mri_segs[n][0], x, y, z, 0, future_WMSA) ; } } #endif // build map of spatial locations that WMSAs can possibly occur in for (n = 0 ; n < nsubjects ; n++) { mri_in = mri_inputs[n][1] ; transform = transforms[n][1] ; for (x = 0 ; x < mri_in->width ; x++) for (y = 0 ; y < mri_in->height ; y++) for (z = 0 ; z < mri_in->depth ; z++) if (is_possible_wmsa(gca, mri_in, transform, x, y, z, 0)) { TransformSourceVoxelToAtlas(transform, mri_in, x, y, z, &xatlas, &yatlas, &zatlas) ; xt = nint(xatlas/tvoxel_size) ; yt = nint(yatlas/tvoxel_size) ; zt = nint(zatlas/tvoxel_size) ; if (xt == Gx && yt == Gy && zt == Gz) DiagBreak() ; MRIsetVoxVal(mri_wmsa_possible, xt, yt, zt, 0, 1) ; } } for ( ; wmsa_whalf > 0 ; wmsa_whalf--) MRIdilate(mri_wmsa_possible, mri_wmsa_possible) ; // now build map of all voxels in training set for (nnot = nwmsa = nfuture = ntraining = n = 0 ; n < nsubjects ; n++) { mri_in = mri_inputs[n][0] ; mri_seg = mri_segs[n][0] ; transform = transforms[n][0] ; for (x = 0 ; x < mri_in->width ; x++) for (y = 0 ; y < mri_in->height; y++) for (z = 0 ; z < mri_in->depth; z++) { label = MRIgetVoxVal(mri_seg, x, y, z, 0) ; TransformSourceVoxelToAtlas(transform, mri_in, x, y, z, &xatlas, &yatlas, &zatlas) ; xt = nint(xatlas/tvoxel_size) ; yt = nint(yatlas/tvoxel_size) ; zt = nint(zatlas/tvoxel_size) ; if (xt == Gx && yt == Gy && zt == Gz) DiagBreak() ; if ((IS_WMSA(label) == 0) && MRIgetVoxVal(mri_wmsa_possible,xt,yt, zt,0) == 0) continue ; if (NOT_TRAINING_LABEL(label)) continue ; ntraining++ ; if (IS_FUTURE_WMSA(label)) { label = FUTURE_WMSA; nfuture++ ; } else if (IS_WMSA(label)) { label = WMSA ; nwmsa++ ; } else { label = NOT_WMSA ; nnot++ ; } // set label to one more than it will be for training so that 0 means this is not a training voxel MRIsetVoxVal(mri_training_voxels, x, y, z, n, label+1) ; } } correct = MRIcountNonzero(mri_training_voxels) ; if (correct != ntraining) DiagBreak() ; printf("total training set size = %2.1fM\n", (float)ntraining/(1024.0f*1024.0f)) ; printf("initial training set found with %dK FUTURE WMSA labels, %dK WMSA labels, and %dK non (ratio=%2.1f:%2.1f)\n", nfuture/1000, nwmsa/1000, nnot/1000, (float)nnot/(float)nfuture, (float)nnot/(float)nwmsa) ; MRIfree(&mri_wmsa_possible) ; if (max_wm_wmsa_ratio*(nfuture+nwmsa) < nnot) // too many wm labels w.r.t. # of wmsas - remove some wm { int removed, total_to_remove = nnot - (max_wm_wmsa_ratio*(nfuture+nwmsa)) ; double premove ; premove = (double)total_to_remove / (double)nnot ; printf("removing %dK WM indices to reduce training set imbalance (p < %f)\n", total_to_remove/1000, premove) ; for (removed = n = 0 ; n < nsubjects ; n++) for (x = 0 ; x < mri_in->width ; x++) for (y = 0 ; y < mri_in->height; y++) for (z = 0 ; z < mri_in->depth; z++) { label = MRIgetVoxVal(mri_training_voxels, x, y, z, n) ; if (label == 1) // a WM voxel { if (randomNumber(0,1) < premove) { removed++ ; MRIsetVoxVal(mri_training_voxels, x, y, z, n, 0) ; // remove it from training set } } } ntraining -= removed ; printf("%d WM voxels removed, new training set size = %dM (ratio = %2.1f)\n", removed, ntraining/(1024*1024), (double)(nnot-removed)/(double)(nwmsa+nfuture)) ; } correct = MRIcountNonzero(mri_training_voxels) ; if (correct != ntraining) DiagBreak() ; // if (Gx >= 0) { int whalf = (parms->wsize-1)/2 ; char buf[STRLEN] ; rf->feature_names = (char **)calloc(rf->nfeatures, sizeof(char *)) ; for (i = 0, x = -whalf ; x <= whalf ; x++) for (y = -whalf ; y <= whalf ; y++) for (z = -whalf ; z <= whalf ; z++) for (n = 0 ; n < mri_in->nframes ; n++, i++) { switch (n) { default: case 0: sprintf(buf, "T1(%d, %d, %d)", x, y, z) ; break ; case 1: sprintf(buf, "T2(%d, %d, %d)", x, y, z) ; break ; case 2: sprintf(buf, "FLAIR(%d, %d, %d)", x, y, z) ; if (x == 0 && y == 0 && z == 0) Gdiag_no = i ; break ; } rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ; strcpy(rf->feature_names[i], buf) ; } printf("FLAIR(0,0,0) = %dth feature\n", Gdiag_no) ; sprintf(buf, "CSF voxels in nbhd") ; rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ; strcpy(rf->feature_names[i], buf) ; i++ ; sprintf(buf, "gm prior") ; rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ; strcpy(rf->feature_names[i], buf) ; i++ ; sprintf(buf, "wm prior") ; rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ; strcpy(rf->feature_names[i], buf) ; i++ ; sprintf(buf, "csf prior") ; rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ; strcpy(rf->feature_names[i], buf) ; i++ ; sprintf(buf, "WMSA in nbhd") ; rf->feature_names[i] = (char *)calloc(strlen(buf)+1, sizeof(char)) ; strcpy(rf->feature_names[i], buf) ; if (Gdiag & DIAG_WRITE) { printf("writing training voxels to tv.mgz\n") ; MRIwrite(mri_training_voxels, "tv.mgz") ; } } // now build training features and classes training_classes = (int *)calloc(ntraining, sizeof(training_classes[0])) ; if (training_classes == NULL) ErrorExit(ERROR_NOFILE, "train_rforest: could not allocate %d-length training buffers",ntraining); training_data = (double **)calloc(ntraining, sizeof(training_data[0])) ; if (training_classes == NULL) ErrorExit(ERROR_NOFILE, "train_rforest: could not allocate %d-length training buffers",ntraining); for (i = n = 0 ; n < nsubjects ; n++) { mri_in = mri_inputs[n][0] ; mri_seg = mri_segs[n][0] ; transform = transforms[n][0] ; for (x = 0 ; x < mri_in->width ; x++) for (y = 0 ; y < mri_in->height; y++) for (z = 0 ; z < mri_in->depth; z++) { if ((int)MRIgetVoxVal(mri_training_voxels, x, y, z, n) == 0) continue ; label = MRIgetVoxVal(mri_seg, x, y, z, 0) ; TransformSourceVoxelToAtlas(transform, mri_in, x, y, z, &xatlas, &yatlas, &zatlas) ; xt = nint(xatlas/tvoxel_size) ; yt = nint(yatlas/tvoxel_size) ; zt = nint(zatlas/tvoxel_size) ; if (IS_FUTURE_WMSA(label)) tlabel = FUTURE_WMSA ; else if (IS_WMSA(label)) tlabel = WMSA ; else tlabel= NOT_WMSA ; training_classes[i] = tlabel ; training_data[i] = (double *)calloc(nfeatures, sizeof(double)) ; if (training_data[i] == NULL) ErrorExit(ERROR_NOMEMORY, "train_rforest: could not allocate %d-len feature vector #%d", nfeatures, i) ; training_classes[i] = training_classes[i] ; // extract_feature(mri_in, parms->wsize, x, y, z, training_data[i], xatlas, yatlas, zatlas) ; extract_long_features(mri_in, mri_seg, transform, gca, parms->wsize, x, y, z, training_data[i]) ; if (training_data[i][Gdiag_no] < 80 && training_classes[i] == 1) DiagBreak() ; i++ ; } MRIfree(&mri_in) ; MRIfree(&mri_seg) ; TransformFree(&transform) ; } if (i < ntraining) { printf("warning!!!! i (%d) < ntraining (%d)! Setting ntraining=i\n", i, ntraining) ; ntraining = i ; } printf("training random forest with %dK FUTURE WMSA labels, %dK WMSA labels, and %dK non (ratio=%2.1f:%2.1f)\n", nfuture/1000, nwmsa/1000, nnot/1000, (float)nnot/(float)nfuture, (float)nnot/(float)nwmsa) ; RFtrain(rf, parms->feature_fraction, parms->training_fraction, training_classes, training_data, ntraining); correct = RFcomputeOutOfBagCorrect(rf, training_classes, training_data,ntraining); printf("out of bag accuracy: %d of %d = %2.2f%%\n", correct, ntraining, 100.0*correct/ntraining) ; if (log_file_name) { struct flock fl; int fd; char line[MAX_LINE_LEN] ; printf("writing results to train.log file %s\n", log_file_name) ; fd = open(log_file_name, O_WRONLY|O_APPEND|O_CREAT, S_IRWXU|S_IRWXG); if (fd < 0) ErrorExit(ERROR_NOFILE, "%s: could not open test log file %s", Progname, log_file_name); fcntl(fd, F_SETLKW, &fl); /* F_GETLK, F_SETLK, F_SETLKW */ sprintf(line, "%f %d %d %f\n", rf->training_fraction, rf->max_depth, rf->ntrees, 100.0*correct/ntraining) ; write(fd, line, (strlen(line))*sizeof(char)) ; fl.l_type = F_UNLCK; /* tell it to unlock the region */ fcntl(fd, F_SETLK, &fl); /* set the region to unlocked */ close(fd) ; } for (i = 0 ; i < ntraining ; i++) // allow for augmenting with other wmsa examples free(training_data[i]) ; free(training_data) ; free(training_classes) ; MRIfree(&mri_training_voxels) ; return(rf) ; }
int main(int argc, char *argv[]) { char **av, *xform_name, *out_fname, fname[STRLEN], *seg_name, *s1, *s2 ; int ac, nargs, i, nsubjects, j, nvoxels ; MRI *mri_seg[MAX_SUBJECTS] ; float overlap, total_overlap ; TRANSFORM *transform1, *transform2 ; FILE *fp ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_evaluate_morph.c,v 1.5 2011/03/02 00:04:15 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; if (strlen(sdir) == 0) { char *cp ; cp = getenv("SUBJECTS_DIR") ; if (!cp) ErrorExit(ERROR_BADPARM, "%s: no SUBJECTS_DIR in envoronment.\n",Progname); strcpy(sdir, cp) ; } ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 3) usage_exit() ; xform_name = argv[1] ; seg_name = argv[2] ; out_fname = argv[argc-1] ; #define FIRST_SUBJECT 3 nsubjects = argc-(FIRST_SUBJECT+1) ; printf("processing %d subjects...\n", nsubjects) ; for (i = FIRST_SUBJECT ; i < argc-1 ; i++) { fprintf(stderr, "processing subject %s...\n", argv[i]) ; sprintf(fname, "%s/%s/mri/%s", sdir, argv[i], seg_name) ; mri_seg[i-FIRST_SUBJECT] = MRIread(fname) ; if (!mri_seg[i-FIRST_SUBJECT]) ErrorExit(ERROR_NOFILE, "%s: could not read segmentation %s", Progname, fname) ; } fp = fopen(out_fname, "w") ; if (!fp) ErrorExit(ERROR_NOFILE, "%s: could not open output file %s...\n", out_fname) ; nvoxels = mri_seg[0]->width * mri_seg[0]->height * mri_seg[0]->depth ; for (total_overlap = 0.0f, i = 0 ; i < nsubjects ; i++) { for (j = i+1 ; j < nsubjects ; j++) { s1 = argv[i+FIRST_SUBJECT] ; s2 = argv[j+FIRST_SUBJECT] ; printf("reading transforms for subjects %s and %s...\n", s1, s2) ; sprintf(fname, "%s/%s/mri/transforms/%s", sdir, s1, xform_name) ; transform1 = TransformRead(fname) ; if (transform1 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read transform %s", Progname, fname) ; sprintf(fname, "%s/%s/mri/transforms/%s", sdir, s1, xform_name) ; transform2 = TransformRead(fname) ; if (transform2 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read transform %s", Progname, fname) ; printf("computing overlap for subjects %s and %s...\n", s1, s2) ; overlap = compute_overlap(mri_seg[i], mri_seg[j], transform1, transform2) ; total_overlap += overlap ; printf("overlap = %2.0f, total = %2.0f\n", overlap, total_overlap) ; fprintf(fp, "%s %s %2.0f %2.1f\n", s1, s2, overlap, 100.0f*overlap/(float)nvoxels) ; fflush(fp) ; TransformFree(&transform1) ; TransformFree(&transform2) ; } } total_overlap /= (float)((nsubjects*(nsubjects-1))/2.0f) ; printf("overlap/subject pair = %2.0f (%2.1f %%)\n", total_overlap, 100.0f*total_overlap/(float)nvoxels) ; fclose(fp) ; exit(0) ; return(0) ; /* for ansi */ }
int main(int argc, char *argv[]) { char **av, *cp ; int ac, nargs, i, dof, no_transform, which, sno = 0, nsubjects = 0 ; MRI *mri=0, *mri_mean = NULL, *mri_std=0, *mri_T1=0,*mri_binary=0,*mri_dof=NULL, *mri_priors = NULL ; char *subject_name, *out_fname, fname[STRLEN] ; /* LTA *lta;*/ MRI *mri_tmp=0 ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_make_template.c,v 1.26 2011/03/02 00:04:22 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (!strlen(subjects_dir)) { cp = getenv("SUBJECTS_DIR") ; if (!cp) ErrorExit(ERROR_BADPARM,"%s: SUBJECTS_DIR not defined in environment.\n", Progname) ; strcpy(subjects_dir, cp) ; } if (argc < 3) usage_exit(1) ; out_fname = argv[argc-1] ; no_transform = first_transform ; if (binary_name) /* generate binarized volume with priors and */ { /* separate means and variances */ for (which = BUILD_PRIORS ; which <= OFF_STATS ; which++) { /* for each subject specified on cmd line */ for (dof = 0, i = 1 ; i < argc-1 ; i++) { if (*argv[i] == '-') /* don't do transform for next subject */ { no_transform = 1 ; continue ; } dof++ ; subject_name = argv[i] ; if (which != BUILD_PRIORS) { sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, T1_name); fprintf(stderr, "%d of %d: reading %s...\n", i, argc-2, fname) ; mri_T1 = MRIread(fname) ; if (!mri_T1) ErrorExit(ERROR_NOFILE,"%s: could not open volume %s", Progname,fname); } sprintf(fname, "%s/%s/mri/%s",subjects_dir,subject_name,binary_name); fprintf(stderr, "%d of %d: reading %s...\n", i, argc-2, fname) ; mri_binary = MRIread(fname) ; if (!mri_binary) ErrorExit(ERROR_NOFILE,"%s: could not open volume %s", Progname,fname); /* only count voxels which are mostly labeled */ MRIbinarize(mri_binary, mri_binary, WM_MIN_VAL, 0, 100) ; if (transform_fname && no_transform-- <= 0) { sprintf(fname, "%s/%s/mri/transforms/%s", subjects_dir, subject_name, transform_fname) ; fprintf(stderr, "reading transform %s...\n", fname) ; //////////////////////////////////////////////////////// #if 1 { TRANSFORM *transform ; transform = TransformRead(fname) ; if (transform == NULL) ErrorExit(ERROR_NOFILE, "%s: could not open transform file %s\n",Progname, fname) ; mri_tmp = TransformApply(transform, mri_T1, NULL) ; TransformFree(&transform) ; } #else lta = LTAreadEx(fname); if (lta == NULL) ErrorExit(ERROR_NOFILE, "%s: could not open transform file %s\n", Progname, fname) ; /* LTAtransform() runs either MRIapplyRASlinearTransform() for RAS2RAS or MRIlinearTransform() for Vox2Vox. */ /* MRIlinearTransform() calls MRIlinearTransformInterp() */ mri_tmp = LTAtransform(mri_T1, NULL, lta); MRIfree(&mri_T1) ; mri_T1 = mri_tmp ; LTAfree(<a); lta = NULL; #endif if (DIAG_VERBOSE_ON) fprintf(stderr, "transform application complete.\n") ; } if (which == BUILD_PRIORS) { mri_priors = MRIupdatePriors(mri_binary, mri_priors) ; } else { if (!mri_mean) { mri_dof = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_UCHAR) ; mri_mean = MRIalloc(mri_T1->width, mri_T1->height,mri_T1->depth,MRI_FLOAT); mri_std = MRIalloc(mri_T1->width,mri_T1->height,mri_T1->depth,MRI_FLOAT); if (!mri_mean || !mri_std) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate templates.\n", Progname) ; } if (DIAG_VERBOSE_ON) fprintf(stderr, "updating mean and variance estimates...\n") ; if (which == ON_STATS) { MRIaccumulateMaskedMeansAndVariances(mri_T1, mri_binary, mri_dof, 90, 100, mri_mean, mri_std) ; fprintf(stderr, "T1 = %d, binary = %d, mean = %2.1f\n", (int)MRIgetVoxVal(mri_T1, 141,100,127,0), MRIvox(mri_binary, 141,100,127), MRIFvox(mri_mean, 141,100,127)) ; } else /* computing means and vars for off */ MRIaccumulateMaskedMeansAndVariances(mri_T1, mri_binary, mri_dof, 0, WM_MIN_VAL-1, mri_mean, mri_std) ; MRIfree(&mri_T1) ; } MRIfree(&mri_binary) ; } if (which == BUILD_PRIORS) { mri = MRIcomputePriors(mri_priors, dof, NULL) ; MRIfree(&mri_priors) ; fprintf(stderr, "writing priors to %s...\n", out_fname) ; } else { MRIcomputeMaskedMeansAndStds(mri_mean, mri_std, mri_dof) ; mri_mean->dof = dof ; fprintf(stderr, "writing T1 means with %d dof to %s...\n", mri_mean->dof, out_fname) ; if (!which) MRIwrite(mri_mean, out_fname) ; else MRIappend(mri_mean, out_fname) ; MRIfree(&mri_mean) ; fprintf(stderr, "writing T1 variances to %s...\n", out_fname); if (dof <= 1) MRIreplaceValues(mri_std, mri_std, 0, 1) ; mri = mri_std ; } if (!which) MRIwrite(mri, out_fname) ; else MRIappend(mri, out_fname) ; MRIfree(&mri) ; } } else { /* for each subject specified on cmd line */ if (xform_mean_fname) { m_xform_mean = MatrixAlloc(4,4,MATRIX_REAL) ; /* m_xform_covariance = MatrixAlloc(12,12,MATRIX_REAL) ;*/ } dof = 0; for (i = 1 ; i < argc-1 ; i++) { if (*argv[i] == '-') { /* don't do transform for next subject */ no_transform = 1 ; continue ; } dof++ ; subject_name = argv[i] ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, T1_name); fprintf(stderr, "%d of %d: reading %s...\n", i, argc-2, fname) ; mri_T1 = MRIread(fname) ; if (!mri_T1) ErrorExit(ERROR_NOFILE,"%s: could not open volume %s",Progname,fname); check_mri(mri_T1) ; if (binarize) MRIbinarize(mri_T1, mri_T1, binarize, 0, 1) ; if (erode) { int i ; printf("eroding input %d times\n", erode) ; for (i = 0 ; i < erode ; i++) MRIerode(mri_T1, mri_T1) ; } if (open) { int i ; printf("opening input %d times\n", open) ; for (i = 0 ; i < open ; i++) MRIerode(mri_T1, mri_T1) ; for (i = 0 ; i < open ; i++) MRIdilate(mri_T1, mri_T1) ; } check_mri(mri_T1) ; if (transform_fname) { sprintf(fname, "%s/%s/mri/transforms/%s", subjects_dir, subject_name, transform_fname) ; fprintf(stderr, "reading transform %s...\n", fname) ; //////////////////////////////////////////////////////// #if 1 { TRANSFORM *transform ; transform = TransformRead(fname) ; if (transform == NULL) ErrorExit(ERROR_NOFILE, "%s: could not open transform file %s\n",Progname, fname) ; mri_tmp = TransformApply(transform, mri_T1, NULL) ; if (DIAG_VERBOSE_ON) MRIwrite(mri_tmp, "t1.mgz") ; TransformFree(&transform) ; } #else lta = LTAreadEx(fname); if (lta == NULL) ErrorExit(ERROR_NOFILE, "%s: could not open transform file %s\n", Progname, fname) ; printf("transform matrix -----------------------\n"); MatrixPrint(stdout,lta->xforms[0].m_L); /* LTAtransform() runs either MRIapplyRASlinearTransform() for RAS2RAS or MRIlinearTransform() for Vox2Vox. */ /* MRIlinearTransform() calls MRIlinearTransformInterp() */ mri_tmp = LTAtransform(mri_T1, NULL, lta); printf("----- -----------------------\n"); LTAfree(<a); #endif MRIfree(&mri_T1); mri_T1 = mri_tmp ; // reassign pointers if (DIAG_VERBOSE_ON) fprintf(stderr, "transform application complete.\n") ; } if (!mri_mean) { mri_mean = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_FLOAT) ; mri_std = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_FLOAT) ; if (!mri_mean || !mri_std) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate templates.\n", Progname) ; // if(transform_fname == NULL){ if (DIAG_VERBOSE_ON) printf("Copying geometry\n"); MRIcopyHeader(mri_T1,mri_mean); MRIcopyHeader(mri_T1,mri_std); // } } check_mri(mri_mean) ; if (!stats_only) { if (DIAG_VERBOSE_ON) fprintf(stderr, "updating mean and variance estimates...\n") ; MRIaccumulateMeansAndVariances(mri_T1, mri_mean, mri_std) ; } check_mri(mri_mean) ; if (DIAG_VERBOSE_ON) MRIwrite(mri_mean, "t2.mgz") ; MRIfree(&mri_T1) ; no_transform = 0; } /* end loop over subjects */ if (xform_mean_fname) { FILE *fp ; VECTOR *v = NULL, *vT = NULL ; MATRIX *m_vvT = NULL ; int rows, cols ; nsubjects = sno ; fp = fopen(xform_covariance_fname, "w") ; if (!fp) ErrorExit(ERROR_NOFILE, "%s: could not open covariance file %s", Progname, xform_covariance_fname) ; fprintf(fp, "nsubjects=%d\n", nsubjects) ; MatrixScalarMul(m_xform_mean, 1.0/(double)nsubjects, m_xform_mean) ; printf("means:\n") ; MatrixPrint(stdout, m_xform_mean) ; MatrixAsciiWrite(xform_mean_fname, m_xform_mean) ; /* subtract the mean from each transform */ rows = m_xform_mean->rows ; cols = m_xform_mean->cols ; for (sno = 0 ; sno < nsubjects ; sno++) { MatrixSubtract(m_xforms[sno], m_xform_mean, m_xforms[sno]) ; v = MatrixReshape(m_xforms[sno], v, rows*cols, 1) ; vT = MatrixTranspose(v, vT) ; m_vvT = MatrixMultiply(v, vT, m_vvT) ; if (!m_xform_covariance) m_xform_covariance = MatrixAlloc(m_vvT->rows, m_vvT->cols,MATRIX_REAL) ; MatrixAdd(m_vvT, m_xform_covariance, m_xform_covariance) ; MatrixAsciiWriteInto(fp, m_xforms[sno]) ; } MatrixScalarMul(m_xform_covariance, 1.0/(double)nsubjects, m_xform_covariance) ; printf("covariance:\n") ; MatrixPrint(stdout, m_xform_covariance) ; MatrixAsciiWriteInto(fp, m_xform_covariance) ; fclose(fp) ; if (stats_only) exit(0) ; } MRIcomputeMeansAndStds(mri_mean, mri_std, dof) ; check_mri(mri_mean) ; check_mri(mri_std) ; mri_mean->dof = dof ; if (smooth) { MRI *mri_kernel, *mri_smooth ; printf("applying smoothing kernel\n") ; mri_kernel = MRIgaussian1d(smooth, 100) ; mri_smooth = MRIconvolveGaussian(mri_mean, NULL, mri_kernel) ; MRIfree(&mri_kernel) ; MRIfree(&mri_mean) ; mri_mean = mri_smooth ; } fprintf(stderr, "\nwriting T1 means with %d dof to %s...\n", mri_mean->dof, out_fname) ; MRIwrite(mri_mean, out_fname) ; MRIfree(&mri_mean) ; if (dof <= 1) /* can't calculate variances - set them to reasonable val */ { // src dst MRIreplaceValues(mri_std, mri_std, 0, 1) ; } if (!novar) { // mri_std contains the variance here (does it?? I don't think so -- BRF) if (!var_fname) { fprintf(stderr, "\nwriting T1 standard deviations to %s...\n", out_fname); MRIappend(mri_std, out_fname) ; } else { fprintf(stderr, "\nwriting T1 standard deviations to %s...\n", var_fname); MRIwrite(mri_std, var_fname) ; } } MRIfree(&mri_std) ; if (mri) MRIfree(&mri); } /* end if binarize */ return(0) ; }