VEdge VAddEdge (VEdges edges, VFloat *edge_fields, int npoints, VFloat *points, VBooleanPromoted closed, VBooleanPromoted copy) { VEdge edge = VMalloc (sizeof (VEdgeRec)); size_t fsize, psize, isize; int i; VPointer p; VFloat *pdata; /* Add the edge to the end of the current list of edges in order to maintain a consistent ordering of edges during IO. */ if (edges->last == NULL) edges->first = edge; else edges->last->next = edge; edges->last = edge; edge->next = NULL; edges->nedges += 1; edges->npoints += npoints; edge->npoints = npoints; edge->closed = closed; isize = sizeof (VFloat *) * npoints; /* Size of points index array. */ /* If copying data, enough space is allocated to hold everything. */ if (copy) { #ifndef __alpha fsize = sizeof (VFloat) * edges->nedge_fields; psize = sizeof (VFloat) * npoints * edges->npoint_fields; #else /* pointers must be quadword-aligned on a DEC alpha */ #define quadalign(a) ((((a)-1)/8+1)*8) fsize = quadalign(sizeof (VFloat) * edges->nedge_fields); psize = quadalign(sizeof (VFloat) * npoints * edges->npoint_fields); #endif p = VMalloc (fsize + psize + isize); edge->free = p; edge->edge_fields = (VFloat *) p; if (fsize > 0) memcpy (p, edge_fields, fsize); pdata = (VFloat *) ((char *) p + fsize); memcpy (pdata, points, psize); edge->point_index = (VFloat **) ((char *) p + fsize + psize); } else { p = VMalloc (isize); edge->free = p; edge->edge_fields = edge_fields; pdata = points; edge->point_index = (VFloat **) p; } /* Initialize index array into set of points. */ for (i = 0; i < npoints; i++) edge->point_index[i] = pdata + i * edges->npoint_fields; return edge; }
PUBLIC VMRef newcode( WORD type, WORD size, WORD vtype, WORD loc, WORD value ) { Code *p; VMRef v; (void)codeptr(); /* ensure there is space */ v = VMalloc(sizeof(Code),codeseg); p = VMAddr(Code,v); trace("newcode: %8x : %3ld %3ld %3ld %8lx",p,type,size,vtype,value); p->type = (byte)type; p->size = (byte)size; p->vtype = (byte)vtype; p->loc = loc; p->value.fill = value; codesize += sizeof(Code); VMDirty(v); return v; }
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; }
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; }
PUBLIC VMRef codeptr() { /* if this would be the last code entry in the segment, get a */ /* new block and add a OBJNEWSEG entry. */ if( VMleft(codeseg) < sizeof(Code)*2 ) { VMRef newseg = VMPage(); VMRef v = VMalloc(sizeof(Code),codeseg); Code *codetop = VMAddr(Code,v); if( NullRef(newseg) ) error("Cannot get code segement"); codetop->type = OBJNEWSEG; codetop->size = 0; codetop->vtype = 0; codetop->value.v = newseg; codetop->loc = -1; codesize += sizeof(Code); trace("code extension: %lx",codeseg); VMDirty(v); codeseg = newseg; } return VMnext(codeseg); }
static int ParseArgValues (int *arg, int argc, char **argv, VOptionDescRec *opt) { VArgVector *vec = (VArgVector *) opt->value; VPointer values; int nvalues = 0; VDictEntry *dict = opt->dict; char *cp; /* Locate the place we're to store the argument values: */ if (opt->number == 0) { /* If a variable number of arguments is expected, allocate storage to hold them: */ vec->vector = values = VMalloc ((argc - *arg) * VRepnSize (opt->repn)); } else values = opt->value; /* If no dictionary is specified for a boolean-valued option, use the default one of true, false, yes, no... */ if (opt->repn == VBooleanRepn && ! dict) dict = VBooleanDict; /* Parse argument values until we've reached the required number, we've run out of entered arguments, or we encounter one that is ill-formed: */ while ((opt->number == 0 || nvalues < opt->number) && (*arg < argc)) { cp = argv[*arg]; /* Special treatment for string-valued options: */ if (opt->repn == VStringRepn) { /* An argument of the form -string is not interpreted as a string value: */ if (cp[0] == '-' && cp[1] != 0 && cp[1] != '-') break; /* An argument of the form --string is interpreted as string: */ if (cp[0] == '-' && cp[1] == '-' && cp[2] != 0) cp += 2; } /* Convert the argument to the specified internal form: */ if (! VDecodeAttrValue (cp, dict, opt->repn, values)) break; nvalues++; values = (VPointer) ((char *) values + VRepnSize (opt->repn)); argv[(*arg)++] = NULL; } /* Special treatment of boolean-valued options: if the option has just one value associated with it then treat -option <other options> like -option true <other options>: */ if (opt->repn == VBooleanRepn && opt->number == 1 && nvalues == 0) { * (VBoolean *) opt->value = TRUE; nvalues = 1; } return nvalues; }
static char *ReadString (FILE *f, char ch, VStringConst name) { VBoolean escaped = (ch == '"'); size_t len = 0; char *cp; size_t max_len; char *buf; buf = VMalloc (StringAllocIncrement); max_len = StringAllocIncrement; if (! escaped) ungetc (ch, f); cp = buf; while (1) { ch = fgetc (f); /* Check for premature EOF: */ if (ch == EOF) { VWarning ("VReadFile: EOF encountered in %s attribute", name); return NULL; } /* Check for closing " or escape sequence: */ if (escaped) { if (ch == '"') break; if (ch == '\\') switch (ch = fgetc (f)) { case '\n': continue; case 'n': ch = '\n'; } } else if (isspace (ch)) break; /* If the buffer in which we're accumulating the value is full, allocate a larger one: */ if (++len == max_len) { buf = VRealloc (buf, max_len += StringAllocIncrement); cp = buf + len - 1; } /* Store the character in the current buffer: */ *cp++ = ch; } *cp = 0; /* Allocate a node of the correct size, or trim one already allocated so it is the correct size: */ return buf; }
static VAttrRec *NewAttr (VStringConst name, VDictEntry *dict, VRepnKind repn, va_list *args) { size_t new_value_size, name_size; VPointer value; VAttrRec *a; name_size = strlen (name); switch (repn) { case VBitRepn: case VUByteRepn: case VSByteRepn: case VShortRepn: case VLongRepn: case VFloatRepn: case VDoubleRepn: case VBooleanRepn: case VStringRepn: /* Determine the amount of storage needed to record the new value. In some cases, this requires first encoding the new value as a string. */ if (repn == VStringRepn && ! dict) value = (VPointer) va_arg (*args, VStringConst); else value = (VPointer) Encode (dict, repn, args); new_value_size = strlen (value) + 1; /* Allocate storage for the new attribute and copy in its value: */ a = VMalloc (sizeof (VAttrRec) + name_size + new_value_size); a->repn = VStringRepn; a->value = (a->name + name_size + 1); strcpy (a->value, value); break; default: a = VMalloc (sizeof (VAttrRec) + name_size); a->repn = repn; a->value = va_arg (*args, VPointer); } strcpy (a->name, name); return a; }
extern VMRef VMNew( int size ) { VMRef v; size = wordlen(size); v = VMalloc(size,vmheap); if( NullRef(v) ) { vmheap = VMPage(); v = VMalloc(size,vmheap); } VMDirty(v); return v; }
static VPointer VGraphEncodeDataMethod (VPointer value, VAttrList list, size_t length, VBoolean *free_itp) { VGraph graph = value; VAttrListPosn posn; VNode n; size_t len; VPointer p, ptr; VAdjacency adj; int i, nadj; #define pack(repn, cnt, dest) \ if (! VPackData (repn, cnt, dest, VMsbFirst, &len, &p, NULL)) return NULL; \ p = (char *) p + len; length -= len; len = length; /* Remove the attributes prepended by the VGraphEncodeAttrsMethod: */ for (VFirstAttr (list, & posn); strcmp (VGetAttrName (& posn), VRepnAttr) != 0; VDeleteAttr (& posn)); VDeleteAttr (& posn); /* Allocate a buffer for the encoded data: */ if (length == 0) { *free_itp = FALSE; return value; /* we may return anything != 0 here */ }; p = ptr = VMalloc (length); len = length; /* Pack each node: */ for (i = 1; i <= graph->size; i++) { n = VGraphGetNode(graph, i); if (n == 0) continue; /* Count the number of adjacencies : */ for (adj = n->base.head, nadj = 0; adj; adj = adj->next) nadj++; /* Pack the header */ pack(VLongRepn, 1, &i); pack(VLongRepn, 1, &nadj); /* Pack the adjacencies : */ for (adj = n->base.head; adj; adj = adj->next) { pack(VLongRepn, 1, &adj->id); if (graph->useWeights) { pack(VFloatRepn, 1, &adj->weight); }; }; /* Pack the node itself: */ if (graph->useWeights) { pack(VFloatRepn, 1, &(n->base.weight)); }; pack(graph->node_repn, graph->nfields, n->data); } *free_itp = TRUE; return ptr; }
static VNodePtrType MakeNode (VPointer item, VNodePtrType prev, VNodePtrType next) { VNodePtrType result = VMalloc (sizeof (struct V_Node)); result->item = item; result->prev = prev; result->next = next; return result; }
VPointer VRealloc (VPointer p, size_t size) { if (size == 0) { VFree (p); return NULL; } if (! p) return VMalloc (size); if (! (p = (VPointer) realloc (p, size))) VSystemError ("VRealloc: Memory allocation failure"); return p; }
VBundle VCreateBundle (VStringConst type_name, VAttrList list, size_t length, VPointer data) { VBundle b; b = VMalloc (sizeof (VBundleRec) + strlen (type_name)); strcpy (b->type_name, type_name); b->list = list; b->length = length; b->data = data; return b; }
VGraph VGraphHemi(VGraph src,VLong hemi) { VString str; VGraph dest=NULL; int i,j,n,ncols,half=0; float x,y,z,val=0; VNode node,node1; int *table; half = 80; /* standard coordinate for inter-hemisperic cleft */ if (VGetAttr (VGraphAttrList (src), "ca", NULL,VStringRepn, (VPointer) & str) == VAttrFound) { sscanf(str,"%f %f %f",&x,&y,&z); ncols = (int) x; half = ncols/2; } table = (int *) VMalloc(sizeof(int) * (src)->lastUsed + 1); for (i=0; i<= src->lastUsed; i++) table[i] = 0; n = (src)->lastUsed/2; dest = VCreateGraph(n,VGraphNFields(src),VNodeRepn(src),src->useWeights); for (i=1; i<=(src)->lastUsed; i++) { node = (VNode) VGraphGetNode (src,i); if (node == 0) continue; VReadNode((src),node,&x,&y,&z,&val); if ((hemi == 0 && x <= half) || (hemi == 1 && x > half)) { n = VGraphAddNode(dest,(VNode) node); table[i] = n; } } for (i=1; i<=(src)->lastUsed; i++) { node = (VNode) VGraphGetNode (src,i); if (node == 0) continue; for (j=1; j<=(src)->lastUsed; j++) { node1 = (VNode) VGraphGetNode (src,j); if (node1 == 0) continue; if (table[i] == 0 || table[j] == 0) continue; if (VGraphIsAdjacent(src,i,j) == TRUE) { VGraphLinkNodes(dest,table[i],table[j]); } } } VFree(table); return dest; }
int VGraphLinkNodes (VGraph graph, int a, int b) { VNode n; VAdjacency adj; if (VGraphNodeIsFree(graph, a) || VGraphNodeIsFree(graph, b)) return FALSE; n = VGraphGetNode(graph, a); adj = VMalloc(sizeof(VAdjRec)); adj->id = b; adj->weight = 0; adj->next = n->base.head; n->base.head = adj; return TRUE; }
VList VListCreate (void) { VList vlist = VMalloc (sizeof (struct V_List)); VNodePtrType dummy_head, dummy_tail; dummy_head = VMalloc (sizeof (struct V_Node)); dummy_tail = VMalloc (sizeof (struct V_Node)); dummy_head->item = NULL; dummy_head->prev = NULL; dummy_head->next = dummy_tail; dummy_tail->item = NULL; dummy_tail->prev = dummy_head; dummy_tail->next = NULL; vlist->head = dummy_head; vlist->tail = dummy_tail; vlist->current = dummy_head; vlist->count = 0; return vlist; }
static void LoadHelpFile (void) { FILE *f; size_t len, incr; Topic *topic; char buf[100]; ntopics = 0; topics = topic = VMalloc (sizeof (Topic) * maxTopics); if (! (f = fopen (helpFilename, "r"))) { VWarning ("Unable to open help database %s", helpFilename); ntopics = 1; topic->topic = "(No help topics)"; topic->text = "(No help text)"; topic->len = strlen (topic->text); return; } do { fgets (buf, sizeof (buf), f); } while (! feof (f) && buf[0] != '@'); while (! feof (f) && ntopics < maxTopics) { len = strlen (buf); if (buf[len - 1] == '\n') buf[len - 1] = 0; topic->topic = VNewString (buf + 1); topic->text = NULL; len = 0; while (1) { fgets (buf, sizeof (buf), f); if (feof (f) || buf[0] == '@') break; incr = strlen (buf); topic->text = VRealloc ((XtPointer) topic->text, len + incr + 1); strcpy (topic->text + len, buf); len += incr; } while (len > 0 && isspace (topic->text[len - 1])) len--; topic->text[len] = 0; topic->len = len; ntopics++; topic++; } fclose (f); }
VImage ConcatDesigns(VImage *design, int nimages) { VImage dest = NULL; VString buf = NULL; VDouble x; int i, r, c, row, col; int nrows, ncols; nrows = ncols = 0; for(i = 0; i < nimages; i++) { ncols += VImageNColumns(design[i]); nrows += VImageNRows(design[i]); } dest = VCreateImage(1, nrows, ncols, VFloatRepn); VFillImage(dest, VAllBands, 0); VCopyImageAttrs(design[0], dest); VSetAttr(VImageAttrList(dest), "nsessions", NULL, VShortRepn, (VShort)nimages); buf = (VString) VMalloc(80); buf[0] = '\0'; for(i = 0; i < nimages; i++) sprintf(buf, "%s %d", buf, (int)VImageNRows(design[i])); VSetAttr(VImageAttrList(dest), "session_lengths", NULL, VStringRepn, buf); buf[0] = '\0'; for(i = 0; i < nimages; i++) sprintf(buf, "%s %d", buf, (int)VImageNColumns(design[i])); VSetAttr(VImageAttrList(dest), "session_covariates", NULL, VStringRepn, buf); row = col = 0; for(i = 0; i < nimages; i++) { for(r = 0; r < VImageNRows(design[i]); r++) { for(c = 0; c < VImageNColumns(design[i]); c++) { x = VGetPixel(design[i], 0, r, c); if(row + r >= VImageNRows(dest)) VError(" row: %d\n", row + r); if(col + c >= VImageNColumns(dest)) VError(" column: %d\n", col + c); VSetPixel(dest, 0, row + r, col + c, x); } } row += VImageNRows(design[i]); col += VImageNColumns(design[i]); } return dest; }
VRepnKind VRegisterType (VStringConst name, VTypeMethods *methods) { VRepnInfoRec *p; /* Move the existing type information into a bigger table: */ if (VRepnInfo == builtin_repn_info) { VRepnInfo = VMalloc ((VNRepnKinds + 1) * sizeof (VRepnInfoRec)); memcpy(VRepnInfo, builtin_repn_info, VNRepnKinds * sizeof (VRepnInfoRec)); } else VRepnInfo = VRealloc (VRepnInfo, (nRepnKinds + 1) * sizeof (VRepnInfoRec)); /* Write the new type's info into the last table entry: */ p = VRepnInfo + nRepnKinds; p->name = VNewString (name); p->size = p->precision = p->min_value = p->max_value = 0.0; p->methods = methods; return nRepnKinds++; }
int VReadObjects (FILE *file, VRepnKind repn, VAttrList *attributes, VPointer **objects) { VAttrList list; VAttrListPosn posn; int i, nobjects = 0; VPointer *vector; /* Read the file's contents: */ list = VReadFile (file, NULL); if (! list) return FALSE; /* Count the objects found: */ for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) nobjects += (VGetAttrRepn (& posn) == repn); if (nobjects == 0) { VWarning ("VReadObjects: No %s objects present in stream", VRepnName (repn)); VDestroyAttrList (list); return FALSE; } /* Allocate a vector of that many object pointers: */ vector = VMalloc (nobjects * sizeof (VPointer)); /* Extract the objects from the attribute list and place them in the vector: */ for (VFirstAttr (list, & posn), i = 0; VAttrExists (& posn); ) if (VGetAttrRepn (& posn) == repn) { VGetAttrValue (& posn, NULL, repn, vector + i); VDeleteAttr (& posn); i++; } else VNextAttr (& posn); /* Return the objects and the remaining attributes: */ *attributes = list; *objects = vector; return nobjects; }
VEdges VCreateEdges (int nrows, int ncolumns, int nedge_fields, int npoint_fields) { VEdges edges; /* Check parameters: */ if (nrows < 1 || ncolumns < 1) VWarning ("VCreateEdges: Invalid number of rows or columns."); /* Allocate memory for the VEdges, its indices, and pixel values: */ edges = VMalloc (sizeof (VEdgesRec)); /* Initialize the VEdges: */ edges->nrows = nrows; edges->ncolumns = ncolumns; edges->attributes = VCreateAttrList (); edges->nedge_fields = nedge_fields; edges->npoint_fields = npoint_fields; edges->nedges = edges->npoints = 0; edges->first = edges->last = NULL; edges->free = NULL; return edges; }
VAttrList GetListInfo(VString in_filename, ListInfo *linfo) { VAttrList list = NULL; VAttrListPosn posn; FILE *in_file = NULL; VString str, voxel = NULL; VRepnKind repn = VShortRepn; int ntimesteps, nrows, ncols; int id, j, itr, found, nobject, nbands; VImageInfo *imageInfo = NULL; in_file = VOpenInputFile(in_filename, TRUE); if(!in_file) VError("error opening file %s", in_filename); if(! ReadHeader(in_file)) VError("error reading header"); if(!(list = ReadAttrList(in_file))) VError("error reading attr list"); j = 0; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { j++; } imageInfo = (VImageInfo *) VMalloc(sizeof(VImageInfo) * (j + 1)); itr = ntimesteps = nrows = ncols = 0; nobject = nbands = found = id = 0; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { str = VGetAttrName(&posn); if(strncmp(str, "history", 7) == 0) { nobject++; continue; } VImageInfoIni(&imageInfo[nbands]); if(! VGetImageInfo(in_file, list, nobject, &imageInfo[nbands])) VError(" error reading image info"); linfo->ntimesteps = linfo->nrows = linfo->ncols = 0; if(imageInfo[nbands].repn == VShortRepn) { found = 1; repn = imageInfo[nbands].repn; if(imageInfo[nbands].nbands > ntimesteps) ntimesteps = imageInfo[nbands].nbands; if(imageInfo[nbands].nrows > nrows) nrows = imageInfo[nbands].nrows; if(imageInfo[nbands].ncolumns > ncols) ncols = imageInfo[nbands].ncolumns; if(voxel == NULL) voxel = imageInfo[nbands].voxel; /* check if slice contains non-zero data */ linfo->zero[nbands] = 1; if(imageInfo[nbands].nrows < 2) linfo->zero[nbands] = 0; linfo->info[id] = imageInfo[nbands]; itr = imageInfo[nbands].repetition_time; id++; nbands++; } nobject++; } fclose(in_file); if(!found) VError(" couldn't find functional data"); linfo->ntimesteps = ntimesteps; linfo->nrows = nrows; linfo->ncols = ncols; linfo->nslices = id; linfo->itr = itr; linfo->repn = repn; linfo->voxel = voxel; linfo->filename = VNewString(in_filename); return list; }
int main(int argc, char *argv[]) { static VArgVector in_files; static VString out_filename; static VBoolean in_found, out_found; static VOptionDescRec options[] = { {"in", VStringRepn, 0, & in_files, & in_found, NULL, "Input files" }, {"out", VStringRepn, 1, & out_filename, & out_found, NULL, "Output file" } }; FILE *fp = NULL; VStringConst in_filename; VAttrList list = NULL, out_list = NULL; VImage *design = NULL, tmp = NULL, dest = NULL; VAttrListPosn posn; int i, nimages; char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vcatdesign V%s", ver); fprintf(stderr, "%s\n", prg_name); /* Parse command line arguments: */ if(! VParseCommand(VNumber(options), options, & argc, argv) || ! VIdentifyFiles(VNumber(options), options, "in", & argc, argv, 0) || ! VIdentifyFiles(VNumber(options), options, "out", & argc, argv, -1)) goto Usage; if(argc > 1) { VReportBadArgs(argc, argv); Usage: VReportUsage(argv[0], VNumber(options), options, NULL); exit(EXIT_FAILURE); } /* Read each input file */ nimages = in_files.number; design = (VImage *) VMalloc(sizeof(VImage) * nimages); for(i = 0; i < nimages; i++) { in_filename = ((VStringConst *) in_files.vector)[i]; fprintf(stderr, " reading: %s\n", in_filename); fp = VOpenInputFile(in_filename, TRUE); list = VReadFile(fp, NULL); if(! list) VError("Error reading file %s", in_filename); fclose(fp); for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & tmp); if(VPixelRepn(tmp) == VFloatRepn || VPixelRepn(tmp) == VDoubleRepn) { design[i] = tmp; break; } } } /* process */ dest = ConcatDesigns(design, nimages); out_list = VCreateAttrList(); VAppendAttr(out_list, "image", NULL, VImageRepn, dest); /* Output: */ VHistory(VNumber(options), options, prg_name, &list, &out_list); fp = VOpenOutputFile(out_filename, TRUE); if(!fp) VError(" error opening outout file %s", out_filename); if(! VWriteFile(fp, out_list)) exit(1); fprintf(stderr, "%s: done.\n", argv[0]); return 0; }
VBoolean VPackData (VRepnKind repn, size_t nels, VPointer unpacked, VPackOrder packed_order, size_t *length, VPointer *packed, VBoolean *alloced) { VPackOrder unpacked_order; size_t unpacked_elsize = VRepnSize (repn) * CHAR_BIT; size_t packed_elsize = VRepnPrecision (repn); size_t packed_length = (nels * packed_elsize + 7) / 8; /* If space for the packed data was supplied, ensure there's enough of it: */ if (! alloced && packed_length > *length) { VWarning ("VPackData: Insufficient space for packed data"); return FALSE; } *length = packed_length; /* Determine the present machine's internal byte order: */ unpacked_order = MachineByteOrder (); /* If the desired byte order matches that of the present machine's, and the unpacked and packed data element sizes are identical, just return the unpacked data: */ if (unpacked_order == packed_order && unpacked_elsize == packed_elsize) { if (alloced) { *packed = unpacked; *alloced = FALSE; } else if (unpacked != packed) memcpy (*packed, unpacked, packed_length); return TRUE; } /* Allocate a buffer for the packed data if none was provided: */ if (alloced) { *packed = VMalloc (packed_length); *alloced = TRUE; } /* Pack data elements into the buffer: */ if (unpacked_elsize == packed_elsize) { /* If the packed and unpacked are the same size, do a straight copy: */ if (unpacked != *packed) memcpy (*packed, unpacked, packed_length); /* Swap bytes if necessary: */ if (packed_order != unpacked_order && packed_elsize > 8) SwapBytes (nels, packed_elsize / 8, (char *) *packed); } else if (packed_elsize == 1) { /* If the elements are VBits, this packs them: */ VPackBits (nels, packed_order, (VBit *) unpacked, (char *) *packed); } else /* Packing multi-byte integers or floats is currently not supported: */ VError ("VPackData: Packing %s from %d to %d bits is not supported", VRepnName (repn), unpacked_elsize, packed_elsize); return TRUE; }
/* ** 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"); }
/* ** 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"); }
VImage VTopSmoothImage3d(VImage bit_image, VImage grey_image, VImage result, VLong neighb, VLong numiter) { long nbands, nrows, ncols, npixels; VRepnKind repn; long i, i0, i1, n, iter, npts, u; long b0, b1, r0, r1, c0, c1, b, r, c; long n1, n6, n18, n26; int isum; double sum, norm = 0; VBit *dest_pp, *bit_pp; VUByte *ubyte_pp; int background = 0; VPoint *array = NULL; repn = VPixelRepn(bit_image); if(repn != VBitRepn) VError("Smooth3d: repn must be bit"); nbands = VImageNBands(bit_image); nrows = VImageNRows(bit_image); ncols = VImageNColumns(bit_image); npixels = nbands * nrows * ncols; if(result == NULL) result = VCreateImage(nbands, nrows, ncols, repn); if(! result) return NULL; bit_pp = VPixelPtr(bit_image, 0, 0, 0); dest_pp = VPixelPtr(result, 0, 0, 0); for(i = 0; i < npixels; i++) *dest_pp++ = *bit_pp++; n1 = 8; n6 = 4; n18 = 2; n26 = 1; switch(neighb) { case 0: norm = n1 + 6 * n6; break; case 1: norm = n1 + 6 * n6 + 12 * n18; break; case 2: norm = n1 + 6 * n6 + 12 * n18 + 8 * n26; break; default: ; } n = 1; ubyte_pp = VPixelPtr(grey_image, 0, 0, 0); for(i = 0; i < npixels; i++) if(*ubyte_pp++ > background) n++; array = (VPoint *) VMalloc(sizeof(VPoint) * (n + 2)); for(i = 0; i < n + 2; i++) array[i].val = array[i].b = array[i].r = array[i].c = 0; n = 1; for(b = 0; b < nbands; b++) { for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { u = VPixel(grey_image, b, r, c, VUByte); if(u > background) { array[n].b = b; array[n].r = r; array[n].c = c; array[n].val = (float)u; n++; } } } } npts = n; VPoint_hpsort(n - 1, array); iter = 0; n = 100; while(n > 1 && iter < numiter) { iter++; n = 0; for(i = 1; i < npts; i++) { b = array[i].b; r = array[i].r; c = array[i].c; b0 = (b < 1) ? 0 : b - 1; b1 = (b > nbands - 2) ? nbands - 1 : b + 1; r0 = (r < 1) ? 0 : r - 1; r1 = (r > nrows - 2) ? nrows - 1 : r + 1; c0 = (c < 1) ? 0 : c - 1; c1 = (c > ncols - 2) ? ncols - 1 : c + 1; isum = 0; i1 = VPixel(bit_image, b, r, c, VBit); isum += (int) i1 * n1; isum += (int) VPixel(bit_image, b0, r, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r0, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r, c0, VBit) * n6; isum += (int) VPixel(bit_image, b1, r, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r1, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r, c1, VBit) * n6; if(neighb == 1) { isum += VPixel(bit_image, b0, r0, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r0, c0, VBit) * n18; isum += (int) VPixel(bit_image, b0, r, c0, VBit) * n18; isum += (int) VPixel(bit_image, b1, r1, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r1, c1, VBit) * n18; isum += (int) VPixel(bit_image, b1, r, c1, VBit) * n18; isum += (int) VPixel(bit_image, b1, r0, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r1, c0, VBit) * n18; isum += (int) VPixel(bit_image, b1, r, c0, VBit) * n18; isum += (int) VPixel(bit_image, b0, r1, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r0, c1, VBit) * n18; isum += (int) VPixel(bit_image, b0, r, c1, VBit) * n18; } if(neighb == 2) { isum += (int) VPixel(bit_image, b0, r0, c0, VBit) * n26; isum += (int) VPixel(bit_image, b1, r0, c0, VBit) * n26; isum += (int) VPixel(bit_image, b0, r1, c0, VBit) * n26; isum += (int) VPixel(bit_image, b0, r0, c1, VBit) * n26; isum += (int) VPixel(bit_image, b1, r1, c0, VBit) * n26; isum += (int) VPixel(bit_image, b1, r0, c1, VBit) * n26; isum += (int) VPixel(bit_image, b0, r1, c1, VBit) * n26; isum += (int) VPixel(bit_image, b1, r1, c1, VBit) * n26; } sum = (double) isum / (double) norm; i0 = 0; if(sum >= 0.5) i0 = 1; if(i1 == 1 && i0 == 0) { if(VSimplePoint(result, b, r, c, 26) == 0) i0 = 1; } else if(i1 == 0 && i0 == 1) { VPixel(result, b, r, c, VBit) = 1; if(VSimplePoint(result, b, r, c, 26) == 0) i0 = 0; } VPixel(result, b, r, c, VBit) = i0; if(i0 != i1) n++; } if(numiter > 1) { bit_pp = (VBit *) VImageData(bit_image); dest_pp = (VBit *) VImageData(result); for(i = 0; i < npixels; i++) *bit_pp++ = *dest_pp++; } } /* Successful completion: */ VCopyImageAttrs(bit_image, result); return result; }
int main(int argc, char *argv[]) { static VFloat reso = -1.0; static VLong itype = 0; static VBoolean flip = TRUE; static VBoolean reorder = TRUE; static VOptionDescRec options[] = { { "reso", VFloatRepn, 1, (VPointer) &reso, VOptionalOpt, NULL, "New voxel resolution in mm, def: -1 means min(1.0,\"best source resolution\")" }, { "flip", VBooleanRepn, 1, (VPointer) &flip, VOptionalOpt, NULL, "Whether to flip to natural convention" }, { "reorder", VBooleanRepn, 1, (VPointer) &reorder, VOptionalOpt, NULL, "Whether to reorder axial slices from axial source image" }, { "interpolation", VLongRepn, 1, & itype, VOptionalOpt, ITYPDict, "Type of interpolation (0: linear, 1: nearest neighbour, 2: cubic spline)" } }; FILE *in_file, *out_file; VAttrList list; VAttrListPosn posn; int nobjects = 0; VImage src = NULL, dest = NULL, result = NULL; int i, b, r, c, nbands, nrows, ncols; VString str, newstr, fixpointString, caString, cpString; float fix_c, fix_r, fix_b; float ca_c, ca_r, ca_b; float cp_c, cp_r, cp_b; float x, y, z, min; VDouble v, scale_band, scale_row, scale_col; float scale[3], shift[3]; /* print information */ char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "visotrop V%s", ver); fprintf(stderr, "%s\n", prg_name); fflush(stderr); /* Parse command line arguments: */ VParseFilterCmd(VNumber(options), options, argc, argv, & in_file, & out_file); /* Read source image(s): */ if(!(list = VReadFile(in_file, NULL))) exit(EXIT_FAILURE); /* Scale each object: */ for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { switch(VGetAttrRepn(& posn)) { case VImageRepn: VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VGetAttr(VImageAttrList(src), "voxel", NULL, VStringRepn, (VPointer) & str) == VAttrFound) { sscanf(str, "%f %f %f", &x, &y, &z); fprintf(stderr, " voxel: %f %f %f\n", x, y, z); min = x < y ? x : y; min = z < min ? z : min; /* if resolution is not set, use default value 1 or smaler value if the image resolution is better */ if(reso < 0.0) reso = min < 1.0 ? min : 1.0; if(reso <= 0.0) exit(EXIT_FAILURE); fprintf(stderr, " new resolution: %f \n", reso); scale_col = x / reso; scale_row = y / reso; scale_band = z / reso; nbands = VImageNBands(src) * scale_band; nrows = VImageNRows(src) * scale_row; ncols = VImageNColumns(src) * scale_col; if(VImageNBands(src) == nbands && VImageNRows(src) == nrows && VImageNColumns(src) == ncols) { itype = 0; } fprintf(stderr, " interpolation type: %s\n", ITYPDict[itype].keyword); fprintf(stderr, " old dim: %3d %3d %3d\n", VImageNBands(src), VImageNRows(src), VImageNColumns(src)); for(i = 0; i < 3; i++) shift[i] = scale[i] = 0; scale[0] = scale_band; scale[1] = scale_row; scale[2] = scale_col; switch(itype) { /* trilinear interpolation resampling */ case 0: dest = VTriLinearScale3d(src, NULL, (int)nbands, (int)nrows, (int)ncols, shift, scale); break; /* nearest neightbour resampling */ case 1: dest = VNNScale3d(src, NULL, (int)nbands, (int)nrows, (int)ncols, shift, scale); break; /* cubic spline */ case 2: dest = VCubicSplineScale3d(src, NULL, (int)nbands, (int)nrows, (int)ncols, shift, scale); break; case 3: /* no interpolation, just reshuffle */ dest = VCopyImage(src, NULL, VAllBands); break; default: VError(" unknown resampling type %d", itype); } if(! dest) exit(EXIT_FAILURE); /*aa 2003/09/11 added function not to rotate siemens data*/ if(! VGetAttr(VImageAttrList(src), "orientation", NULL, VStringRepn, (VPointer) & str) == VAttrFound) VError(" attribute 'orientation' missing"); if(strcmp(str, "axial") == 0) { fprintf(stderr, " new dim: %3d %3d %3d\n", nbands, nrows, ncols); result = VCreateImage(nbands, nrows, ncols, VPixelRepn(src)); VFillImage(result, VAllBands, 0); for(b = 0; b < nbands; b++) for(r = 0; r < nrows; r++) for(c = 0; c < ncols; c++) { v = VGetPixel(dest, b, r, c); if((flip == FALSE) && (reorder == FALSE)) VSetPixel(result, b, r, ncols - c - 1, v); else if((flip == TRUE) && (reorder == FALSE)) VSetPixel(result, b, r, c, v); else if((flip == FALSE) && (reorder == TRUE)) VSetPixel(result, nbands - b - 1, r, ncols - c - 1, v); else if((flip == TRUE) && (reorder == TRUE)) VSetPixel(result, nbands - b - 1, r, c, v); } } else if(strcmp(str, "sagittal") == 0) { /* re-arrange from sagittal to axial orientation */ fprintf(stderr, " new dim: %3d %3d %3d\n", nrows, ncols, nbands); result = VCreateImage(nrows, ncols, nbands, VPixelRepn(src)); VFillImage(result, VAllBands, 0); for(b = 0; b < nbands; b++) for(r = 0; r < nrows; r++) for(c = 0; c < ncols; c++) { v = VGetPixel(dest, b, r, c); if(flip == FALSE) VSetPixel(result, r, c, nbands - b - 1, v); else VSetPixel(result, r, c, b, v); } } else if(strcmp(str, "coronal") == 0) { /* re-arrange from coronal to axial orientation */ fprintf(stderr, " new dim: %3d %3d %3d\n", nrows, nbands, ncols); result = VCreateImage(nrows, nbands, ncols, VPixelRepn(src)); VFillImage(result, VAllBands, 0); for(b = 0; b < nbands; b++) for(r = 0; r < nrows; r++) for(c = 0; c < ncols; c++) { v = VGetPixel(dest, b, r, c); if(flip == FALSE) VSetPixel(result, r, b, ncols - c - 1, v); else VSetPixel(result, r, b, c, v); } } else { VError(" unknown resampling type %d", itype); exit(EXIT_FAILURE); } /* copy attributes from source image */ VCopyImageAttrs(src, result); // [TS] 08/03/27 // correct 'fixpoint', 'ca' and 'cp' if they exist in the source image // // NOTE: // this is only done when no flipping or reordering is requested :-( // (WARNING!!!!) '-flip true' actually means that no flipping is done (WHAAAAT ????) // and therefore we test for reorder = false and flip = true fixpointString = VMalloc(80); caString = VMalloc(80); cpString = VMalloc(80); VBoolean _issueWarning = FALSE; if(VGetAttr(VImageAttrList(src), "fixpoint", NULL, VStringRepn, (VPointer)&fixpointString) == VAttrFound) { if(reorder == FALSE && flip == TRUE) { sscanf(fixpointString, "%f %f %f", &fix_c, &fix_r, &fix_b); fix_c *= scale_col; fix_r *= scale_row; fix_b *= scale_band; sprintf((char *)fixpointString, "%f %f %f", fix_c, fix_r, fix_b); VSetAttr(VImageAttrList(result), "fixpoint", NULL, VStringRepn, fixpointString); } else { _issueWarning = TRUE; } } if(VGetAttr(VImageAttrList(src), "ca", NULL, VStringRepn, (VPointer)&caString) == VAttrFound) { if(reorder == FALSE && flip == TRUE) { sscanf(caString, "%f %f %f", &ca_c, &ca_r, &ca_b); ca_c *= scale_col; ca_r *= scale_row; ca_b *= scale_band; sprintf((char *)caString, "%f %f %f", ca_c, ca_r, ca_b); VSetAttr(VImageAttrList(result), "ca", NULL, VStringRepn, caString); } else { _issueWarning = TRUE; } } if(VGetAttr(VImageAttrList(src), "cp", NULL, VStringRepn, (VPointer)&cpString) == VAttrFound) { if(reorder == FALSE && flip == TRUE) { sscanf(cpString, "%f %f %f", &cp_c, &cp_r, &cp_b); cp_c *= scale_col; cp_r *= scale_row; cp_b *= scale_band; sprintf((char *)cpString, "%f %f %f", cp_c, cp_r, cp_b); VSetAttr(VImageAttrList(result), "cp", NULL, VStringRepn, cpString); } else { _issueWarning = TRUE; } } if(_issueWarning) { VWarning("Attributes 'fixpoint', 'ca' and 'cp' exist but were not corrected and are therefore likely to be wrong"); VWarning("This was caused by setting -flip to false or -reorder to true"); VWarning("Please correct the values manually using vattredit"); } /* set the attributes to the changed values */ newstr = VMalloc(80); sprintf((char *)newstr, "%f %f %f", reso, reso, reso); VSetAttr(VImageAttrList(result), "voxel", NULL, VStringRepn, newstr); VSetAttr(VImageAttrList(result), "orientation", NULL, VStringRepn, "axial"); if(flip) VSetAttr(VImageAttrList(result), "convention", NULL, VStringRepn, "natural"); else VSetAttr(VImageAttrList(result), "convention", NULL, VStringRepn, "radiologic"); } VSetAttrValue(& posn, NULL, VImageRepn, result); VDestroyImage(src); break; default: continue; } nobjects++; } /* Make History */ VHistory(VNumber(options), options, prg_name, &list, &list); /* Write the results to the output file: */ if(! VWriteFile(out_file, list)) exit(EXIT_FAILURE); fprintf(stderr, "%s: done.\n", argv[0]); return EXIT_SUCCESS; }
VImage PairedTest(VImage *src1, VImage *src2, VImage dest, int n, VShort type) { int i, j, k, b, r, c, nslices, nrows, ncols; float ave1, ave2, var1, var2, nx, u; float sum, smooth = 0; float t, z, df, sd, cov, *data1 = NULL, *data2 = NULL; float tiny = 1.0e-10; nslices = VImageNBands(src1[0]); nrows = VImageNRows(src1[0]); ncols = VImageNColumns(src1[0]); gsl_set_error_handler_off(); dest = VCopyImage(src1[0], NULL, VAllBands); VFillImage(dest, VAllBands, 0); VSetAttr(VImageAttrList(dest), "num_images", NULL, VShortRepn, (VShort)n); VSetAttr(VImageAttrList(dest), "patient", NULL, VStringRepn, "paired_ttest"); if(type == 0) VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, "tmap"); else VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, "zmap"); VSetAttr(VImageAttrList(dest), "df", NULL, VShortRepn, (VShort)(n - 1)); /* get smoothness estimates */ sum = nx = 0; for(i = 0; i < n; i++) { if(VGetAttr(VImageAttrList(src1[i]), "smoothness", NULL, VFloatRepn, &smooth) == VAttrFound) { sum += smooth; nx++; } } for(i = 0; i < n; i++) { if(VGetAttr(VImageAttrList(src2[i]), "smoothness", NULL, VFloatRepn, &smooth) == VAttrFound) { sum += smooth; nx++; } } if(nx > 1) { VSetAttr(VImageAttrList(dest), "smoothness", NULL, VFloatRepn, sum / nx); } data1 = (float *) VMalloc(n * sizeof(float)); data2 = (float *) VMalloc(n * sizeof(float)); df = n - 1; nx = (float)n; for(b = 0; b < nslices; b++) { for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { k = 0; for(i = 0; i < n; i++) { data1[i] = VPixel(src1[i], b, r, c, VFloat); data2[i] = VPixel(src2[i], b, r, c, VFloat); if(ABS(data1[i]) > tiny && ABS(data2[i]) > tiny) k++; } if(k < n - 3) continue; avevar(data1, n, &ave1, &var1); avevar(data2, n, &ave2, &var2); if(var1 < tiny || var2 < tiny) continue; z = t = 0; cov = 0; for(j = 0; j < n; j++) cov += (data1[j] - ave1) * (data2[j] - ave2); cov /= df; u = (var1 + var2 - 2.0 * cov); if(u < tiny) continue; sd = sqrt(u / nx); if(sd < tiny) continue; t = (ave1 - ave2) / sd; if(isnan(t) || isinf(t)) continue; switch(type) { case 0: VPixel(dest, b, r, c, VFloat) = t; break; case 1: /* z = t2z_approx(t,df); */ z = t2z((double)t, (double)df); if(t < 0) z = -z; VPixel(dest, b, r, c, VFloat) = z; break; default: VError(" illegal type"); } } } } return dest; }
int main(int argc, char *argv[]) { static VArgVector in_files; static VString out_filename; static VString filename; static VShort minval = 0; static VFloat fwhm = 4.0; static VOptionDescRec options[] = { {"in", VStringRepn, 0, & in_files, VRequiredOpt, NULL, "Input files" }, {"out", VStringRepn, 1, & out_filename, VRequiredOpt, NULL, "Output file" }, {"design", VStringRepn, 1, (VPointer) &filename, VRequiredOpt, NULL, "Design file"}, { "fwhm", VFloatRepn, 1, (VPointer) &fwhm, VOptionalOpt, NULL, "FWHM of temporal Gaussian filter in seconds" }, {"minval", VShortRepn, 1, (VPointer) &minval, VOptionalOpt, NULL, "Signal threshold"} }; FILE *fp = NULL, *f = NULL; VStringConst in_filename; VString ifilename; VAttrList list = NULL, list1 = NULL; VAttrList out_list = NULL, history_list = NULL; VAttrListPosn posn; VImage design = NULL; ListInfo *linfo; VLong itr = 0; VFloat sigma = 0, tr = 0; int i, n, nimages; char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vcolorglm 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); } /* ** read design matrix */ fp = VOpenInputFile(filename, TRUE); list1 = VReadFile(fp, NULL); if(! list1) VError("Error reading design file"); fclose(fp); n = 0; for(VFirstAttr(list1, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & design); if(VPixelRepn(design) != VFloatRepn /* && VPixelRepn(design) != VDoubleRepn */) continue; n++; break; } if(n == 0) VError(" design matrix not found "); /* ** get pre-coloring info */ if(VGetAttr(VImageAttrList(design), "repetition_time", NULL, VLongRepn, &itr) != VAttrFound) VError(" TR info missing in header"); tr = (float) itr / 1000.0; sigma = 0; if(tr > 0.001 && fwhm > 0.001) { fprintf(stderr, " TR: %.3f seconds\n", tr); sigma = fwhm / 2.35482; sigma /= tr; if(sigma < 0.1) { VWarning(" 'fwhm/sigma' too small (%.3f / %.3f), will be set to zero", fwhm, sigma); sigma = 0; } } /* ** Read each input file */ nimages = in_files.number; linfo = (ListInfo *) VMalloc(sizeof(ListInfo) * nimages); for(i = 0; i < nimages; i++) { in_filename = ((VStringConst *) in_files.vector)[i]; ifilename = VNewString(in_filename); fprintf(stderr, " file: %s\n", ifilename); list = GetListInfo(ifilename, &linfo[i]); /* Create history */ if(i == 0) { history_list = VReadHistory(&list); if(history_list == NULL) history_list = VCreateAttrList(); VPrependHistory(VNumber(options), options, prg_name, &history_list); } } /* ** GLM */ out_list = VRegression(linfo, nimages, minval, design, sigma, itr); /* ** Output: */ VPrependAttr(out_list, "history", NULL, VAttrListRepn, history_list); f = VOpenOutputFile(out_filename, TRUE); if(!f) VError(" error opening outout file %s", out_filename); if(! VWriteFile(f, out_list)) exit(1); fprintf(stderr, "%s: done.\n", argv[0]); return 0; }