/*------------------------------------------------------------ EVScb1Error() - computes a measure of how far a given sequence is from having ideal first-order counter-balancing. It is computed as the relative difference between the ideal counter-balance probability matrix and the actual matrix, averaged over all the elements in the matrix. ------------------------------------------------------------*/ float EVScb1Error(EVSCH *EvSch) { MATRIX *IdealPcb1, *Pcb1; int i,j; float cb1err; IdealPcb1 = EVScb1IdealProbMatrix(EvSch); Pcb1 = EVScb1ProbMatrix(EvSch); cb1err = 0; for (i=1; i<= EvSch->nEvTypes; i++) { for (j=1; j<= EvSch->nEvTypes; j++) { cb1err += fabs(IdealPcb1->rptr[i][j]-Pcb1->rptr[i][j])/ IdealPcb1->rptr[i][j]; } } cb1err /= (EvSch->nEvTypes*EvSch->nEvTypes); MatrixFree(&IdealPcb1); MatrixFree(&Pcb1); EvSch->cb1err = cb1err; return(cb1err); }
/*----------------------------------------------------------------------- EVSfirMtxAll() - convert an event schedule to a design matrix for all events types. The matrices for the individual event types are horizontally concatenated. ---------------------------------------------------------------------*/ MATRIX *EVSfirMtxAll(EVSCH *EvSch, float tDelay, float TR, int Ntps, float PSDMin, float PSDMax, float dPSD) { int ev; MATRIX *Xevfir=NULL, *Xtmp=NULL, *Xfir=NULL; for (ev=1; ev <= EvSch->nEvTypes; ev++) { Xevfir = EVS2FIRmtx(ev, EvSch, 0, TR, Ntps, PSDMin, PSDMax, dPSD, Xevfir); if (Xevfir == NULL) { printf("ERROR: EVSfirMtxAll: Cannot compute Xevfir\n"); return(NULL); } Xtmp = MatrixHorCat(Xfir,Xevfir,NULL); if (Xfir != NULL) MatrixFree(&Xfir); Xfir = Xtmp; MatrixFree(&Xevfir); Xevfir = NULL; } return(Xfir); }
int main(int argc, char ** argv) { char op; char mStr[1024]; matrix ans, m1, m2; int sc = 0; if(argc > 1){ op = getOp(argv[1]); } else { printf("Which operation: "); op = getOp(NULL); } printf("First matrix:\n"); scanf("%s", mStr); m1 = MatrixInit(mStr); if(op == 'a' || op == 's' || op == 'm'){ printf("Second matrix:\n"); scanf("%s", mStr); m2 = MatrixInit(mStr); } else if(op == 'c') { printf("Scalar multiple:\n"); scanf("%d", &sc); } switch(op){ case 'a': ans = MatrixAdd(m1, m2); break; case 's': ans = MatrixSub(m1, m2); break; case 'm': ans = MatrixMul(m1, m2); break; case 'i': ans = MatrixInv(m1); break; case 'c': ans = MatrixSMul(m1, i2f(sc)); break; default: printf("Something went very wrong.\n"); return 1; } printf("Answer:\n"); MatrixPrint(ans); MatrixFree(m1); MatrixFree(ans); if(op == 'a' || op == 's' || op == 'm'){ MatrixFree(m2); } return 0; }
int regio_write_surfacexform_to_register_dat(MATRIX *B, char *fname, MRI_SURFACE *mris, MRI *mri, char *subject, int float2int) { MATRIX *Ta, *Sa, *invTa, *A, *R, *S, *invS, *T, *m1, *m2 ; MRI *mri_surf = MRIallocHeader(mris->vg.width, mris->vg.height, mris->vg.depth, MRI_UCHAR,1) ; MRIcopyVolGeomToMRI(mri_surf, &mris->vg) ; T = MRIxfmCRS2XYZtkreg(mri) ; S = MRIgetVoxelToRasXform(mri) ; invS = MatrixInverse(S, NULL) ; Ta = MRIxfmCRS2XYZtkreg(mri_surf); Sa = MRIgetVoxelToRasXform(mri_surf); invTa = MatrixInverse(Ta,NULL); A = MatrixMultiply(Sa,invTa, NULL); m1 = MatrixMultiply(A, B, NULL) ; m2 = MatrixMultiply(invS, m1, NULL) ; R = MatrixMultiply(T, m2, NULL) ; regio_write_register(fname,subject,mri->xsize, mri->zsize,1,R,float2int); MatrixFree(&A) ; MatrixFree(&Ta) ; MatrixFree(&Sa) ; MatrixFree(&invTa) ; MatrixFree(&R) ; MatrixFree(&m1) ; MatrixFree(&m2) ; MatrixFree(&S) ; MatrixFree(&invS); MatrixFree(&T) ; MRIfree(&mri_surf) ; return(NO_ERROR) ; }
/*------------------------------------------------------ DVTgetDepVar() - extracts dependent variables, weights, returns a single column. ------------------------------------------------------*/ MATRIX *DVTgetDepVar(DVT *dvt, int nDepVars, char **DepVarList, float *DepVarWeight) { MATRIX *y, *W; int index,n; float wc; W = MatrixConstVal(1, dvt->D->cols, 1, NULL); if (nDepVars != 0) { for (n=0; n < dvt->D->cols; n++) { index = gdfStringIndex(dvt->ColNames[n],DepVarList,nDepVarList); if (index == -1) wc = 0; else if (DepVarWeight != NULL) wc = DepVarWeight[index]; else wc = 1.0; W->rptr[n+1][1] = wc; } } //printf("W-------------\n"); //MatrixPrint(stdout,W); //printf("W-------------\n"); y = MatrixMultiply(dvt->D,W,NULL); MatrixFree(&W); return(y); }
void InversMatrix(const int n, double **b, double **ib) { double **a; double *e; int i,j; int *p; a=MatrixAlloc(n); e=VectorAlloc(n); p=IntVectorAlloc(n); MatrixCopy(n, a, b); LUfact(n, a, p); for(i=0; i<n; i++) { for(j=0; j<n; j++) e[j]=0.0; e[i]=1.0; LUsubst(n, a, p, e); for(j=0; j<n; j++) ib[j][i]=e[j]; } /* for i=1..n */ MatrixFree(n, a); VectorFree(n, e); IntVectorFree(n, p); } /* InversMatrix */
/*----------------------------------------------------- Parameters: Returns value: Description ------------------------------------------------------*/ static int init_translation(MRI *mri_in, MRI *mri_ref, MATRIX *m_L) { MATRIX *m_translation ; float in_means[4], ref_means[4] ; double dx, dy, dz ; m_translation = MatrixIdentity(4, NULL) ; MRIfindCenterOfBrain(mri_in, in_means, in_means+1, in_means+2) ; MRIfindCenterOfBrain(mri_ref, ref_means, ref_means+1, ref_means+2) ; dx = (double)(ref_means[0] - in_means[0]) * mri_in->thick ; dy = (double)(ref_means[1] - in_means[1]) * mri_in->thick ; dz = (double)(ref_means[2] - in_means[2]) * mri_in->thick ; if (Gdiag & DIAG_SHOW) { fprintf(stderr, "centering template around (%d,%d,%d) and input around" " (%d,%d,%d)\n", (int)ref_means[0], (int)ref_means[1], (int)ref_means[2], (int)in_means[0], (int)in_means[1], (int)in_means[2]) ; fprintf(stderr, "initial translation = (%2.0f, %2.0f, %2.0f).\n",dx,dy,dz); } *MATRIX_RELT(m_translation, 1, 4) = dx ; *MATRIX_RELT(m_translation, 2, 4) = dy ; *MATRIX_RELT(m_translation, 3, 4) = dz ; MatrixMultiply(m_translation, m_L, m_L) ; MatrixFree(&m_translation) ; return(NO_ERROR) ; }
/*----------------------------------------------------- Parameters: Returns value: Description ------------------------------------------------------*/ IMAGE * ImageRead(const char*fname) { IMAGE *I = NULL ; MATRIX *mat ; FILE *fp ; int type, frame ; char buf[STRLEN] ; strcpy(buf, fname) ; /* don't destroy callers string */ ImageUnpackFileName(buf, &frame, &type, buf) ; switch (type) { case TIFF_IMAGE: I = TiffReadImage(buf, frame) ; if (I == NULL) return(NULL) ; break ; case MATLAB_IMAGE: DiagPrintf(DIAG_WRITE, "ImageRead: buf=%s, frame=%d, type=%d (M=%d,H=%d)\n", buf, frame, type , MATLAB_IMAGE, HIPS_IMAGE); mat = MatlabRead(buf) ; if (!mat) ErrorReturn(NULL, (ERROR_NO_FILE, "ImageRead(%s) failed\n", buf)) ; I = ImageFromMatrix(mat, NULL) ; ImageInvert(I, I) ; MatrixFree(&mat) ; break ; case HIPS_IMAGE: fp = fopen(buf, "rb") ; if (!fp) ErrorReturn(NULL, (ERROR_NO_FILE, "ImageRead(%s, %d) failed\n", buf, frame)) ; I = ImageFRead(fp, buf, frame, 1) ; fclose(fp) ; break ; case JPEG_IMAGE: I = JPEGReadImage(buf); break ; case PGM_IMAGE: I = PGMReadImage(buf); break; case PPM_IMAGE: I = PPMReadImage(buf); break; case PBM_IMAGE: I = PBMReadImage(buf); break; case RGBI_IMAGE: I= RGBReadImage(buf); default: break ; } return(I) ; }
void MatrixTest::tearDown() { MatrixFree( &mPascalMatrix ); MatrixFree( &mBuckyMatrix ); MatrixFree( &mZeroesMatrix ); MatrixFree( &mIdentityMatrix ); MatrixFree( &mSingularMatrix ); MatrixFree( &mNonSquareMatrix ); MatrixFree( &mOneMatrix ); MatrixFree( &mOneSmallMatrix ); }
static int uniform_region(GCA *gca, MRI *mri, TRANSFORM *transform, int x, int y, int z, int wsize, GCA_SAMPLE *gcas, float nsigma) { int xk, yk, zk, whalf, xi, yi, zi, n, frame ; Real val0, val, sigma, min_val,max_val, thresh ; MATRIX *m ; GC1D *gc ; gc = GCAfindSourceGC(gca, mri, transform, x, y, z, gcas->label) ; if (!gc) return(0) ; m = load_covariance_matrix(gc, NULL, gca->ninputs) ; whalf = (wsize-1)/2 ; for (n = 0 ; n < gca->ninputs ; n++) { sigma = sqrt(*MATRIX_RELT(m, n+1, n+1)) ; MRIsampleVolumeFrame(mri, (Real)x, (Real)y, (Real)z, n, &val0) ; if (sigma < 0.05*val0) /* don't let it be too small */ sigma = 0.05*val0 ; if (sigma > 0.1*val0) /* don't let it be too big */ sigma = 0.1*val0 ; min_val = max_val = val0 ; thresh = nsigma*sigma ; for (frame = 0 ; frame < mri->nframes ; frame++) for (xk = -whalf ; xk <= whalf ; xk++) { xi = mri->xi[x+xk] ; for (yk = -whalf ; yk <= whalf ; yk++) { yi = mri->yi[y+yk] ; for (zk = -whalf ; zk <= whalf ; zk++) { zi = mri->zi[z+zk] ; MRIsampleVolumeFrame (mri, (Real)xi, (Real)yi, (Real)zi, frame, &val) ; if (val < min_val) min_val = val ; if (val > max_val) max_val = val ; if (fabs(val-val0) > thresh || fabs(max_val-min_val) > thresh) return(0) ; } } } } MatrixFree(&m) ; return(1) ; }
char *regio_read_subject(const char *regfile) { float inplaneres, betplaneres, intensity; int float2int; MATRIX *R; char *subject; regio_read_register(regfile, &subject, &inplaneres,&betplaneres, &intensity, &R,&float2int); MatrixFree(&R); return(subject); }
static int test(MRI *mri1, MRI *mri2, MRI *mri3, MATRIX *m_vol1_to_vol2_ras) { VECTOR *v_test, *v_vox ; float x_ras1, y_ras1, z_ras1, x_ras2, y_ras2, z_ras2, x_vox1, y_vox1, z_vox1, x_vox2, y_vox2, z_vox2 ; MATRIX *m_vol2_vox2ras, *m_vol2_ras2vox, *m_vol1_ras2vox, *m_vol1_vox2ras, *m_vol3_ras2vox, *m_vol3_vox2ras ; int val ; v_test = VectorAlloc(4, MATRIX_REAL) ; m_vol1_vox2ras = MRIgetVoxelToRasXform(mri1) ; m_vol2_vox2ras = MRIgetVoxelToRasXform(mri2) ; m_vol1_ras2vox = MRIgetRasToVoxelXform(mri1) ; m_vol2_ras2vox = MRIgetRasToVoxelXform(mri2) ; m_vol3_vox2ras = MRIgetVoxelToRasXform(mri3) ; m_vol3_ras2vox = MRIgetRasToVoxelXform(mri3) ; x_ras1 = 126.50 ; y_ras1 = -125.500 ; z_ras1 = 127.50 ; V3_X(v_test) = x_ras1 ; V3_Y(v_test) = y_ras1 ; V3_Z(v_test) = z_ras1 ; *MATRIX_RELT(v_test, 4, 1) = 1.0 ; v_vox = MatrixMultiply(m_vol1_ras2vox, v_test, NULL) ; x_vox1 = V3_X(v_vox) ; y_vox1 = V3_Y(v_vox) ; z_vox1 = V3_Z(v_vox) ; val = MRISvox(mri1, nint(x_vox1), nint(y_vox1), nint(z_vox1)) ; printf("VOL1: ras (%1.1f, %1.1f, %1.1f) --> VOX (%1.1f, %1.1f, %1.1f) = %d\n", x_ras1, y_ras1, z_ras1, x_vox1, y_vox1, z_vox1, val) ; x_ras2 = 76.5421 ; y_ras2 = 138.5352 ; z_ras2 = 96.0910 ; V3_X(v_test) = x_ras2 ; V3_Y(v_test) = y_ras2 ; V3_Z(v_test) = z_ras2 ; *MATRIX_RELT(v_test, 4, 1) = 1.0 ; v_vox = MatrixMultiply(m_vol2_ras2vox, v_test, NULL) ; x_vox2 = V3_X(v_vox) ; y_vox2 = V3_Y(v_vox) ; z_vox2 = V3_Z(v_vox) ; val = MRISvox(mri2, nint(x_vox2), nint(y_vox2), nint(z_vox2)) ; printf("VOL2: ras (%2.1f, %2.1f, %2.1f) --> VOX (%2.1f, %2.1f, %2.1f) = %d\n", x_ras2, y_ras2, z_ras2, x_vox2, y_vox2, z_vox2, val) ; MatrixFree(&v_test) ; return(NO_ERROR) ; }
int IOPFree(IOP **piop) { IOP *iop ; iop = *piop ; *piop = NULL ; if (iop->dipole_vertices) free(iop->dipole_vertices) ; if (iop->spatial_priors) free(iop->spatial_priors) ; if (iop->pvals) free(iop->pvals) ; if (iop->m_iop) MatrixFree(&iop->m_iop) ; if (iop->m_forward) MatrixFree(&iop->m_forward) ; if (iop->bad_sensors) free(iop->bad_sensors) ; return(NO_ERROR) ; }
MATRIX * regio_read_surfacexform_from_register_dat(char *fname, MRI_SURFACE *mris, MRI *mri, char **subject) { MATRIX *Ta, *Sa, *invT, *A, *R, *S, *invSa, *T, *m1, *m2, *B ; float pres, bres, intensity ; int float2int ; MRI *mri_surf = MRIallocHeader(mris->vg.width, mris->vg.height, mris->vg.depth, MRI_UCHAR,1) ; if (regio_read_register(fname, subject, &pres, &bres, &intensity,&B,&float2int) != 0) ErrorReturn(NULL, (ERROR_NOFILE, "regio_read_surfacexform_from_register_dat(%s) failed", fname)) ; MRIcopyVolGeomToMRI(mri_surf, &mris->vg) ; T = MRIxfmCRS2XYZtkreg(mri) ; S = MRIgetVoxelToRasXform(mri) ; Ta = MRIxfmCRS2XYZtkreg(mri_surf); Sa = MRIgetVoxelToRasXform(mri_surf); invSa = MatrixInverse(Sa, NULL) ; invT = MatrixInverse(T,NULL); A = MatrixMultiply(S,invT, NULL); m1 = MatrixMultiply(A, B, NULL) ; m2 = MatrixMultiply(invSa, m1, NULL) ; R = MatrixMultiply(Ta, m2, NULL) ; MatrixFree(&A) ; MatrixFree(&Ta) ; MatrixFree(&Sa) ; MatrixFree(&invT) ; MatrixFree(&B) ; MatrixFree(&m1) ; MatrixFree(&m2) ; MatrixFree(&S) ; MatrixFree(&invSa); MatrixFree(&T) ; MRIfree(&mri_surf) ; return(R) ; }
static MRI * apply_bias(MRI *mri_orig, MRI *mri_norm, MRI *mri_bias) { MATRIX *m_vox2vox; VECTOR *v1, *v2; int x, y, z ; double xd, yd, zd, bias, val_orig, val_norm ; if (mri_norm == NULL) mri_norm = MRIclone(mri_orig, NULL) ; m_vox2vox = MRIgetVoxelToVoxelXform(mri_orig, mri_bias) ; v1 = VectorAlloc(4, MATRIX_REAL); v2 = VectorAlloc(4, MATRIX_REAL); VECTOR_ELT(v1, 4) = 1.0 ; VECTOR_ELT(v2, 4) = 1.0 ; for (x = 0 ; x < mri_orig->width ; x++) { V3_X(v1) = x ; for (y = 0 ; y < mri_orig->height ; y++) { V3_Y(v1) = y ; for (z = 0 ; z < mri_orig->depth ; z++) { V3_Z(v1) = z ; if (x == Gx && y == Gy && z == Gz) DiagBreak() ; val_orig = MRIgetVoxVal(mri_orig, x, y, z, 0) ; MatrixMultiply(m_vox2vox, v1, v2) ; xd = V3_X(v2) ; yd = V3_Y(v2) ; zd = V3_Z(v2); MRIsampleVolume(mri_bias, xd, yd, zd, &bias) ; val_norm = val_orig * bias ; if (mri_norm->type == MRI_UCHAR) { if (val_norm > 255) val_norm = 255 ; else if (val_norm < 0) val_norm = 0 ; } MRIsetVoxVal(mri_norm, x, y, z, 0, val_norm) ; } } } MatrixFree(&m_vox2vox) ; VectorFree(&v1) ; VectorFree(&v2) ; return(mri_norm) ; }
/*-----------------------------------------------------*/ int DVTfree(DVT **ppdvt) { DVT *dvt; int r,c; dvt = *ppdvt; if (dvt->dvtfile != NULL) free(dvt->dvtfile); for (c = 0; c < dvt->D->cols; c++) free(dvt->ColNames[c]); for (r = 0; r < dvt->D->rows; r++) free(dvt->RowNames[r]); free(dvt->ColNames); free(dvt->RowNames); MatrixFree(&(dvt->D)); free(*ppdvt); return(0); }
/*-------------------------------------------------------------- EVScb1ProbMatrix() - computes an estimate of the first-order counter-balance PROBABILITY matrix. The value in element i,j is the probability (or rate) that condition i was followed by condition j. This does not include condition 0. In theory, the rows of Pcb1 should sum to 1.0, but this will not be the case for which ever condition the sequence ends on. --------------------------------------------------------------*/ MATRIX *EVScb1ProbMatrix(EVSCH *EvSch) { MATRIX *Ncb1, *Pcb1=NULL; int i,j; Ncb1 = EVScb1Matrix(EvSch); Pcb1 = MatrixZero(EvSch->nEvTypes,EvSch->nEvTypes,NULL); for (i=1; i<= EvSch->nEvTypes; i++) { for (j=1; j<= EvSch->nEvTypes; j++) { Pcb1->rptr[i][j] = Ncb1->rptr[i][j]/EvSch->nEvReps[i-1]; /* Note: i-1 needed in nEvReps because its normal C array */ } } MatrixFree(&Ncb1); return(Pcb1); }
void Jacobi(const int n, double **a, double *b, double *x, double eps, int max_iter) { double d; /* temporary real */ int i, j, iter; /* counters */ double **a_new; /* a is altered */ double *b_new; /* b is altered */ double *u; /* new solution */ double norm; /* L1-norm */ a_new=MatrixAlloc(3); b_new=VectorAlloc(3); u=VectorAlloc(3); for(i=0; i<n; i++) { /* the trick */ d=1.0/a[i][i]; b_new[i]=d*b[i]; for(j=0; j<n; j++) a_new[i][j]=d*a[i][j]; } /* for i */ iter=0; do { iter++; norm=0.0; for(i=0; i<n; i++) { /* update process */ d=-a_new[i][i]*x[i]; /* don't include term i=j */ for(j=0; j<n; j++) d+=a_new[i][j]*x[j]; u[i]=b_new[i]-d; norm=fabs(u[i]-x[i]); } /* for i */ for(i=0; i<n; i++) /* copy solution */ x[i]=u[i]; } while ((iter<=max_iter) && (norm>=eps)); MatrixFree(3, a_new); VectorFree(3, b_new); VectorFree(3, u); } /* Jacobi */
static int build_label_histograms(MRI *mri_labels, MRI *mri_intensities, HISTOGRAM **histos) { int labels[MAX_LABEL+1], x, y, z, l ; MRI *mri_xformed ; MATRIX *m_vox2vox ; memset(labels, 0, sizeof(labels)) ; m_vox2vox = MRIgetVoxelToVoxelXform(mri_intensities, mri_labels) ; mri_xformed = MRIclone(mri_labels, NULL) ; MRIlinearTransform(mri_intensities, mri_xformed, m_vox2vox) ; MatrixFree(&m_vox2vox) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) MRIwrite(mri_xformed, "x.mgz") ; for (x = 0 ; x < mri_labels->width ; x++) for (y = 0 ; y < mri_labels->height ; y++) for (z = 0 ; z < mri_labels->depth ; z++) { l = nint(MRIgetVoxVal(mri_labels, x, y, z, 0)) ; // if (l == 0) // continue ; if (labels[l] == 0) // first time { char fname[STRLEN] ; histos[l] = MRIhistogramLabel(mri_xformed, mri_labels, l, 50) ; HISTOmakePDF(histos[l], histos[l]) ; sprintf(fname, "label%d.plt", l) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) HISTOplot(histos[l], fname) ; } labels[l] = 1 ; } MRIfree(&mri_xformed) ; return(NO_ERROR) ; }
/*------------------------------------------------------------ ContrastVMF() - computes the variance multiplication factor ------------------------------------------------------------*/ static double ContrastVMF(MATRIX *X, MATRIX *C) { float vmf; MATRIX *Xt, *XtX, *iXtX, *CiXtX, *Ct, *CiXtXCt; Xt = MatrixTranspose(X,NULL); XtX = MatrixMultiply(Xt,X,NULL); iXtX = MatrixInverse(XtX,NULL); CiXtX = MatrixMultiply(C,iXtX,NULL); Ct = MatrixTranspose(C,NULL); CiXtXCt = MatrixMultiply(CiXtX,Ct,NULL); vmf = CiXtXCt->rptr[1][1]; MatrixFree(&Xt); MatrixFree(&XtX); MatrixFree(&iXtX); MatrixFree(&CiXtX); MatrixFree(&Ct); MatrixFree(&CiXtXCt); return(vmf); }
void MatrixTest::DeleteMatrix(MATRIX* m) { MatrixFree( &m ); m = NULL; }
/*---------------------------------------------------------------*/ int main(int argc, char **argv) { int n, v, c; FILE *fp; char *covarname; char SumFile[2000]; char DatFile[2000]; char MatFile[2000]; char OutGDFile[2000]; int nargs; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_gdfglm.c,v 1.8.2.1 2011/05/05 15:29:51 greve Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; argc --; argv++; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; if (argc == 0) usage_exit(); printf("\n\n"); printf("%s ",Progname); for (n=0; n < argc; n++) printf("%s ",argv[n]); printf("\n\n"); printf("%s\n\n",vcid); parse_commandline(argc, argv); check_options(); dump_options(stdout); X = gdfMatrixDODS(fsgd,NULL); if (X==NULL) exit(1); if (debug) MatrixPrint(stdout,X); Xnorm = MatrixNormalizeCol(X,NULL,NULL); Xcondition = sqrt(MatrixNSConditionNumber(Xnorm)); MatrixFree(&Xnorm); printf("INFO: Normalized Design Matrix Condition Number is %g\n", Xcondition); if (Xcondition > 100000) { printf("ERROR: Design matrix is badly conditioned, check for linear\n" "dependency between columns (ie, two or more columns \n" "that add up to another column).\n\n"); exit(1); } printf("Extracting DepVar\n"); y = DVTgetDepVar(dvt,nDepVarList,DepVarList,wDepVar); printf("Performing Estimation\n"); pinvX = MatrixPseudoInverse(X,NULL); beta = MatrixMultiply(pinvX,y,NULL); yhat = MatrixMultiply(X,beta,NULL); r = MatrixSubtract(y,yhat,NULL); dof = X->rows-X->cols; rvar = VectorVar(r, &rmean); rvar = rvar * (X->rows-1)/dof; printf("Beta: -----------------\n"); MatrixPrint(stdout,beta); printf("---------------------------------\n\n"); printf("rvar = %g, rstd = %g\n",rvar,sqrt(rvar)); C = gdfContrastDODS(fsgd, wClass, wCovar); printf("C: -----------------\n"); MatrixPrint(stdout,C); printf("---------------------------------\n\n"); ces = MatrixMultiply(C,beta,NULL); vmf = ContrastVMF(X,C); tval = ces->rptr[1][1]/sqrt(rvar*vmf); sigtval = sigt(tval, rint(dof)); printf("ces = %g, vmf = %g, t = %g, sigt = %g\n", ces->rptr[1][1],vmf,tval,sigtval); sprintf(SumFile,"%s.sum",OutBase); fp = fopen(SumFile,"w"); fprintf(fp,"mri_gdfglm summary file\n\n"); fprintf(fp,"Group Descriptor File %s\n",GDFile); fprintf(fp,"Dependent Variable File %s\n",DVTFile); fprintf(fp,"Dependent Variable Weights: "); if (wDepVar == NULL) fprintf(fp," all 1s\n"); else { fprintf(fp,"\n"); for (n=0; n < nwDepVar; n++) fprintf(fp," %s %g\n",DepVarList[n],wDepVar[n]); } fprintf(fp,"\n"); fprintf(fp,"Class Contrast Weights: "); if (nwClass == 0) fprintf(fp," all 1s\n"); else { fprintf(fp,"\n"); for (n=0; n < nwClass; n++) fprintf(fp," %s %g\n",fsgd->classlabel[n],wClass[n]); } fprintf(fp,"\n"); fprintf(fp,"Covar Contrast Weights: "); if (nwCovar == 0) if (!TestOffset) fprintf(fp," all 1s\n"); else fprintf(fp," all 0s\n"); else { fprintf(fp,"\n"); for (n=0; n < nwCovar; n++) fprintf(fp," %s %g",CovarList[n],wCovar[n]); fprintf(fp,"\n"); } fprintf(fp,"TestOffset = %d\n",TestOffset); fprintf(fp,"\n"); fprintf(fp,"Parameter Estimates and Contrast Weighting:\n\n"); n = 0; for (v=0; v < fsgd->nvariables+1; v++) { if (v==0) covarname = "Offset"; else covarname = fsgd->varlabel[v-1]; for (c=0; c < fsgd->nclasses; c++) { fprintf(fp,"%-10s %-10s %12.5f %5.2f\n",fsgd->classlabel[c], covarname,beta->rptr[n+1][1],C->rptr[1][n+1]); n++; } fprintf(fp,"\n"); } fprintf(fp,"\n"); fprintf(fp,"Residual Variance %g\n",rvar); fprintf(fp,"Residual StdDev %g\n",sqrt(rvar)); fprintf(fp,"DOF %g\n",dof); fprintf(fp,"\n"); fprintf(fp,"Contrast Effect Size %g\n",ces->rptr[1][1]); fprintf(fp,"Variance Reduction Factor %g\n",1/vmf); fprintf(fp,"t-Ratio %g\n",tval); fprintf(fp,"Significance %g\n",sigtval); fprintf(fp,"\n"); fclose(fp); /*----------------------------------------*/ sprintf(DatFile,"%s.dat",OutBase); fp = fopen(DatFile,"w"); for (n=0; n < fsgd->ninputs; n++) { fprintf(fp,"%2d ",n); if (KeepSubjId) fprintf(fp,"%s",fsgd->subjid[n]); for (v=0; v < fsgd->nvariables; v++) fprintf(fp," %g",fsgd->varvals[n][v]); fprintf(fp," %g %g",y->rptr[n+1][1],yhat->rptr[n+1][1]); fprintf(fp,"\n"); } fclose(fp); /*----------------------------------------*/ sprintf(MatFile,"%s.mat",OutBase); all = MatrixHorCat(X,y,NULL); all = MatrixHorCat(all,yhat,NULL); all = MatrixHorCat(all,r,NULL); MatlabWrite(all,MatFile,"X"); /*----------------------------------------*/ sprintf(OutGDFile,"%s.gdf",OutBase); fp = fopen(OutGDFile,"w"); gdfPrintHeader(fp,fsgd); fclose(fp); /*----------------------------------------*/ WriteAllClassDat(OutBase,fsgd,y,yhat,X,beta); return(0); }
int main(int argc, char *argv[]) { char **av, *source_fname, *target_fname, *out_fname, fname[STRLEN] ; int ac, nargs, new_transform = 0, pad ; MRI *mri_target, *mri_source, *mri_orig_source ; MRI_REGION box ; struct timeb start ; int msec, minutes, seconds ; GCA_MORPH *gcam ; MATRIX *m_L/*, *m_I*/ ; LTA *lta ; /* initialize the morph params */ memset(&mp, 0, sizeof(GCA_MORPH_PARMS)); /* for nonlinear morph */ mp.l_jacobian = 1 ; mp.min_sigma = 0.4 ; mp.l_distance = 0 ; mp.l_log_likelihood = .025 ; mp.dt = 0.005 ; mp.noneg = True ; mp.exp_k = 20 ; mp.diag_write_snapshots = 1 ; mp.momentum = 0.9 ; if (FZERO(mp.l_smoothness)) mp.l_smoothness = 2 ; mp.sigma = 8 ; mp.relabel_avgs = -1 ; mp.navgs = 256 ; mp.levels = 6 ; mp.integration_type = GCAM_INTEGRATE_BOTH ; mp.nsmall = 1 ; mp.reset_avgs = -1 ; mp.npasses = 3 ; mp.regrid = regrid? True : False ; mp.tol = 0.1 ; mp.niterations = 1000 ; TimerStart(&start) ; setRandomSeed(-1L) ; DiagInit(NULL, NULL, NULL) ; ErrorInit(NULL, NULL, NULL) ; Progname = argv[0] ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 4) usage_exit(1) ; source_fname = argv[1] ; target_fname = argv[2] ; out_fname = argv[3] ; FileNameOnly(out_fname, fname) ; FileNameRemoveExtension(fname, fname) ; strcpy(mp.base_name, fname) ; mri_source = MRIread(source_fname) ; if (!mri_source) ErrorExit(ERROR_NOFILE, "%s: could not read source label volume %s", Progname, source_fname) ; if (mri_source->type == MRI_INT) { MRI *mri_tmp = MRIchangeType(mri_source, MRI_FLOAT, 0, 1, 1) ; MRIfree(&mri_source); mri_source = mri_tmp ; } mri_target = MRIread(target_fname) ; if (!mri_target) ErrorExit(ERROR_NOFILE, "%s: could not read target label volume %s", Progname, target_fname) ; if (mri_target->type == MRI_INT) { MRI *mri_tmp = MRIchangeType(mri_target, MRI_FLOAT, 0, 1, 1) ; MRIfree(&mri_target); mri_target = mri_tmp ; } if (erosions > 0) { int n ; for (n = 0 ; n < erosions ; n++) { MRIerodeZero(mri_target, mri_target) ; MRIerodeZero(mri_source, mri_source) ; } } if (scale_values > 0) { MRIscalarMul(mri_source, mri_source, scale_values) ; MRIscalarMul(mri_target, mri_target, scale_values) ; } if (transform && transform->type == MORPH_3D_TYPE) TransformRas2Vox(transform, mri_source,NULL) ; if (use_aseg == 0) { if (match_peak_intensity_ratio) MRImatchIntensityRatio(mri_source, mri_target, mri_source, .8, 1.2, 100, 125) ; else if (match_mean_intensity) MRImatchMeanIntensity(mri_source, mri_target, mri_source) ; MRIboundingBox(mri_source, 0, &box) ; pad = (int)ceil(PADVOX * MAX(mri_target->xsize,MAX(mri_target->ysize,mri_target->zsize)) / MIN(mri_source->xsize,MIN(mri_source->ysize,mri_source->zsize))); #if 0 { MRI *mri_tmp ; if (pad < 1) pad = 1 ; printf("padding source with %d voxels...\n", pad) ; mri_tmp = MRIextractRegionAndPad(mri_source, NULL, &box, pad) ; if ((Gdiag & DIAG_WRITE) && DIAG_VERBOSE_ON) MRIwrite(mri_tmp, "t.mgz") ; MRIfree(&mri_source) ; mri_source = mri_tmp ; } #endif } mri_orig_source = MRIcopy(mri_source, NULL) ; mp.max_grad = 0.3*mri_source->xsize ; if (transform == NULL) transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ; if (transform->type != MORPH_3D_TYPE) // initializing m3d from a linear transform { new_transform = 1 ; lta = ((LTA *)(transform->xform)) ; if (lta->type != LINEAR_VOX_TO_VOX) { printf("converting ras xform to voxel xform\n") ; m_L = MRIrasXformToVoxelXform(mri_source, mri_target, lta->xforms[0].m_L, NULL) ; MatrixFree(<a->xforms[0].m_L) ; lta->type = LINEAR_VOX_TO_VOX ; } else { printf("using voxel xform\n") ; m_L = lta->xforms[0].m_L ; } #if 0 if (Gsx >= 0) // update debugging coords { VECTOR *v1, *v2 ; v1 = VectorAlloc(4, MATRIX_REAL) ; Gsx -= (box.x-pad) ; Gsy -= (box.y-pad) ; Gsz -= (box.z-pad) ; V3_X(v1) = Gsx ; V3_Y(v1) = Gsy ; V3_Z(v1) = Gsz ; VECTOR_ELT(v1,4) = 1.0 ; v2 = MatrixMultiply(m_L, v1, NULL) ; Gsx = nint(V3_X(v2)) ; Gsy = nint(V3_Y(v2)) ; Gsz = nint(V3_Z(v2)) ; MatrixFree(&v2) ; MatrixFree(&v1) ; printf("mapping by transform (%d, %d, %d) --> (%d, %d, %d) for rgb writing\n", Gx, Gy, Gz, Gsx, Gsy, Gsz) ; } #endif if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) write_snapshot(mri_target, mri_source, m_L, &mp, 0, 1, "linear_init"); lta->xforms[0].m_L = m_L ; printf("initializing GCAM with vox->vox matrix:\n") ; MatrixPrint(stdout, m_L) ; gcam = GCAMcreateFromIntensityImage(mri_source, mri_target, transform) ; #if 0 gcam->gca = gcaAllocMax(1, 1, 1, mri_target->width, mri_target->height, mri_target->depth, 0, 0) ; #endif GCAMinitVolGeom(gcam, mri_source, mri_target) ; if (use_aseg) { if (ribbon_name) { char fname[STRLEN], path[STRLEN], *str, *hemi ; int h, s, label ; MRI_SURFACE *mris_white, *mris_pial ; MRI *mri ; for (s = 0 ; s <= 1 ; s++) // source and target { if (s == 0) { str = source_surf ; mri = mri_source ; FileNamePath(mri->fname, path) ; strcat(path, "/../surf") ; } else { mri = mri_target ; FileNamePath(mri->fname, path) ; strcat(path, "/../elastic") ; str = target_surf ; } // sorry - these values come from FreeSurferColorLUT.txt MRIreplaceValueRange(mri, mri, 1000, 1034, Left_Cerebral_Cortex) ; MRIreplaceValueRange(mri, mri, 1100, 1180, Left_Cerebral_Cortex) ; MRIreplaceValueRange(mri, mri, 2000, 2034, Right_Cerebral_Cortex) ; MRIreplaceValueRange(mri, mri, 2100, 2180, Right_Cerebral_Cortex) ; for (h = LEFT_HEMISPHERE ; h <= RIGHT_HEMISPHERE ; h++) { if (h == LEFT_HEMISPHERE) { hemi = "lh" ; label = Left_Cerebral_Cortex ; } else { label = Right_Cerebral_Cortex ; hemi = "rh" ; } sprintf(fname, "%s/%s%s.white", path, hemi, str) ; mris_white = MRISread(fname) ; if (mris_white == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ; MRISsaveVertexPositions(mris_white, WHITE_VERTICES) ; sprintf(fname, "%s/%s%s.pial", path, hemi, str) ; mris_pial = MRISread(fname) ; if (mris_pial == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ; MRISsaveVertexPositions(mris_pial, PIAL_VERTICES) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { sprintf(fname, "sb.mgz") ; MRIwrite(mri_source, fname) ; sprintf(fname, "tb.mgz") ; MRIwrite(mri_target, fname) ; } insert_ribbon_into_aseg(mri, mri, mris_white, mris_pial, h) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { sprintf(fname, "sa.mgz") ; MRIwrite(mri_source, fname) ; sprintf(fname, "ta.mgz") ; MRIwrite(mri_target, fname) ; } MRISfree(&mris_white) ; MRISfree(&mris_pial) ; } } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { sprintf(fname, "s.mgz") ; MRIwrite(mri_source, fname) ; sprintf(fname, "t.mgz") ; MRIwrite(mri_target, fname) ; } } GCAMinitLabels(gcam, mri_target) ; GCAMsetVariances(gcam, 1.0) ; mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ; } } else /* use a previously create morph and integrate it some more */ { printf("using previously create gcam...\n") ; gcam = (GCA_MORPH *)(transform->xform) ; GCAMrasToVox(gcam, mri_source) ; if (use_aseg) { GCAMinitLabels(gcam, mri_target) ; GCAMsetVariances(gcam, 1.0) ; mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ; } else GCAMaddIntensitiesFromImage(gcam, mri_target) ; } if (gcam->width != mri_source->width || gcam->height != mri_source->height || gcam->depth != mri_source->depth) ErrorExit(ERROR_BADPARM, "%s: warning gcam (%d, %d, %d), doesn't match source vol (%d, %d, %d)", Progname, gcam->width, gcam->height, gcam->depth, mri_source->width, mri_source->height, mri_source->depth) ; mp.mri_diag = mri_source ; mp.diag_morph_from_atlas = 0 ; mp.diag_write_snapshots = 1 ; mp.diag_sample_type = use_aseg ? SAMPLE_NEAREST : SAMPLE_TRILINEAR ; mp.diag_volume = use_aseg ? GCAM_LABEL : GCAM_MEANS ; if (renormalize) GCAMnormalizeIntensities(gcam, mri_target) ; if (mp.write_iterations != 0) { char fname[STRLEN] ; MRI *mri_gca ; if (getenv("DONT_COMPRESS")) sprintf(fname, "%s_target.mgh", mp.base_name) ; else sprintf(fname, "%s_target.mgz", mp.base_name) ; if (mp.diag_morph_from_atlas == 0) { printf("writing target volume to %s...\n", fname) ; MRIwrite(mri_target, fname) ; sprintf(fname, "%s_target", mp.base_name) ; MRIwriteImageViews(mri_target, fname, IMAGE_SIZE) ; } else { if (use_aseg) mri_gca = GCAMwriteMRI(gcam, NULL, GCAM_LABEL) ; else { mri_gca = MRIclone(mri_source, NULL) ; GCAMbuildMostLikelyVolume(gcam, mri_gca) ; } printf("writing target volume to %s...\n", fname) ; MRIwrite(mri_gca, fname) ; sprintf(fname, "%s_target", mp.base_name) ; MRIwriteImageViews(mri_gca, fname, IMAGE_SIZE) ; MRIfree(&mri_gca) ; } } if (nozero) { printf("disabling zero nodes\n") ; GCAMignoreZero(gcam, mri_target) ; } mp.mri = mri_target ; if (mp.regrid == True && new_transform == 0) GCAMregrid(gcam, mri_target, PAD, &mp, &mri_source) ; mp.write_fname = out_fname ; GCAMregister(gcam, mri_source, &mp) ; // atlas is target, morph target into register with it if (apply_transform) { MRI *mri_aligned ; char fname[STRLEN] ; FileNameRemoveExtension(out_fname, fname) ; strcat(fname, ".mgz") ; mri_aligned = GCAMmorphToAtlas(mp.mri, gcam, NULL, -1, mp.diag_sample_type) ; printf("writing transformed output volume to %s...\n", fname) ; MRIwrite(mri_aligned, fname) ; MRIfree(&mri_aligned) ; } printf("writing warp vector field to %s\n", out_fname) ; GCAMvoxToRas(gcam) ; GCAMwrite(gcam, out_fname) ; GCAMrasToVox(gcam, mri_source) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("registration took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
/* Actually no need to modify this function, since I will only use the float * type here, so the roundoff I added will never take effect. * What I need to modify is the MRIchangeType function! */ MRI *MRIlinearTransformInterpBSpline(MRI *mri_src, MRI *mri_dst, MATRIX *mA, int splinedegree) { int y1, y2, y3, width, height, depth ; VECTOR *v_X, *v_Y ; /* original and transformed coordinate systems */ MATRIX *mAinv ; /* inverse of mA */ double val, x1, x2, x3 ; MRI *mri_Bcoeff; mAinv = MatrixInverse(mA, NULL) ; /* will sample from dst back to src */ if (!mAinv) ErrorReturn(NULL, (ERROR_BADPARM, "MRIlinearTransformBSpline: xform is singular")) ; if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ; else MRIclear(mri_dst) ; /* set all values to zero */ if (mri_src->type != MRI_FLOAT) mri_Bcoeff = MRIchangeType(mri_src, MRI_FLOAT, 0, 1.0, 1); else mri_Bcoeff = MRIcopy(mri_src, NULL); /* convert between a representation based on image samples */ /* and a representation based on image B-spline coefficients */ if (SamplesToCoefficients(mri_Bcoeff, splinedegree)) { ErrorReturn(NULL, (ERROR_BADPARM, "Change of basis failed\n")); } printf("Direct B-spline Transform Finished. \n"); width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; v_X = VectorAlloc(4, MATRIX_REAL) ; /* input (src) coordinates */ v_Y = VectorAlloc(4, MATRIX_REAL) ; /* transformed (dst) coordinates */ v_Y->rptr[4][1] = 1.0f ; for (y3 = 0 ; y3 < mri_dst->depth ; y3++) { V3_Z(v_Y) = y3 ; for (y2 = 0 ; y2 < mri_dst->height ; y2++) { V3_Y(v_Y) = y2 ; for (y1 = 0 ; y1 < mri_dst->width ; y1++) { V3_X(v_Y) = y1 ; MatrixMultiply(mAinv, v_Y, v_X) ; x1 = V3_X(v_X) ; x2 = V3_Y(v_X) ; x3 = V3_Z(v_X) ; if (x1 <= -0.5 || x1 >= (width - 0.5) || x2 <= -0.5 || x2 >= (height - 0.5) || x3 <= -0.5 || x3 >= (depth-0.5)) val = 0.0; else val = InterpolatedValue(mri_Bcoeff, x1, x2, x3, splinedegree); switch (mri_dst->type) { case MRI_UCHAR: if (val <-0.5) val = -0.5; if (val > 254.5) val = 254.5; MRIvox(mri_dst,y1,y2,y3) = (BUFTYPE)nint(val+0.5) ; break ; case MRI_SHORT: MRISvox(mri_dst,y1,y2,y3) = (short)nint(val+0.5) ; break ; case MRI_FLOAT: MRIFvox(mri_dst,y1,y2,y3) = (float)(val) ; break ; case MRI_INT: MRIIvox(mri_dst,y1,y2,y3) = nint(val+0.5) ; break ; default: ErrorReturn(NULL, (ERROR_UNSUPPORTED, "MRIlinearTransformBSpline: unsupported dst type %d", mri_dst->type)) ; break ; } } } } MatrixFree(&v_X) ; MatrixFree(&mAinv) ; MatrixFree(&v_Y) ; MRIfree(&mri_Bcoeff); return(mri_dst) ; }
int main(int argc, char *argv[]) { char **av, *in_vol, *out_vol; int ac, nargs; MRI *mri_in, *mri_out, *mri_tmp ; LTA *lta = 0; MATRIX *i_to_r_src = 0; /* src geometry of the input LTA */ MATRIX *V_to_V = 0; /* Final voxel-to-voxel transform */ MATRIX *r_to_i_dst = 0; /* dst geometry of the input LTA */ MATRIX *m_tmp = 0; MATRIX *i_to_r_reg = 0; /* i_to_r of the volume after registration */ MATRIX *r_to_i_out = 0; /* r_to_i of the final output volume */ VOL_GEOM vgm_in; int x, y, z; double maxV, minV, value; // MATRIX *i_to_r, *r_to_i; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_transform_to_COR.c,v 1.8 2011/03/02 00:04:55 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) usage_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 (argc < 3) usage_exit(0) ; in_vol = argv[1] ; out_vol = argv[2] ; printf("reading volume from %s...\n", in_vol) ; mri_in = MRIread(in_vol) ; if (!mri_in) ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume %s", Progname, in_vol) ; /* Convert mri_in to float type */ /* double would be more accurate */ if (mri_in->type != MRI_FLOAT) { printf("Input volume type is %d\n", mri_in->type); printf("Change input volume to float type for convenience and accuracy"); mri_tmp = MRIchangeType(mri_in, MRI_FLOAT, 0, 1.0, 1); MRIfree(&mri_in); mri_in = mri_tmp; //swap } /* Get input volume geometry, which is needed to compute i_to_r * and r_to_i of input volume. Note that i_to_r and r_to_i assumed * a certain prespecified c_r, c_a, c_s */ getVolGeom(mri_in, &vgm_in); maxV = -10000.0; minV = 10000.0; for (z=0; z < mri_in->depth; z++) for (y=0; y< mri_in->height; y++) for (x=0; x < mri_in->width; x++) { if (MRIFvox(mri_in, x, y, z) > maxV ) maxV = MRIFvox(mri_in, x, y,z) ; if (MRIFvox(mri_in, x, y, z) < minV ) minV = MRIFvox(mri_in, x, y,z) ; } printf("Input volume has max = %g, min =%g\n", maxV, minV); printf("Scale input volume by %g \n", scale); maxV = -10000.0; minV = 10000.0; for (z=0; z < mri_in->depth; z++) for (y=0; y< mri_in->height; y++) for (x=0; x < mri_in->width; x++) { MRIFvox(mri_in, x, y, z) *= scale; if (MRIFvox(mri_in, x, y, z) > maxV ) maxV = MRIFvox(mri_in, x, y,z) ; if (MRIFvox(mri_in, x, y, z) < minV ) minV = MRIFvox(mri_in, x, y,z) ; } printf("Input volume after scaling has max = %g, min =%g\n", maxV, minV); /* Try to compute the Voxel_to_Voxel transform from the input volume * and the registration target/reference volume! * If no registration is involved, vox_to_vox is simply identity */ /* Things become more complicated when allowing inverse transform */ if (transform_flag) { int transform_type; printf("INFO: Applying transformation from file %s...\n", transform_fname); transform_type = TransformFileNameType(transform_fname); /* Read in LTA transform file name */ if (transform_type == MNI_TRANSFORM_TYPE || transform_type == TRANSFORM_ARRAY_TYPE || transform_type == REGISTER_DAT || transform_type == FSLREG_TYPE ) { printf("Reading transform ...\n"); lta = LTAreadEx(transform_fname) ; if (!lta) ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s", Progname, transform_fname) ; if (transform_type == FSLREG_TYPE) { if (lta_src == 0 || lta_dst == 0) { fprintf(stderr, "ERROR: fslmat does not have information on the src and dst volumes\n"); fprintf(stderr, "ERROR: you must give options '-src' and '-dst' to specify the src and dst volume infos for the registration\n"); } LTAmodifySrcDstGeom(lta, lta_src, lta_dst); // add src and dst information //The following is necessary to interpret FSLMAT correctly!!! LTAchangeType(lta, LINEAR_VOX_TO_VOX); } if (lta->xforms[0].src.valid == 0) { if (lta_src == 0) { fprintf(stderr, "The transform does not have the valid src volume info.\n"); fprintf(stderr, "Either you give src volume info by option -src or\n"); fprintf(stderr, "make the transform to have the valid src info.\n"); ErrorExit(ERROR_BAD_PARM, "Bailing out...\n"); } else { LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information } } if (lta->xforms[0].dst.valid == 0) { if (lta_dst == 0) { fprintf(stderr, "The transform does not have the valid dst volume info.\n"); fprintf(stderr, "Either you give src volume info by option -dst or\n"); fprintf(stderr, "make the transform to have the valid dst info.\n"); fprintf(stderr, "If the dst was average_305, then you can set\n"); fprintf(stderr, "environmental variable USE_AVERAGE305 true\n"); fprintf(stderr, "instead.\n"); ErrorExit(ERROR_BAD_PARM, "Bailing out...\n"); } else { LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add dst information } } // The following procedure aims to apply an LTA computed from COR format to a volume in non-COR format, or vice versa, as long as they share the same RAS // first change to LINEAR RAS_TO_RAS using old info if (lta->type != LINEAR_RAS_TO_RAS) { LTAchangeType(lta, LINEAR_RAS_TO_RAS); } // now possiblly reset the src and dst if (lta_src != NULL) { //always trust the user LTAmodifySrcDstGeom(lta, lta_src, NULL); } if (lta_dst != NULL) { //always trust the user LTAmodifySrcDstGeom(lta, NULL, lta_dst); } if (lta->type == LINEAR_RAS_TO_RAS) { /* Convert it to VOX_TO_VOX */ /* VOXELsrc_to_VOXELdst = R2Vdst*R2Rlta*V2Rsrc */ /* Note whether the input should be identical to src or dst here depends * on whether the LTA here is the direct or inverse transform */ i_to_r_src = vg_i_to_r(<a->xforms[0].src); r_to_i_dst = vg_r_to_i(<a->xforms[0].dst); if (!r_to_i_dst || !i_to_r_src) ErrorExit(ERROR_BADFILE, "%s: failed to extract volume geometries from input LTA file",Progname); m_tmp = MatrixMultiply(lta->xforms[0].m_L, i_to_r_src, NULL); V_to_V = MatrixMultiply(r_to_i_dst, m_tmp, NULL); MatrixFree(&m_tmp); MatrixFree(&i_to_r_src); MatrixFree(&r_to_i_dst); } } else { fprintf(stderr, "unknown transform type in file %s\n", transform_fname); exit(1); } if (invert_flag) { /* Geometry of input volume should match that of the dst of the LTA */ if (MYvg_isEqual(<a->xforms[0].dst, &vgm_in) == 0) { ErrorExit(ERROR_BADFILE, "%s: dst volume of lta doesn't match that of input volume",Progname); } i_to_r_reg = vg_i_to_r(<a->xforms[0].src); if (!i_to_r_reg) ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r of registered volume from LTA",Progname); m_tmp = MatrixInverse(V_to_V, NULL); if (!m_tmp) ErrorExit(ERROR_BADPARM, "%s: transform is singular!", Progname); MatrixFree(&V_to_V); V_to_V = m_tmp; } else { /* Geometry of input volume should match that of the src of the LTA */ if (MYvg_isEqual(<a->xforms[0].src, &vgm_in) == 0) { ErrorExit(ERROR_BADFILE, "%s: src volume of lta doesn't match that of input volume",Progname); } i_to_r_reg = vg_i_to_r(<a->xforms[0].dst); if (!i_to_r_reg) ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r of registered volume from LTA",Progname); } } else { /* No registration transform need be applied */ V_to_V = MatrixIdentity(4, NULL); i_to_r_reg = extract_i_to_r(mri_in); if (!i_to_r_reg) ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r from input volume",Progname); } /* Now need to find the vox-to-vox transformation between registered volume * (or input volume itself if no registration involved) and the output * volume, either in COR format or as the out-like volume */ /* Given a volume with a certain i_to_r, we need to compute the necessary * vox-to-voxel transform to change its i_to_r to like another volume. * The vox-to-vox is equal to R2V(r_to_i)_likevol*i_to_r_current_vol. */ if (out_like_fname) { mri_tmp = MRIread(out_like_fname) ; if (!mri_tmp) ErrorExit(ERROR_NOFILE, "%s: could not read template volume from %s",out_like_fname) ; /* out_type = mri_tmp->type; */ /* specify the out-type to float initially so as not to lose accuracy * during reslicing, will change type to correct type later. */ mri_out = MRIalloc(mri_tmp->width, mri_tmp->height, mri_tmp->depth, MRI_FLOAT) ; MRIcopyHeader(mri_tmp, mri_out) ; MRIfree(&mri_tmp); } else /* assume output is in COR format */ { mri_out = MRIalloc(256, 256, 256, MRI_FLOAT) ; /* out_type = MRI_UCHAR; */ /* Who says MRIlinearTransformInterp will change the header?? * I don't think so! */ //E/ set xyzc_ras to coronal ones.. - these'll get zorched //by MRIlinearTransformInterp() - copy again later - is there //any use in having them here now? yes, so we can pass mri_out //to the ras2vox fns. mri_out->imnr0 = 1; /* what's this? */ mri_out->imnr1 = 256; /* what's this? */ mri_out->thick = 1.0; mri_out->ps = 1.0; /* what's this? */ mri_out->xsize = mri_out->ysize = mri_out->zsize = 1.0; mri_out->xstart = mri_out->ystart = mri_out->zstart = -128.0; mri_out->xend = mri_out->yend = mri_out->zend = 128.0; mri_out->x_r =-1; mri_out->y_r = 0; mri_out->z_r = 0; mri_out->x_a = 0; mri_out->y_a = 0; mri_out->z_a = 1; mri_out->x_s = 0; mri_out->y_s =-1; mri_out->z_s = 0; /* In this case, the RAS itself is not fully determined, i.e., c_ras. * It's quite arbitrary, different values just change the final * sitting of the volume inside the RAS system. */ /* NO! The C_RAS has to be set correctly, depending which target * volume the previous Vox_to_Vox transformation assumes! * When a registration is involved, the target volume is either * the src of LTA (direct) or the dst (inverse transform). When * just change format, the target volume is the input itself!! */ if (transform_flag) { if (invert_flag) { mri_out->c_r = lta->xforms[0].src.c_r; mri_out->c_a = lta->xforms[0].src.c_a; mri_out->c_s = lta->xforms[0].src.c_s; } else { mri_out->c_r = lta->xforms[0].dst.c_r; mri_out->c_a = lta->xforms[0].dst.c_a; mri_out->c_s = lta->xforms[0].dst.c_s; } } else { mri_out->c_r = mri_in->c_r; mri_out->c_a = mri_in->c_a; mri_out->c_s = mri_in->c_s; } mri_out->ras_good_flag=1; /* What does this flag mean ? */ /* since output is just transformed input */ MRIcopyPulseParameters(mri_in, mri_out) ; } /* Compute the final input-to-output VOX_to_VOX transformation matrix */ r_to_i_out = extract_r_to_i(mri_out); m_tmp = MatrixMultiply(r_to_i_out, i_to_r_reg, NULL); V_to_V = MatrixMultiply(m_tmp, V_to_V, V_to_V); MatrixFree(&m_tmp); printf("InterpMethod = %d\n", InterpMethod); /* Modify the MyMRIlinearTr... if I want to implement my cubic-B-spline * interpolation method. Otherwise, unnecessary */ /* mri_out = MyMRIlinearTransformInterp(mri_in, mri_out, V_to_V, InterpMethod); */ if (InterpMethod == SAMPLE_BSPLINE) mri_out = MRIlinearTransformInterpBSpline(mri_in, mri_out, V_to_V, SplineDegree); else mri_out = MRIlinearTransformInterp(mri_in, mri_out, V_to_V, InterpMethod); maxV = -10000.0; minV = 10000.0; for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { if (MRIFvox(mri_out, x, y, z) > maxV ) maxV = MRIFvox(mri_out, x, y,z) ; if (MRIFvox(mri_out, x, y, z) < minV ) minV = MRIFvox(mri_out, x, y,z) ; } if (autoscale) { noscale = 1; /* compute histogram of output volume */ HISTOGRAM *h, *hsmooth ; float fmin, fmax, val, peak, smooth_peak; int i, nbins, bin; fmin = minV; fmax = maxV; if (fmin < 0) fmin = 0; nbins = 256 ; h = HISTOalloc(nbins) ; hsmooth = HISTOcopy(h, NULL) ; HISTOclear(h, h) ; h->bin_size = (fmax-fmin)/255.0 ; for (i = 0 ; i < nbins ; i++) h->bins[i] = (i+1)*h->bin_size ; for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { val = MRIFvox(mri_out, x, y, z); if (val <= 0) continue; bin = nint((val - fmin)/h->bin_size); if (bin >= h->nbins) bin = h->nbins-1; else if (bin < 0) bin = 0; h->counts[bin] += 1.0; } HISTOfillHoles(h) ; HISTOsmooth(h, hsmooth, 5) ; peak = hsmooth->bins[HISTOfindHighestPeakInRegion(h, 1, h->nbins)] ; // smooth_peak = // hsmooth->bins[HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins)] ; smooth_peak = hsmooth->bins[HISTOfindLastPeak(hsmooth, 5, 0.8)] ; /* bin = nint((smooth_peak - fmin)/hsmooth->bin_size) ; printf("Highest peak has count = %d\n", (int)hsmooth->counts[bin]); bin = nint((420 - fmin)/hsmooth->bin_size) ; printf("bin at 420 has count = %d\n", (int)hsmooth->counts[bin]); */ scale = 110.0/smooth_peak; printf("peak of output volume is %g, smooth-peak is %g, multiply by %g to scale it to 110\n", peak, smooth_peak, scale); for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { val = MRIFvox(mri_out, x, y, z); MRIFvox(mri_out, x, y, z) = val*scale; } } printf("Output volume (before type-conversion) has max = %g, min =%g\n", maxV, minV); /* Finally change type to desired */ if (mri_out->type != out_type) { printf("Change output volume to type %d\n", out_type); /* I need to modify the MIRchangeType function to make sure * it does roundoff instead of simple truncation! */ /* Note if the last flag is set to 1, then it won't do scaling and small float numbers will become zero after convert to BYTE */ if (out_type == 0 && noscale == 1) { //convert data to UCHAR mri_tmp = MRIalloc(mri_out->width, mri_out->height, mri_out->depth, out_type) ; MRIcopyHeader(mri_out, mri_tmp); for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { value = floor(MRIgetVoxVal(mri_out, x, y, z, 0) + 0.5); if (value < 0 ) value = 0; if (value > 255) value = 255; MRIvox(mri_tmp,x,y,z) = (unsigned char)value; } } else mri_tmp = MRIchangeType(mri_out, out_type, thred_low, thred_high, noscale); MRIfree(&mri_out); mri_out = mri_tmp; //swap } MRIwrite(mri_out, out_vol) ; MRIfree(&mri_in); MRIfree(&mri_out); if (lta_src) MRIfree(<a_src); if (lta_dst) MRIfree(<a_dst); MatrixFree(&V_to_V); if (!r_to_i_out) MatrixFree(&r_to_i_out); if (!i_to_r_reg) MatrixFree(&i_to_r_reg); return(0) ; /* for ansi */ }
int main(int argc, char *argv[]) { char **av, *avg_surf_name, *canon_surf_name, fname[STRLEN], *mdir, ico_fname[STRLEN], *hemi, *out_sname ; int ac, nargs, i, vno, n ; VERTEX *v ; MRI_SURFACE *mris_ico ; MRI_SP *mrisp_total ; LTA *lta ; VOL_GEOM vg; float average_surface_area = 0.0 ; MATRIX *XFM=NULL; GCA_MORPH *gcam=NULL; memset((void *) &vg, 0, sizeof (VOL_GEOM)); /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mris_make_average_surface.c,v 1.29 2011/03/02 00:04:33 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; mdir = getenv("FREESURFER_HOME") ; if (!mdir) ErrorExit(ERROR_BADPARM, "%s: no FREESURFER_HOME in environment.\n",Progname); ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (sdir == NULL) { sdir = getenv("SUBJECTS_DIR"); if (!sdir) ErrorExit(ERROR_BADPARM, "%s: no SUBJECTS_DIR in environment.\n",Progname); } if (sdirout == NULL) sdirout = sdir; if (argc < 6) usage_exit() ; hemi = argv[1] ; avg_surf_name = argv[2] ; canon_surf_name = argv[3] ; out_sname = argv[4] ; printf("---------------------------------------------------\n"); printf("hemi = %s\n",hemi); printf("avg_surf_name = %s\n",avg_surf_name); printf("canon_surf_name = %s\n",canon_surf_name); printf("out_sname = %s\n",out_sname); printf("xform = %s\n",xform_name); printf("---------------------------------------------------\n"); printf("\n\n"); fflush(stdout); #define SCALE 1 mrisp_total = MRISPalloc(SCALE, 3) ; for (n = 0, i = 5 ; i < argc ; i++) { MRI *mri; MRI_SURFACE *mris; MRI_SP *mrisp; printf("\n---------------------------------------------------\n"); printf("#@# processing subject %d/%d %s...\n", i-4,argc-5,argv[i]) ; fflush(stdout); // read sphere.reg sprintf(fname, "%s/%s/surf/%s.%s", sdir, argv[i], hemi, canon_surf_name) ; printf(" Reading %s\n",fname); fflush(stdout); mris = MRISread(fname) ; if (!mris) { ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s", Progname, fname) ; exit(1); } // get "pial" surface vertex into ->origx, origy, origz if (MRISreadOriginalProperties(mris, orig_name) != NO_ERROR) ErrorExit(ERROR_BADFILE,"%s: could not read orig file for %s.\n", Progname, argv[1]); // read transform if (0) { sprintf(fname, "%s/%s/mri/transforms/%s", sdir, argv[i], xform_name) ; lta = LTAreadEx(fname) ; if (!lta) ErrorExit(ERROR_BADPARM, "%s: could not read transform from %s", Progname, fname) ; } // read T1 volume sprintf(fname, "%s/%s/mri/T1.mgz", sdir, argv[i]) ; if (fio_FileExistsReadable(fname)) mri = MRIreadHeader(fname,MRI_MGH_FILE); else { sprintf(fname, "%s/%s/mri/T1", sdir, argv[i]) ; mri = MRIreadHeader(fname, MRI_UCHAR); // MRI_CORONAL_SLICE_DIRECTORY) ; } printf(" Read %s\n",fname); fflush(stdout); if (!mri) ErrorExit(ERROR_BADPARM, "%s: could not read reference MRI volume from %s", Progname, fname) ; // save current vertex position into ->cx MRISsaveVertexPositions(mris, CANONICAL_VERTICES) ; // get the vertex position from ->origx, ... // (get the "pial" vertex position) MRISrestoreVertexPositions(mris, ORIGINAL_VERTICES) ; MRIScomputeMetricProperties(mris) ; printf(" Surface area: %2.1f cm^2\n", mris->total_area/100) ; fflush(stdout); average_surface_area += mris->total_area ; // this means that we transform "pial" surface if (xform_name) { if (!strcmp(xform_name,"talairach.xfm")) { printf(" Applying linear transform\n"); fflush(stdout); XFM = DevolveXFMWithSubjectsDir(argv[i], NULL, "talairach.xfm", sdir); if (XFM == NULL) exit(1); MRISmatrixMultiply(mris, XFM); MatrixFree(&XFM); } else if (!strcmp(xform_name,"talairach.m3z")) { printf(" Applying GCA Morph\n"); fflush(stdout); sprintf(fname, "%s/%s/mri/transforms/talairach.m3z", sdir, argv[i]) ; gcam = GCAMreadAndInvert(fname); if (gcam == NULL) exit(1); GCAMmorphSurf(mris, gcam); GCAMfree(&gcam); } else { printf("ERROR: don't know what to do with %s\n",xform_name); exit(1); } } // save transformed position in ->orig // (store "pial" vertices position in orig) MRIScomputeMetricProperties(mris) ; MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ; // get the vertex position from ->cx // (note that this is not transformed) sphere.reg vertices MRISrestoreVertexPositions(mris, CANONICAL_VERTICES) ; // mris contains sphere.reg in vertex and pial vertices in orig // map to a theta-phi space and accumulate values mrisp = MRIScoordsToParameterization(mris, NULL, SCALE, ORIGINAL_VERTICES) ; MRISPaccumulate(mrisp, mrisp_total, 0) ; MRISPaccumulate(mrisp, mrisp_total, 1) ; MRISPaccumulate(mrisp, mrisp_total, 2) ; MRISPfree(&mrisp) ; MRISfree(&mris) ; MRIfree(&mri) ; //LTAfree(<a) ; fflush(stdout); n++ ; } printf("Finished loading all data\n"); average_surface_area /= (float)n ; printf("Avg surf area = %g cm\n",average_surface_area/100.0); fflush(stdout); // mrisp_total lost info on the modified surface sprintf(ico_fname, "%s/lib/bem/ic%d.tri", mdir, ico_no) ; printf("Reading icosahedron from %s...\n", ico_fname) ; mris_ico = ICOread(ico_fname) ; if (!mris_ico) ErrorExit(ERROR_NOFILE, "%s: could not read icosahedron file %s\n", Progname,ico_fname) ; MRISscaleBrain(mris_ico, mris_ico, DEFAULT_RADIUS/MRISaverageRadius(mris_ico)) ; // save current ico position to ->cx, cy, cz MRISsaveVertexPositions(mris_ico, CANONICAL_VERTICES) ; // using mrisp_total to calculate position into ->origx, origy, origz // (orig is the "pial" vertices) MRIScoordsFromParameterization(mrisp_total, mris_ico, ORIGINAL_VERTICES) ; // copy geometry info memcpy((void *) &mris_ico->vg, (void *) &vg, sizeof (VOL_GEOM)); if (Gdiag_no >= 0 && Gdiag_no < mris_ico->nvertices) { int n ; VERTEX *vn ; v = &mris_ico->vertices[Gdiag_no] ; printf( "v %d: x = (%2.2f, %2.2f, %2.2f)\n", Gdiag_no, v->origx, v->origy, v->origz) ; for (n = 0 ; n < v->vnum ; n++) { vn = &mris_ico->vertices[v->v[n]] ; printf( "v %d: x = (%2.2f, %2.2f, %2.2f)\n", v->v[n], vn->origx, vn->origy, vn->origz) ; } } // write *h.sphere.reg sprintf(fname, "%s/%s/surf/%s.%s", sdirout, out_sname, hemi, canon_surf_name) ; if (Gdiag & DIAG_SHOW) printf("writing average canonical surface to %s\n", fname); MRISwrite(mris_ico, fname) ; // get "pial vertices" from orig MRISrestoreVertexPositions(mris_ico, ORIG_VERTICES); for (vno = 0 ; vno < mris_ico->nvertices ; vno++) { v = &mris_ico->vertices[vno] ; // n = number of subjects v->x /= (float)n ; v->y /= (float)n ; v->z /= (float)n ; } if (normalize_area) { MRIScomputeMetricProperties(mris_ico) ; printf("setting group surface area to be %2.1f cm^2 (scale=%2.2f)\n", average_surface_area/100.0, sqrt(average_surface_area/mris_ico->total_area)) ; #if 0 MRISscaleBrain(mris_ico, mris_ico, sqrt(average_surface_area/mris_ico->total_area)) ; #else mris_ico->group_avg_surface_area = average_surface_area ; #endif MRIScomputeMetricProperties(mris_ico) ; } sprintf(fname, "%s/%s/surf/%s.%s", sdirout,out_sname, hemi, avg_surf_name) ; printf("writing average %s surface to %s\n", avg_surf_name, fname); MRISwrite(mris_ico, fname) ; if (0) { char path[STRLEN] ; LTA *lta ; FileNamePath(fname, path) ; lta = LTAalloc(1, NULL) ; // write to a different location sprintf(fname, "%s/../mri/transforms/%s", path,xform_name) ; LTAwriteEx(lta, fname) ; LTAfree(<a) ; } MRISfree(&mris_ico) ; MRISPfree(&mrisp_total) ; printf("mris_make_average_surface done\n"); exit(0) ; return(0) ; /* for ansi */ }
int main(int argc, char *argv[]) { char **av ; int ac, nargs, n ; MRI *mri_src, *mri_dst = NULL, *mri_bias, *mri_orig, *mri_aseg = NULL ; char *in_fname, *out_fname ; int msec, minutes, seconds ; struct timeb start ; char cmdline[CMD_LINE_LEN] ; make_cmd_version_string (argc, argv, "$Id: mri_normalize.c,v 1.80 2012/10/16 21:38:35 nicks Exp $", "$Name: $", cmdline); /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_normalize.c,v 1.80 2012/10/16 21:38:35 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) { exit (0); } argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; mni.max_gradient = MAX_GRADIENT ; 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(0) ; } if (argc < 1) { ErrorExit(ERROR_BADPARM, "%s: no input name specified", Progname) ; } in_fname = argv[1] ; if (argc < 2) { ErrorExit(ERROR_BADPARM, "%s: no output name specified", Progname) ; } out_fname = argv[2] ; if(verbose) { printf( "reading from %s...\n", in_fname) ; } mri_src = MRIread(in_fname) ; if (!mri_src) ErrorExit(ERROR_NO_FILE, "%s: could not open source file %s", Progname, in_fname) ; MRIaddCommandLine(mri_src, cmdline) ; if(nsurfs > 0) { MRI_SURFACE *mris ; MRI *mri_dist=NULL, *mri_dist_sup=NULL, *mri_ctrl, *mri_dist_one ; LTA *lta= NULL ; int i ; TRANSFORM *surface_xform ; if (control_point_fname) // do one pass with only file control points first { MRI3dUseFileControlPoints(mri_src, control_point_fname) ; mri_dst = MRI3dGentleNormalize(mri_src, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, NULL, intensity_above, intensity_below/2,1, bias_sigma, mri_not_control); } else { mri_dst = MRIcopy(mri_src, NULL) ; } for (i = 0 ; i < nsurfs ; i++) { mris = MRISread(surface_fnames[i]) ; if (mris == NULL) ErrorExit(ERROR_NOFILE,"%s: could not surface %s", Progname,surface_fnames[i]); surface_xform = surface_xforms[i] ; TransformInvert(surface_xform, NULL) ; if (surface_xform->type == MNI_TRANSFORM_TYPE || surface_xform->type == TRANSFORM_ARRAY_TYPE || surface_xform->type == REGISTER_DAT) { lta = (LTA *)(surface_xform->xform) ; #if 0 if (invert) { VOL_GEOM vgtmp; LT *lt; MATRIX *m_tmp = lta->xforms[0].m_L ; lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ; MatrixFree(&m_tmp) ; lt = <a->xforms[0]; if (lt->dst.valid == 0 || lt->src.valid == 0) { printf( "WARNING:***************************************************************\n"); printf( "WARNING:dst volume infor is invalid. Most likely produce wrong inverse.\n"); printf( "WARNING:***************************************************************\n"); } copyVolGeom(<->dst, &vgtmp); copyVolGeom(<->src, <->dst); copyVolGeom(&vgtmp, <->src); } #endif } if (stricmp(surface_xform_fnames[i], "identity.nofile") != 0) { MRIStransform(mris, NULL, surface_xform, NULL) ; } mri_dist_one = MRIcloneDifferentType(mri_dst, MRI_FLOAT) ; printf("computing distance transform\n") ; MRIScomputeDistanceToSurface(mris, mri_dist_one, mri_dist_one->xsize) ; if (i == 0) { mri_dist = MRIcopy(mri_dist_one, NULL) ; } else { MRIcombineDistanceTransforms(mri_dist_one, mri_dist, mri_dist) ; } // MRIminAbs(mri_dist_one, mri_dist, mri_dist) ; MRIfree(&mri_dist_one) ; } MRIscalarMul(mri_dist, mri_dist, -1) ; if (nonmax_suppress) { printf("computing nonmaximum suppression\n") ; mri_dist_sup = MRInonMaxSuppress(mri_dist, NULL, 0, 1) ; mri_ctrl = MRIcloneDifferentType(mri_dist_sup, MRI_UCHAR) ; MRIbinarize(mri_dist_sup, mri_ctrl, min_dist, CONTROL_NONE, CONTROL_MARKED) ; } else if (erode) { int i ; mri_ctrl = MRIcloneDifferentType(mri_dist, MRI_UCHAR) ; MRIbinarize(mri_dist, mri_ctrl, min_dist, CONTROL_NONE, CONTROL_MARKED) ; for (i = 0 ; i < erode ; i++) { MRIerode(mri_ctrl, mri_ctrl) ; } } else { mri_ctrl = MRIcloneDifferentType(mri_dist, MRI_UCHAR) ; MRIbinarize(mri_dist, mri_ctrl, min_dist, CONTROL_NONE, CONTROL_MARKED) ; } if (control_point_fname) { MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ; } if (mask_sigma > 0) { MRI *mri_smooth, *mri_mag, *mri_grad ; mri_smooth = MRIgaussianSmooth(mri_dst, mask_sigma, 1, NULL) ; mri_mag = MRIcloneDifferentType(mri_dst, MRI_FLOAT) ; mri_grad = MRIsobel(mri_smooth, NULL, mri_mag) ; MRIbinarize(mri_mag, mri_mag, mask_thresh, 1, 0) ; MRImask(mri_ctrl, mri_mag, mri_ctrl, 0, CONTROL_NONE) ; MRIfree(&mri_grad) ; MRIfree(&mri_mag) ; MRIfree(&mri_smooth) ; } if (mask_orig_fname) { MRI *mri_orig ; mri_orig = MRIread(mask_orig_fname) ; MRIbinarize(mri_orig, mri_orig, mask_orig_thresh, 0, 1) ; MRImask(mri_ctrl, mri_orig, mri_ctrl, 0, CONTROL_NONE) ; MRIfree(&mri_orig) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dist, "d.mgz"); MRIwrite(mri_dist_sup, "dm.mgz"); MRIwrite(mri_ctrl, "c.mgz"); } MRIeraseBorderPlanes(mri_ctrl, 4) ; if (aseg_fname) { mri_aseg = MRIread(aseg_fname) ; if (mri_aseg == NULL) { ErrorExit(ERROR_NOFILE, "%s: could not load aseg from %s", Progname, aseg_fname) ; } remove_nonwm_voxels(mri_ctrl, mri_aseg, mri_ctrl) ; MRIfree(&mri_aseg) ; } else { remove_surface_outliers(mri_ctrl, mri_dist, mri_dst, mri_ctrl) ; } mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; if (mri_dist) { MRIfree(&mri_dist) ; } if (mri_dist_sup) { MRIfree(&mri_dist_sup) ; } if (bias_sigma> 0) { MRI *mri_kernel = MRIgaussian1d(bias_sigma, -1) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_bias, "b.mgz") ; } printf("smoothing bias field\n") ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_bias, "bs.mgz") ; } MRIfree(&mri_kernel); } MRIfree(&mri_ctrl) ; mri_dst = MRIapplyBiasCorrectionSameGeometry (mri_dst, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; printf("writing normalized volume to %s\n", out_fname) ; MRIwrite(mri_dst, out_fname) ; exit(0) ; } // end if(surface_fname) if (!mriConformed(mri_src) && conform > 0) { printf("unconformed source detected - conforming...\n") ; mri_src = MRIconform(mri_src) ; } if (mask_fname) { MRI *mri_mask ; mri_mask = MRIread(mask_fname) ; if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n", Progname, mask_fname) ; MRImask(mri_src, mri_mask, mri_src, 0, 0) ; MRIfree(&mri_mask) ; } if (read_flag) { MRI *mri_ctrl ; double scale ; mri_bias = MRIread(bias_volume_fname) ; if (!mri_bias) ErrorExit (ERROR_BADPARM, "%s: could not read bias volume %s", Progname, bias_volume_fname) ; mri_ctrl = MRIread(control_volume_fname) ; if (!mri_ctrl) ErrorExit (ERROR_BADPARM, "%s: could not read control volume %s", Progname, control_volume_fname) ; MRIbinarize(mri_ctrl, mri_ctrl, 1, 0, 128) ; mri_dst = MRImultiply(mri_bias, mri_src, NULL) ; scale = MRImeanInLabel(mri_dst, mri_ctrl, 128) ; printf("mean in wm is %2.0f, scaling by %2.2f\n", scale, 110/scale) ; scale = 110/scale ; MRIscalarMul(mri_dst, mri_dst, scale) ; MRIwrite(mri_dst, out_fname) ; exit(0) ; } if(long_flag) { MRI *mri_ctrl ; double scale ; mri_bias = MRIread(long_bias_volume_fname) ; if (!mri_bias) ErrorExit (ERROR_BADPARM, "%s: could not read bias volume %s", Progname, long_bias_volume_fname) ; mri_ctrl = MRIread(long_control_volume_fname) ; if (!mri_ctrl) ErrorExit (ERROR_BADPARM, "%s: could not read control volume %s", Progname, long_control_volume_fname) ; MRIbinarize(mri_ctrl, mri_ctrl, 1, 0, CONTROL_MARKED) ; if (mri_ctrl->type != MRI_UCHAR) { MRI *mri_tmp ; mri_tmp = MRIchangeType(mri_ctrl, MRI_UCHAR, 0, 1,1); MRIfree(&mri_ctrl) ; mri_ctrl = mri_tmp ; } scale = MRImeanInLabel(mri_src, mri_ctrl, CONTROL_MARKED) ; printf("mean in wm is %2.0f, scaling by %2.2f\n", scale, 110/scale) ; scale = DEFAULT_DESIRED_WHITE_MATTER_VALUE/scale ; mri_dst = MRIscalarMul(mri_src, NULL, scale) ; MRIremoveWMOutliers(mri_dst, mri_ctrl, mri_ctrl, intensity_below/2) ; mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, 50, 1) ; MRIapplyBiasCorrectionSameGeometry(mri_dst, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE); // MRIwrite(mri_dst, out_fname) ; // exit(0) ; } // end if(long_flag) if (grad_thresh > 0) { float thresh ; MRI *mri_mag, *mri_grad, *mri_smooth ; MRI *mri_kernel = MRIgaussian1d(.5, -1) ; mri_not_control = MRIcloneDifferentType(mri_src, MRI_UCHAR) ; switch (scan_type) { case MRI_MGH_MPRAGE: thresh = 15 ; break ; case MRI_WASHU_MPRAGE: thresh = 20 ; break ; case MRI_UNKNOWN: default: thresh = 12 ; break ; } mri_smooth = MRIconvolveGaussian(mri_src, NULL, mri_kernel) ; thresh = grad_thresh ; mri_mag = MRIcloneDifferentType(mri_src, MRI_FLOAT) ; mri_grad = MRIsobel(mri_smooth, NULL, mri_mag) ; MRIwrite(mri_mag, "m.mgz") ; MRIbinarize(mri_mag, mri_not_control, thresh, 0, 1) ; MRIwrite(mri_not_control, "nc.mgz") ; MRIfree(&mri_mag) ; MRIfree(&mri_grad) ; MRIfree(&mri_smooth) ; MRIfree(&mri_kernel) ; } #if 0 #if 0 if ((mri_src->type != MRI_UCHAR) || (!(mri_src->xsize == 1 && mri_src->ysize == 1 && mri_src->zsize == 1))) #else if (conform || (mri_src->type != MRI_UCHAR && conform > 0)) #endif { MRI *mri_tmp ; fprintf (stderr, "downsampling to 8 bits and scaling to isotropic voxels...\n") ; mri_tmp = MRIconform(mri_src) ; mri_src = mri_tmp ; } #endif if(aseg_fname) { printf("Reading aseg %s\n",aseg_fname); mri_aseg = MRIread(aseg_fname) ; if (mri_aseg == NULL) ErrorExit (ERROR_NOFILE, "%s: could not read aseg from file %s", Progname, aseg_fname) ; if (!mriConformed(mri_aseg)) { ErrorExit(ERROR_UNSUPPORTED, "%s: aseg volume %s must be conformed", Progname, aseg_fname) ; } } else { mri_aseg = NULL ; } if(verbose) { printf( "normalizing image...\n") ; } fflush(stdout); fflush(stderr); TimerStart(&start) ; if (control_point_fname) { MRI3dUseFileControlPoints(mri_src, control_point_fname) ; } // this just setup writing control-point volume saving if(control_volume_fname) { MRI3dWriteControlPoints(control_volume_fname) ; } /* first do a gentle normalization to get things in the right intensity range */ if(long_flag == 0) // if long, then this will already have been done with base control points { if(control_point_fname != NULL) /* do one pass with only file control points first */ mri_dst = MRI3dGentleNormalize(mri_src, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, NULL, intensity_above, intensity_below/2,1, bias_sigma, mri_not_control); else { mri_dst = MRIcopy(mri_src, NULL) ; } } fflush(stdout); fflush(stderr); if(mri_aseg) { MRI *mri_ctrl, *mri_bias ; int i ; printf("processing with aseg\n"); mri_ctrl = MRIclone(mri_aseg, NULL) ; for (i = 0 ; i < NWM_LABELS ; i++) { MRIcopyLabel(mri_aseg, mri_ctrl, aseg_wm_labels[i]) ; } printf("removing outliers in the aseg WM...\n") ; MRIremoveWMOutliersAndRetainMedialSurface(mri_dst, mri_ctrl, mri_ctrl, intensity_below) ; MRIbinarize(mri_ctrl, mri_ctrl, 1, CONTROL_NONE, CONTROL_MARKED) ; MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ; if (interior_fname1) { MRIS *mris_interior1, *mris_interior2 ; mris_interior1 = MRISread(interior_fname1) ; if (mris_interior1 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname1) ; mris_interior2 = MRISread(interior_fname2) ; if (mris_interior2 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname2) ; add_interior_points(mri_ctrl, mri_dst, intensity_above, 1.25*intensity_below, mris_interior1, mris_interior2, mri_aseg, mri_ctrl) ; MRISfree(&mris_interior1) ; MRISfree(&mris_interior2) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_ctrl, "norm_ctrl.mgz") ; } printf("Building bias image\n"); fflush(stdout); fflush(stderr); mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; fflush(stdout); fflush(stderr); if (bias_sigma> 0) { printf("Smoothing with sigma %g\n",bias_sigma); MRI *mri_kernel = MRIgaussian1d(bias_sigma, -1) ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; MRIfree(&mri_kernel); fflush(stdout); fflush(stderr); } MRIfree(&mri_ctrl) ; MRIfree(&mri_aseg) ; printf("Applying bias correction\n"); mri_dst = MRIapplyBiasCorrectionSameGeometry (mri_dst, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst, "norm_1.mgz") ; } fflush(stdout); fflush(stderr); } // if(mri_aseg) else { printf("processing without aseg, no1d=%d\n",no1d); if (!no1d) { printf("MRInormInit(): \n"); MRInormInit(mri_src, &mni, 0, 0, 0, 0, 0.0f) ; printf("MRInormalize(): \n"); mri_dst = MRInormalize(mri_src, NULL, &mni) ; if (!mri_dst) { no1d = 1 ; printf("1d normalization failed - trying no1d...\n") ; // ErrorExit(ERROR_BADPARM, "%s: normalization failed", Progname) ; } } if(no1d) { if ((file_only && nosnr) || ((gentle_flag != 0) && (control_point_fname != NULL))) { if (mri_dst == NULL) { mri_dst = MRIcopy(mri_src, NULL) ; } } else { if (nosnr) { if (interior_fname1) { MRIS *mris_interior1, *mris_interior2 ; MRI *mri_ctrl ; printf("computing initial normalization using surface interiors\n"); mri_ctrl = MRIcloneDifferentType(mri_src, MRI_UCHAR) ; mris_interior1 = MRISread(interior_fname1) ; if (mris_interior1 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname1) ; mris_interior2 = MRISread(interior_fname2) ; if (mris_interior2 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname2) ; add_interior_points(mri_ctrl, mri_dst, intensity_above, 1.25*intensity_below, mris_interior1, mris_interior2, mri_aseg, mri_ctrl) ; MRISfree(&mris_interior1) ; MRISfree(&mris_interior2) ; mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; if (bias_sigma> 0) { MRI *mri_kernel = MRIgaussian1d(bias_sigma, -1) ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; MRIfree(&mri_kernel); } mri_dst = MRIapplyBiasCorrectionSameGeometry (mri_src, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; MRIfree(&mri_ctrl) ; } else if (long_flag == 0) // no initial normalization specified { mri_dst = MRIcopy(mri_src, NULL) ; } } else { printf("computing initial normalization using SNR...\n") ; mri_dst = MRInormalizeHighSignalLowStd (mri_src, mri_dst, bias_sigma, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; } } if (!mri_dst) ErrorExit (ERROR_BADPARM, "%s: could not allocate volume", Progname) ; } } // else (not using aseg) fflush(stdout); fflush(stderr); if (file_only == 0) MRI3dGentleNormalize(mri_dst, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, mri_dst, intensity_above, intensity_below/2, file_only, bias_sigma, mri_not_control); mri_orig = MRIcopy(mri_dst, NULL) ; printf("\n"); printf("Iterating %d times\n",num_3d_iter); for (n = 0 ; n < num_3d_iter ; n++) { if(file_only) { break ; } printf( "---------------------------------\n"); printf( "3d normalization pass %d of %d\n", n+1, num_3d_iter) ; if (gentle_flag) MRI3dGentleNormalize(mri_dst, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, mri_dst, intensity_above/2, intensity_below/2, file_only, bias_sigma, mri_not_control); else MRI3dNormalize(mri_orig, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE, mri_dst, intensity_above, intensity_below, file_only, prune, bias_sigma, scan_type, mri_not_control); } printf( "Done iterating ---------------------------------\n"); // this just setup writing control-point volume saving if(control_volume_fname) { MRI3dWriteControlPoints(control_volume_fname) ; } if(bias_volume_fname) { mri_bias = compute_bias(mri_src, mri_dst, NULL) ; printf("writing bias field to %s....\n", bias_volume_fname) ; MRIwrite(mri_bias, bias_volume_fname) ; MRIfree(&mri_bias) ; } if (verbose) { printf("writing output to %s\n", out_fname) ; } MRIwrite(mri_dst, out_fname) ; msec = TimerStop(&start) ; MRIfree(&mri_src); MRIfree(&mri_dst); seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf( "3D bias adjustment took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
/*---------------------------------------------------------------- SurfClusterSummaryFast() - gives identical results as SurfClusterSummary() but much, much faster. ----------------------------------------------------------------*/ SCS *SurfClusterSummaryFast(MRI_SURFACE *Surf, MATRIX *T, int *nClusters) { int n,vtx,clusterno; SURFCLUSTERSUM *scs; MATRIX *xyz, *xyzxfm; float vtxarea, vtxval; struct timeb mytimer; int msecTime; double *weightvtx, *weightarea; // to be consistent with orig code VERTEX *v; if(Gdiag_no > 0) printf("SurfClusterSummaryFast()\n"); TimerStart(&mytimer) ; *nClusters = sclustCountClusters(Surf); if(*nClusters == 0) return(NULL); xyz = MatrixAlloc(4,1,MATRIX_REAL); xyz->rptr[4][1] = 1; xyzxfm = MatrixAlloc(4,1,MATRIX_REAL); scs = (SCS *) calloc(*nClusters, sizeof(SCS)); weightvtx = (double *) calloc(*nClusters, sizeof(double)); weightarea = (double *) calloc(*nClusters, sizeof(double)); for(vtx=0; vtx < Surf->nvertices; vtx++){ v = &(Surf->vertices[vtx]); clusterno = v->undefval; if(clusterno == 0) continue; n = clusterno-1; scs[n].nmembers ++; vtxval = v->val; // Initialize if(scs[n].nmembers == 1){ scs[n].maxval = vtxval; scs[n].vtxmaxval = vtx; weightvtx[n] = 0.0; weightarea[n] = 0.0; scs[n].cx = 0.0; scs[n].cy = 0.0; scs[n].cz = 0.0; } if(! Surf->group_avg_vtxarea_loaded) vtxarea = v->area; else vtxarea = v->group_avg_area; scs[n].area += vtxarea; if(fabs(vtxval) > fabs(scs[n].maxval)){ scs[n].maxval = vtxval; scs[n].vtxmaxval = vtx; } weightvtx[n] += vtxval; weightarea[n] += (vtxval*vtxarea); scs[n].cx += v->x; scs[n].cy += v->y; scs[n].cz += v->z; } // end loop over vertices for (n = 0; n < *nClusters ; n++){ scs[n].clusterno = n+1; scs[n].x = Surf->vertices[scs[n].vtxmaxval].x; scs[n].y = Surf->vertices[scs[n].vtxmaxval].y; scs[n].z = Surf->vertices[scs[n].vtxmaxval].z; scs[n].weightvtx = weightvtx[n]; scs[n].weightarea = weightarea[n]; scs[n].cx /= scs[n].nmembers; scs[n].cy /= scs[n].nmembers; scs[n].cz /= scs[n].nmembers; if (T != NULL){ xyz->rptr[1][1] = scs[n].x; xyz->rptr[2][1] = scs[n].y; xyz->rptr[3][1] = scs[n].z; MatrixMultiply(T,xyz,xyzxfm); scs[n].xxfm = xyzxfm->rptr[1][1]; scs[n].yxfm = xyzxfm->rptr[2][1]; scs[n].zxfm = xyzxfm->rptr[3][1]; xyz->rptr[1][1] = scs[n].cx; xyz->rptr[2][1] = scs[n].cy; xyz->rptr[3][1] = scs[n].cz; MatrixMultiply(T,xyz,xyzxfm); scs[n].cxxfm = xyzxfm->rptr[1][1]; scs[n].cyxfm = xyzxfm->rptr[2][1]; scs[n].czxfm = xyzxfm->rptr[3][1]; } } MatrixFree(&xyz); MatrixFree(&xyzxfm); free(weightvtx); free(weightarea); msecTime = TimerStop(&mytimer) ; if(Gdiag_no > 0) printf("SurfClusterSumFast: n=%d, t = %g\n",*nClusters,msecTime/1000.0); return(scs); }
/*----------------------------------------------------------------*/ SCS *SurfClusterSummary(MRI_SURFACE *Surf, MATRIX *T, int *nClusters) { int n; SURFCLUSTERSUM *scs; MATRIX *xyz, *xyzxfm; double centroidxyz[3]; struct timeb mytimer; int msecTime; char *UFSS; // Must explicity "setenv USE_FAST_SURF_SMOOTHER 0" to turn off fast UFSS = getenv("USE_FAST_SURF_SMOOTHER"); if(!UFSS) UFSS = "1"; if(strcmp(UFSS,"0")){ scs = SurfClusterSummaryFast(Surf, T, nClusters); return(scs); } if(Gdiag_no > 0) printf("SurfClusterSummary()\n"); TimerStart(&mytimer) ; *nClusters = sclustCountClusters(Surf); if (*nClusters == 0) return(NULL); xyz = MatrixAlloc(4,1,MATRIX_REAL); xyz->rptr[4][1] = 1; xyzxfm = MatrixAlloc(4,1,MATRIX_REAL); scs = (SCS *) calloc(*nClusters, sizeof(SCS)); for (n = 0; n < *nClusters ; n++) { scs[n].clusterno = n+1; scs[n].area = sclustSurfaceArea(n+1, Surf, &scs[n].nmembers); scs[n].weightvtx = sclustWeight(n+1, Surf, NULL, 0); scs[n].weightarea = sclustWeight(n+1, Surf, NULL, 1); scs[n].maxval = sclustSurfaceMax(n+1, Surf, &scs[n].vtxmaxval); scs[n].x = Surf->vertices[scs[n].vtxmaxval].x; scs[n].y = Surf->vertices[scs[n].vtxmaxval].y; scs[n].z = Surf->vertices[scs[n].vtxmaxval].z; sclustSurfaceCentroid(n+1, Surf, ¢roidxyz[0]); scs[n].cx = centroidxyz[0]; scs[n].cy = centroidxyz[1]; scs[n].cz = centroidxyz[2]; if (T != NULL){ xyz->rptr[1][1] = scs[n].x; xyz->rptr[2][1] = scs[n].y; xyz->rptr[3][1] = scs[n].z; MatrixMultiply(T,xyz,xyzxfm); scs[n].xxfm = xyzxfm->rptr[1][1]; scs[n].yxfm = xyzxfm->rptr[2][1]; scs[n].zxfm = xyzxfm->rptr[3][1]; xyz->rptr[1][1] = scs[n].cx; xyz->rptr[2][1] = scs[n].cy; xyz->rptr[3][1] = scs[n].cz; MatrixMultiply(T,xyz,xyzxfm); scs[n].cxxfm = xyzxfm->rptr[1][1]; scs[n].cyxfm = xyzxfm->rptr[2][1]; scs[n].czxfm = xyzxfm->rptr[3][1]; } } MatrixFree(&xyz); MatrixFree(&xyzxfm); msecTime = TimerStop(&mytimer) ; if(Gdiag_no > 0) printf("SurfClusterSum: n=%d, t = %g\n",*nClusters,msecTime/1000.0); return(scs); }
static int compute_cluster_statistics(MRI_SURFACE *mris, MRI *mri_profiles, MATRIX **m_covs, VECTOR **v_means, int k) { int i, vno, cluster, nsamples, num[MAX_CLUSTERS]; int singular, cno_pooled, cno ; MATRIX *m1, *mpooled, *m_inv_covs[MAX_CLUSTERS] ; VECTOR *v1 ; FILE *fp ; double det, det_pooled ; memset(num, 0, sizeof(num)) ; nsamples = mri_profiles->nframes ; v1 = VectorAlloc(nsamples, MATRIX_REAL) ; m1 = MatrixAlloc(nsamples, nsamples, MATRIX_REAL) ; mpooled = MatrixAlloc(nsamples, nsamples, MATRIX_REAL) ; for (cluster = 0 ; cluster < k ; cluster++) { VectorClear(v_means[cluster]) ; MatrixClear(m_covs[cluster]) ; } // compute means // fp = fopen("co.dat", "w") ; fp = NULL ; for (vno = 0 ; vno < mris->nvertices ; vno++) { cluster = mris->vertices[vno].curv ; for (i = 0 ; i < nsamples ; i++) { VECTOR_ELT(v1, i+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, i) ; if (cluster == 0 && fp) fprintf(fp, "%f ", VECTOR_ELT(v1, i+1)); } if (cluster == 0 && fp) fprintf(fp, "\n") ; num[cluster]++ ; VectorAdd(v_means[cluster], v1, v_means[cluster]) ; } if (fp) fclose(fp) ; for (cluster = 0 ; cluster < k ; cluster++) if (num[cluster] > 0) VectorScalarMul(v_means[cluster], 1.0/(double)num[cluster], v_means[cluster]) ; // compute inverse covariances for (vno = 0 ; vno < mris->nvertices ; vno++) { cluster = mris->vertices[vno].curv ; for (i = 0 ; i < nsamples ; i++) VECTOR_ELT(v1, i+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, i) ; VectorSubtract(v_means[cluster], v1, v1) ; VectorOuterProduct(v1, v1, m1) ; MatrixAdd(m_covs[cluster], m1, m_covs[cluster]) ; MatrixAdd(mpooled, m1, mpooled) ; } MatrixScalarMul(mpooled, 1.0/(double)mris->nvertices, mpooled) ; cno_pooled = MatrixConditionNumber(mpooled) ; det_pooled = MatrixDeterminant(mpooled) ; for (cluster = 0 ; cluster < k ; cluster++) if (num[cluster] > 0) MatrixScalarMul(m_covs[cluster], 1.0/(double)num[cluster], m_covs[cluster]) ; // invert all the covariance matrices MatrixFree(&m1) ; singular = 0 ; for (cluster = 0 ; cluster < k ; cluster++) { m1 = MatrixInverse(m_covs[cluster], NULL) ; cno = MatrixConditionNumber(m_covs[cluster]) ; det = MatrixDeterminant(m_covs[cluster]) ; if (m1 == NULL) singular++ ; while (cno > 100*cno_pooled || 100*det < det_pooled) { if (m1) MatrixFree(&m1) ; m1 = MatrixScalarMul(mpooled, 0.1, NULL) ; MatrixAdd(m_covs[cluster], m1, m_covs[cluster]) ; MatrixFree(&m1) ; cno = MatrixConditionNumber(m_covs[cluster]) ; m1 = MatrixInverse(m_covs[cluster], NULL) ; det = MatrixDeterminant(m_covs[cluster]) ; } m_inv_covs[cluster] = m1 ; } for (cluster = 0 ; cluster < k ; cluster++) { if (m_inv_covs[cluster] == NULL) DiagBreak() ; else { MatrixFree(&m_covs[cluster]) ; m_covs[cluster] = m_inv_covs[cluster] ; // MatrixIdentity(m_covs[cluster]->rows, m_covs[cluster]); } } MatrixFree(&mpooled) ; VectorFree(&v1) ; return(NO_ERROR) ; }