int main(int argc, char *argv[]) { MRI_SURFACE *mris ; char **av, *curv_name, *surf_name, *hemi, fname[STRLEN], *cp, *subject_name, subjects_dir[STRLEN], **c1_subjects, **c2_subjects ; int ac, nargs, n, num_class1, num_class2, i, nvertices, avgs, max_snr_avgs, nlabels = 0, done ; float **c1_thickness, **c2_thickness, *curvs, *total_mean, *c1_mean, *c2_mean, *class_mean, *c1_var, *c2_var, *class_var,*pvals, **c1_avg_thickness, *vbest_snr, *vbest_avgs, *vtotal_var, *vsnr, **c2_avg_thickness, *vbest_pvalues, current_min_label_area, current_fthresh ; MRI_SP *mrisp ; LABEL *area, **labels = NULL ; FILE *fp = NULL ; double snr, max_snr ; struct timeb start ; int msec, minutes, seconds ; double **c1_label_thickness, **c2_label_thickness ; int *sorted_indices = NULL, vno ; float *test_thickness, *test_avg_thickness ; double label_avg ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mris_classify_thickness.c,v 1.8 2011/03/02 00:04:29 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; if (write_flag && DIAG_VERBOSE_ON) fp = fopen("scalespace.dat", "w") ; 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 ; } TimerStart(&start) ; /* subject_name hemi surface curvature */ if (argc < 7) usage_exit() ; if (output_subject == NULL) ErrorExit(ERROR_BADPARM, "output subject must be specified with -o <subject name>"); cp = getenv("SUBJECTS_DIR") ; if (!cp) ErrorExit(ERROR_BADPARM, "%s: SUBJECTS_DIR not defined in environment", Progname) ; strcpy(subjects_dir, cp) ; hemi = argv[1] ; surf_name = argv[2] ; curv_name = argv[3] ; #define ARGV_OFFSET 4 /* first determine the number of subjects in each class */ num_class1 = 0 ; n = ARGV_OFFSET ; do { num_class1++ ; n++ ; if (argv[n] == NULL || n >= argc) ErrorExit(ERROR_BADPARM, "%s: must spectify ':' between class lists", Progname) ; } while (argv[n][0] != ':') ; /* find # of vertices in output subject surface */ sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,output_subject,hemi,surf_name); mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; nvertices = mris->nvertices ; MRISfree(&mris) ; total_mean = (float *)calloc(nvertices, sizeof(float)) ; if (!total_mean) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate mean list of %d curvatures", Progname, n, nvertices) ; c1_mean = (float *)calloc(nvertices, sizeof(float)) ; if (!c1_mean) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate c1 mean list of %d curvatures", Progname, n, nvertices) ; pvals = (float *)calloc(nvertices, sizeof(float)) ; if (!pvals) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate pvals", Progname, n, nvertices) ; c2_mean = (float *)calloc(nvertices, sizeof(float)) ; if (!c2_mean) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate c2 mean list of %d curvatures", Progname, n, nvertices) ; c1_var = (float *)calloc(nvertices, sizeof(float)) ; if (!c1_var) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate c1 var list of %d curvatures", Progname, n, nvertices) ; c2_var = (float *)calloc(nvertices, sizeof(float)) ; if (!c2_var) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate c2 var list of %d curvatures", Progname, n, nvertices) ; num_class2 = 0 ; n++ ; /* skip ':' */ if (n >= argc) ErrorExit(ERROR_BADPARM, "%s: class2 list empty", Progname) ; do { num_class2++ ; n++ ; if (n >= argc) break ; } while (argv[n] != NULL) ; fprintf(stderr, "%d subjects in class 1, %d subjects in class 2\n", num_class1, num_class2) ; c1_subjects = (char **)calloc(num_class1, sizeof(char *)) ; c1_thickness = (float **)calloc(num_class1, sizeof(char *)) ; c1_avg_thickness = (float **)calloc(num_class1, sizeof(char *)) ; c2_subjects = (char **)calloc(num_class2, sizeof(char *)) ; c2_thickness = (float **)calloc(num_class2, sizeof(char *)) ; c2_avg_thickness = (float **)calloc(num_class2, sizeof(char *)) ; for (n = 0 ; n < num_class1 ; n++) { c1_subjects[n] = argv[ARGV_OFFSET+n] ; c1_thickness[n] = (float *)calloc(nvertices, sizeof(float)) ; c1_avg_thickness[n] = (float *)calloc(nvertices, sizeof(float)) ; if (!c1_thickness[n] || !c1_avg_thickness[n]) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %dth list of %d curvatures", Progname, n, nvertices) ; strcpy(c1_subjects[n], argv[ARGV_OFFSET+n]) ; /* fprintf(stderr, "class1[%d] - %s\n", n, c1_subjects[n]) ;*/ } i = n+1+ARGV_OFFSET ; /* starting index */ for (n = 0 ; n < num_class2 ; n++) { c2_subjects[n] = argv[i+n] ; c2_thickness[n] = (float *)calloc(nvertices, sizeof(float)) ; c2_avg_thickness[n] = (float *)calloc(nvertices, sizeof(float)) ; if (!c2_thickness[n] || !c2_avg_thickness[n]) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %dth list of %d curvatures", Progname, n, nvertices) ; strcpy(c2_subjects[n], argv[i+n]) ; /* fprintf(stderr, "class2[%d] - %s\n", n, c2_subjects[n]) ;*/ } if (label_name) { area = LabelRead(output_subject, label_name) ; if (!area) ErrorExit(ERROR_NOFILE, "%s: could not read label %s", Progname, label_name) ; } else area = NULL ; if (read_dir) { sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,output_subject,hemi,surf_name); mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ; /* real all the curvatures in for group1 */ for (n = 0 ; n < num_class1+num_class2 ; n++) { /* transform each subject's curvature into the output subject's space */ subject_name = n < num_class1 ? c1_subjects[n]:c2_subjects[n-num_class1]; fprintf(stderr, "reading subject %d of %d: %s\n", n+1, num_class1+num_class2, subject_name) ; sprintf(fname, "%s/%s.%s", read_dir,hemi,subject_name); if (MRISreadValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: could not read curvature file %s",Progname,fname); if (area) MRISmaskNotLabel(mris, area) ; curvs = (n < num_class1) ? c1_thickness[n] : c2_thickness[n-num_class1] ; class_mean = (n < num_class1) ? c1_mean : c2_mean ; class_var = (n < num_class1) ? c1_var : c2_var ; MRISexportValVector(mris, curvs) ; cvector_accumulate(curvs, total_mean, nvertices) ; cvector_accumulate(curvs, class_mean, nvertices) ; cvector_accumulate_square(curvs, class_var, nvertices) ; } } else { /* real all the curvatures in for group1 */ for (n = 0 ; n < num_class1+num_class2 ; n++) { /* transform each subject's curvature into the output subject's space */ subject_name = n < num_class1 ? c1_subjects[n]:c2_subjects[n-num_class1]; fprintf(stderr, "reading subject %d of %d: %s\n", n+1, num_class1+num_class2, subject_name) ; sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,subject_name,hemi,surf_name); mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ; if (strchr(curv_name, '/') != NULL) strcpy(fname, curv_name) ; /* full path specified */ else sprintf(fname,"%s/%s/surf/%s.%s", subjects_dir,subject_name,hemi,curv_name); if (MRISreadCurvatureFile(mris, fname) != NO_ERROR) ErrorExit(Gerror,"%s: could no read curvature file %s",Progname,fname); mrisp = MRIStoParameterization(mris, NULL, 1, 0) ; MRISfree(&mris) ; sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,output_subject,hemi,surf_name); mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; MRISfromParameterization(mrisp, mris, 0) ; if (area) MRISmaskNotLabel(mris, area) ; curvs = (n < num_class1) ? c1_thickness[n] : c2_thickness[n-num_class1] ; class_mean = (n < num_class1) ? c1_mean : c2_mean ; class_var = (n < num_class1) ? c1_var : c2_var ; MRISextractCurvatureVector(mris, curvs) ; cvector_accumulate(curvs, total_mean, nvertices) ; cvector_accumulate(curvs, class_mean, nvertices) ; cvector_accumulate_square(curvs, class_var, nvertices) ; MRISPfree(&mrisp) ; MRISfree(&mris) ; } } /* compute within-group means, and total mean */ cvector_normalize(total_mean, num_class1+num_class2, nvertices) ; cvector_normalize(c1_mean, num_class1, nvertices) ; cvector_normalize(c2_mean, num_class2, nvertices) ; cvector_compute_variance(c1_var, c1_mean, num_class1, nvertices) ; cvector_compute_variance(c2_var, c2_mean, num_class2, nvertices) ; cvector_compute_t_test(c1_mean, c1_var, c2_mean, c2_var, num_class1, num_class2, pvals, nvertices) ; sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,output_subject,hemi,surf_name); fprintf(stderr, "reading output surface %s...\n", fname) ; mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; if (area) MRISripNotLabel(mris, area) ; vbest_snr = cvector_alloc(nvertices) ; vbest_pvalues = cvector_alloc(nvertices) ; vbest_avgs = cvector_alloc(nvertices) ; vtotal_var = cvector_alloc(nvertices) ; vsnr = cvector_alloc(nvertices) ; if (read_dir == NULL) /* recompute everything */ { if (use_buggy_snr) cvector_multiply_variances(c1_var, c2_var, num_class1, num_class2, vtotal_var, nvertices) ; else cvector_add_variances(c1_var, c2_var, num_class1, num_class2, vtotal_var, nvertices) ; if (use_no_distribution) snr = cvector_compute_dist_free_snr(c1_thickness, num_class1, c2_thickness, num_class2, c1_mean, c2_mean, vsnr, nvertices, &i); else snr = cvector_compute_snr(c1_mean, c2_mean, vtotal_var, vsnr, nvertices, &i, 0.0f); fprintf(stderr, "raw SNR %2.2f, n=%2.4f, d=%2.4f, vno=%d\n", sqrt(snr), c1_mean[i]-c2_mean[i], sqrt(vtotal_var[i]), i) ; max_snr = snr ; max_snr_avgs = 0 ; cvector_track_best_snr(vsnr, vbest_snr, vbest_avgs, 0, nvertices) ; for (n = 0 ; n < num_class1 ; n++) cvector_copy(c1_thickness[n], c1_avg_thickness[n], nvertices) ; for (n = 0 ; n < num_class2 ; n++) cvector_copy(c2_thickness[n], c2_avg_thickness[n], nvertices) ; /* now incrementally average the data, keeping track of the best snr at each location, and at what scale it occurred. vbest_avgs and vbest_snr will contain the scale and the snr at that scale. */ for (avgs = 1 ; avgs <= max_avgs ; avgs++) { /* c?_avg_thickness is the thickness at the current scale */ if (!(avgs % 50)) fprintf(stderr, "testing %d averages...\n", avgs) ; cvector_clear(c1_mean, nvertices) ; cvector_clear(c2_mean, nvertices) ; cvector_clear(c1_var, nvertices) ; cvector_clear(c2_var, nvertices) ; cvector_clear(total_mean, nvertices) ; for (n = 0 ; n < num_class1 ; n++) { MRISimportCurvatureVector(mris, c1_avg_thickness[n]) ; MRISaverageCurvatures(mris, 1) ; MRISextractCurvatureVector(mris, c1_avg_thickness[n]) ; cvector_accumulate(c1_avg_thickness[n], total_mean, nvertices) ; cvector_accumulate(c1_avg_thickness[n], c1_mean, nvertices) ; cvector_accumulate_square(c1_avg_thickness[n], c1_var, nvertices) ; } for (n = 0 ; n < num_class2 ; n++) { MRISimportCurvatureVector(mris, c2_avg_thickness[n]) ; MRISaverageCurvatures(mris, 1) ; MRISextractCurvatureVector(mris, c2_avg_thickness[n]) ; cvector_accumulate(c2_avg_thickness[n], total_mean, nvertices) ; cvector_accumulate(c2_avg_thickness[n], c2_mean, nvertices) ; cvector_accumulate_square(c2_avg_thickness[n], c2_var, nvertices) ; } cvector_normalize(total_mean, num_class1+num_class2, nvertices) ; cvector_normalize(c1_mean, num_class1, nvertices) ; cvector_normalize(c2_mean, num_class2, nvertices) ; cvector_compute_variance(c1_var, c1_mean, num_class1, nvertices) ; cvector_compute_variance(c2_var, c2_mean, num_class2, nvertices) ; if (use_buggy_snr) cvector_multiply_variances(c1_var, c2_var, num_class1, num_class2, vtotal_var, nvertices) ; else cvector_add_variances(c1_var, c2_var, num_class1, num_class2, vtotal_var, nvertices) ; if (use_no_distribution) snr = cvector_compute_dist_free_snr(c1_avg_thickness,num_class1, c2_avg_thickness, num_class2, c1_mean, c2_mean, vsnr, nvertices, &i); else snr = cvector_compute_snr(c1_mean, c2_mean, vtotal_var, vsnr, nvertices,&i, bonferroni ? log((double)avgs) : 0.0f); if (write_flag && DIAG_VERBOSE_ON) { fprintf(fp, "%d %2.1f %2.2f %2.2f %2.2f ", avgs, sqrt((float)avgs), sqrt(snr), c1_mean[i]-c2_mean[i], sqrt(vtotal_var[i])) ; fflush(fp) ; for (n = 0 ; n < num_class1 ; n++) fprintf(fp, "%2.2f ", c1_avg_thickness[n][i]) ; for (n = 0 ; n < num_class2 ; n++) fprintf(fp, "%2.2f ", c2_avg_thickness[n][i]) ; fprintf(fp, "\n") ; fclose(fp) ; } if (snr > max_snr) { fprintf(stderr, "new max SNR found at avgs=%d (%2.1f mm)=%2.1f, n=%2.4f, " "d=%2.4f, vno=%d\n", avgs, sqrt((float)avgs), sqrt(snr), c1_mean[i]-c2_mean[i], sqrt(vtotal_var[i]), i) ; max_snr = snr ; max_snr_avgs = avgs ; } cvector_track_best_snr(vsnr, vbest_snr, vbest_avgs, avgs, nvertices) ; } if (compute_stats) cvector_compute_t(vbest_snr, vbest_pvalues,num_class1+num_class2, nvertices) ; printf("max snr=%2.2f at %d averages\n", max_snr, max_snr_avgs) ; if (write_flag) { MRISimportValVector(mris, vbest_snr) ; sprintf(fname, "./%s.%s_best_snr", hemi,prefix) ; MRISwriteValues(mris, fname) ; MRISimportValVector(mris, vbest_avgs) ; sprintf(fname, "./%s.%s_best_avgs", hemi, prefix) ; MRISwriteValues(mris, fname) ; if (compute_stats) { MRISimportValVector(mris, vbest_pvalues) ; sprintf(fname, "./%s.%s_best_pval", hemi,prefix) ; MRISwriteValues(mris, fname) ; } } } else /* read from directory containing precomputed optimal values */ { sprintf(fname, "%s/%s.%s_best_snr", read_dir, hemi, prefix) ; if (MRISreadValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: MRISreadValues(%s) failed",Progname,fname) ; MRISexportValVector(mris, vbest_snr) ; sprintf(fname, "%s/%s.%s_best_avgs", read_dir, hemi, prefix) ; if (MRISreadValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: MRISreadValues(%s) failed",Progname,fname) ; MRISexportValVector(mris, vbest_avgs) ; } if (write_dir) { sprintf(fname, "%s/%s.%s_best_snr", write_dir, hemi,prefix) ; MRISimportValVector(mris, vbest_snr) ; if (MRISwriteValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: MRISwriteValues(%s) failed",Progname,fname) ; sprintf(fname, "%s/%s.%s_best_avgs", write_dir, hemi, prefix) ; MRISimportValVector(mris, vbest_avgs) ; if (MRISwriteValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: MRISwriteValues(%s) failed",Progname,fname) ; } if (nsort < -1) nsort = mris->nvertices ; if (nsort <= 0) { nlabels = 0 ; current_min_label_area = min_label_area ; for (done = 0, current_fthresh = fthresh ; !FZERO(current_fthresh) && !done ; current_fthresh *= 0.95) { int npos_labels, nneg_labels ; LABEL **pos_labels, **neg_labels ; for (current_min_label_area = min_label_area ; current_min_label_area > 0.5 ; current_min_label_area *= 0.75) { MRISclearMarks(mris) ; sprintf(fname, "%s-%s_thickness", hemi, prefix ? prefix : "") ; mark_thresholded_vertices(mris, vbest_snr, vbest_avgs,current_fthresh); segment_and_write_labels(output_subject, fname, mris, &pos_labels, &npos_labels, 0, current_min_label_area) ; MRISclearMarks(mris) ; mark_thresholded_vertices(mris, vbest_snr,vbest_avgs,-current_fthresh); segment_and_write_labels(output_subject, fname, mris, &neg_labels, &nneg_labels, npos_labels, current_min_label_area) ; nlabels = nneg_labels + npos_labels ; if (nlabels) { labels = (LABEL **)calloc(nlabels, sizeof(LABEL *)) ; for (i = 0 ; i < npos_labels ; i++) labels[i] = pos_labels[i] ; for (i = 0 ; i < nneg_labels ; i++) labels[i+npos_labels] = neg_labels[i] ; free(pos_labels) ; free(neg_labels) ; } done = (nlabels >= min_labels) ; if (done) /* found enough points */ break ; /* couldn't find enough points - free stuff and try again */ for (i = 0 ; i < nlabels ; i++) LabelFree(&labels[i]) ; if (nlabels) free(labels) ; #if 0 fprintf(stderr,"%d labels found (min %d), reducing constraints...\n", nlabels, min_labels) ; #endif } } printf("%d labels found with F > %2.1f and area > %2.0f\n", nlabels, current_fthresh, current_min_label_area) ; for (i = 0 ; i < nlabels ; i++) fprintf(stderr, "label %d: %d points, %2.1f mm\n", i, labels[i]->n_points, LabelArea(labels[i], mris)) ; } /* read or compute thickness at optimal scale and put it into c?_avg_thickness. */ if (!read_dir) { fprintf(stderr, "extracting thickness at optimal scale...\n") ; /* now build feature vectors for each subject */ extract_thickness_at_best_scale(mris, c1_avg_thickness, vbest_avgs, c1_thickness, nvertices, num_class1); fprintf(stderr, "extracting thickness for class 2...\n") ; extract_thickness_at_best_scale(mris, c2_avg_thickness, vbest_avgs, c2_thickness, nvertices, num_class2); } else /* read in precomputed optimal thicknesses */ { char fname[STRLEN] ; fprintf(stderr, "reading precomputed thickness vectors\n") ; for (n = 0 ; n < num_class1 ; n++) { sprintf(fname, "%s/%s.%s", read_dir, hemi, argv[ARGV_OFFSET+n]) ; fprintf(stderr, "reading thickness vector from %s...\n", fname) ; if (MRISreadValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: could not read thickness file %s", Progname,fname) ; MRISexportValVector(mris, c1_avg_thickness[n]) ; } for (n = 0 ; n < num_class2 ; n++) { sprintf(fname, "%s/%s.%s", read_dir, hemi, argv[n+num_class1+1+ARGV_OFFSET]) ; fprintf(stderr, "reading curvature vector from %s...\n", fname) ; if (MRISreadValues(mris, fname) != NO_ERROR) ErrorExit(Gerror, "%s: could not read thickness file %s", Progname,fname) ; MRISexportValVector(mris, c2_avg_thickness[n]) ; } } if (write_dir) /* write out optimal thicknesses */ { char fname[STRLEN] ; for (n = 0 ; n < num_class1 ; n++) { sprintf(fname, "%s/%s.%s", write_dir, hemi, argv[ARGV_OFFSET+n]) ; fprintf(stderr, "writing curvature vector to %s...\n", fname) ; MRISimportValVector(mris, c1_avg_thickness[n]) ; MRISwriteValues(mris, fname) ; } for (n = 0 ; n < num_class2 ; n++) { sprintf(fname, "%s/%s.%s", write_dir, hemi, argv[n+num_class1+1+ARGV_OFFSET]) ; fprintf(stderr, "writing curvature vector to %s...\n", fname) ; MRISimportValVector(mris, c2_avg_thickness[n]) ; MRISwriteValues(mris, fname) ; } } /* should free c?_thickness here */ if (nsort <= 0) { /* We have the thickness values at the most powerful scale stored for each subject in the c1_avg_thickness and c2_avg_thickness vectors. Now collapse them across each label and build feature vector for classification. */ c1_label_thickness = (double **)calloc(num_class1, sizeof(double *)) ; c2_label_thickness = (double **)calloc(num_class2, sizeof(double *)) ; for (n = 0 ; n < num_class1 ; n++) c1_label_thickness[n] = (double *)calloc(nlabels, sizeof(double)) ; for (n = 0 ; n < num_class2 ; n++) c2_label_thickness[n] = (double *)calloc(nlabels, sizeof(double)) ; fprintf(stderr, "collapsing thicknesses within labels for class 1\n") ; for (n = 0 ; n < num_class1 ; n++) for (i = 0 ; i < nlabels ; i++) c1_label_thickness[n][i] = cvector_average_in_label(c1_avg_thickness[n], labels[i], nvertices) ; fprintf(stderr, "collapsing thicknesses within labels for class 2\n") ; for (n = 0 ; n < num_class2 ; n++) for (i = 0 ; i < nlabels ; i++) c2_label_thickness[n][i] = cvector_average_in_label(c2_avg_thickness[n], labels[i], nvertices) ; sprintf(fname, "%s_%s_class1.dat", hemi,prefix) ; fprintf(stderr, "writing class 1 info to %s...\n", fname) ; fp = fopen(fname, "w") ; for (i = 0 ; i < nlabels ; i++) /* for each row */ { for (n = 0 ; n < num_class1 ; n++) /* for each column */ fprintf(fp, "%2.2f ", c1_label_thickness[n][i]) ; fprintf(fp, "\n") ; } fclose(fp) ; sprintf(fname, "%s_%s_class2.dat", hemi,prefix) ; fprintf(stderr, "writing class 2 info to %s...\n", fname) ; fp = fopen(fname, "w") ; for (i = 0 ; i < nlabels ; i++) { for (n = 0 ; n < num_class2 ; n++) fprintf(fp, "%2.2f ", c2_label_thickness[n][i]) ; fprintf(fp, "\n") ; } fclose(fp) ; } else { sorted_indices = cvector_sort(vbest_snr, nvertices) ; vno = sorted_indices[0] ; write_vertex_data("c1.dat", vno, c1_avg_thickness,num_class1); write_vertex_data("c2.dat", vno, c2_avg_thickness,num_class2); printf("sorting complete\n") ; /* re-write class means at these locations */ sprintf(fname, "%s_%s_class1.dat", hemi,prefix) ; fprintf(stderr, "writing class 1 info to %s...\n", fname) ; fp = fopen(fname, "w") ; for (i = 0 ; i < nsort ; i++) { for (n = 0 ; n < num_class1 ; n++) fprintf(fp, "%2.2f ", c1_avg_thickness[n][sorted_indices[i]]) ; fprintf(fp, "\n") ; } fclose(fp) ; sprintf(fname, "%s_%s_class2.dat", hemi,prefix) ; fprintf(stderr, "writing class 2 info to %s...\n", fname) ; fp = fopen(fname, "w") ; for (i = 0 ; i < nsort ; i++) { for (n = 0 ; n < num_class2 ; n++) fprintf(fp, "%2.2f ", c2_avg_thickness[n][sorted_indices[i]]) ; fprintf(fp, "\n") ; } fclose(fp) ; } if (test_subject) { test_thickness = cvector_alloc(nvertices) ; test_avg_thickness = cvector_alloc(nvertices) ; MRISfree(&mris) ; fprintf(stderr, "reading subject %s\n", test_subject) ; sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,test_subject,hemi,surf_name); mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ; if (strchr(curv_name, '/') != NULL) strcpy(fname, curv_name) ; /* full path specified */ else sprintf(fname,"%s/%s/surf/%s.%s", subjects_dir,test_subject,hemi,curv_name); if (MRISreadCurvatureFile(mris, fname) != NO_ERROR) ErrorExit(Gerror,"%s: could no read curvature file %s",Progname,fname); mrisp = MRIStoParameterization(mris, NULL, 1, 0) ; MRISfree(&mris) ; sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,output_subject,hemi,surf_name); mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; MRISfromParameterization(mrisp, mris, 0) ; if (area) MRISmaskNotLabel(mris, area) ; MRISextractCurvatureVector(mris, test_thickness) ; for (avgs = 0 ; avgs <= max_avgs ; avgs++) { cvector_extract_best_avg(vbest_avgs, test_thickness,test_avg_thickness, avgs-1, nvertices) ; MRISimportCurvatureVector(mris, test_thickness) ; MRISaverageCurvatures(mris, 1) ; MRISextractCurvatureVector(mris, test_thickness) ; } if (nsort <= 0) { sprintf(fname, "%s_%s.dat", hemi,test_subject) ; fprintf(stderr, "writing test subject feature vector to %s...\n", fname) ; fp = fopen(fname, "w") ; for (i = 0 ; i < nlabels ; i++) /* for each row */ { label_avg = cvector_average_in_label(test_avg_thickness, labels[i], nvertices) ; fprintf(fp, "%2.2f\n", label_avg) ; } fclose(fp) ; } else /* use sorting instead of connected areas */ { double classification, offset, w ; int total_correct, total_wrong, first_wrong, vno ; sprintf(fname, "%s_%s.dat", hemi,test_subject) ; fprintf(stderr, "writing test subject feature vector to %s...\n", fname) ; fp = fopen(fname, "w") ; first_wrong = -1 ; total_wrong = total_correct = 0 ; for (i = 0 ; i < nsort ; i++) { vno = sorted_indices[i] ; fprintf(fp, "%2.2f\n ", test_avg_thickness[sorted_indices[i]]) ; offset = (c1_mean[vno]+c2_mean[vno])/2.0 ; w = (c1_mean[vno]-c2_mean[vno]) ; classification = (test_avg_thickness[vno] - offset) * w ; if (((classification < 0) && (true_class == 1)) || ((classification > 0) && (true_class == 2))) { total_wrong++ ; if (first_wrong < 0) first_wrong = i ; } else total_correct++ ; } fclose(fp) ; fprintf(stderr, "%d of %d correct = %2.1f%% (first wrong %d (%d))," "min snr=%2.1f\n", total_correct, total_correct+total_wrong, 100.0*total_correct / (total_correct+total_wrong), first_wrong, first_wrong >= 0 ? sorted_indices[first_wrong]:-1, vbest_snr[sorted_indices[nsort-1]]) ; if (first_wrong >= 0) { write_vertex_data("c1w.dat", sorted_indices[first_wrong], c1_avg_thickness,num_class1); write_vertex_data("c2w.dat", sorted_indices[first_wrong], c2_avg_thickness,num_class2); } } } msec = TimerStop(&start) ; free(total_mean); free(c1_mean) ; free(c2_mean) ; free(c1_var); free(c2_var); seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; fprintf(stderr, "classification took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; /* for ansi */ }
int main(int argc, char *argv[]) { char **av, fname[STRLEN], *input_name, *subject_name, *cp,*hemi, *svm_name, *surf_name, *output_subject_name ; int ac, nargs, vno ; int msec, minutes, seconds ; struct timeb start ; MRI_SURFACE *mris ; SVM *svm ; double classification ; float *inputs ; MRI_SP *mrisp ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mris_svm_classify.c,v 1.6 2011/03/02 00:04:34 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; 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)) /* 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 < 7) usage_exit(1) ; subject_name = argv[1] ; hemi = argv[2] ; surf_name = argv[3] ; input_name = argv[4] ; output_subject_name = argv[5] ; svm_name = argv[6] ; printf("reading svm from %s...\n", svm_name) ; svm = SVMread(svm_name) ; if (!svm) ErrorExit(ERROR_NOFILE, "%s: could not read classifier from %s", Progname, svm_name) ; if (log_fname != NULL) printf("logging results to %s, true_class = %s\n", log_fname, true_class > 0 ? svm->class1_name : svm->class2_name) ; sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,subject_name,hemi,surf_name); printf("reading surface from %s...\n", fname) ; mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s for %s", Progname, fname, subject_name) ; MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ; if (MRISreadCurvature(mris, input_name) != NO_ERROR) ErrorExit(ERROR_BADPARM, "%s: could not read curvature from %s", input_name) ; if (nannotations > 0) { int vno, a, found ; VERTEX *v ; if (MRISreadAnnotation(mris, annot_name) != NO_ERROR) ErrorExit(ERROR_NOFILE, "%s: could not read annot file %s for subject %s", Progname, annot_name, subject_name) ; for (a = 0 ; a < nannotations ; a++) { int index ; CTABfindName(mris->ct, anames[a], &index) ; CTABannotationAtIndex(mris->ct, index, &annotations[a]) ; printf("mapping annot %s to %d\n", anames[a], annotations[a]) ; } // rip all vertices that don't have one of the specified annotations for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (v->ripflag) continue ; found = 0 ; for (a = 0 ; a < nannotations ; a++) if (v->annotation == annotations[a]) found = 1 ; if (found == 0) v->ripflag = 1 ; } } if (navgs > 0) MRISaverageCurvatures(mris, navgs) ; mrisp = MRIStoParameterization(mris, NULL, 1, 0) ; MRISfree(&mris) ; /* read in output surface */ sprintf(fname, "%s/%s/surf/%s.%s", subjects_dir,output_subject_name,hemi,surf_name); printf("reading output surface from %s...\n", fname) ; mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s for %s", Progname, fname, output_subject_name) ; MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ; MRISfromParameterization(mrisp, mris, 0) ; if (label_name) { area = LabelRead(output_subject_name, label_name) ; if (!area) ErrorExit(ERROR_NOFILE, "%s: could not read label %s", Progname, label_name) ; MRISmaskNotLabel(mris, area) ; } else area = NULL ; if (mris->nvertices != svm->ninputs) ErrorExit(ERROR_BADPARM, "%s: svm input (%d) does not match # of " "surface vertices (%d)", Progname, svm->ninputs, mris->nvertices); inputs = (float *)calloc(mris->nvertices, sizeof(float)) ; if (!inputs) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %d input vector", Progname, mris->nvertices) ; for (vno = 0 ; vno < mris->nvertices ; vno++) inputs[vno] = mris->vertices[vno].curv ; classification = SVMclassify(svm, inputs) ; printf("classification %f, class = %s",classification, classification > 0 ? svm->class1_name : svm->class2_name) ; if (true_class != 0) printf(", %s", true_class*classification>0 ? "CORRECT" : "INCORRECT") ; printf("\n") ; if (log_fname) { FILE *fp ; fp = fopen(log_fname, "a") ; if (!fp) ErrorExit(ERROR_BADPARM, "%s: could not open log file %s", log_fname) ; fprintf(fp, "%-30.30s %s %d %f %f\n", subject_name, hemi, (true_class*classification)>0, classification, true_class) ; fclose(fp) ; } free(inputs) ; MRISfree(&mris) ; SVMfree(&svm) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("classification took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }