void EDIT_add_bricklist( THD_3dim_dataset *dset , int nbr, int *tbr, float *fbr , void *sbr[] ) { int ibr , typ , nx,ny,nz , nvals,new_nvals ; THD_datablock *dblk ; MRI_IMAGE *qim ; char str[32] ; ENTRY("EDIT_add_bricklist") ; /**-- Sanity Checks --**/ if( ! ISVALID_3DIM_DATASET(dset) || nbr <= 0 ) EXRETURN; /* error! */ if( dset->dblk->brick == NULL ) EXRETURN; /* error! */ if( dset->dblk->malloc_type != DATABLOCK_MEM_MALLOC )EXRETURN; /* error! */ dblk = dset->dblk ; nvals = dblk->nvals ; nx = dblk->diskptr->dimsizes[0] ; ny = dblk->diskptr->dimsizes[1] ; nz = dblk->diskptr->dimsizes[2] ; /**-- reallocate the brick control information --**/ new_nvals = nvals + nbr ; dblk->brick_bytes = (int64_t *) XtRealloc( (char *) dblk->brick_bytes , sizeof(int64_t) * new_nvals ) ; dblk->brick_fac = (float *) XtRealloc( (char *) dblk->brick_fac , sizeof(float) * new_nvals ) ; dblk->nvals = dblk->diskptr->nvals = new_nvals ; /** allocate new sub-brick images **/ for( ibr=0 ; ibr < nbr ; ibr++ ){ typ = (tbr != NULL ) ? tbr[ibr] : MRI_short ; qim = mri_new_vol_empty( nx,ny,nz , typ ) ; /* image with no data */ if( sbr != NULL && sbr[ibr] != NULL ) /* attach data to image */ mri_fix_data_pointer( sbr[ibr] , qim ) ; ADDTO_IMARR( dblk->brick , qim ) ; /* attach image to dset */ dblk->brick_fac[nvals+ibr] = (fbr != NULL) ? fbr[ibr] : 0.0 ; dblk->brick_bytes[nvals+ibr] = (int64_t)qim->pixel_size * (int64_t)qim->nvox ; dblk->total_bytes += dblk->brick_bytes[ibr] ; } /** allocate new sub-brick auxiliary data: labels **/ if( dblk->brick_lab == NULL ) THD_init_datablock_labels( dblk ) ; else dblk->brick_lab = (char **) XtRealloc( (char *) dblk->brick_lab , sizeof(char *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ){ sprintf( str , "#%d" , nvals+ibr ) ; dblk->brick_lab[nvals+ibr] = NULL ; THD_store_datablock_label( dblk , nvals+ibr , str ) ; } /** keywords **/ if( dblk->brick_keywords == NULL ) THD_init_datablock_keywords( dblk ) ; else dblk->brick_keywords = (char **) XtRealloc( (char *) dblk->brick_keywords , sizeof(char *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ){ dblk->brick_keywords[nvals+ibr] = NULL ; THD_store_datablock_keywords( dblk , nvals+ibr , NULL ) ; } /** stataux **/ if( dblk->brick_statcode != NULL ){ dblk->brick_statcode = (int *) XtRealloc( (char *) dblk->brick_statcode , sizeof(int) * new_nvals ) ; dblk->brick_stataux = (float **) XtRealloc( (char *) dblk->brick_stataux , sizeof(float *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ){ dblk->brick_statcode[nvals+ibr] = 0 ; dblk->brick_stataux[nvals+ibr] = NULL ; } } /** fdrcurve **/ if( dblk->brick_fdrcurve != NULL ){ dblk->brick_fdrcurve = (floatvec **) realloc( (void *)dblk->brick_fdrcurve , sizeof(floatvec *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ) dblk->brick_fdrcurve[nvals+ibr] = NULL ; } if( dblk->brick_mdfcurve != NULL ){ /* 22 Oct 2008 */ dblk->brick_mdfcurve = (floatvec **) realloc( (void *)dblk->brick_mdfcurve , sizeof(floatvec *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ) dblk->brick_mdfcurve[nvals+ibr] = NULL ; } EXRETURN; }
int THD_datablock_from_atr( THD_datablock *dblk, char *dirname, char *headname ) { THD_diskptr *dkptr ; ATR_int *atr_rank , *atr_dimen , *atr_scene , *atr_btype ; ATR_float *atr_flt ; ATR_string *atr_labs ; int ii , view_type , func_type , dset_type , nx,ny,nz,nvox , nvals , ibr,typ ; Boolean ok ; char prefix[THD_MAX_NAME]="Unknown" ; MRI_IMAGE *qim ; int brick_ccode ; char name[666] ; ENTRY("THD_datablock_from_atr") ; if( dblk == NULL || dblk->natr <= 0 ) RETURN(0) ; /* bad input */ dkptr = dblk->diskptr ; /*-- get relevant attributes: rank, dimensions, view_type & func_type --*/ atr_rank = THD_find_int_atr( dblk , ATRNAME_DATASET_RANK ) ; atr_dimen = THD_find_int_atr( dblk , ATRNAME_DATASET_DIMENSIONS ) ; atr_scene = THD_find_int_atr( dblk , ATRNAME_SCENE_TYPE ) ; /*-- missing an attribute ==> quit now --*/ if( atr_rank == NULL || atr_dimen == NULL || atr_scene == NULL ) RETURN(0) ; /*-- load type codes from SCENE attribute --*/ STATUS("loading *_type from SCENE") ; view_type = atr_scene->in[0] ; func_type = atr_scene->in[1] ; dset_type = atr_scene->in[2] ; /*-- load other values from attributes into relevant places --*/ ok = True ; nvox = 1 ; STATUS("loading from RANK") ; dkptr->rank = atr_rank->in[0] ; /* N.B.: rank isn't used much */ dkptr->nvals = dblk->nvals = nvals = atr_rank->in[1] ; /* but nvals is used */ STATUS("loading from DIMENSIONS") ; for( ii=0 ; ii < dkptr->rank ; ii++ ){ dkptr->dimsizes[ii] = atr_dimen->in[ii] ; ok = ( ok && dkptr->dimsizes[ii] >= 1 ) ; nvox *= dkptr->dimsizes[ii] ; } #if 0 if( PRINT_TRACING ){ char str[256] ; sprintf(str,"rank=%d nvals=%d dim[0]=%d dim[1]=%d dim[2]=%d nvox=%d", dkptr->rank , dkptr->nvals , dkptr->dimsizes[0] , dkptr->dimsizes[1] , dkptr->dimsizes[2] , nvox ) ; STATUS(str) ; } #endif if( !ok || nvals < 1 || dkptr->rank < THD_MIN_RANK || dkptr->rank > THD_MAX_RANK ){ STATUS("bad rank!!??") ; RETURN(0) ; } /*-- create the storage filenames --*/ STATUS("creating storage filenames") ; if( headname != NULL && strchr(headname,'+') != NULL ){ FILENAME_TO_PREFIX(headname,prefix) ; THD_init_diskptr_names( dkptr, dirname,NULL,prefix , view_type , True ) ; } else { if( headname != NULL ) MCW_strncpy(prefix,headname,THD_MAX_NAME) ; THD_init_diskptr_names( dkptr, dirname,NULL,prefix , view_type , True ) ; } /*-- determine if the BRIK file exists --*/ STATUS("checking if .BRIK file exists") ; brick_ccode = COMPRESS_filecode(dkptr->brick_name) ; if (dkptr->storage_mode == STORAGE_UNDEFINED) { /* ZSS: Oct. 2011 the next line was being called all the time before */ if( brick_ccode != COMPRESS_NOFILE ) dkptr->storage_mode = STORAGE_BY_BRICK ; /* a .BRIK file */ } /*-- if VOLUME_FILENAMES attribute exists, make it so [20 Jun 2002] --*/ if( headname != NULL && dkptr->storage_mode == STORAGE_UNDEFINED ){ atr_labs = THD_find_string_atr(dblk,"VOLUME_FILENAMES") ; if( atr_labs != NULL ){ dkptr->storage_mode = STORAGE_BY_VOLUMES ; dblk->malloc_type = DATABLOCK_MEM_MALLOC ; } } /*-- now set the memory allocation codes, etc. --*/ dblk->brick_fac = (float *) XtMalloc( sizeof(float) * nvals ) ; for( ibr=0 ; ibr < nvals ; ibr++ ) dblk->brick_fac[ibr] = 0.0 ; /* scaling factors from short type to float type, if nonzero */ if( !AFNI_yesenv("AFNI_IGNORE_BRICK_FLTFAC") ){ atr_flt = THD_find_float_atr( dblk , ATRNAME_BRICK_FLTFAC ) ; if( atr_flt != NULL ){ for( ibr=0 ; ibr < nvals && ibr < atr_flt->nfl ; ibr++ ) dblk->brick_fac[ibr] = atr_flt->fl[ibr] ; } } /** Now create an empty shell of the "brick" == the data structure that will hold all the voxel data. Note that all datablocks will have a brick, even if they never actually contain data themselves (are only warp-on-demand). If the BRICK_TYPES input attribute doesn't exist, then all sub-bricks are shorts. This makes the code work with old-style datasets, which were always made up of shorts. **/ atr_btype = THD_find_int_atr( dblk , ATRNAME_BRICK_TYPES ) ; if( atr_btype == NULL ){ THD_init_datablock_brick( dblk , MRI_short , NULL ) ; } else { THD_init_datablock_brick( dblk , atr_btype->nin , atr_btype->in ) ; } if( !THD_datum_constant(dblk) ){ /* 15 Sep 2004 */ fprintf(stderr, "\n** WARNING: File %s has mixed-type sub-bricks. ", MYHEAD ) ; } /* 25 April 1998: check if the byte order is stored inside */ atr_labs = THD_find_string_atr( dblk , ATRNAME_BYTEORDER ) ; if( atr_labs != NULL && atr_labs->nch > 0 ){ if( strncmp(atr_labs->ch,LSB_FIRST_STRING,ORDER_LEN) == 0 ) dkptr->byte_order = LSB_FIRST ; else if( strncmp(atr_labs->ch,MSB_FIRST_STRING,ORDER_LEN) == 0 ) dkptr->byte_order = MSB_FIRST ; else fprintf(stderr,"*** Unknown %s found in dataset %s\n", ATRNAME_BYTEORDER , MYHEAD ) ; } else if( !no_ordwarn && DBLK_BRICK_TYPE(dblk,0) != MRI_byte && dblk->diskptr->storage_mode == STORAGE_BY_BRICK ){ /* 20 Sep 1999 */ static int first=1 ; if( first ){ fprintf(stderr, "\n*** The situation below can be rectified with program '3drefit -byteorder':\n"); first = 0 ; } fprintf(stderr," ** Dataset %s: assuming byteorder %s\n", MYHEAD , BYTE_ORDER_STRING(dkptr->byte_order) ) ; } /* if the data is not on disk, the flag remains at DATABLOCK_MEM_UNDEFINED, otherwise the flag says how the memory for the bricks is to be created. */ if( dkptr->storage_mode == STORAGE_BY_BRICK ){ #if MMAP_THRESHOLD > 0 dblk->malloc_type = (dblk->total_bytes > MMAP_THRESHOLD) ? DATABLOCK_MEM_MMAP : DATABLOCK_MEM_MALLOC ; DBLK_mmapfix(dblk) ; /* 18 Mar 2005 */ #else dblk->malloc_type = DATABLOCK_MEM_MALLOC ; #endif /* must be malloc-ed if: data is compressed, data is not in native byte order, or user explicity forbids use of mmap */ if( brick_ccode >= 0 || dkptr->byte_order != native_order || no_mmap ) dblk->malloc_type = DATABLOCK_MEM_MALLOC ; } /* 30 Nov 1997: create the labels for sub-bricks */ THD_init_datablock_labels( dblk ) ; atr_labs = THD_find_string_atr( dblk , ATRNAME_BRICK_LABS ) ; if( atr_labs != NULL && atr_labs->nch > 0 ){ /* create labels from attribute */ int ipos = -1 , ipold , ngood ; for( ibr=0 ; ibr < nvals ; ibr++ ){ /* loop over bricks */ for( ipold = ipos++ ; /* skip to */ ipos < atr_labs->nch && atr_labs->ch[ipos] != '\0' ; /* next \0 */ ipos++ ) /* nada */ ; /* or end. */ ngood = ipos - ipold - 1 ; /* number of good chars */ if( ngood > 0 ){ XtFree(dblk->brick_lab[ibr]) ; /* 27 Oct 2011 - increase to 64 */ if( ngood > THD_MAX_SBLABEL ) ngood = THD_MAX_SBLABEL; dblk->brick_lab[ibr] = (char *) XtMalloc(sizeof(char)*(ngood+2)) ; memcpy( dblk->brick_lab[ibr] , atr_labs->ch+(ipold+1) , ngood ) ; dblk->brick_lab[ibr][ngood] = '\0' ; } if( ipos >= atr_labs->nch ) break ; /* nothing more to do */ } /* end of loop over sub-bricks */ } /* create the keywords for sub-bricks */ THD_init_datablock_keywords( dblk ) ; atr_labs = THD_find_string_atr( dblk , ATRNAME_BRICK_KEYWORDS ) ; if( atr_labs != NULL && atr_labs->nch > 0 ){ /* create keywords from attribute */ int ipos = -1 , ipold , ngood ; for( ibr=0 ; ibr < nvals ; ibr++ ){ /* loop over bricks */ for( ipold = ipos++ ; /* skip to */ ipos < atr_labs->nch && atr_labs->ch[ipos] != '\0' ; /* next \0 */ ipos++ ) /* nada */ ; /* or end. */ ngood = ipos - ipold - 1 ; /* number of good chars */ if( ngood > 0 ){ XtFree(dblk->brick_keywords[ibr]) ; dblk->brick_keywords[ibr] = (char *) XtMalloc(sizeof(char)*(ngood+2)) ; memcpy( dblk->brick_keywords[ibr] , atr_labs->ch+(ipold+1) , ngood ) ; dblk->brick_keywords[ibr][ngood] = '\0' ; } if( ipos >= atr_labs->nch ) break ; /* nothing more to do */ } /* end of loop over sub-bricks */ } /* create the auxiliary statistics stuff for each brick, if present */ atr_labs = THD_find_string_atr( dblk , "BRICK_STATSYM" ) ; /* 01 Jun 2005 */ if( atr_labs != NULL && atr_labs->nch > 0 ){ NI_str_array *sar ; int scode,np ; float parm[3] ; sar = NI_decode_string_list( atr_labs->ch , ";" ) ; if( sar != NULL && sar->num > 0 ){ for( ibr=0 ; ibr < nvals && ibr < sar->num ; ibr++ ){ NI_stat_decode( sar->str[ibr] , &scode , parm,parm+1,parm+2 ) ; if( scode >= AFNI_FIRST_STATCODE && scode <= AFNI_LAST_STATCODE ){ np = NI_stat_numparam(scode) ; THD_store_datablock_stataux( dblk , ibr,scode,np,parm ) ; } } NI_delete_str_array(sar) ; } } else { /*--- the olde way to get ye brick stataux parameters ---*/ atr_flt = THD_find_float_atr( dblk , ATRNAME_BRICK_STATAUX ) ; if( atr_flt != NULL && atr_flt->nfl >= 3 ){ int ipos=0 , iv,nv,jv ; /* attribute stores all stataux stuff as follows: sub-brick-index statcode no.-of-values value ... value sub-brick-index statcode no.-of-values value ... value, etc. */ while( ipos <= atr_flt->nfl - 3 ){ iv = (int) ( atr_flt->fl[ipos++] ) ; /* which sub-brick */ jv = (int) ( atr_flt->fl[ipos++] ) ; /* statcode */ nv = (int) ( atr_flt->fl[ipos++] ) ; /* # of values that follow */ if( nv > atr_flt->nfl - ipos ) nv = atr_flt->nfl - ipos ; THD_store_datablock_stataux( dblk , iv , jv , nv , atr_flt->fl + ipos ) ; ipos += nv ; } } } #if 0 if( PRINT_TRACING ){ char str[256] ; sprintf(str,"rank=%d nvals=%d dim[0]=%d dim[1]=%d dim[2]=%d", dkptr->rank , dkptr->nvals , dkptr->dimsizes[0] , dkptr->dimsizes[1] , dkptr->dimsizes[2] ) ; STATUS(str) ; } #endif /*-- FDR curves [23 Jan 2008] --*/ for( ibr=0 ; ibr < dblk->nvals ; ibr++ ){ sprintf(name,"FDRCURVE_%06d",ibr) ; atr_flt = THD_find_float_atr( dblk , name ) ; if( atr_flt != NULL && atr_flt->nfl > 3 ){ int nv = atr_flt->nfl - 2 ; floatvec *fv ; MAKE_floatvec(fv,nv) ; fv->x0 = atr_flt->fl[0] ; fv->dx = atr_flt->fl[1] ; memcpy( fv->ar , atr_flt->fl + 2 , sizeof(float)*nv ) ; if( dblk->brick_fdrcurve == NULL ) dblk->brick_fdrcurve = (floatvec **)calloc(sizeof(floatvec *),dblk->nvals); dblk->brick_fdrcurve[ibr] = fv ; } } for( ibr=0 ; ibr < dblk->nvals ; ibr++ ){ sprintf(name,"MDFCURVE_%06d",ibr) ; atr_flt = THD_find_float_atr( dblk , name ) ; if( atr_flt != NULL && atr_flt->nfl > 3 ){ int nv = atr_flt->nfl - 2 ; floatvec *fv ; MAKE_floatvec(fv,nv) ; fv->x0 = atr_flt->fl[0] ; fv->dx = atr_flt->fl[1] ; memcpy( fv->ar , atr_flt->fl + 2 , sizeof(float)*nv ) ; if( dblk->brick_mdfcurve == NULL ) dblk->brick_mdfcurve = (floatvec **)calloc(sizeof(floatvec *),dblk->nvals); dblk->brick_mdfcurve[ibr] = fv ; } } RETURN(1) ; }
void THD_datablock_apply_atr( THD_3dim_dataset *dset ) { THD_datablock *blk ; THD_diskptr *dkptr ; THD_dataxes *daxes ; ATR_int *atr_int = NULL ; ATR_float *atr_flt = NULL; ATR_string *atr_str = NULL ; int ii , view_type , func_type , dset_type , nx,ny,nz,nvox , nvals , ibr,typ ; Boolean ok ; char prefix[THD_MAX_NAME]="Unknown" ; MRI_IMAGE *qim ; int brick_ccode ; char name[666] ; ENTRY("THD_datablock_apply_atr") ; if( !ISVALID_DSET(dset) ) EXRETURN ; /* bad input */ blk = dset->dblk ; if( blk == NULL ) EXRETURN ; nvals = blk->nvals ; if( nvals <= 0 ) EXRETURN ; daxes = dset->daxes ; if( daxes == NULL ) EXRETURN ; dkptr = blk->diskptr ; /*-- brick labels --*/ if( ATR_IS_STR(ATRNAME_BRICK_LABS) ){ int ipos = -1 , ipold , ngood ; STATUS("brick labels") ; if( blk->brick_lab == NULL ) THD_init_datablock_labels( blk ) ; for( ibr=0 ; ibr < nvals ; ibr++ ){ /* loop over bricks */ for( ipold = ipos++ ; /* skip to */ ipos < atr_str->nch && atr_str->ch[ipos] != '\0' ; /* next \0 */ ipos++ ) /* nada */ ; /* or end. */ ngood = ipos - ipold - 1 ; /* number of good chars */ if( ngood > 0 ){ XtFree(blk->brick_lab[ibr]) ; if( ngood > THD_MAX_SBLABEL ) ngood = THD_MAX_SBLABEL ; blk->brick_lab[ibr] = (char *) XtMalloc(sizeof(char)*(ngood+2)) ; memcpy( blk->brick_lab[ibr] , atr_str->ch+(ipold+1) , ngood ) ; blk->brick_lab[ibr][ngood] = '\0' ; } if( ipos >= atr_str->nch ) break ; /* nothing more to do */ } /* end of loop over sub-bricks */ } /*-- keywords for the dataset itself --*/ if( ATR_IS_STR(ATRNAME_KEYWORDS) ){ STATUS("dataset keywords") ; dset->keywords = XtNewString( atr_str->ch ) ; } /*-- keywords for sub-bricks --*/ if( ATR_IS_STR(ATRNAME_BRICK_KEYWORDS) ){ int ipos = -1 , ipold , ngood ; STATUS("brick keywords") ; if( blk->brick_keywords == NULL ) THD_init_datablock_keywords( blk ) ; for( ibr=0 ; ibr < nvals ; ibr++ ){ /* loop over bricks */ for( ipold = ipos++ ; /* skip to */ ipos < atr_str->nch && atr_str->ch[ipos] != '\0' ; /* next \0 */ ipos++ ) /* nada */ ; /* or end. */ ngood = ipos - ipold - 1 ; /* number of good chars */ if( ngood > 0 ){ XtFree(blk->brick_keywords[ibr]) ; blk->brick_keywords[ibr] = (char *) XtMalloc(sizeof(char)*(ngood+2)) ; memcpy( blk->brick_keywords[ibr] , atr_str->ch+(ipold+1) , ngood ) ; blk->brick_keywords[ibr][ngood] = '\0' ; } if( ipos >= atr_str->nch ) break ; /* nothing more to do */ } /* end of loop over sub-bricks */ } /*-- auxiliary statistics stuff for each brick --*/ if( ATR_IS_FLT(ATRNAME_BRICK_STATAUX) ){ int ipos=0 , iv,nv,jv ; STATUS("brick stataux") ; /* attribute stores all stataux stuff as follows: sub-brick-index statcode no.-of-values value ... value sub-brick-index statcode no.-of-values value ... value, etc. */ while( ipos <= atr_flt->nfl - 3 ){ iv = (int) ( atr_flt->fl[ipos++] ) ; /* which sub-brick */ jv = (int) ( atr_flt->fl[ipos++] ) ; /* statcode */ nv = (int) ( atr_flt->fl[ipos++] ) ; /* # of values that follow */ if( nv > atr_flt->nfl - ipos ) nv = atr_flt->nfl - ipos ; THD_store_datablock_stataux( blk , iv , jv , nv , atr_flt->fl + ipos ) ; ipos += nv ; } } /*-- FDR curves [23 Jan 2008] --*/ for( ibr=0 ; ibr < blk->nvals ; ibr++ ){ sprintf(name,"FDRCURVE_%06d",ibr) ; atr_flt = THD_find_float_atr( blk , name ) ; if( atr_flt != NULL && atr_flt->nfl > 3 ){ int nv = atr_flt->nfl - 2 ; floatvec *fv ; MAKE_floatvec(fv,nv) ; fv->x0 = atr_flt->fl[0] ; fv->dx = atr_flt->fl[1] ; memcpy( fv->ar , atr_flt->fl + 2 , sizeof(float)*nv ) ; if( blk->brick_fdrcurve == NULL ) blk->brick_fdrcurve = (floatvec **)calloc(sizeof(floatvec *),blk->nvals); blk->brick_fdrcurve[ibr] = fv ; } } for( ibr=0 ; ibr < blk->nvals ; ibr++ ){ sprintf(name,"MDFCURVE_%06d",ibr) ; atr_flt = THD_find_float_atr( blk , name ) ; if( atr_flt != NULL && atr_flt->nfl > 3 ){ int nv = atr_flt->nfl - 2 ; floatvec *fv ; MAKE_floatvec(fv,nv) ; fv->x0 = atr_flt->fl[0] ; fv->dx = atr_flt->fl[1] ; memcpy( fv->ar , atr_flt->fl + 2 , sizeof(float)*nv ) ; if( blk->brick_mdfcurve == NULL ) blk->brick_mdfcurve = (floatvec **)calloc(sizeof(floatvec *),blk->nvals); blk->brick_mdfcurve[ibr] = fv ; } } /*-- ID codes --*/ if( ATR_IS_STR(ATRNAME_IDSTRING) ) MCW_strncpy( dset->idcode.str , atr_str->ch , MCW_IDSIZE ) ; if( ATR_IS_STR(ATRNAME_IDDATE) ) MCW_strncpy( dset->idcode.date , atr_str->ch , MCW_IDDATE ) ; if( ATR_IS_STR(ATRNAME_IDANATPAR) ) MCW_strncpy( dset->anat_parent_idcode.str , atr_str->ch , MCW_IDSIZE ) ; if( ATR_IS_STR(ATRNAME_IDWARPPAR) ) MCW_strncpy( dset->warp_parent_idcode.str , atr_str->ch , MCW_IDSIZE ) ; /*-- parent names --*/ if( ATR_IS_STR(ATRNAME_ANATOMY_PARENT) && ISZERO_IDCODE(dset->anat_parent_idcode) ) MCW_strncpy( dset->anat_parent_name , atr_str->ch , THD_MAX_NAME ) ; if( ATR_IS_STR(ATRNAME_WARP_PARENT) && ISZERO_IDCODE(dset->warp_parent_idcode) ) MCW_strncpy( dset->warp_parent_name , atr_str->ch , THD_MAX_NAME ) ; if( ATR_IS_STR(ATRNAME_DATANAME) ) MCW_strncpy( dset->self_name , atr_str->ch , THD_MAX_NAME ) ; /*-- markers --*/ if( ATR_IS_FLT(ATRNAME_MARKSXYZ) && ATR_IS_STR(ATRNAME_MARKSLAB) ){ int im , llen ; THD_ivec3 iv ; float xxdown,xxup , yydown,yyup , zzdown,zzup ; STATUS("markers") ; if( dset->markers == NULL ){ dset->markers = myXtNew( THD_marker_set ) ; /* new set */ ADDTO_KILL(dset->kl , dset->markers) ; } COPY_INTO_STRUCT( *(dset->markers) , /* actual struct */ MARKS_FSTART , /* byte offset */ float , /* type being copied */ atr_flt->fl , /* start of source */ MARKS_FSIZE ) ; /* number of floats */ COPY_INTO_STRUCT( *(dset->markers) , MARKS_LSTART , char , atr_str->ch , MARKS_LSIZE ) ; xxdown = daxes->xxmin ; xxup = daxes->xxmax ; yydown = daxes->yymin ; yyup = daxes->yymax ; zzdown = daxes->zzmin ; zzup = daxes->zzmax ; dset->markers->numdef = dset->markers->numset = 0 ; for( im=0 ; im < MARKS_MAXNUM ; im++ ){ llen = strlen( &(dset->markers->label[im][0]) ) ; dset->markers->valid[im] = (llen > 0) && ( dset->markers->xyz[im][0] >= xxdown ) && ( dset->markers->xyz[im][0] <= xxup ) && ( dset->markers->xyz[im][1] >= yydown ) && ( dset->markers->xyz[im][1] <= yyup ) && ( dset->markers->xyz[im][2] >= zzdown ) && ( dset->markers->xyz[im][2] <= zzup ) ; if( dset->markers->valid[im] ) (dset->markers->numset)++ ; if( llen > 0 ) (dset->markers->numdef)++ ; dset->markers->ovcolor[im] = -1 ; /* default color */ } if( ATR_IS_STR(ATRNAME_MARKSHELP) ){ COPY_INTO_STRUCT( *(dset->markers) , MARKS_HSTART , char , atr_str->ch , MARKS_HSIZE ) ; } else { for( im=0 ; im < MARKS_MAXNUM ; im++ ) /* no help */
THD_3dim_dataset * MAKER_4D_to_typed_fbuc( THD_3dim_dataset * old_dset , char * new_prefix , int new_datum , int ignore , int detrend , int nbrik , generic_func * user_func , void * user_data , byte *mmm, int nscale) { THD_3dim_dataset * new_dset ; /* output dataset */ byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ complex ** cptr = NULL ; float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of input brick scaling factors */ float ** fout = NULL ; /* will be arrays of output floats */ float * dtr = NULL ; /* will be array of detrending coeff */ float * val = NULL ; /* will be array of output values */ float d0fac , d1fac , x0,x1; double tzero=0 , tdelta , ts_mean , ts_slope ; int ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox , iv ; register int kk ; int nbad=0 ; /* 08 Aug 2000 */ void (*ufunc)(double,double,int,float *,double,double,void *,int,float *) = (void (*)(double,double,int,float *,double,double,void *,int,float *)) user_func; /*----------------------------------------------------------*/ /*----- Check inputs to see if they are reasonable-ish -----*/ if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ; if( new_datum >= 0 && new_datum != MRI_byte && new_datum != MRI_short && new_datum != MRI_float ) return NULL ; if( user_func == NULL ) return NULL ; if( nbrik <= 0 ) return NULL ; if( ignore < 0 ) ignore = 0 ; /*--------- set up pointers to each sub-brick in the input dataset ---------*/ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum */ nuse = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */ /* maybe allow nuse == 1 2 Nov 2010 [rickr] */ if( nuse < 1 ) return NULL ; if( nuse == 1 && ! g_thd_maker_allow_1brick ) return NULL ; g_thd_maker_allow_1brick = 0; /* and beware repeat calls from plugins */ if( new_datum < 0 ) new_datum = old_datum ; /* output datum = input */ if( new_datum == MRI_complex ) return NULL ; /* but complex = bad news */ DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ kk = THD_count_databricks( old_dset->dblk ) ; /* check if it was */ if( kk < DSET_NVALS(old_dset) ){ /* loaded correctly */ DSET_unload( old_dset ) ; return NULL ; } switch( old_datum ){ /* pointer type depends on input datum type */ default: /** don't know what to do **/ DSET_unload( old_dset ) ; return NULL ; /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is complex ---------*/ /* voxel #i at time #k is cptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_complex: cptr = (complex **) malloc( sizeof(complex *) * nuse ) ; if( cptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ; break ; } /* end of switch on input type */ /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * nuse ) ; /* voxel timeseries */ if( fxar == NULL ){ FREE_WORKSPACE ; return NULL ; } /*--- get scaling factors for input sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * nuse ) ; /* factors */ if( fac == NULL ){ FREE_WORKSPACE ; return NULL ; } use_fac = 0 ; for( kk=0 ; kk < nuse ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ) FREEUP(fac) ; /*--- setup for detrending ---*/ dtr = (float *) malloc( sizeof(float) * nuse ) ; if( dtr == NULL ){ FREE_WORKSPACE ; return NULL ; } d0fac = 1.0 / nuse ; d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ; for( kk=0 ; kk < nuse ; kk++ ) dtr[kk] = kk - 0.5 * (nuse-1) ; /* linear trend, orthogonal to 1 */ /*---------------------- make a new dataset ----------------------*/ new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */ /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , nbrik , /* # sub-bricks */ ADN_ntt , 0 , /* # time points */ ADN_type , ISHEAD(old_dset) /* dataset type */ ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_BUCK_TYPE , /* function type */ ADN_none ) ; if( ii != 0 ){ ERROR_message("Error creating dataset '%s'",new_prefix) ; THD_delete_3dim_dataset( new_dset , False ) ; /* some error above */ FREE_WORKSPACE ; return NULL ; } THD_init_datablock_labels( new_dset->dblk ) ; THD_init_datablock_keywords( new_dset->dblk ) ; THD_init_datablock_stataux( new_dset->dblk ) ; /*------ make floating point output bricks (only at the end will scale to byte or shorts) ------*/ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; fout = (float **) malloc( sizeof(float *) * nbrik ) ; if( fout == NULL ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return NULL ; } for( iv=0 ; iv < nbrik ; iv++ ) fout[iv] = NULL ; for( iv=0 ; iv < nbrik ; iv++ ){ fout[iv] = (float *) malloc( sizeof(float) * nvox ) ; if( fout[iv] == NULL ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return NULL ; } } /*-- floating point storage for output from 1 voxel --*/ val = (float *) malloc( sizeof(float) * nbrik ) ; if( val == NULL ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return NULL ; } /*----- set up to find time at each voxel -----*/ tdelta = old_dset->taxis->ttdel ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ; if( tdelta == 0.0 ) tdelta = 1.0 ; izold = -666 ; nxy = old_dset->daxes->nxx * old_dset->daxes->nyy ; /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /* start notification */ #if 0 user_func( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , nbrik , NULL ) ; #else ufunc( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , nbrik , NULL ) ; #endif /***** loop over voxels *****/ for( ii=0 ; ii < nvox ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ /*** input = bytes ***/ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; /*** input = shorts ***/ case MRI_short: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; /*** input = floats ***/ case MRI_float: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; /*** input = complex (note we use absolute value) ***/ case MRI_complex: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ; break ; } /* end of switch over input type */ /*** scale? ***/ if( use_fac ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ; /** compute mean and slope **/ x0 = x1 = 0.0 ; for( kk=0 ; kk < nuse ; kk++ ){ x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ; } x0 *= d0fac ; x1 *= d1fac ; /* factors to remove mean and trend */ ts_mean = x0 ; ts_slope = x1 / tdelta ; /** detrend? **/ if( detrend ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ; /** compute start time of this timeseries **/ iz = ii / nxy ; /* which slice am I in? */ if( iz != izold ){ /* in a new slice? */ tzero = THD_timeof( ignore , old_dset->daxes->zzorg + iz*old_dset->daxes->zzdel , old_dset->taxis ) ; izold = iz ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ; } /*** compute output ***/ for( iv=0 ; iv < nbrik ; iv++ ) val[iv] = 0.0 ; if (!mmm || mmm[ii]) { /* not the most efficient place to mask, but it is the least obtrusive */ #if 0 user_func( tzero,tdelta, nuse,fxar,ts_mean,ts_slope, user_data, nbrik,val ); #else ufunc( tzero,tdelta, nuse,fxar,ts_mean,ts_slope, user_data, nbrik,val ); #endif } for( iv=0 ; iv < nbrik ; iv++ ) fout[iv][ii] = val[iv] ; } /* end of outer loop over 1 voxels at a time */ DSET_unload( old_dset ) ; /* don't need this no more */ /* end notification */ #if 0 user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , nbrik , NULL ) ; #else ufunc( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , nbrik , NULL ) ; #endif /*---- Count and correct float errors ----*/ for( iv=0 ; iv < nbrik ; iv++ ) nbad += thd_floatscan( nvox, fout[iv] ) ; if( nbad > 0 ) fprintf(stderr, "++ Warning: %d bad floats computed in MAKER_4D_to_typed_fbuc\n\a", nbad ) ; /*------------------------------------------------------------------------*/ /*------- The output is now in fout[iv][ii], iv=0..nbrik-1, ii=0..nvox-1. We must now put this into the output dataset. ------------------*/ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout brick to the dataset ***/ case MRI_float: for( iv=0 ; iv < nbrik ; iv++ ){ EDIT_substitute_brick( new_dset , iv , MRI_float , fout[iv] ) ; fout[iv] = NULL ; /* so it won't be freed later */ } break ; /*** output is shorts: we have to create scaled sub-bricks from fout ***/ case MRI_short:{ short * bout ; float sfac ; for( iv=0 ; iv < nbrik ; iv++ ){ bout = (short *) malloc( sizeof(short) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fbuc - is memory exhausted?\n\a"); EXIT(1) ; } if (nscale) { sfac = 0.0; EDIT_coerce_type( nvox, MRI_float, fout[iv] , MRI_short, bout ) ; } else { sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout[iv] ) ; if( sfac > 0.0 ){ sfac = 32767.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout[iv] , MRI_short,bout ) ; sfac = 1.0 / sfac ; } } val[iv] = sfac ; EDIT_substitute_brick( new_dset , iv , MRI_short , bout ) ; } EDIT_dset_items( new_dset , ADN_brick_fac , val , ADN_none ) ; } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * bout ; float sfac ; for( iv=0 ; iv < nbrik ; iv++ ){ bout = (byte *) malloc( sizeof(byte) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fbuc - is memory exhausted?\n\a"); EXIT(1) ; } if (nscale) { sfac = 0.0; EDIT_coerce_type( nvox, MRI_float, fout[iv] , MRI_byte, bout ) ; } else { sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout[iv] ) ; if( sfac > 0.0 ){ sfac = 255.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout[iv] , MRI_byte,bout ) ; sfac = 1.0 / sfac ; } } val[iv] = sfac ; EDIT_substitute_brick( new_dset , iv , MRI_byte , bout ) ; } EDIT_dset_items( new_dset , ADN_brick_fac , val , ADN_none ) ; } break ; } /* end of switch on output data type */ /*-------------- Cleanup and go home ----------------*/ FREE_WORKSPACE ; return new_dset ; }