/* ** concordance mapping */ VImage VCCM2(float *A1,float *A2,VImage map,int type) { VImage dest=NULL; size_t b,r,c,i,j,k,kk,nvoxels; int nslices=0,nrows=0,ncols=0; double *arr1=NULL,*arr2=NULL,u; nslices = VPixel(map,0,3,0,VShort); nrows = VPixel(map,0,3,1,VShort); ncols = VPixel(map,0,3,2,VShort); nvoxels = VImageNColumns(map); dest = VCreateImage(nslices,nrows,ncols,VFloatRepn); VFillImage(dest,VAllBands,0); VCopyImageAttrs (map, dest); VSetAttr(VImageAttrList(dest),"modality",NULL,VStringRepn,"conimg"); arr1 = (double *) VCalloc(nvoxels,sizeof(double)); arr2 = (double *) VCalloc(nvoxels,sizeof(double)); fprintf(stderr," concordance mapping...\n"); for (i=0; i<nvoxels; i++) { if (i%50 == 0) fprintf(stderr," %6d of %d\r",i,nvoxels); b = (int)VPixel(map,0,0,i,VShort); r = (int)VPixel(map,0,1,i,VShort); c = (int)VPixel(map,0,2,i,VShort); for (j=0; j<nvoxels; j++) arr1[j] = arr2[j] = 0; kk = 0; for (j=0; j<i; j++) { k=j+i*(i+1)/2; arr1[kk] = (double)A1[k]; arr2[kk] = (double)A2[k]; kk++; } for (j=i+1; j<nvoxels; j++) { k=i+j*(j+1)/2; arr1[kk] = (double)A1[k]; arr2[kk] = (double)A2[k]; kk++; } u = 0; switch (type) { case 0: u = kendall(arr1,arr2,nvoxels); break; case 1: u = CCC(arr1,arr2,nvoxels); break; default: VError("illegal type"); } VPixel(dest,b,r,c,VFloat) = (VFloat)u; } fprintf(stderr,"\n"); return dest; }
VGraph VCreateGraph (int size, int nfields, VRepnKind repn, int useW) { VGraph graph; /* Check parameters: */ if (size < 1 || nfields < 1) VWarning ("VCreateGraph: Invalid number of nodes or fields."); /* Allocate memory for the VGraph, and the node table: */ graph = VMalloc (sizeof (VGraphRec)); if (graph == NULL) return NULL; graph->table = VCalloc(size, sizeof(VNode)); if (graph->table == NULL) { VFree(graph); return NULL; }; /* Initialize the VGraph: */ graph->nnodes = 0; graph->nfields = nfields; graph->node_repn = repn; graph->attributes = VCreateAttrList (); graph->lastUsed = 0; graph->size = size; graph->useWeights = useW; graph->iter = 0; return graph; }
/* ** read slice onset times from ASCII file, if not in header */ float * ReadSlicetimes(VString filename) { FILE *fp; int i, j, id, n = 256; float onset; float *onset_array = NULL; char buf[LEN]; onset_array = (float *) VCalloc(n, sizeof(float)); fp = fopen(filename, "r"); if(!fp) VError(" error opening file %s", filename); /* fprintf(stderr," reading file: %s\n",filename); */ i = 0; while(!feof(fp)) { if(i >= n) VError(" too many lines in file %s, max is %d", filename, n); for(j = 0; j < LEN; j++) buf[j] = '\0'; fgets(buf, LEN, fp); if(buf[0] == '%' || buf[0] == '#') continue; if(strlen(buf) < 2) continue; if(sscanf(buf, "%f", &onset) != 1) VError(" line %d: illegal input format", i + 1); onset_array[i] = onset; i++; } fclose(fp); return onset_array; }
static VNode VCopyNodeDeep(VGraph graph, VNode src) { VNode dst; VAdjacency o, n; int cnt; if (src == 0) return 0; /* allocate and copy base part */ dst = VCalloc(1, VNodeSize(graph)); dst->base.hops = src->base.hops; dst->base.visited = src->base.visited; dst->base.weight = src->base.weight; dst->base.head = 0; /* copy all adjacencies */ for (o = src->base.head; o; o = o->next) { n = VMalloc(sizeof(VAdjRec)); n->id = o->id; n->weight = o->weight; n->next = dst->base.head; dst->base.head = n; }; /* copy private area */ cnt = (graph->nfields * VRepnPrecision(graph->node_repn)) / 8; memcpy(dst->data, src->data, cnt); return dst; }
static VNode VCopyNodeShallow (VGraph graph, VNode src) { VNode dst; if (src == 0) return 0; dst = VCalloc(1, VNodeSize(graph)); memcpy(dst, src, VNodeSize(graph)); dst->base.head = 0; return dst; }
static int growGraph (VGraph graph) /* note that we grow just a pointer table */ { int newsize = (graph->size * 3) / 2; VNode *t = VCalloc(newsize, sizeof(VNode)); if (t == 0) return 0; memcpy(t, graph->table, graph->size * sizeof(VNode)); VFree(graph->table); graph->table = t; graph->size = newsize; graph->nnodes = newsize; return newsize; }
static int growGraphPos(VGraph graph, int pos) /* note that we grow just a pointer table */ { VNode *t; int newsize = (graph->size * 3) / 2; if (pos > newsize) newsize = pos+1; t = (VNode *)VCalloc(newsize, sizeof(VNode)); if (t == 0) return 0; memcpy(t, graph->table, graph->size * sizeof(VNode)); VFree(graph->table); graph->table = t; graph->size = newsize; graph->nnodes = newsize; return newsize; }
int VGraphAddAndGrow(VGraph graph, VNode node, int pos) { VNode dst; if (graph->lastUsed == graph->size || pos > graph->size) if (growGraphPos(graph, pos) == 0) return 0; if (node == 0) return 0; VDestroyNode(graph, pos); dst = (VNode)VCalloc(1, VNodeSize(graph)); memcpy(dst, node, VNodeSize(graph)); dst->base.head = 0; VGraphGetNode(graph, pos) = dst; if (pos > graph->lastUsed) graph->lastUsed = pos; return pos; }
int VGraphResizeFields (VGraph graph, int newfields) { VNode o, n; int i; int nsize = sizeof(VNodeBaseRec) + (newfields * VRepnPrecision(graph->node_repn)) / 8; int osize = VNodeSize(graph); if (newfields <= graph->nfields) return TRUE; for (i = 1; i <= graph->lastUsed; i++) { if (VGraphNodeIsFree(graph, i)) continue; o = VGraphGetNode(graph, i); n = VCalloc(1, nsize); memcpy(n, o, osize); VGraphGetNode(graph, i) = n; VFree(o); }; graph->nfields = newfields; return TRUE; }
/* ** check if IDs of ROIs match across masks */ int CheckROI(Volumes *volumes, int m, int nROI) { int i; Volume vol; int *table; if(m < 2) return 1; /* no problem if just one mask */ table = (int *) VCalloc(nROI + 1, sizeof(int)); for(i = 0; i < m; i++) { for(vol = volumes[i]->first; vol != NULL; vol = vol->next) { table[vol->label]++; } } for(i = 1; i <= nROI; i++) { if(table[i] != m) VError(" ROI %d missing in at least one mask", i + 1); } return 1; }
double kendall(double *arr1,double *arr2,int n) { static gsl_vector *vec = NULL; static gsl_permutation *perm=NULL,*rank1=NULL,*rank2=NULL; static double *r=NULL; int i; double S,W,R; double nx=0; if (vec == NULL) { vec = gsl_vector_calloc(n); perm = gsl_permutation_alloc(n); rank1 = gsl_permutation_alloc(n); rank2 = gsl_permutation_alloc(n); r = (double *) VCalloc(n,sizeof(double)); } for (i=0; i<n; i++) gsl_vector_set(vec,i,arr1[i]); gsl_sort_vector_index (perm, vec); gsl_permutation_inverse (rank1, perm); for (i=0; i<n; i++) gsl_vector_set(vec,i,arr2[i]); gsl_sort_vector_index (perm, vec); gsl_permutation_inverse (rank2, perm); for (i=0; i<n; i++) r[i] = (double)(rank1->data[i] + rank2->data[i]); nx = (double)n; R = 0; for (i=0; i<n; i++) R += r[i]; R /= nx; S = 0; for (i=0; i<n; i++) S += SQR(r[i] - R); W = 12.0*S/(4.0*(nx*nx-1.0)*nx); return W; }
float * VCorrMatrix(VAttrList list,VImage map,VShort first,VShort length) { VAttrListPosn posn; VImage src[NSLICES]; size_t b,r,c,i,j,i1,n,m,nt,last,ntimesteps,nrows,ncols,nslices; gsl_matrix_float *mat=NULL; float *A=NULL; /* ** get image dimensions */ i = ntimesteps = nrows = ncols = 0; for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src[i]); if (VPixelRepn(src[i]) != VShortRepn) continue; if (VImageNBands(src[i]) > ntimesteps) ntimesteps = VImageNBands(src[i]); if (VImageNRows(src[i]) > nrows) nrows = VImageNRows(src[i]); if (VImageNColumns(src[i]) > ncols) ncols = VImageNColumns(src[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices = i; /* get time steps to include */ if (length < 1) length = ntimesteps-2; last = first + length -1; if (last >= ntimesteps) last = ntimesteps-1; if (first < 0) first = 1; nt = last - first + 1; i1 = first+1; if (nt < 2) VError(" not enough timesteps, nt= %d",nt); /* number of voxels */ n = VImageNColumns(map); fprintf(stderr," ntimesteps: %d, first= %d, last= %d, nt= %d, nvoxels: %ld\n", (int)ntimesteps,(int)first,(int)last,(int)nt,(long)n); /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n,nt); if (!mat) VError(" err allocating mat"); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VShort); r = VPixel(map,0,1,i,VShort); c = VPixel(map,0,2,i,VShort); float *ptr = gsl_matrix_float_ptr(mat,i,0); int k; j = 0; for (k=first; k<=last; k++) { if (j >= mat->size2) VError(" j= %d %d",j,mat->size2); if (k >= VImageNBands(src[b])) VError(" k= %d %d",k, VImageNBands(src[b])); *ptr++ = (float) VPixel(src[b],k,r,c,VShort); j++; } } /* ** compute similarity matrix */ m = (n*(n+1))/2; fprintf(stderr," compute correlation matrix...\n"); A = (float *) VCalloc(m,sizeof(float)); if (!A) VError(" err allocating correlation matrix"); memset(A,0,m*sizeof(float)); size_t progress=0; #pragma omp parallel for shared(progress) private(j) schedule(guided) firstprivate(mat,A) for (i=0; i<n; i++) { if (i%100 == 0) fprintf(stderr," %d00\r",(int)(++progress)); const float *arr1 = gsl_matrix_float_const_ptr(mat,i,0); for (j=0; j<i; j++) { const float *arr2 = gsl_matrix_float_const_ptr(mat,j,0); const double v = Correlation(arr1,arr2,nt); const size_t k=j+i*(i+1)/2; if (k >= m) VError(" illegal addr k= %d, m= %d",k,m); A[k] = v; } } fprintf(stderr," matrix done.\n"); gsl_matrix_float_free(mat); return A; }
VAttrList VNCM(VAttrList list,VImage mask,VShort minval,VShort first,VShort length,VFloat threshold) { VAttrList out_list=NULL; VAttrListPosn posn; VImage src[NSLICES],map=NULL; VImage dest=NULL; size_t b,r,c,i,j,i1,n,m,nt,last,ntimesteps,nrows,ncols,nslices; gsl_matrix_float *mat=NULL; float *A=NULL,*ev=NULL; /* ** get image dimensions */ i = ntimesteps = nrows = ncols = 0; for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src[i]); if (VPixelRepn(src[i]) != VShortRepn) continue; if (VImageNBands(src[i]) > ntimesteps) ntimesteps = VImageNBands(src[i]); if (VImageNRows(src[i]) > nrows) nrows = VImageNRows(src[i]); if (VImageNColumns(src[i]) > ncols) ncols = VImageNColumns(src[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices = i; /* get time steps to include */ if (length < 1) length = ntimesteps-2; last = first + length -1; if (last >= ntimesteps) last = ntimesteps-1; if (first < 0) first = 1; nt = last - first + 1; i1 = first+1; if (nt < 2) VError(" not enough timesteps, nt= %d",nt); fprintf(stderr,"# ntimesteps: %d, first= %d, last= %d, nt= %d\n", (int)ntimesteps,(int)first,(int)last,(int)nt); /* count number of voxels */ n = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src[b],i1,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; n++; } } } fprintf(stderr," nvoxels: %ld\n",(long)n); /* ** voxel addresses */ map = VCreateImage(1,5,n,VFloatRepn); if (map == NULL) VError(" error allocating addr map"); VFillImage(map,VAllBands,0); VPixel(map,0,3,0,VFloat) = nslices; VPixel(map,0,3,1,VFloat) = nrows; VPixel(map,0,3,2,VFloat) = ncols; i = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src[b],i1,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; VPixel(map,0,0,i,VFloat) = b; VPixel(map,0,1,i,VFloat) = r; VPixel(map,0,2,i,VFloat) = c; i++; } } } /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n,nt); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VFloat); r = VPixel(map,0,1,i,VFloat); c = VPixel(map,0,2,i,VFloat); float *ptr = gsl_matrix_float_ptr(mat,i,0); int k; j = 0; for (k=first; k<=last; k++) { if (j >= mat->size2) VError(" j= %d %d",j,mat->size2); if (k >= VImageNBands(src[b])) VError(" k= %d %d",k, VImageNBands(src[b])); *ptr++ = (float) VPixel(src[b],k,r,c,VShort); j++; } } /* ** compute similarity matrix */ m = (n*(n+1))/2; fprintf(stderr," matrix computation, n= %ld...\n",(long)n); A = (float *) calloc(m,sizeof(float)); if (!A) VError(" err allocating correlation matrix"); memset(A,0,m*sizeof(float)); size_t progress=0; #pragma omp parallel for shared(progress) private(j) schedule(guided) firstprivate(mat,A) for (i=0; i<n; i++) { if (i%100 == 0) fprintf(stderr," %d00\r",(int)(++progress)); const float *arr1 = gsl_matrix_float_const_ptr(mat,i,0); for (j=0; j<i; j++) { const float *arr2 = gsl_matrix_float_const_ptr(mat,j,0); const double v = Correlation(arr1,arr2,nt); const size_t k=j+i*(i+1)/2; if (k >= m) VError(" illegal addr k= %d, m= %d",k,m); A[k] = (float)v; } } fprintf(stderr," matrix done.\n"); gsl_matrix_float_free(mat); /* ** eigenvector centrality */ ev = (float *) VCalloc(n,sizeof(float)); DegreeCentrality(A,ev,n,threshold); dest = WriteOutput(src[0],map,nslices,nrows,ncols,ev,n); VSetAttr(VImageAttrList(dest),"name",NULL,VStringRepn,"DegreeCM"); out_list = VCreateAttrList(); VAppendAttr(out_list,"image",NULL,VImageRepn,dest); return out_list; }
/* ** slicetime correction for non-constant TR */ void VSlicetime_NC(VAttrList list, VShort minval, VFloat tdel, VBoolean slicetime_correction, float *onset_array, VString filename) { FILE *fp = NULL; VImage src; VAttrListPosn posn; VString buf, str; int b, r, c, i, j, nt = 0, mt = 0, val, del = 0; double xmin, xmax, sum, nx, estim_tr = 0; double *xx = NULL, *yy = NULL, xi, yi, slicetime = 0, u = 0; gsl_interp_accel *acc = NULL; gsl_spline *spline = NULL; xmin = (VShort) VRepnMinValue(VShortRepn); xmax = (VShort) VRepnMaxValue(VShortRepn); buf = VMalloc(LEN); /* ** read scan times from file, non-constant TR */ if(strlen(filename) > 2) { fp = fopen(filename, "r"); if(!fp) VError(" error opening file %s", filename); i = 0; while(!feof(fp)) { for(j = 0; j < LEN; j++) buf[j] = '\0'; fgets(buf, LEN, fp); if(buf[0] == '%' || buf[0] == '#') continue; if(strlen(buf) < 2) continue; i++; } rewind(fp); nt = i; fprintf(stderr, " num timesteps: %d\n", nt); xx = (double *) VCalloc(nt, sizeof(double)); yy = (double *) VCalloc(nt, sizeof(double)); i = 0; sum = 0; while(!feof(fp)) { for(j = 0; j < LEN; j++) buf[j] = '\0'; fgets(buf, LEN, fp); if(buf[0] == '%' || buf[0] == '#') continue; if(strlen(buf) < 2) continue; if(sscanf(buf, "%lf", &u) != 1) VError(" line %d: illegal input format", i + 1); xx[i] = u * 1000.0; /* convert to millisec */ if(i > 1) sum += xx[i] - xx[i - 1]; i++; } fclose(fp); estim_tr = sum / (double)(nt - 2); fprintf(stderr, " average scan interval = %.3f sec\n", estim_tr / 1000.0); } /* ** process data */ b = -1; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VShortRepn) continue; VSetAttr(VImageAttrList(src), "repetition_time", NULL, VLongRepn, (VLong)estim_tr); VExtractAttr(VImageAttrList(src), "MPIL_vista_0", NULL, VStringRepn, &str, FALSE); b++; if(VImageNRows(src) < 2) continue; /* ** get header info */ if(VGetAttr(VImageAttrList(src), "slice_time", NULL, VDoubleRepn, (VPointer) & slicetime) != VAttrFound && slicetime_correction && onset_array == NULL) VError(" 'slice_time' info missing"); if(onset_array != NULL) slicetime = onset_array[b]; if(nt != VImageNBands(src)) VError(" inconsistent number of time steps, %d %d", nt, VImageNBands(src)); if(acc == NULL && slicetime_correction) { acc = gsl_interp_accel_alloc(); spline = gsl_spline_alloc(gsl_interp_akima, nt); for(i = 0; i < 5; i++) { if(xx[i] / 1000.0 > tdel) break; } del = i; fprintf(stderr, " The first %.2f secs (%d timesteps) will be replaced.\n", tdel, del); } /* ** loop through all voxels in current slice */ if(slicetime_correction) fprintf(stderr, " slice: %3d, %10.3f ms\r", b, slicetime); for(r = 0; r < VImageNRows(src); r++) { for(c = 0; c < VImageNColumns(src); c++) { if(VPixel(src, 0, r, c, VShort) < minval) continue; /* replace first few time steps by average */ if(del > 0) { mt = del + 10; if(mt > nt) mt = nt; sum = nx = 0; for(i = del; i < mt; i++) { sum += VPixel(src, i, r, c, VShort); nx++; } if(nx < 1) continue; val = sum / nx; for(i = 0; i < del; i++) { VPixel(src, i, r, c, VShort) = val; } } if(!slicetime_correction) continue; /* correct for slicetime offsets using cubic spline interpolation */ for(i = 0; i < nt; i++) { yy[i] = VPixel(src, i, r, c, VShort); } gsl_spline_init(spline, xx, yy, nt); for(i = 1; i < nt; i++) { xi = xx[i] - slicetime; yi = gsl_spline_eval(spline, xi, acc); val = (int)(yi + 0.49); if(val > xmax) val = xmax; if(val < xmin) val = xmin; VPixel(src, i, r, c, VShort) = val; } } } } fprintf(stderr, "\n"); }
void HighPassFilter(double *z,int n,float tr,VFloat high) { int i,j,nn,nc,tail; static double *in=NULL; static double *highp=NULL; static fftw_complex *out=NULL; double sharp=0.8,x,alpha; fftw_plan p1,p2; tail = n/10; if (tail < 50) tail = 50; if (tail >= n/2) tail = n/2-1; if (tail >= n-1) tail = n-2; if (tail < 0) tail = 0; if(n <= tail) tail = n - 2; nn = n + 2*tail; nc = (nn / 2) + 1; if (out == NULL) { in = (double *) VCalloc(nn,sizeof(double)); out = fftw_malloc (sizeof (fftw_complex ) * nc); } i = 0; for(j=0; j<tail; j++) in[i++] = z[tail-j]; for(j=0; j<n; j++) in[i++] = z[j]; j = n-2; while (i < n && j >= 0) in[i++] = z[j]; /* for (i=0; i<n; i++) in[i] = z[i]; */ /* make plans */ p1 = fftw_plan_dft_r2c_1d (nn,in,out,FFTW_ESTIMATE); p2 = fftw_plan_dft_c2r_1d (nn,out,in,FFTW_ESTIMATE); alpha = (double)n * tr; if (highp == NULL) highp = (double *) VCalloc(nc,sizeof(double)); sharp = 0.8; for (i=1; i <nc; i++) { highp[i] = 1.0 / (1.0 + exp( (alpha/high -(double)i)*sharp )); } /* forward fft */ fftw_execute(p1); /* highpass */ for (i=1; i<nc; i++) { x = highp[i]; out[i][0] *= x; out[i][1] *= x; } /* inverse fft */ fftw_execute(p2); for (i=0; i<n; i++) z[i] = in[i+tail]/(double)n; }
/* ** slicetime correction with constant TR */ void VSlicetime(VAttrList list, VShort minval, VFloat tdel, VBoolean slicetime_correction, float *onset_array) { VImage src; VAttrListPosn posn; VString str, buf; int b, r, c, i, nt, mt, val, del = 0; double xmin, xmax, sum, nx; double *xx = NULL, *yy = NULL, xi, yi, tr = 0, xtr = 0, slicetime = 0; gsl_interp_accel *acc = NULL; gsl_spline *spline = NULL; xmin = (VShort) VRepnMinValue(VShortRepn); xmax = (VShort) VRepnMaxValue(VShortRepn); buf = VMalloc(256); /* ** process data */ b = -1; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VShortRepn) continue; b++; if(VImageNRows(src) < 2) continue; /* ** get header info */ if(VGetAttr(VImageAttrList(src), "slice_time", NULL, VDoubleRepn, (VPointer) & slicetime) != VAttrFound && slicetime_correction && onset_array == NULL) VError(" 'slice_time' info missing");; if(onset_array != NULL) slicetime = onset_array[b]; tr = 0; if(VGetAttr(VImageAttrList(src), "repetition_time", NULL, VDoubleRepn, (VPointer) & tr) != VAttrFound) { tr = 0; if(VGetAttr(VImageAttrList(src), "MPIL_vista_0", NULL, VStringRepn, (VPointer) & str) == VAttrFound) { sscanf(str, " repetition_time=%lf %s", &tr, buf); } } if(tr < 1) VError(" attribute 'repetition_time' missing"); xtr = tr / 1000.0; del = (int)(tdel / xtr + 0.5); /* num timesteps to be ignored */ nt = VImageNBands(src); if(acc == NULL) { acc = gsl_interp_accel_alloc(); spline = gsl_spline_alloc(gsl_interp_akima, nt); xx = (double *) VCalloc(nt, sizeof(double)); yy = (double *) VCalloc(nt, sizeof(double)); fprintf(stderr, " The first %.2f secs (%d timesteps) will be replaced.\n", tdel, del); } /* ** loop through all voxels in current slice */ if(slicetime_correction) fprintf(stderr, " slice: %3d, %10.3f ms, TR: %.3f\r", b, slicetime, xtr); for(r = 0; r < VImageNRows(src); r++) { for(c = 0; c < VImageNColumns(src); c++) { if(VPixel(src, 0, r, c, VShort) < minval) continue; /* replace first few time steps by average */ if(del > 0) { mt = del + 10; if(mt > nt) mt = nt; sum = nx = 0; for(i = del; i < mt; i++) { sum += VPixel(src, i, r, c, VShort); nx++; } if(nx < 1) continue; val = sum / nx; for(i = 0; i < del; i++) { VPixel(src, i, r, c, VShort) = val; } } if(!slicetime_correction) continue; /* correct for slicetime offsets using cubic spline interpolation */ for(i = 0; i < nt; i++) { xi = i; xx[i] = xi * tr; yy[i] = VPixel(src, i, r, c, VShort); } gsl_spline_init(spline, xx, yy, nt); for(i = 1; i < nt; i++) { xi = xx[i] - slicetime; yi = gsl_spline_eval(spline, xi, acc); val = (int)(yi + 0.49); if(val > xmax) val = xmax; if(val < xmin) val = xmin; VPixel(src, i, r, c, VShort) = val; } } } } fprintf(stderr, "\n"); }
int main(int argc, char *argv[]) { static VArgVector in_files1; static VArgVector in_files2; static VString out_filename; static VShort type = 1; static VBoolean gauss = FALSE; static VOptionDescRec options[] = { {"in1", VStringRepn, 0, & in_files1, VRequiredOpt, NULL, "Input files 1" }, {"in2", VStringRepn, 0, & in_files2, VRequiredOpt, NULL, "Input files 2" }, {"type", VShortRepn, 1, (VPointer) &type, VOptionalOpt, TypeDict, "output type"}, {"gaussianize", VBooleanRepn, 1, (VPointer) &gauss, VOptionalOpt, NULL, "Whether to Gaussianize"}, {"out", VStringRepn, 1, & out_filename, VRequiredOpt, NULL, "Output file" } }; FILE *fp = NULL; VStringConst in_filename, buf1, buf2; VAttrList list1, list2, out_list; VAttrListPosn posn; VString str; VImage src, *src1, *src2, dest = NULL; int i, nimages, npix = 0; char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vpaired_ttest V%s", ver); fprintf(stderr, "%s\n", prg_name); /* ** parse command line */ if(! VParseCommand(VNumber(options), options, & argc, argv)) { VReportUsage(argv[0], VNumber(options), options, NULL); exit(EXIT_FAILURE); } if(argc > 1) { VReportBadArgs(argc, argv); exit(EXIT_FAILURE); } if(type < 0 || type > 1) VError(" illegal type"); /* ini */ nimages = in_files1.number; if(in_files2.number != nimages) VError(" inconsistent number of files %d %d", nimages, in_files2.number); for(i = 0; i < nimages; i++) { buf1 = ((VStringConst *) in_files1.vector)[i]; buf2 = ((VStringConst *) in_files2.vector)[i]; fprintf(stderr, "%3d: %s %s\n", i, buf1, buf2); } fprintf(stderr, "\n"); /* images 1 */ src1 = (VImage *) VCalloc(nimages, sizeof(VImage)); for(i = 0; i < nimages; i++) { src1[i] = NULL; in_filename = ((VStringConst *) in_files1.vector)[i]; fp = VOpenInputFile(in_filename, TRUE); list1 = VReadFile(fp, NULL); if(! list1) VError("Error reading image"); fclose(fp); for(VFirstAttr(list1, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VFloatRepn) continue; if(VGetAttr(VImageAttrList(src), "modality", NULL, VStringRepn, &str) == VAttrFound) { if(strcmp(str, "conimg") != 0) continue; } if(i == 0) npix = VImageNPixels(src); else if(npix != VImageNPixels(src)) VError(" inconsistent image dimensions"); src1[i] = src; break; } if(src1[i] == NULL) VError(" no contrast image found in %s", in_filename); } /* images 2 */ src2 = (VImage *) VCalloc(nimages, sizeof(VImage)); for(i = 0; i < nimages; i++) { src2[i] = NULL; in_filename = ((VStringConst *) in_files2.vector)[i]; fp = VOpenInputFile(in_filename, TRUE); list2 = VReadFile(fp, NULL); if(! list2) VError("Error reading image"); fclose(fp); for(VFirstAttr(list2, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VFloatRepn) continue; if(VGetAttr(VImageAttrList(src), "modality", NULL, VStringRepn, &str) == VAttrFound) { if(strcmp(str, "conimg") != 0) continue; } if(npix != VImageNPixels(src)) VError(" inconsistent image dimensions"); src2[i] = src; break; } if(src2[i] == NULL) VError(" no contrast image found in %s", in_filename); } /* make normally distributed */ if(gauss) { VGaussianize(src1, nimages); VGaussianize(src2, nimages); } /* paired t-test */ dest = PairedTest(src1, src2, dest, nimages, type); /* ** output */ out_list = VCreateAttrList(); VHistory(VNumber(options), options, prg_name, &list1, &out_list); VAppendAttr(out_list, "image", NULL, VImageRepn, dest); fp = VOpenOutputFile(out_filename, TRUE); if(! VWriteFile(fp, out_list)) exit(1); fclose(fp); fprintf(stderr, "%s: done.\n", argv[0]); exit(0); }
VImage VContrastAny(VImage src,VImage dest,VFloat low,VFloat high) { int nbands,nrows,ncols; double xmin,xmax,slope,sum,a; float *histo; int b,r,c,j,dim; VUByte *dest_pp; double smin,smax,u,v,tiny; nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); dest = VSelectDestImage("VContrastAny",dest,nbands,nrows,ncols,VUByteRepn); if (! dest) VError(" err creating dest image"); VFillImage(dest,VAllBands,0); smin = VPixelMaxValue(src); smax = VPixelMinValue(src); for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { u = VGetPixel(src,b,r,c); if (u < smin) smin = u; if (u > smax) smax = u; } } } dim = 10000; if (VPixelRepn(src) == VUByteRepn) dim = 256; histo = (float *) VCalloc(dim,sizeof(float)); for (j=0; j<dim; j++) histo[j] = 0; tiny = 2.0/(double)dim; a = ((double) dim) / (smax - smin); for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { u = VGetPixel(src,b,r,c); if (ABS(u) < tiny) continue; j = (int) (a * (u - smin) + 0.5); if (j < 0) j = 0; if (j >= dim) j = dim-1; histo[j]++; } } } sum = 0; for (j=0; j<dim; j++) sum += histo[j]; for (j=0; j<dim; j++) histo[j] /= sum; xmin = 0; sum = 0; for (j=0; j<dim; j++) { sum += histo[j]; if (sum > low) break; } xmin = ((double)j)/a + smin; xmax = dim; sum = 0; for (j=dim; j>0; j--) { sum += histo[j]; if (sum > high) break; } xmax = ((double)j)/a + smin; slope = 255.0 / (xmax - xmin); dest_pp = (VUByte *) VImageData(dest); for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { u = VGetPixel(src,b,r,c); v = (int) (slope * (u - xmin) + 0.5); if (ABS(u) < tiny) v = 0; if (v < 0) v = 0; if (v > 255) v = 255; *dest_pp++ = (VUByte) v; } } } VCopyImageAttrs (src, dest); return dest; }
/* Parse command without license information */ VBoolean VParseCommand_nl (int noptions, VOptionDescRec options[], int *argc, char **argv) { int arg, nvalues, i, j; char *cp; VBoolean *opts_seen, result = TRUE; VOptionDescRec *opt, *opt_t; /* Note the program's name: */ VSetProgramName (argv[0]); /* Allocate storage for a set of flags indicating which arguments have been seen: */ opts_seen = VCalloc (noptions, sizeof (VBoolean)); /* Initialize any "found" flags to false, and the number field of any VArgVector values to zero: */ for (opt = options + noptions - 1; opt >= options; opt--) { if (opt->found) *opt->found = FALSE; if (opt->number == 0 && opt->value) ((VArgVector *) opt->value)->number = 0; } /* For each argument supplied with the command: */ for (arg = 1; arg < *argc; ) { cp = argv[arg++]; /* If it doesn't start with - it can't be an option: */ if (cp[0] != '-' || cp[1] == 0) continue; /* Check for -help: */ if (strcmp (cp + 1, "help") == 0) { /* If found, return FALSE to force printing of usage info: */ *argc = 1; return FALSE; } /* Look up the argument in the list of options: */ i = strlen (cp + 1); opt = NULL; for (opt_t = options + noptions - 1; opt_t >= options; opt_t--) { if (strncmp (cp + 1, opt_t->keyword, i) != 0) continue; /* not this one */ if (i == strlen (opt_t->keyword)) { opt = opt_t; break; /* an exact match */ } if (opt) goto NextArg; /* already matched another prefix */ opt = opt_t; /* note a prefix match */ } /* If the argument isn't recognized, skip it: */ if (! opt) goto NextArg; /* not recognized */ /* Remove it from the list of command arguments: */ argv[arg - 1] = 0; /* Ensure that the option has not already been seen: */ if (opts_seen[opt - options]) { fprintf (stderr, "%s: Duplicate -%s option; ignoring all but last.\n", argv[0], opt->keyword); /* If it has been seen, delete its previous value: */ if (opt->number == 0) { VFree (((VArgVector *) opt->value)->vector); ((VArgVector *) opt->value)->number = 0; } } else opts_seen[opt - options] = TRUE; /* Swallow any value(s) that follow: */ switch (opt->repn) { case VBitRepn: case VUByteRepn: case VSByteRepn: case VShortRepn: case VLongRepn: case VFloatRepn: case VDoubleRepn: case VBooleanRepn: case VStringRepn: nvalues = ParseArgValues (& arg, *argc, argv, opt); break; default: VError ("Parsing of command options with %s values " "is not implemented", VRepnName (opt->repn)); nvalues = 0; /* to quiet lint */ } /* Ensure that the expected number of arguments was found: */ if (opt->number && nvalues != opt->number) { /* Either we encountered an argument we couldn't parse, or we used up all arguments before finding the expected number of them: */ fprintf (stderr, "%s: Option -%s ", argv[0], opt->keyword); if (arg < *argc) fprintf (stderr, "has incorrect value %s.\n", argv[arg]); else if (opt->number > 1) fprintf (stderr, "requires %d values; found only %d.\n", opt->number, nvalues); else fprintf (stderr, "requires a value.\n"); result = FALSE; break; } if (opt->number == 0) ((VArgVector *) opt->value)->number = nvalues; /* Note that a value was successfully obtained for this option: */ if (opt->found) *(opt->found) = TRUE; NextArg: ; } /* Ensure that each mandatory option was seen: */ for (i = 0; i < noptions; i++) if (options[i].found == VRequiredOpt && ! opts_seen[i]) { fprintf (stderr, "%s: Option -%s must be specified.\n", argv[0], options[i].keyword); result = FALSE; } VFree ((VPointer) opts_seen); /* Squeeze together the remaining arguments in argv: */ for (i = j = 1; i < *argc; i++) if (argv[i]) argv[j++] = argv[i]; *argc = j; return result; }
VBoolean VParseCommand (int noptions, VOptionDescRec options[], int *argc, char **argv) { int arg, nvalues, i, j; char *cp; VBoolean *opts_seen, result = TRUE; VOptionDescRec *opt, *opt_t; /* Note the program's name: */ VSetProgramName (argv[0]); /* Allocate storage for a set of flags indicating which arguments have been seen: */ opts_seen = VCalloc (noptions, sizeof (VBoolean)); /* Initialize any "found" flags to false, and the number field of any VArgVector values to zero: */ for (opt = options + noptions - 1; opt >= options; opt--) { if (opt->found) *opt->found = FALSE; if (opt->number == 0 && opt->value) ((VArgVector *) opt->value)->number = 0; } /* For each argument supplied with the command: */ for (arg = 1; arg < *argc; ) { cp = argv[arg++]; /* If it doesn't start with - it can't be an option: */ if (cp[0] != '-' || cp[1] == 0) continue; /* Check for -help: */ if (strcmp (cp + 1, "license") == 0) { char* license="This program is free software; you can redistribute it and/or\n modify it under the terms of the GNU General Public License\n as published by the Free Software Foundation; either version 2\n of the License, or (at your option) any later version.\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; fprintf(stderr,"%s\n",license); exit(0); } } /* For each argument supplied with the command: */ for (arg = 1; arg < *argc; ) { cp = argv[arg++]; /* If it doesn't start with - it can't be an option: */ if (cp[0] != '-' || cp[1] == 0) continue; /* Check for -help: */ if (strcmp (cp + 1, "help") == 0) { /* If found, return FALSE to force printing of usage info: */ *argc = 1; return FALSE; } /* Look up the argument in the list of options: */ i = strlen (cp + 1); opt = NULL; for (opt_t = options + noptions - 1; opt_t >= options; opt_t--) { if (strncmp (cp + 1, opt_t->keyword, i) != 0) continue; /* not this one */ if (i == strlen (opt_t->keyword)) { opt = opt_t; break; /* an exact match */ } if (opt) goto NextArg; /* already matched another prefix */ opt = opt_t; /* note a prefix match */ } /* If the argument isn't recognized, skip it: */ if (! opt) goto NextArg; /* not recognized */ /* Remove it from the list of command arguments: */ argv[arg - 1] = 0; /* Ensure that the option has not already been seen: */ if (opts_seen[opt - options]) { fprintf (stderr, "%s: Duplicate -%s option; ignoring all but last.\n", argv[0], opt->keyword); /* If it has been seen, delete its previous value: */ if (opt->number == 0) { VFree (((VArgVector *) opt->value)->vector); ((VArgVector *) opt->value)->number = 0; } } else opts_seen[opt - options] = TRUE; /* Swallow any value(s) that follow: */ switch (opt->repn) { case VBitRepn: case VUByteRepn: case VSByteRepn: case VShortRepn: case VLongRepn: case VFloatRepn: case VDoubleRepn: case VBooleanRepn: case VStringRepn: nvalues = ParseArgValues (& arg, *argc, argv, opt); break; default: VError ("Parsing of command options with %s values " "is not implemented", VRepnName (opt->repn)); nvalues = 0; /* to quiet lint */ } /* Ensure that the expected number of arguments was found: */ if (opt->number && nvalues != opt->number) { /* Either we encountered an argument we couldn't parse, or we used up all arguments before finding the expected number of them: */ fprintf (stderr, "%s: Option -%s ", argv[0], opt->keyword); if (arg < *argc) fprintf (stderr, "has incorrect value %s.\n", argv[arg]); else if (opt->number > 1) fprintf (stderr, "requires %d values; found only %d.\n", opt->number, nvalues); else fprintf (stderr, "requires a value.\n"); result = FALSE; break; } if (opt->number == 0) ((VArgVector *) opt->value)->number = nvalues; /* Note that a value was successfully obtained for this option: */ if (opt->found) *(opt->found) = TRUE; NextArg: ; } /* Ensure that each mandatory option was seen: */ for (i = 0; i < noptions; i++) if (options[i].found == VRequiredOpt && ! opts_seen[i]) { fprintf (stderr, "%s: Option -%s must be specified.\n", argv[0], options[i].keyword); result = FALSE; } VFree ((VPointer) opts_seen); /* Squeeze together the remaining arguments in argv: */ for (i = j = 1; i < *argc; i++) if (argv[i]) argv[j++] = argv[i]; *argc = j; return result; }
int main(int argc, char *argv[]) { static VArgVector in_files1; static VArgVector in_files2; static VString out_filename; static VOptionDescRec options[] = { { "in1", VStringRepn, 0, & in_files1, VRequiredOpt, NULL, "Input files 1" }, { "in2", VStringRepn, 0, & in_files2, VRequiredOpt, NULL, "Input files 2" }, { "out", VStringRepn, 1, & out_filename, VRequiredOpt, NULL, "Output file" } }; FILE *fp = NULL; VStringConst in_filename, buf1, buf2; VAttrList list1, list2, out_list; VAttrListPosn posn; VImage src, *src1, *src2, dest = NULL; int i, nimages, npix = 0; char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vpaired_wilcoxtest V%s", ver); fprintf(stderr, "%s\n", prg_name); /* ** parse command line */ if(! VParseCommand(VNumber(options), options, & argc, argv)) { VReportUsage(argv[0], VNumber(options), options, NULL); exit(EXIT_FAILURE); } if(argc > 1) { VReportBadArgs(argc, argv); exit(EXIT_FAILURE); } /* number of images */ nimages = in_files1.number; if(in_files2.number != nimages) VError(" inconsistent number of files "); for(i = 0; i < nimages; i++) { buf1 = ((VStringConst *) in_files1.vector)[i]; buf2 = ((VStringConst *) in_files2.vector)[i]; fprintf(stderr, "%3d: %s %s\n", i, buf1, buf2); } fprintf(stderr, "\n"); /* ** read images 1 */ src1 = (VImage *) VCalloc(nimages, sizeof(VImage)); for(i = 0; i < nimages; i++) { src1[i] = NULL; in_filename = ((VStringConst *) in_files1.vector)[i]; fp = VOpenInputFile(in_filename, TRUE); list1 = VReadFile(fp, NULL); if(! list1) VError("Error reading image"); fclose(fp); for(VFirstAttr(list1, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VFloatRepn) continue; src1[i] = src; break; } if(i == 0) npix = VImageNPixels(src1[i]); else if(npix != VImageNPixels(src1[i])) VError(" inconsistent image dimensions"); if(src1[i] == NULL) VError(" no image found in %s", in_filename); } /* ** read images 2 */ src2 = (VImage *) VCalloc(nimages, sizeof(VImage)); for(i = 0; i < nimages; i++) { src2[i] = NULL; in_filename = ((VStringConst *) in_files2.vector)[i]; fp = VOpenInputFile(in_filename, TRUE); list2 = VReadFile(fp, NULL); if(! list2) VError("Error reading image"); fclose(fp); for(VFirstAttr(list2, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VFloatRepn) continue; src2[i] = src; break; } if(npix != VImageNPixels(src2[i])) VError(" inconsistent image dimensions"); if(src2[i] == NULL) VError(" no image found in %s", in_filename); } /* ** paired wilcoxon test */ dest = PairedWilcoxTest(src1, src2, dest, nimages); /* ** output */ out_list = VCreateAttrList(); VHistory(VNumber(options), options, prg_name, &list1, &out_list); VAppendAttr(out_list, "image", NULL, VImageRepn, dest); fp = VOpenOutputFile(out_filename, TRUE); if(! VWriteFile(fp, out_list)) exit(1); fclose(fp); fprintf(stderr, "%s: done.\n", argv[0]); exit(0); }
/*! \fn VImage VContrastShort(VImage src,VImage dest,VFloat percent,VFloat background) \param src input image (short repn) \param dest output image (ubyte repn) */ VImage VContrastShort(VImage src,VImage dest,VFloat low,VFloat high) { int nbands,nrows,ncols,npixels; float u,v,xmin,xmax,slope,sum; float *histo; int i,j,dim; VShort *src_pp; VUByte *dest_pp; double smin,smax; double percent1,percent2; if (VPixelRepn(src) != VShortRepn) VError(" input pixel repn must be short"); nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); npixels = nbands * nrows * ncols; dest = VSelectDestImage("VContrastShort",dest,nbands,nrows,ncols,VUByteRepn); if (! dest) VError(" err creating dest image"); VFillImage(dest,VAllBands,0); smin = VRepnMinValue(VShortRepn); smax = VRepnMaxValue(VShortRepn); percent1 = low; /* unten */ percent2 = high; /* oben */ dim = 2.0 * smax + 1.0; histo = (float *) VCalloc(dim,sizeof(float)); for (j=0; j<dim; j++) histo[j] = 0; src_pp = (VShort *) VImageData(src); for (i=0; i<npixels; i++) { j = *src_pp++; j -= smin; histo[j]++; } sum = 0; for (j=0; j<dim; j++) sum += histo[j]; for (j=0; j<dim; j++) histo[j] /= sum; xmin = 0; sum = 0; for (j=0; j<dim; j++) { sum += histo[j]; if (sum > percent1) break; } xmin = j+smin; xmax = dim; sum = 0; for (j=dim; j>0; j--) { sum += histo[j]; if (sum > percent2) break; } xmax = j+smin; slope = 255.0f / (xmax - xmin); src_pp = (VShort *) VImageData(src); dest_pp = (VUByte *) VImageData(dest); for (i=0; i<npixels; i++) { u = *src_pp++; v = (int) (slope * (u - xmin) + 0.5); if (v < 0) v = 0; if (v > 255) v = 255; *dest_pp++ = (VUByte) v; } VFree(histo); VCopyImageAttrs (src, dest); return dest; }
void VROIpaired_ttest(VImage *src1, VImage *src2, VImage *mask, int n, int nmask, FILE *fp) { VString str; int i, j, id, b, r, c, c0, c1, nROI = 0; float ave1 = 0, ave2 = 0, var1 = 0, var2 = 0; float sum1 = 0, sum2 = 0, u, mx; float t, z, p, df, sd, cov, *data1 = NULL, *data2 = NULL; float tiny = 1.0e-8; float xa, ya, za, xx, yy, zz, voxelsize = 1; double mean[3]; Volumes *volumes; Volume vol; VTrack tc; VBoolean found = FALSE; gsl_set_error_handler_off(); /* ** get ROIs from mask */ fprintf(stderr, "\n List of ROIs:\n"); fprintf(fp, "\n List of ROIs:\n"); volumes = (Volumes *) VCalloc(nmask, sizeof(Volumes)); nROI = 0; for(i = 0; i < nmask; i++) { fprintf(stderr, "\n Mask %2d:\n", i + 1); fprintf(fp, "\n Mask %2d:\n", i + 1); volumes[i] = VImage2Volumes(mask[i]); voxelsize = 1; if(VGetAttr(VImageAttrList(mask[i]), "voxel", NULL, VStringRepn, (VPointer) & str) == VAttrFound) { sscanf(str, "%f %f %f", &xa, &ya, &za); voxelsize = xa * ya * za; } fprintf(stderr, " ROI addr size(mm^3)\n"); fprintf(stderr, "-----------------------------------------------\n"); fprintf(fp, " ROI addr size(mm^3)\n"); fprintf(fp, "-----------------------------------------------\n"); for(vol = volumes[i]->first; vol != NULL; vol = vol->next) { VolumeCentroid(vol, mean); if(nROI < vol->label) nROI = vol->label; b = mean[0]; r = mean[1]; c = mean[2]; xx = mean[2]; yy = mean[1]; zz = mean[0]; VGetTalCoord(src1[0], zz, yy, xx, &xa, &ya, &za); id = vol->label; fprintf(stderr, " %2d %7.2f %7.2f %7.2f %7.0f\n", id, xa, ya, za, voxelsize *(double)VolumeSize(vol)); fprintf(fp, " %2d %7.2f %7.2f %7.2f %7.0f\n", id, xa, ya, za, voxelsize *(double)VolumeSize(vol)); } } fprintf(stderr, "\n\n"); fprintf(fp, "\n\n"); /* check consistency */ if(nROI < 1) VError(" no ROIs found"); CheckROI(volumes, nmask, nROI); /* ** process each ROI */ fprintf(stderr, "\n"); fprintf(stderr, " ROI mean t z p \n"); fprintf(stderr, " --------------------------------------------------\n"); if(fp) { fprintf(fp, "\n"); fprintf(fp, " ROI mean t z p \n"); fprintf(fp, " --------------------------------------------------\n"); } df = n - 1; data1 = (float *) VCalloc(n, sizeof(float)); data2 = (float *) VCalloc(n, sizeof(float)); for(id = 1; id <= nROI; id++) { for(i = 0; i < n; i++) { j = 0; if(nmask > 1) j = i; found = FALSE; for(vol = volumes[j]->first; vol != NULL; vol = vol->next) { if(vol->label != id) continue; found = TRUE; sum1 = sum2 = mx = 0; for(j = 0; j < VolumeNBuckets(vol); j++) { for(tc = VFirstTrack(vol, j); VTrackExists(tc); tc = VNextTrack(tc)) { b = tc->band; r = tc->row; c0 = tc->col; c1 = c0 + tc->length; for(c = c0; c < c1; c++) { u = VPixel(src1[i], b, r, c, VFloat); if(ABS(u) < tiny) continue; sum1 += u; u = VPixel(src2[i], b, r, c, VFloat); if(ABS(u) < tiny) continue; sum2 += u; mx++; } } } if(mx < 1) { VWarning(" no voxels in ROI %d of mask %d", id, i); data1[i] = data2[i] = 0; continue; } data1[i] = sum1 / mx; data2[i] = sum2 / mx; } if(!found) goto next; } avevar(data1, n, &ave1, &var1); avevar(data2, n, &ave2, &var2); if(var1 < tiny || var2 < tiny) { VWarning(" no variance in ROI %d", id); continue; } z = t = p = 0; cov = 0; for(j = 0; j < n; j++) cov += (data1[j] - ave1) * (data2[j] - ave2); cov /= df; sd = sqrt((var1 + var2 - 2.0 * cov) / (df + 1.0)); if(sd < tiny) continue; t = (ave1 - ave2) / sd; if(ABS(t) < tiny) p = z = 0; else { p = t2p((double)t, (double)df); z = t2z((double)t, (double)df); if(t < 0) z = -z; } fprintf(stderr, " %3d %8.4f (%.3f) %7.3f %7.3f %7.4f\n", id, (ave1 - ave2), sd, t, z, p); if(fp) fprintf(fp, " %3d %8.4f (%.3f) %7.3f %7.3f %7.4f\n", id, (ave1 - ave2), sd, t, z, p); next: ; } fprintf(stderr, "\n"); if(fp) { fprintf(fp, "\n"); fclose(fp); } }
VImage VHistoEqualize(VImage src,VImage dest,VFloat exponent) { int nbands,nrows,ncols,npixels; float u,v,sum; float *histo,*p; int i,j,dim; VShort *src_pp; VUByte *dest_pp; double smin,smax,x,y; if (VPixelRepn(src) != VShortRepn) VError(" input pixel repn must be short"); if (exponent < 0.5) VError("parameter '-exponent' should be >= 0.5"); if (exponent > 10) VWarning("parameter '-exponent' should be < 10"); nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); npixels = nbands * nrows * ncols; dest = VSelectDestImage("VContrastShort",dest,nbands,nrows,ncols,VUByteRepn); if (! dest) VError(" err creating dest image"); VFillImage(dest,VAllBands,0); y = (double) exponent; smin = VRepnMinValue(VShortRepn); smax = VRepnMaxValue(VShortRepn); dim = 2.0 * smax + 1.0; histo = (float *) VCalloc(dim,sizeof(float)); for (j=0; j<dim; j++) histo[j] = 0; p = (float *) VCalloc(dim,sizeof(float)); src_pp = (VShort *) VImageData(src); for (i=0; i<npixels; i++) { j = *src_pp++; j -= smin; if (j == 0) continue; histo[j]++; } sum = 0; for (j=0; j<dim; j++) sum += histo[j]; for (j=0; j<dim; j++) histo[j] /= sum; /* cumulative hist */ for (i=0; i<dim; i++) { sum = 0; for (j=0; j<=i; j++) sum += histo[j]; p[i] = sum; } /* make lut */ for (i=0; i<dim; i++) { x = (double)p[i]; if (x > 0) p[i] = (float)(pow(x,y) * 255.0); } /* apply lut */ src_pp = (VShort *) VImageData(src); dest_pp = (VUByte *) VImageData(dest); for (i=0; i<npixels; i++) { u = *src_pp++; j = (int) (u-smin); v = (double)p[j]; if (v < 0) v = 0; if (v > 255) v = 255; *dest_pp++ = (VUByte) v; } VFree(p); VFree(histo); VCopyImageAttrs (src, dest); return dest; }
VImage VScaleIntensity(VImage src, double white, double black) /* scale any input image to VUByte, mapping white (black) percent of the voxel to white (black) */ { int x, y, z, nx, ny, nz, i, range, maxshort; unsigned int lb, ub, limit, sum, *histo; double m, b, max, min, mean, var, v; VImage dst; maxshort = (int)(VRepnMaxValue(VShortRepn)); histo = (unsigned int *)VCalloc(maxshort, sizeof(unsigned int)); nx = VImageNColumns(src); ny = VImageNRows(src); nz = VImageNBands(src); if (white < 0 || white > 100 || black < 0 || black > 100 || white+black >= 100) { fprintf(stderr, "VScaleIntensity: illegal percentage given.\n"); return 0; }; /* first pass: find maximum and minimum values */ VImageStats(src, VAllBands, &min, &max, &mean, &var); if (max == min) { fprintf(stderr, "VScaleIntensity: illegal data in image.\n"); return 0; }; b = min; m = (max-min) / (double)maxshort; /* second pass: build a histogram*/ for (z = 0; z < nz; z++) { for (y = 0; y < ny; y++) { for (x = 0; x < nx; x++) { v = VGetPixel(src, z, y, x); i = (int)((v-b)/m+0.5); histo[i]++; }; }; }; /* throw away pc percent of the voxel below lb and pc percent above ub */ limit = (black * nx * ny * nz) / 100; lb = 0; sum = 0; for (i = 0; i < maxshort; i++) { sum += histo[i]; if (sum >= limit) { lb = i; break; }; }; limit = (white * nx * ny * nz) / 100; ub = maxshort-1; sum = 0; for (i = maxshort-1; i >= 0; i--) { sum += histo[i]; if (sum >= limit) { ub = i; break; }; }; min = lb*m+b; max = ub*m+b; /* third pass: create and convert image */ dst = VCreateImage(nz, ny, nx, VUByteRepn); if (dst == 0) return 0; range = 256; m = range / (max - min); b = range - (m * max); for (z = 0; z < nz; z++) { for (y = 0; y < ny; y++) { for (x = 0; x < nx; x++) { v = VGetPixel(src, z, y, x); i = (int)(v * m + b + 0.5); if (i < 0) i = 0; else if (i >= range) i = range-1; VPixel(dst, z, y, x, VUByte) = i; }; }; }; VFree(histo); VCopyImageAttrs(src, dst); return dst; }
int * KMeans(gsl_matrix *mat, int nclusters, double *bic, double *aic) { int *labels = NULL, *bestlabels = NULL, *list = NULL; int i, j, s, dim, iter, nvectors, maxiter = 1000; double xmax, dmin, d, nx, mx, best, xbic = 0; double rss = 0; gsl_vector *kmean[N], *kmean_sav[N]; gsl_vector *vec = NULL, *tmp = NULL; unsigned long int seed; gsl_rng *rx = NULL; const gsl_rng_type *T = NULL; /* random */ seed = 35521738; gsl_rng_env_setup(); T = gsl_rng_default; rx = gsl_rng_alloc(T); gsl_rng_set(rx, (unsigned long int)seed); /* alloc */ xmax = VRepnMaxValue(VDoubleRepn); dim = mat->size1; /* vector length */ nvectors = mat->size2; /* num vectors (matrix columns) */ vec = gsl_vector_calloc(dim); tmp = gsl_vector_calloc(dim); labels = (int *) VCalloc(nvectors, sizeof(int)); bestlabels = (int *) VCalloc(nvectors, sizeof(int)); list = (int *) VCalloc(nclusters, sizeof(int)); for(i = 0; i < nclusters; i++) { kmean[i] = gsl_vector_calloc(dim); kmean_sav[i] = gsl_vector_calloc(dim); } /* ini */ best = VRepnMaxValue(VDoubleRepn); /* best = 1.0e+999 !!!!!!!!!!!!!! */ for(s = 0; s < 50; s++) { /* try several starting values */ Centers(nvectors, nclusters, list, rx); for(i = 0; i < nclusters; i++) gsl_matrix_get_col(kmean[i], mat, list[i]); /* iterations */ for(iter = 0; iter < maxiter; iter++) { /* get nearest neighbour */ for(j = 0; j < nvectors; j++) { gsl_matrix_get_col(vec, mat, j); dmin = xmax; for(i = 0; i < nclusters; i++) { d = dist(kmean[i], vec); if(d < dmin) { dmin = d; labels[j] = i; } } } /* update cluster means */ for(i = 0; i < nclusters; i++) { gsl_vector_memcpy(kmean_sav[i], kmean[i]); gsl_vector_set_zero(kmean[i]); nx = 0; for(j = 0; j < nvectors; j++) { if(labels[j] != i) continue; gsl_matrix_get_col(vec, mat, j); gsl_vector_add(kmean[i], vec); nx++; } gsl_vector_scale(kmean[i], 1.0 / nx); } /* stop iterations if no significant changes occurr */ d = 0; for(i = 0; i < nclusters; i++) d += dist(kmean[i], kmean_sav[i]); if(d < 1.0e-10) break; } /* residual sum of squares, RSS */ rss = 0; for(i = 0; i < nclusters; i++) { for(j = 0; j < nvectors; j++) { if(labels[j] != i) continue; gsl_matrix_get_col(vec, mat, j); rss += dist(kmean[i], vec); } } if(rss < best) { best = rss; for(j = 0; j < nvectors; j++) bestlabels[j] = labels[j]; } } /* Bayesian information criterion (not very useful) */ nx = (double)nvectors; mx = (double)nclusters; xbic = nx * log(best) + mx * log(nx); (*bic) = log(best) + log(nx) * mx / nx; (*aic) = log(best) + 2.0 * mx / nx; (*bic) = xbic; return bestlabels; }
static VPointer VGraphDecodeMethod (VStringConst name, VBundle b) { VGraph graph; VLong size, nfields, node_repn, useWeights; VAttrList list; VLong idx, nadj; int length; size_t len; VNode n; VPointer p, ptr; VAdjacency adj; #define Extract(name, dict, locn, required) \ VExtractAttr (b->list, name, dict, VLongRepn, & locn, required) /* Extract the required attribute values for Graph. */ if (!Extract (VRepnAttr, VNumericRepnDict, node_repn, TRUE) || !Extract (VNNodeFieldsAttr, NULL, nfields, TRUE) || !Extract (VNNodeWeightsAttr, NULL, useWeights, TRUE)) return NULL; /* Look for size attribute, if not present, look for nnodes (for backward compatibility */ if (Extract (VNGraphSizeAttr, NULL, size, TRUE) == FALSE && Extract (VNGraphNodesAttr, NULL, size, TRUE) == FALSE) return NULL; if (size <= 0 || nfields <= 0) { VWarning ("VGraphReadDataMethod: Bad Graph file attributes"); return NULL; } /* Create the Graph data structure. */ graph = VCreateGraph ((int)size, (int) nfields, (VRepnKind) node_repn, (int) useWeights); if (! graph) return NULL; /* Give it whatever attributes remain: */ list = VGraphAttrList (graph); VGraphAttrList (graph) = b->list; b->list = list; length = b->length; if (length == 0) return graph; p = b->data; #define unpack(repn, cnt, dest) \ ptr = dest; \ if (VUnpackData(repn, cnt, p, VMsbFirst, & len, & ptr, 0) == 0) return 0; \ p = (char *) p + len; length -= len; len = length; \ if (length < 0) goto Fail; len = length; while (length > 0) { /* Get the index : */ unpack(VLongRepn, 1, &idx); graph->table[idx-1] = n = VCalloc(1, VNodeSize(graph)); if (idx > graph->lastUsed) graph->lastUsed = idx; graph->nnodes++; /* Get the number of adjacencies : */ unpack(VLongRepn, 1, &nadj); /* Unpack the adjacencies : */ while (nadj--) { adj = VMalloc(sizeof(VAdjRec)); unpack(VLongRepn, 1, &adj->id); if (graph->useWeights) { unpack(VFloatRepn, 1, &adj->weight); } else adj->weight = 0.0; adj->next = n->base.head; n->base.head = adj; }; /* Unpack the node itself: */ if (graph->useWeights) { unpack(VFloatRepn, 1, &(n->base.weight)); } else n->base.weight = 0.0; unpack(graph->node_repn, graph->nfields, n->data); } return graph; Fail: VWarning ("VGraphDecodeMethod: %s graph has wrong data length", name); VDestroyGraph (graph); return NULL; #undef Extract }