Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

3ddata.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 /*! \file
00008    This file contains the definition of the structs, macros, etc. for AFNI datasets.
00009 */
00010 
00011 #ifndef _MCW_3DDATASET_
00012 #define _MCW_3DDATASET_
00013 
00014 /**                                  yyyy-mm-dd  **/
00015 #define DSET_VERSION_LATEST         "1996-07-10"
00016 #define DSET_VERSION_COMPARE(v1,v2) strcmp(v1,v2)
00017 
00018 /** #include <dirent.h> **/
00019 #include <unistd.h>
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <math.h>
00024 #include <errno.h>
00025 #include <ctype.h>
00026 
00027 #include <X11/Intrinsic.h>
00028 
00029 #include "mcw_malloc.h"
00030 
00031 #include "killer.h"
00032 #include "vecmat.h"
00033 #include "machdep.h"
00034 #include "mrilib.h"
00035 #include "tagset.h"
00036 
00037 #include "thd_compress.h"
00038 
00039 #ifndef myXtFree
00040 /*! Macro to free a pointer and NULL-ize it as well. */
00041 #define myXtFree(xp) (XtFree((char *)(xp)) , (xp)=NULL)
00042 #endif
00043 
00044 #ifndef myXtNew
00045 /*! Macro to allocate memory and zero-ize it. */
00046 #define myXtNew(type) ((type *) XtCalloc(1,(unsigned) sizeof(type)))
00047 #endif
00048 
00049 struct THD_3dim_dataset ;  /* incomplete definition */
00050 
00051 #include "niml.h"          /* NIML */
00052 #include "afni_suma.h"     /* SUrface MApper */
00053 
00054 /*! Enables compilation of the MINC dataset code. */
00055 
00056 #define ALLOW_MINC   /* 29 Oct 2001 */
00057 
00058 /*! Macro to check if string ss ends in string suf. */
00059 
00060 #define STRING_HAS_SUFFIX(ss,suf)              \
00061   ((ss != NULL) && (suf != NULL) &&            \
00062    (strlen(ss) >= strlen(suf))   &&            \
00063    (strcmp(ss+strlen(ss)-strlen(suf),suf) == 0))
00064 
00065 /***************************** dimensions ***************************/
00066 
00067 /*! Max length of a "name" of a file, or stuff like that. */
00068 
00069 #define THD_MAX_NAME      256
00070 
00071 /*! Max length of a dataset label. */
00072 
00073 #define THD_MAX_LABEL     38
00074 
00075 /*! Max length of a dataset prefix. */
00076 
00077 #define THD_MAX_PREFIX     (127+1)  /* must be more than THD_MAX_LABEL */
00078 
00079 /*! Max length of a dataset view code (+orig, etc). */
00080 
00081 #define THD_MAX_VIEWCODE   (4+1)
00082 
00083 /*! Max length of a dataset suffix (BRIK, etc). */
00084 
00085 #define THD_MAX_SUFFIX     (4+1)
00086 
00087 /*! Max length of a dataset filecode (prefix+view). */
00088 
00089 #define THD_MAX_FILECODE   (THD_MAX_PREFIX+THD_MAX_VIEWCODE)
00090 
00091 /*! Default label for a dataset.
00092 
00093     Labels aren't really used anymore, since the stupid users didn't like them
00094 */
00095 #define THD_DEFAULT_LABEL "Viggo!"
00096 
00097 /*! Max num datasets per session. */
00098 
00099 #define THD_MAX_SESSION_SIZE  4096
00100 
00101 /*! Max number of directories. */
00102 
00103 #define THD_MAX_NUM_SESSION    80
00104 
00105 #define THD_MAX_CHOICES THD_MAX_SESSION_SIZE
00106 
00107 #define THD_MAX_MARKSET       5
00108 
00109 #define FAIL    -1
00110 #define SUCCESS  1
00111 
00112 /*! General "type code" for invalid data.
00113 
00114     Various things are labeled with non-negative type codes (e.g., statistics types).
00115     Negative type codes indicate something is not valid.
00116 */
00117 
00118 #define ILLEGAL_TYPE -666
00119 
00120 /***************  generic function with no return value  **********************/
00121 
00122 /*! Generic function type returning void. */
00123 
00124 typedef void generic_func() ;
00125 
00126 /*! Generic function type returning float. */
00127 
00128 typedef float float_func() ;
00129 
00130 /*! Stores a list of "registered" functions (e.g., "Transforms") */
00131 
00132 typedef struct {
00133    int num ;                     /*!< number of functions */
00134    int * flags ;                 /*!< flags[i] = bitmask flag for function #i */
00135    char ** labels ;              /*!< labels[i] = string name for function #i */
00136    generic_func ** funcs ;       /*!< funcs[i] = function #i */
00137 
00138    void ** func_data ;           /*!< 30 Jan 2000 */
00139    int *   func_code ;
00140 
00141    generic_func ** func_init ;   /*!< 21 Jul 2003 */
00142 } MCW_function_list ;
00143 
00144 /*! MCW_function_list possible bitmask flag */
00145 #define RETURNS_STRING    1
00146 
00147 /*! MCW_function_list possible bitmask flag */
00148 #define NEEDS_DSET_INDEX  2
00149 
00150 /*! MCW_function_list possible bitmask flag */
00151 #define PROCESS_MRI_IMAGE 4
00152 
00153 /*! MCW_function_list possible func_code */
00154 #define FUNC_0D   0
00155 /*! MCW_function_list possible func_code */
00156 #define FUNC_1D   1
00157 /*! MCW_function_list possible func_code */
00158 #define FUNC_2D   2
00159 /*! MCW_function_list possible func_code */
00160 #define FUNC_3D   3
00161 
00162 /*! MCW_function_list possible func_code */
00163 #define FUNC_FIM  71
00164 
00165 /******************************** macros ******************************/
00166 
00167 /*! First part of TWO_TWO macro. */
00168 
00169 #define TWO_ONE(x,y) x ## y
00170 
00171 /*! Combine two interpreted tokens into one using TWO_TWO. */
00172 
00173 #define TWO_TWO(x,y) TWO_ONE(x,y)
00174 
00175 /*! Copy n units of the given type "type * ptr", into a structure "str",
00176      starting at byte offset "off";
00177    N.B.: str is the structure itself, not a pointer to it
00178          off is most easily computed with XtOffsetOf       */
00179 
00180 #define COPY_INTO_STRUCT(str,off,type,ptr,n) \
00181    (void) memcpy( (char *)(&(str))+(off), (char *)(ptr), (n)*sizeof(type) )
00182 
00183 /*! Copy n units of the given type "type * ptr", from a structure "str",
00184      starting at byte offset "off";
00185    N.B.: str is the structure itself, not a pointer to it
00186          off is most easily computed with XtOffsetOf       */
00187 
00188 #define COPY_FROM_STRUCT(str,off,type,ptr,n) \
00189    (void) memcpy( (char *)(ptr), (char *)(&(str))+(off), (n)*sizeof(type) )
00190 
00191 /*! Safe version of strncpy, which always leaves a NUL at the end.
00192 
00193     The standard stupid strncpy(dest,src,n) might not leave a NUL character
00194     at the end if the src string is too long.  This criminal behavior is
00195     reformed by this macro.
00196 */
00197 
00198 #ifndef MCW_strncpy
00199 #define MCW_strncpy(dest,src,n) \
00200    ( (void) strncpy( (dest) , (src) , (n)-1 ) , (dest)[(n)-1] = '\0' )
00201 #endif
00202 
00203 /*********************** dynamic array of XtPointers **********************/
00204 
00205 #define IC_DSET 44301
00206 #define IC_FLIM 55402
00207 
00208 /*! Dynamically extendable array of XtPointer. */
00209 
00210 typedef struct {
00211       int num ;          /*!< Number currently in use */
00212       int nall ;         /*!< Number currently allocated */
00213       XtPointer * ar ;   /*!< Array of pointers: [0..num-1] are valid */
00214       int * ic ;         /*!< added 26 Mar 2001 */
00215 } XtPointer_array ;
00216 
00217 /*! Increment for extending XtPointer_array allocation */
00218 
00219 #define INC_XTARR 8
00220 
00221 /*! Initialize dynamic XtPointer array named "name".
00222 
00223     You must declare "XtPointer_array *name;".
00224 */
00225 #define INIT_XTARR(name)               \
00226    ( (name) = XtNew(XtPointer_array) , \
00227      (name)->num = (name)->nall = 0 ,  \
00228      (name)->ar  = NULL ,              \
00229      (name)->ic  = NULL   )
00230 
00231 /*! Add a pointer to a dynamic XtPointer array. */
00232 
00233 #define ADDTO_XTARR(name,bblk)                                 \
00234    { if( (name)->num == (name)->nall ){                        \
00235       (name)->nall += INC_XTARR ;                              \
00236       (name)->ar    = (XtPointer *)                            \
00237                        XtRealloc( (char *) (name)->ar ,        \
00238                           sizeof(XtPointer) * (name)->nall ) ; \
00239       (name)->ic    = (int *) XtRealloc( (char *) (name)->ic , \
00240                           sizeof(int) * (name)->nall ) ;       \
00241      }                                                         \
00242      if( (XtPointer) (bblk) != NULL ){               \
00243       (name)->ar[(name)->num] = (XtPointer) (bblk) ; \
00244       (name)->ic[(name)->num] = 0                  ; \
00245       ((name)->num)++ ;                              \
00246      } }
00247 
00248 /*! Number of good entries in a dynamic XtPointer array. */
00249 
00250 #define XTARR_NUM(name)  ((name)->num)
00251 
00252 /*! i-th entry in a dynamic XtPointer array. */
00253 
00254 #define XTARR_XT(name,i) ((name)->ar[i])
00255 
00256 #define XTARR_IC(name,i) ((name)->ic[i])
00257 
00258 /*! Free a dynamic XtPointer array.
00259 
00260     But not what the pointers point to - that is a completely separate matter.
00261 */
00262 
00263 #define FREE_XTARR(name)      \
00264    if( (name) != NULL ){      \
00265      myXtFree( (name)->ar ) ; \
00266      myXtFree( (name)->ic ) ; \
00267      myXtFree( (name) ) ;     \
00268      (name) = NULL ; }
00269 
00270 /*! Duplicate definition for FREE_XTARR */
00271 #define DESTROY_XTARR  FREE_XTARR
00272 
00273 /************************* string array stuff *************************/
00274 
00275 /*! Dynamic array of character strings. */
00276 
00277 typedef struct {
00278       int num ;      /*!< Number of strings currently stored */
00279       int nall ;     /*!< Number of strings space is set aside for */
00280       char ** ar ;   /*!< Array of pointers to strings */
00281       KILL_list kl ; /*!< For semi-automatic memory cleanup */
00282 } THD_string_array ;
00283 
00284 /*! Return pointer to qq-th string in dynamic string array ss. */
00285 
00286 #define SARR_STRING(ss,qq) ((ss)->ar[(qq)])
00287 
00288 /*! Return number of strings stored in dynamic string array ss. */
00289 
00290 #define SARR_NUM(ss)       ((ss)->num)
00291 
00292 #define INC_SARR 64
00293 
00294 /*! Initialize an empty dynamic string array named "name".
00295 
00296     You must declare "THD_string_array *name;".
00297 */
00298 
00299 #define INIT_SARR(name)                 \
00300    ( (name) = XtNew(THD_string_array) , \
00301      (name)->num = (name)->nall = 0 ,   \
00302      (name)->ar  = NULL ,               \
00303      INIT_KILL((name)->kl) )
00304 
00305 /*! Add string str to dynamic string array "name". */
00306 
00307 #define ADDTO_SARR(name,str)                                          \
00308  do{ if( (name)->num == (name)->nall ){                               \
00309       (name)->nall += INC_SARR ;                                      \
00310       (name)->ar    = (char **) XtRealloc( (char *) (name)->ar ,      \
00311                                  sizeof(char *) * (name)->nall ) ;    \
00312      }                                                                \
00313      if( (str) != NULL ){                                             \
00314       (name)->ar[(name)->num] = (char *) XtMalloc( strlen((str))+1 ) ;\
00315       strcpy( (name)->ar[(name)->num] , (str) ) ;                     \
00316       ADDTO_KILL((name)->kl,(name)->ar[(name)->num]) ;                \
00317       ((name)->num)++ ;                                               \
00318      } } while(0)
00319 
00320 /*! Remove the ijk-th string from dynamic string array "name". */
00321 
00322 #define REMOVEFROM_SARR(name,ijk)                \
00323  do{ SINGLE_KILL((name)->kl,(name)->ar[(ijk)]) ; \
00324      (name)->ar[(ijk)] = NULL ; } while(0)
00325 
00326 /*! Kill all entries in the dynamic string array "name". */
00327 
00328 #define DESTROY_SARR(name)    \
00329  do{ if( (name) != NULL ){    \
00330      KILL_KILL((name)->kl) ;  \
00331      myXtFree( (name)->ar ) ; \
00332      myXtFree( (name) ) ; } } while(0)
00333 
00334 extern int SARR_find_string( THD_string_array * sar , char * str ) ;
00335 extern int SARR_find_substring( THD_string_array * sar , char * sub ) ;
00336 
00337 extern int SARR_lookfor_string   ( THD_string_array * sar , char * str , int nstart ) ;
00338 extern int SARR_lookfor_substring( THD_string_array * sar , char * sub , int nstart ) ;
00339 
00340 /*! Concatenate strings p1 and p2 into string pout, making them a filesystem path.
00341 
00342     If p1 doesn't end in a '/', the '/' between p1/p2 will be added.
00343     The pout array must be previously allocated.
00344 */
00345 
00346 #define PATH_CONCAT(pout,p1,p2)                            \
00347   do{ int zq ; strcpy((pout),(p1)) ; zq = strlen((pout)) ; \
00348       if( (pout)[zq-1] != '/' ) strcat((pout),"/") ;       \
00349       strcat((pout),(p2)) ; } while(0)
00350 
00351 /*************** dynamic array of sorted (x,y,z) points *************/
00352 
00353 #undef  ALLOW_DATASET_VLIST
00354 #ifdef  ALLOW_DATASET_VLIST
00355 
00356 /*! Dynamic array of xyz and ijk points. */
00357 
00358 typedef struct {
00359       int num ;                          /*!< Number of points currently in use */
00360       int nall ;                         /*!< Number of points currently allocated */
00361       THD_fvec3 * xyz ;                  /*!< Array of xyz coordinates in parent */
00362       THD_ivec3 * ijk ;                  /*!< Array of ijk indexes in parent */
00363       struct THD_3dim_dataset * parent ; /*!< Dataset these things come from */
00364 } THD_vector_list ;
00365 
00366 #define INC_VLIST 64
00367 
00368 /*! Initialize a dynamic array of xyz points, attached to datset ddd. */
00369 
00370 #define INIT_VLIST(name,ddd) \
00371    ( (name) = XtNew(THD_vector_list) ,  \
00372      (name)->num = (name)->nall = 0 ,   \
00373      (name)->xyz = NULL , (name)->ijk = NULL , \
00374      (name)->parent = (ddd) )
00375 
00376 /*! Add 1 xyz-vector to the array of xyz points.
00377 
00378     The ijk-vector will be converted from the xyz coordinates,
00379     using the parent dataset for this array.
00380 */
00381 
00382 #define ADD_FVEC_TO_VLIST(name,vec) \
00383    { if( (name)->num == (name)->nall ){                                    \
00384       (name)->nall += INC_VLIST ;                                          \
00385       (name)->xyz   = (THD_fvec3 * ) XtRealloc( (char *) (name)->xyz ,     \
00386                                       sizeof(THD_fvec3) * (name)->nall ) ; \
00387       (name)->ijk   = (THD_ivec3 * ) XtRealloc( (char *) (name)->ijk ,     \
00388                                       sizeof(THD_ivec3) * (name)->nall ) ; \
00389      }                                                                     \
00390      (name)->xyz[(name)->num] = (vec);                                     \
00391      (name)->ijk[(name)->num] = THD_3dmm_to_3dind((name)->parent,(vec)) ;  \
00392      ((name)->num)++; }
00393 
00394 /*! Add one ijk-vector to the array of xyz points.
00395 
00396     The xyz-vector will be converted from the ijk indexes, using
00397     the parent dataset for this array.
00398 */
00399 
00400 #define ADD_IVEC_TO_VLIST(name,vec) \
00401    { if( (name)->num == (name)->nall ){                                    \
00402       (name)->nall += INC_VLIST ;                                          \
00403       (name)->xyz   = (THD_fvec3 * ) XtRealloc( (char *) (name)->xyz ,     \
00404                                       sizeof(THD_fvec3) * (name)->nall ) ; \
00405       (name)->ijk   = (THD_ivec3 * ) XtRealloc( (char *) (name)->ijk ,     \
00406                                       sizeof(THD_ivec3) * (name)->nall ) ; \
00407      }                                                                     \
00408      (name)->ijk[(name)->num] = (vec);                                     \
00409      (name)->xyz[(name)->num] = THD_3dind_to_3dmm((name)->parent,(vec)) ;  \
00410      ((name)->num)++; }
00411 
00412 /*! Destroy an array of xyz points. */
00413 
00414 #define DESTROY_VLIST(name)      \
00415    { if( (name) != NULL ){       \
00416        myXtFree( (name)->xyz ) ; \
00417        myXtFree( (name)->ijk ) ; \
00418        myXtFree( (name) ) ; } }
00419 
00420 #endif /* ALLOW_DATASET_VLIST */
00421 
00422 /**************************** typedefs ******************************/
00423 
00424 /*---------- structure to hold attributes from disk files ----------*/
00425 
00426 #define ATR_STRING_TYPE   0
00427 #define ATR_FLOAT_TYPE    1
00428 #define ATR_INT_TYPE      2
00429 
00430 #define FIRST_ATR_TYPE 0
00431 #define LAST_ATR_TYPE  2
00432 
00433 /*! Things to look for in the .HEAD file; these define start of an attribute. */
00434 
00435 static char * ATR_typestr[] = {
00436    "string-attribute" , "float-attribute" , "integer-attribute"
00437 } ;
00438 
00439 /*! Stores an integer-attribute (array of ints). */
00440 
00441 typedef struct {
00442       int    type ;   /*!< should be ATR_INT_TYPE */
00443       char * name ;   /*!< name of attribute, read from HEAD file */
00444       int    nin ;    /*!< number of ints stored here */
00445       int  * in ;     /*!< array of ints stored here */
00446 } ATR_int ;
00447 
00448 /*! Stores a float-attribute (array of floats). */
00449 
00450 typedef struct {
00451       int     type ;  /*!< should be ATR_FLOAT_TYPE */
00452       char *  name ;  /*!< name of attribute, read from HEAD file */
00453       int     nfl ;   /*!< number of floats stored here */
00454       float * fl ;    /*!< array of floats stored here */
00455 } ATR_float ;
00456 
00457 /*! Stores a string-attribute (array of strings). */
00458 
00459 typedef struct {
00460       int    type ;   /*!< should be ATR_STRING_TYPE */
00461       char * name ;   /*!< name of attribute, read from HEAD file */
00462       int    nch ;    /*!< number of characters in string */
00463       char * ch ;     /*!< array of characters (may not be NUL terminated) */
00464 } ATR_string ;
00465 
00466 #define ZBLOCK 126
00467 extern void THD_zblock(int,char *) ;   /* replace zeros with ZBLOCKs */
00468 extern void THD_unzblock(int,char *) ; /* undo the above */
00469 
00470 /*! Union type to hold an arbitrary attribute. */
00471 
00472 typedef union {
00473       int          type ;      /*!< Determines type of data here */
00474       ATR_string   str_atr ;
00475       ATR_float    flo_atr ;
00476       ATR_int      int_atr ;
00477 } ATR_any ;
00478 
00479 /*---------------------------------------------------------------------*/
00480 /*-------------------- structure for linear mapping -------------------*/
00481 
00482 #define MAPPING_LINEAR_TYPE 0
00483 #define MAPPING_LINEAR_STR  "LINEAR_MAPPING"
00484 
00485 #define FIRST_MAPPING_TYPE 0
00486 #define LAST_MAPPING_TYPE  0
00487 
00488 static char * MAPPING_typestr[] = {
00489    MAPPING_LINEAR_STR
00490 } ;
00491 
00492 /*! Structure to hold a linear mapping between coordinate systems. */
00493 
00494 typedef struct {
00495       int type ;            /*!< type code: only type now is MAPPING_LINEAR_TYPE */
00496 
00497       THD_mat33 mfor ;      /*!< x_map = [mfor] * x_in  - bvec  */
00498       THD_mat33 mbac ;      /*!< x_in  = [mbac] * x_map - svec  */
00499 
00500       THD_fvec3 bvec;       /* x_map = [mfor] * x_in  - bvec  */
00501       THD_fvec3 svec;       /* svec = - [mbac] * bvec */
00502       THD_fvec3 bot ;       /* lower bound for transformation use */
00503       THD_fvec3 top ;       /* upper bound for transformation use */
00504 } THD_linear_mapping ;
00505 
00506 /*! Copy the .bot and .top bounds between two THD_linear_mapping structs. */
00507 
00508 #define COPY_LMAP_BOUNDS(m1,m2) ( (m1).bot=(m2).bot , (m1).top=(m2).top )
00509 
00510 /*! Use the matrix operations to define a macro
00511     to load the inverse to a THD_linear_mapping once the forward is done. */
00512 
00513 #define LOAD_INVERSE_LMAP(map) \
00514    ( (map).mbac = MAT_INV((map).mfor) ,          \
00515      (map).svec = MATVEC((map).mbac,(map).bvec) ,\
00516      NEGATE_FVEC3((map).svec) )
00517 
00518 #define MAPPING_LINEAR_FSTART XtOffsetOf(THD_linear_mapping,mfor)
00519 #define MAPPING_LINEAR_FEND   (XtOffsetOf(THD_linear_mapping,top)+sizeof(THD_fvec3))
00520 #define MAPPING_LINEAR_FSIZE  ((MAPPING_LINEAR_FEND-MAPPING_LINEAR_FSTART)/sizeof(float))
00521 
00522 /*! Debugging printout of a THD_linear_mapping struct. */
00523 
00524 #define DUMP_LMAP(m) \
00525 ( printf("THD_linear_mapping:\n") ,                                     \
00526   printf("   mfor = %8.4f %8.4f %8.4f\n",                               \
00527          (m).mfor.mat[0][0], (m).mfor.mat[0][1], (m).mfor.mat[0][2] ) , \
00528   printf("          %8.4f %8.4f %8.4f\n",                               \
00529          (m).mfor.mat[1][0], (m).mfor.mat[1][1], (m).mfor.mat[1][2] ) , \
00530   printf("          %8.4f %8.4f %8.4f\n",                               \
00531          (m).mfor.mat[2][0], (m).mfor.mat[2][1], (m).mfor.mat[2][2] ) , \
00532   printf("   mbac = %8.4f %8.4f %8.4f\n",                               \
00533          (m).mbac.mat[0][0], (m).mbac.mat[0][1], (m).mbac.mat[0][2] ) , \
00534   printf("          %8.4f %8.4f %8.4f\n",                               \
00535          (m).mbac.mat[1][0], (m).mbac.mat[1][1], (m).mbac.mat[1][2] ) , \
00536   printf("          %8.4f %8.4f %8.4f\n",                               \
00537          (m).mbac.mat[2][0], (m).mbac.mat[2][1], (m).mbac.mat[2][2] ) , \
00538   printf("   bvec = %8.4f %8.4f %8.4f\n",                               \
00539          (m).bvec.xyz[0] , (m).bvec.xyz[1] , (m).bvec.xyz[2] ) ,        \
00540   printf("   svec = %8.4f %8.4f %8.4f\n",                               \
00541          (m).svec.xyz[0] , (m).svec.xyz[1] , (m).svec.xyz[2] ) ,        \
00542   printf("   bot  = %8.4f %8.4f %8.4f\n",                               \
00543          (m).bot.xyz[0]  , (m).bot.xyz[1]  , (m).bot.xyz[2] )  ,        \
00544   printf("   top  = %8.4f %8.4f %8.4f\n\n",                             \
00545          (m).top.xyz[0]  , (m).top.xyz[1]  , (m).top.xyz[2] ) )
00546 
00547 /*-----------------------------------------------------------------*/
00548 /*--------------- structure for user placed markers ---------------*/
00549 
00550 #define MARKS_MAXNUM  10
00551 #define MARKS_MAXLAB  20
00552 #define MARKS_MAXHELP 256
00553 #define MARKS_MAXFLAG 8
00554 
00555 /*! Structure for user placed markers. */
00556 
00557 typedef struct {
00558      int numdef ;                             /*!< Number of markers defined */
00559      int numset ;                             /*!< Number of markers now set */
00560 
00561      char label[MARKS_MAXNUM][MARKS_MAXLAB] ; /*!< Names for these marks */
00562 
00563      char help[MARKS_MAXNUM][MARKS_MAXHELP] ; /*!< Help for these marks */
00564 
00565      int ovcolor[MARKS_MAXNUM] ;              /*!< Overlay color index; -1 --> use defaults */
00566 
00567      Boolean valid[MARKS_MAXNUM] ;            /*!< True if actually set */
00568 
00569      float xyz[MARKS_MAXNUM][3] ;             /*!< Coordinates (3dmm, not Dicom) */
00570 
00571      int aflags[MARKS_MAXFLAG] ;              /*!< Action flags */
00572 
00573      int type ;                               /*!< Type of markers (same as aflags[0]) */
00574      char name[MARKS_MAXLAB] ;                /*!< Name of this type of markers */
00575 } THD_marker_set ;
00576 
00577 #define MARKS_FSIZE  (MARKS_MAXNUM*3)
00578 #define MARKS_FSTART XtOffsetOf(THD_marker_set,xyz)
00579 
00580 #define MARKS_LSIZE  (MARKS_MAXNUM*MARKS_MAXLAB)
00581 #define MARKS_LSTART XtOffsetOf(THD_marker_set,label)
00582 
00583 #define MARKS_HSIZE  (MARKS_MAXNUM*MARKS_MAXHELP)
00584 #define MARKS_HSTART XtOffsetOf(THD_marker_set,help)
00585 
00586 #define MARKS_ASIZE  MARKS_MAXFLAG
00587 #define MARKS_ASTART XtOffsetOf(THD_marker_set,aflags)
00588 
00589 /*--------------- definitions for markers I know about now ---------------*/
00590 
00591 #define MARKSET_ALIGN    1  /* types of marker sets */
00592 #define MARKSET_BOUNDING 2
00593 
00594 #define MARKACTION_NONE     0  /* action codes for marker sets */
00595 #define MARKACTION_WARP     1
00596 #define MARKACTION_REGISTER 2  /* not used at present */
00597 
00598 /*........................................................................*/
00599 
00600 /*! Number of orig->acpc markers. */
00601 
00602 #define NMARK_ALIGN 5
00603 
00604 static int THD_align_aflags[MARKS_MAXFLAG] = {
00605   MARKSET_ALIGN , MARKACTION_WARP
00606 } ;
00607 
00608 #define IMARK_ACSE 0
00609 #define IMARK_ACPM 1
00610 #define IMARK_PCIE 2
00611 #define IMARK_MSA1 3
00612 #define IMARK_MSA2 4
00613 
00614 /*! Labels for orig->acpc markers. */
00615 
00616 static char * THD_align_label[NMARK_ALIGN] = {
00617    "AC superior edge"     ,
00618    "AC posterior margin"  ,
00619    "PC inferior edge"     ,
00620    "First mid-sag pt"     ,
00621    "Another mid-sag pt"
00622 } ;
00623 
00624 /*! Help for orig->acpc markers. */
00625 
00626 static char * THD_align_help[NMARK_ALIGN] = {
00627    "This is the uppermost point\n"
00628    "on the anterior commisure,\n"
00629    "in the mid-sagittal plane." ,
00630 
00631    "This is the rearmost point\n"
00632    "on the anterior commisure,\n"
00633    "in the mid-sagittal plane.\n"
00634    "[Just a couple mm behind and\n"
00635    " below the AC superior edge.]" ,
00636 
00637    "This is the bottommost point\n"
00638    "on the posterior commissure,\n"
00639    "in the mid-sagittal plane." ,
00640 
00641    "You must also specify two other points in the\n"
00642    "mid-sagittal plane, ABOVE the corpus callosum\n"
00643    "(i.e., in the longitudinal fissure).  These\n"
00644    "points are needed to define the vertical plane." ,
00645 
00646    "You must also specify two other points in the\n"
00647    "mid-sagittal plane, ABOVE the corpus callosum\n"
00648    "(i.e., in the longitudinal fissure).  These\n"
00649    "points are needed to define the vertical plane." ,
00650 
00651 } ;
00652 
00653 /*.....................................................................*/
00654 
00655 /*! Number of acpc->tlrc markers. */
00656 
00657 #define NMARK_BOUNDING 6
00658 
00659 static int THD_bounding_aflags[MARKS_MAXFLAG] = {
00660    MARKSET_BOUNDING , MARKACTION_WARP
00661 } ;
00662 
00663 #define IMARK_MANT 0
00664 #define IMARK_MPOS 1
00665 #define IMARK_MSUP 2
00666 #define IMARK_MINF 3
00667 #define IMARK_MLEF 4
00668 #define IMARK_MRIG 5
00669 
00670 /*! Atlas distances for acpc->tlrc markers.
00671     If you change these, change the helps below too */
00672 
00673 #define ATLAS_FRONT_TO_AC 70.0
00674 #define ATLAS_AC_TO_PC    23.0
00675 #define ATLAS_PC_TO_BACK  79.0
00676 
00677 #define ATLAS_BOT_TO_AC   42.0
00678 #define ATLAS_AC_TO_TOP   74.0
00679 #define ATLAS_AC_TO_LAT   68.0
00680 
00681 #define ATLAS_BBOX_LAT    80.0    /* dimensions used for         */
00682 #define ATLAS_BBOX_ANT    80.0    /* Talairach view clipping box */
00683 #define ATLAS_BBOX_POS   110.0
00684 #define ATLAS_BBOX_INF    55.0
00685 #define ATLAS_BBOX_SUP    85.0
00686 
00687 #define ATLAS_BBOX_INF_NEW 65.0   /* 3/06/96: extra 10 mm for cerebellum */
00688 
00689 #define ATLAS_ALIGNBOX_LAT  95.0  /* dimensions used for AC-PC */
00690 #define ATLAS_ALIGNBOX_ANT  95.0  /* aligned view clipping box */
00691 #define ATLAS_ALIGNBOX_POS 140.0  /* (3/25/95)                 */
00692 #define ATLAS_ALIGNBOX_SUP 100.0
00693 #define ATLAS_ALIGNBOX_INF  70.0
00694 
00695 #define MAX_ALLOWED_DEVIATION 2.0
00696 #define MIN_ALLOWED_DEVIATION 0.5
00697 
00698 /*! Labels for acpc->tlrc markers. */
00699 
00700 static char * THD_bounding_label[NMARK_BOUNDING] = {
00701    "Most anterior point"  ,
00702    "Most posterior point" ,
00703    "Most superior point"  ,
00704    "Most inferior point"  ,
00705    "Most left point"      ,
00706    "Most right point"
00707 } ;
00708 
00709 /*! Help for acpc->tlrc markers. */
00710 
00711 static char * THD_bounding_help[NMARK_BOUNDING] = {
00712 "The frontmost point of the frontal cortex;\n"
00713 "needed for brain length [atlas y = -70 mm]" ,
00714 
00715 "The hindmost point of the occipital cortex;\n"
00716 "needed for brain length [atlas y = +102 mm]" ,
00717 
00718 "The topmost point of the parietal cortex;\n"
00719 "needed for brain height [atlas z = +74 mm]" ,
00720 
00721 "The lowest point of the temporal cortex;\n"
00722 "needed for brain height [atlas z = -42 mm]" ,
00723 
00724 "The most lateral (left) point of the parietotemporal cortex;\n"
00725 "needed for brain width [atlas x = +68 mm]" ,
00726 
00727 "The most lateral (right) point of the parietotemporal cortex;\n"
00728 "needed for brain width [atlas x = -68 mm]"
00729 
00730 } ;
00731 
00732 /*---------------------------------------------------------------------*/
00733 /*---------------------- structures to hold warps ---------------------*/
00734 
00735 #define WARP_AFFINE_TYPE   0
00736 #define WARP_AFFINE_STR    "WARP_AFFINE"
00737 
00738 #define WARP_TALAIRACH_12_TYPE 1
00739 #define WARP_TALAIRACH_12_STR  "WARP_TALAIRACH_12"
00740 
00741 #define FIRST_WARP_TYPE 0
00742 #define LAST_WARP_TYPE  1
00743 
00744 static char * WARP_typestr[] = {
00745    WARP_AFFINE_STR , WARP_TALAIRACH_12_STR
00746 } ;
00747 
00748 /*----------------------- resample types -----------------------*/
00749 
00750 #define RESAM_NN_TYPE      0
00751 #define RESAM_NN_STR      "Nearest Neighbor"
00752 
00753 #define RESAM_LINEAR_TYPE  1
00754 #define RESAM_LINEAR_STR  "Linear Interpolation"
00755 
00756 #define RESAM_CUBIC_TYPE   2
00757 #define RESAM_CUBIC_STR   "Cubic Interpolation"
00758 
00759 #define RESAM_BLOCK_TYPE   3
00760 #define RESAM_BLOCK_STR   "Blocky Interpolation"
00761 
00762 #define FIRST_RESAM_TYPE 0
00763 #define LAST_RESAM_TYPE  3
00764 
00765 static char * RESAM_typestr[] = {
00766    RESAM_NN_STR , RESAM_LINEAR_STR , RESAM_CUBIC_STR , RESAM_BLOCK_STR
00767 } ;
00768 
00769 #define NSTR_SHORT_RESAM 2
00770 static char * RESAM_shortstr[] = { "NN" , "Li" , "Cu" , "Bk" } ;
00771 
00772 /*! 12-piece Warp struct for orig/acpc -> tlrc coordinates. */
00773 
00774 typedef struct {
00775       int type ;       /*!< type code: WARP_TALAIRACH_12_TYPE */
00776       int resam_type ; /*!< Resampling method */
00777 
00778       THD_linear_mapping warp[12] ; /* The 12 pieces of the transformation */
00779 } THD_talairach_12_warp ;
00780 
00781 #define W_RAS  0  /* right-anterior -superior mapping index */
00782 #define W_LAS  1  /* left -anterior -superior */
00783 #define W_RMS  2  /* right-medial   -superior */
00784 #define W_LMS  3  /* left -medial   -superior */
00785 #define W_RPS  4  /* right-posterior-superior */
00786 #define W_LPS  5  /* left -posterior-superior */
00787 #define W_RAI  6  /* right-anterior -inferior */
00788 #define W_LAI  7  /* left -anterior -inferior */
00789 #define W_RMI  8  /* right-medial   -inferior */
00790 #define W_LMI  9  /* left -medial   -inferior */
00791 #define W_RPI 10  /* right-posterior-inferior */
00792 #define W_LPI 11  /* left -posterior-inferior */
00793 
00794 #define WARP_TALAIRACH_12_SIZE (12*MAPPING_LINEAR_FSIZE)
00795 
00796 /*! Debug printout for 1 piece of a Talairach warp. */
00797 
00798 #define DUMP_T12_MAP(t12,xx,yy,zz) \
00799  (  printf("\n--- submap " # xx # yy # zz "\n" ) , \
00800     DUMP_LMAP( (t12).warp[W_ ## xx ## yy ## zz] )    )
00801 
00802 /*! Debug printout for all 12 pieces of a Talairach warp. */
00803 
00804 #define DUMP_T12_WARP(t12) \
00805  ( printf("\n12 region Talairach warp:") ,                 \
00806    DUMP_T12_MAP((t12),R,A,S) , DUMP_T12_MAP((t12),L,A,S) , \
00807    DUMP_T12_MAP((t12),R,M,S) , DUMP_T12_MAP((t12),L,M,S) , \
00808    DUMP_T12_MAP((t12),R,P,S) , DUMP_T12_MAP((t12),L,P,S) , \
00809    DUMP_T12_MAP((t12),R,A,I) , DUMP_T12_MAP((t12),L,A,I) , \
00810    DUMP_T12_MAP((t12),R,M,I) , DUMP_T12_MAP((t12),L,M,I) , \
00811    DUMP_T12_MAP((t12),R,P,I) , DUMP_T12_MAP((t12),L,P,I)    )
00812 
00813 /*! Struct to hold a simple affine warp (orig -> acpc). */
00814 
00815 typedef struct {
00816       int type ;         /*!< type code: WARP_AFFINE_TYPE */
00817       int resam_type ;   /*!< Resampling method */
00818 
00819       THD_linear_mapping warp ; /*!< The single affine mapping */
00820 } THD_affine_warp ;
00821 
00822 #define WARP_AFFINE_SIZE (MAPPING_LINEAR_FSIZE)
00823 
00824 /*! Union type to hold all possible warp types. */
00825 
00826 typedef union {
00827       int type ;                      /*!< WARP_AFFINE_TYPE or WARP_TALAIRACH_12_TYPE */
00828       THD_affine_warp       rig_bod ;
00829       THD_talairach_12_warp tal_12 ;
00830 } THD_warp ;
00831 
00832 /*! Check if ww is a good warp. */
00833 
00834 #define ISVALID_WARP(ww) ( (ww) != NULL &&                  \
00835                            (ww)->type >= FIRST_WARP_TYPE && \
00836                            (ww)->type <= LAST_WARP_TYPE )
00837 
00838 /*! Temporary warp. */
00839 
00840 static THD_warp tempA_warp ;
00841 
00842 /*! Return value is an affine warp set to the identity transformation. */
00843 
00844 #define IDENTITY_WARP                                                   \
00845    ( tempA_warp.rig_bod.type       = WARP_AFFINE_TYPE ,                 \
00846      tempA_warp.rig_bod.resam_type = RESAM_NN_TYPE ,                    \
00847      tempA_warp.rig_bod.warp.type  = MAPPING_LINEAR_TYPE ,              \
00848      LOAD_DIAG_MAT( tempA_warp.rig_bod.warp.mfor ,     1,    1,    1 ) ,\
00849      LOAD_DIAG_MAT( tempA_warp.rig_bod.warp.mbac ,     1,    1,    1 ) ,\
00850      LOAD_FVEC3(    tempA_warp.rig_bod.warp.bvec ,     0,    0,    0 ) ,\
00851      LOAD_FVEC3(    tempA_warp.rig_bod.warp.svec ,     0,    0,    0 ) ,\
00852      LOAD_FVEC3(    tempA_warp.rig_bod.warp.bot  , -9999,-9999,-9999 ) ,\
00853      LOAD_FVEC3(    tempA_warp.rig_bod.warp.top  ,  9999, 9999, 9999 ) ,\
00854      tempA_warp )
00855 
00856 /*! Return values is a warp of angle th about axis ff, in aa-bb plane. */
00857 
00858 #define ROTGEN_WARP(th,ff,aa,bb)                                        \
00859    ( tempA_warp.rig_bod.type       = WARP_AFFINE_TYPE ,                 \
00860      tempA_warp.rig_bod.resam_type = RESAM_NN_TYPE ,                    \
00861      tempA_warp.rig_bod.warp.type  = MAPPING_LINEAR_TYPE ,              \
00862      LOAD_ROTGEN_MAT(tempA_warp.rig_bod.warp.mfor, th,ff,aa,bb) ,       \
00863      LOAD_ROTGEN_MAT(tempA_warp.rig_bod.warp.mbac,-th,ff,aa,bb) ,       \
00864      LOAD_FVEC3(     tempA_warp.rig_bod.warp.bvec,     0,    0,    0 ) ,\
00865      LOAD_FVEC3(     tempA_warp.rig_bod.warp.svec,     0,    0,    0 ) ,\
00866      LOAD_FVEC3(     tempA_warp.rig_bod.warp.bot , -9999,-9999,-9999 ) ,\
00867      LOAD_FVEC3(     tempA_warp.rig_bod.warp.top ,  9999, 9999, 9999 ) ,\
00868      tempA_warp )
00869 
00870 #define ROTX_WARP(th) ROTGEN_WARP(th,0,1,2)
00871 #define ROTY_WARP(th) ROTGEN_WARP(th,1,2,0)
00872 #define ROTZ_WARP(th) ROTGEN_WARP(th,2,0,1)
00873 
00874 /*! Make the affine warp map point (xin,yin,zin) to (xout,yout,zout). */
00875 
00876 #define CEN_WARP(ww,xin,yin,zin,xout,yout,zout)                  \
00877   do{ THD_fvec3 tv , uv ;                                        \
00878       LOAD_FVEC3(tv,xin,yin,zin) ;                               \
00879       uv = MATVEC((ww).rig_bod.warp.mfor,tv) ;                   \
00880       LOAD_FVEC3(tv,xout,yout,zout) ;                            \
00881       (ww).rig_bod.warp.bvec = SUB_FVEC3(uv,tv) ;                \
00882       (ww).rig_bod.warp.svec =                                   \
00883          MATVEC((ww).rig_bod.warp.mbac,(ww).rig_bod.warp.bvec) ; \
00884       NEGATE_FVEC3((ww).rig_bod.warp.svec) ;                     \
00885   } while(0)
00886 
00887 /*---------------------------------------------------------------------*/
00888 /*----------- structure to hold pointer to data on disk ---------------*/
00889 
00890 #define DISKPTR_TYPE  47
00891 
00892 #define THD_MAX_RANK       3
00893 #define THD_MIN_RANK       3
00894 #define THD_MAX_RANK_EVER  5
00895 
00896 /* none of these should be over 4 characters! */
00897 
00898 #define DATASET_HEADER_SUFFIX "HEAD"
00899 #define DATASET_BRICK_SUFFIX  "BRIK"
00900 #define DATASET_NOTES_SUFFIX  "NOTE"
00901 
00902 /***
00903   The following codes define how the data is stored on disk.
00904   At one time, I started to support more than one storage
00905   type, but that is history.  Data either isn't stored
00906   (i.e., is warped-on-demand), or is stored in one big
00907   brick file.
00908 
00909   Later: OK, now we have more than one type.  However, type #1
00910          was never implemented (the ill-fated STORAGE_BY_SLICES).
00911 ***/
00912 
00913 #define STORAGE_UNDEFINED  0
00914 #define STORAGE_BY_BRICK   2
00915 #define STORAGE_BY_MINC    3
00916 #define STORAGE_BY_VOLUMES 4  /* 20 Jun 2002 */
00917 #define STORAGE_BY_ANALYZE 5
00918 #define STORAGE_BY_CTFMRI  6  /* 04 Dec 2002 */
00919 #define STORAGE_BY_CTFSAM  7
00920 #define STORAGE_BY_1D      8  /* 04 Mar 2003 */
00921 #define STORAGE_BY_3D      9  /* 21 Mar 2003 */
00922 #define STORAGE_BY_NIFTI  10  /* 28 Aug 2003 */
00923 #define STORAGE_BY_MPEG   11  /* 03 Dec 2003 */
00924 
00925 #define LAST_STORAGE_MODE 11
00926 
00927 /*! Contains information about where/how dataset is stored on disk.
00928 
00929      The filenames in this structure are really path names
00930      (that is, they have the directory name prependend).
00931 */
00932 
00933 typedef struct {
00934       int type ;                           /*!< must be DISKPTR_TYPE */
00935       int rank ;                           /*!< must be 3 */
00936       int nvals ;                          /*!< number of 3D volumes; must agree with THD_datablock */
00937       int dimsizes[THD_MAX_RANK] ;         /*!< size of each dimension of 3D array */
00938       int storage_mode ;                   /*!< one of the STORAGE_ codes  */
00939 
00940       int byte_order ;                     /*!< LSB_FIRST or MSB_FIRST [25 Apr 1998] */
00941 
00942       char prefix[THD_MAX_PREFIX] ;        /*!< prefix part of filename */
00943       char viewcode[THD_MAX_VIEWCODE] ;    /*!< viewcode part of filename */
00944       char filecode[THD_MAX_FILECODE] ;    /*!< filecode = prefix+viewcode */
00945 
00946       char directory_name[THD_MAX_NAME] ;  /*!< contain all files for this dataset */
00947       char header_name[THD_MAX_NAME] ;     /*!< contains attributes */
00948       char brick_name[THD_MAX_NAME] ;      /*!< THIS contains actual data volumes */
00949 } THD_diskptr ;
00950 
00951 #define ATRNAME_BYTEORDER "BYTEORDER_STRING"
00952 
00953 extern void THD_delete_diskptr( THD_diskptr * ) ;
00954 
00955 /*! Determine if THD_diskptr dk is valid. */
00956 
00957 #define ISVALID_DISKPTR(dk) ( (dk)!=NULL && (dk)->type==DISKPTR_TYPE )
00958 
00959 /*! Convert a file prefix and viewcode into a filecode (prefix+view). */
00960 
00961 #define PREFIX_VIEW_TO_FILECODE(pr,vv,fc) sprintf( (fc),"%s+%s",(pr),(vv) )
00962 
00963 /*! Extract the prefix from a filecode (prefix+view).
00964 
00965     - If there is no '+', puts an empty string into pr
00966     - Otherwise, scans backward from end to find last '+'; everything before that is the prefix
00967     - Space for pr must be allocated beforehand
00968 */
00969 
00970 #define FILECODE_TO_PREFIX(fc,pr)                                     \
00971   do{ char *qq , *ff , *pp ;                                          \
00972       if( strstr((fc),"+") == NULL ){                                 \
00973          (pr)[0] = '\0' ;                                             \
00974       } else {                                                        \
00975          for( qq=fc+strlen((fc)) ; *qq != '+' ; qq-- ) ;              \
00976          for( ff=(fc) , (pp)=(pr) ; ff < qq ; ff++,pp++ ) *pp = *ff ; \
00977          *pp = '\0' ; } break ; } while(1)
00978 
00979 #if 0
00980 #define FILECODE_TO_PREFIX(fc,pr) \
00981   do{ char *qq , *ff , *pp ;               \
00982       if( (qq=strstr((fc),"+")) == NULL ){ \
00983          (pr)[0] = '\0' ;                  \
00984       } else {                             \
00985          for( ff=(fc) , (pp)=(pr) ; ff < qq ; ff++,pp++ ) *pp = *ff ; \
00986          *pp = '\0' ; } break ; } while(1)
00987 #endif
00988 
00989 /*! Extract the prefix from a filename. */
00990 
00991 #define FILENAME_TO_PREFIX(fn,pr)             \
00992   do{ int ii ;                                \
00993       for( ii=strlen((fn)) ; ii >= 0 ; ii-- ) \
00994          if( (fn)[ii] == '/' ) break ;        \
00995       FILECODE_TO_PREFIX( (fn)+(ii+1) , (pr) ) ; break ; } while(1)
00996 
00997 /*---------------------------------------------------------------------*/
00998 /*------- structure to hold actual 3D data, or pointers thereto -------*/
00999 
01000 #define DATABLOCK_TYPE 37
01001 
01002 #define DATABLOCK_MEM_UNDEFINED  1
01003 #define DATABLOCK_MEM_MALLOC     2
01004 #define DATABLOCK_MEM_MMAP       4
01005 #define DATABLOCK_MEM_ANY        (DATABLOCK_MEM_MALLOC | DATABLOCK_MEM_MMAP)
01006 #define DATABLOCK_MEM_SHARED     8    /* 02 May 2003 */
01007 
01008 /*! Determine if mm is a valid memory allocation code. */
01009 
01010 #define ISVALID_MEM_CODE(mm) \
01011   ( (mm) == DATABLOCK_MEM_MALLOC || (mm) == DATABLOCK_MEM_MMAP \
01012                                  || (mm) == DATABLOCK_MEM_ANY  \
01013                                  || (mm) == DATABLOCK_MEM_SHARED )
01014 
01015 #ifndef MMAP_THRESHOLD           /* if not previously defined in machdep.h */
01016 /*! A brick file should have this many bytes before we try to use mmap */
01017 #  define MMAP_THRESHOLD 999999
01018 #endif
01019 
01020 /*!  All subvolumes are stored in an array of MRI_IMAGE (the "brick").
01021      - If mmap is used, then the whole external file is mmap()-ed in one
01022        block and the data pointers for each image computed from this base.
01023      - If malloc() is used, then each image is separately allocated and read in.
01024      - Each datablock has a brick, even if it doesn't actually contain
01025        data (is only warp-on-demand).
01026      - Whether or not a datablock contains actual voxel data can be
01027        determined by examining the "malloc_type".
01028     \date Feb 1996
01029 */
01030 
01031 typedef struct {
01032       int type ;              /*!< type code: DATABLOCK_TYPE */
01033 
01034       int nvals ;             /*!< number of 3D bricks */
01035 
01036       MRI_IMARR * brick  ;    /*!< array of pointers to each 3D brick */
01037       float * brick_fac  ;    /*!< array of scale factors to convert sub-bricks to floats */
01038       int *  brick_bytes ;    /*!< array of data size of each sub-brick */
01039 
01040                                 /* These fields added for "bucket" datasets: */
01041 
01042       char **  brick_lab  ;     /*!< labels for all sub-bricks                 */
01043       char **  brick_keywords ; /*!< keywords strings for all sub-bricks       */
01044       int *    brick_statcode ; /*!< a FUNC_*_TYPE ==> kind of statistic here  */
01045       float ** brick_stataux ;  /*!< stat_aux parameters for each sub-brick with brick_statcode[iv] > 0               */
01046 
01047       int64_t total_bytes ;   /*!< totality of data storage needed */
01048       int     malloc_type ;   /*!< memory allocation method */
01049       int     locked ;        /*!< Feb 1998: locked in memory (un-purgeable) */
01050 
01051                                 /* Jan 1999: for datasets that are extracted from a master dataset */
01052       int    master_nvals ;   /*!< Number of nvals in master dataset */
01053       int *  master_ival ;    /*!< master_ival[i] = sub-brick index in master of sub-brick #i here */
01054       int *  master_bytes ;   /*!< master_bytes[i] = size of sub-brick #i in master */
01055 
01056       float master_bot ;      /*!< range of data values to keep from master - bottom */
01057       float master_top ;      /*!< range of data values to keep from master - top */
01058 
01059       THD_diskptr * diskptr ; /*!< where the data is on disk (if anywhere!) */
01060 
01061       int       natr ;        /*!< number of attributes read from disk (or to write to disk) */
01062       int       natr_alloc ;  /*!< number of attributes allocated in atr below */
01063       ATR_any * atr ;         /*!< array of attributes (from the header) */
01064 
01065    /* pointers to other stuff */
01066 
01067       KILL_list kl ;          /*!< Stuff to delete if this struct is deleted */
01068       XtPointer parent ;      /*!< Somebody who "owns" me */
01069 
01070       char shm_idcode[32] ;   /*!< Idcode for shared memory buffer, if any [02 May 2003]. */
01071       int  shm_idint ;        /*!< Integer id for shared memory buffer. */
01072 } THD_datablock ;
01073 
01074 /*! Force bricks to be allocated with malloc(). */
01075 
01076 #define DBLK_mallocize(db) THD_force_malloc_type((db),DATABLOCK_MEM_MALLOC)
01077 
01078 /*! Force bricks to be allocated with mmap(). */
01079 
01080 #define DBLK_mmapize(db)   THD_force_malloc_type((db),DATABLOCK_MEM_MMAP)
01081 
01082 /*! Don't care how bricks are allocated. */
01083 
01084 #define DBLK_anyize(db)    THD_force_malloc_type((db),DATABLOCK_MEM_ANY)
01085 
01086 /*! Test if brick is set to be malloc()-ed. */
01087 
01088 #define DBLK_IS_MALLOC(db)  ((db)->malloc_type == DATABLOCK_MEM_MALLOC)
01089 
01090 /*! Test if brick is set to be mmap()-ed. */
01091 
01092 #define DBLK_IS_MMAP(db)    ((db)->malloc_type == DATABLOCK_MEM_MMAP)
01093 
01094 /*! Test if brick is set to be shared. */
01095 
01096 #define DBLK_IS_SHARED(db)  ((db)->malloc_type == DATABLOCK_MEM_SHARED)
01097 
01098 /*! Force bricks to be allocated in shared memory.  */
01099 
01100 #define DBLK_shareize(db) THD_force_malloc_type((db),DATABLOCK_MEM_SHARED)
01101 
01102 /*! Lock bricks in memory. */
01103 
01104 #define DBLK_lock(db)   ((db)->locked = 1)
01105 
01106 /*! Unlock bricks from memory, if they aren't "superlocked". */
01107 
01108 #define DBLK_unlock(db) ((db)->locked = ((db)->locked<2) ? 0 : 2)
01109 
01110 /*! Test if brick is locked into memory. */
01111 
01112 #define DBLK_LOCKED(db) ((db)->locked)
01113 
01114 /*! Superlock brick in memory.  Can only be undone by explicit access to db->locked. */
01115 #define DBLK_superlock(db) ((db)->locked = 2)
01116 
01117 /*! Check if brick is mastered from another dataset. */
01118 
01119 #define DBLK_IS_MASTERED(db) \
01120   ((db)->master_nvals > 0 && (db)->master_ival != NULL && (db)->master_bytes != NULL)
01121 
01122 extern void THD_delete_datablock         ( THD_datablock * ) ;
01123 extern void THD_init_datablock_brick     ( THD_datablock * , int , void * ) ;
01124 extern void THD_init_datablock_labels    ( THD_datablock * ) ;
01125 extern void THD_init_datablock_keywords  ( THD_datablock * ) ;
01126 extern void THD_copy_datablock_auxdata   ( THD_datablock * , THD_datablock * ) ;
01127 extern void THD_init_datablock_stataux   ( THD_datablock * ) ;
01128 extern void THD_store_datablock_stataux  ( THD_datablock *,int,int,int,float * );
01129 extern void THD_store_datablock_label    ( THD_datablock * , int , char * ) ;
01130 extern void THD_store_datablock_keywords ( THD_datablock * , int , char * ) ;
01131 extern void THD_append_datablock_keywords( THD_datablock * , int , char * ) ;
01132 extern int  THD_datablock_from_atr       ( THD_datablock *, char *, char * ) ;
01133 
01134 /*! Initialize all sub-bricks auxiliary data to nothing. */
01135 
01136 #define THD_null_datablock_auxdata(blk) ( (blk)->brick_lab      = NULL , \
01137                                           (blk)->brick_keywords = NULL , \
01138                                           (blk)->brick_statcode = NULL , \
01139                                           (blk)->brick_stataux  = NULL  )
01140 
01141 extern int  THD_string_has( char * , char * ) ;
01142 
01143 /*! Check if datablock is OK. */
01144 
01145 #define ISVALID_DATABLOCK(bk) ( (bk) != NULL && (bk)->type == DATABLOCK_TYPE )
01146 
01147 /*! Synonym for ISVALID_DATABLOCK. */
01148 
01149 #define ISVALID_DBLK           ISVALID_DATABLOCK  /* 26 Mar 2001 */
01150 
01151 /*------------- a dynamic array type for datablocks --------------*/
01152 
01153 /*! A dynamic array type for datablocks - used when assembling datasets. */
01154 
01155 typedef struct {
01156       int num ;                /*!< Number of datablocks stored */
01157       int nall ;               /*!< Number of datablocks space allocated for */
01158       THD_datablock ** ar ;    /*!< Array of datablocks */
01159 } THD_datablock_array ;
01160 
01161 #define INC_DBARR 8
01162 
01163 /*! Initialize a THD_datablock_array. */
01164 
01165 #define INIT_DBARR(name)                  \
01166    ( (name) = XtNew(THD_datablock_array) ,\
01167      (name)->num = (name)->nall = 0 ,     \
01168      (name)->ar  = NULL )
01169 
01170 /*! Add a datablock to a THD_datablock_array. */
01171 
01172 #define ADDTO_DBARR(name,bblk)                                     \
01173    { if( (name)->num == (name)->nall ){                            \
01174       (name)->nall += INC_DBARR ;                                  \
01175       (name)->ar    = (THD_datablock **)                           \
01176                        XtRealloc( (char *) (name)->ar ,            \
01177                         sizeof(THD_datablock *) * (name)->nall ) ; \
01178      }                                                             \
01179      if( (bblk) != NULL ){               \
01180       (name)->ar[(name)->num] = (bblk) ; \
01181       ((name)->num)++ ;                  \
01182      } }
01183 
01184 /*! Free the space used by a THD_datablock_array (but not the datablocks themselves). */
01185 
01186 #define FREE_DBARR(name)      \
01187    if( (name) != NULL ){      \
01188      myXtFree( (name)->ar ) ; \
01189      myXtFree( (name) ) ; }
01190 
01191 /*--------------------------------------------------------------------*/
01192 /*---------- stuff to hold axes information for 3D dataset -----------*/
01193 
01194 #define DATAXES_TYPE 27
01195 
01196 /*! Default resampling grid size (in mm). */
01197 
01198 #define DEFAULT_RESAMPLE_VOX 1.0
01199 
01200 /*--- orientation types ---*/
01201 
01202 #define ORI_R2L_TYPE  0
01203 #define ORI_R2L_STR  "Right-to-Left"
01204 
01205 #define ORI_L2R_TYPE  1
01206 #define ORI_L2R_STR  "Left-to-Right"
01207 
01208 #define ORI_P2A_TYPE  2
01209 #define ORI_P2A_STR  "Posterior-to-Anterior"
01210 
01211 #define ORI_A2P_TYPE  3
01212 #define ORI_A2P_STR  "Anterior-to-Posterior"
01213 
01214 #define ORI_I2S_TYPE  4
01215 #define ORI_I2S_STR  "Inferior-to-Superior"
01216 
01217 #define ORI_S2I_TYPE  5
01218 #define ORI_S2I_STR  "Superior-to-Inferior"
01219 
01220 #define ORI_GEN_TYPE  6
01221 #define ORI_GEN_STR  "General"  /* not used at present */
01222 
01223 #define FIRST_ORIENT_TYPE 0
01224 #define LAST_ORIENT_TYPE  5
01225 
01226 #define LONGEST_ORIENT_TYPESTR strlen(ORI_P2A_STR)
01227 
01228 static char * ORIENT_typestr[] = {
01229    ORI_R2L_STR , ORI_L2R_STR , ORI_P2A_STR ,
01230    ORI_A2P_STR , ORI_I2S_STR , ORI_S2I_STR , ORI_GEN_STR
01231 } ;
01232 
01233 static char * ORIENT_shortstr[] = {
01234    "R-L" , "L-R" , "P-A" , "A-P" , "I-S" , "S-I" , "GEN"
01235 } ;
01236 
01237 static char * ORIENT_tinystr[] = {
01238    "RL" , "LR" , "PA" , "AP" , "IS" , "SI" , "??"
01239 } ;
01240 
01241 static char ORIENT_xyz[]   = "xxyyzzg" ;  /* Dicom directions are
01242                                              x = R->L , y = A->P , z = I->S */
01243 
01244 /*! Determines if orientation code (0..5) is Dicom positive or negative. */
01245 
01246 static char ORIENT_sign[]  = "+--++-" ;
01247 
01248 static char ORIENT_first[] = "RLPAIS" ;
01249 
01250 static int  ORIENT_xyzint[] = { 1,1 , 2,2 , 3,3 , 666 } ;
01251 
01252 #define ORIENT_OPPOSITE(orc) \
01253   ( ((orc) % 2 == 0) ? ((orc)+1) : ((orc)-1) )
01254 
01255 /*! Struct to hold information about 3D brick grid in space.
01256     Voxel center x[i] is at xxorg + i * xxdel, et cetera.
01257 */
01258 
01259 typedef struct {
01260       int type ;     /*!< type code: DATAXES_TYPE */
01261 
01262       int nxx ;      /*!< Number of points in grid in x direction */
01263       int nyy ;      /*!< Number of points in grid in y direction */
01264       int nzz ;      /*!< Number of points in grid in z direction */
01265 
01266       float xxorg ;  /*!< Center of (0,0,0) voxel */
01267       float yyorg ;  /*!< Center of (0,0,0) voxel */
01268       float zzorg ;  /*!< center of (0,0,0) voxel */
01269       float xxdel ;  /*!< Spacings between voxel centers (mm) - may be negative */
01270       float yydel ;  /*!< Spacings between voxel centers (mm) - may be negative */
01271       float zzdel ;  /*!< Spacings between voxel centers (mm) - may be negative */
01272 
01273       float xxmin ;  /*!< Bounding box for grid */
01274       float xxmax ;  /*!< Bounding box for grid */
01275       float yymin ;  /*!< Bounding box for grid */
01276       float yymax ;  /*!< Bounding box for grid */
01277       float zzmin ;  /*!< Bounding box for grid */
01278       float zzmax ;  /*!< Bounding box for grid */
01279 
01280       int xxorient ;  /*!< Orientation code */
01281       int yyorient ;  /*!< Orientation code */
01282       int zzorient ;  /*!< Orientation code */
01283 
01284       THD_mat33 to_dicomm ; /*!< Orthogonal matrix transforming from
01285                                 dataset coordinates to Dicom coordinates */
01286 
01287    /* pointers to other stuff */
01288 
01289       XtPointer parent ;    /*!< Dataset that "owns" this struct */
01290 } THD_dataxes ;
01291 
01292 /*! Center of grid in x-direction. */
01293 #define DAXES_XCEN(dax) ((dax)->xxorg + 0.5*((dax)->nxx - 1) * (dax)->xxdel)
01294 
01295 /*! Center of grid in y-direction. */
01296 #define DAXES_YCEN(dax) ((dax)->yyorg + 0.5*((dax)->nyy - 1) * (dax)->yydel)
01297 
01298 /*! Center of grid in z-direction. */
01299 #define DAXES_ZCEN(dax) ((dax)->zzorg + 0.5*((dax)->nzz - 1) * (dax)->zzdel)
01300 
01301 #if 1
01302 #define DAXES_NUM(dax,ori) \
01303    ( (ORIENT_xyzint[(ori)] == ORIENT_xyzint[(dax)->xxorient]) ? (dax)->nxx : \
01304      (ORIENT_xyzint[(ori)] == ORIENT_xyzint[(dax)->yyorient]) ? (dax)->nyy : \
01305      (ORIENT_xyzint[(ori)] == ORIENT_xyzint[(dax)->zzorient]) ? (dax)->nzz : 0 )
01306 #else
01307 #define DAXES_NUM(dax,ori) ( ( ORIENT_xyzint[(ori)] == 1 ) ? (dax)->nxx : \
01308                              ( ORIENT_xyzint[(ori)] == 2 ) ? (dax)->nyy : \
01309                              ( ORIENT_xyzint[(ori)] == 3 ) ? (dax)->nzz : 0 )
01310 #endif
01311 
01312 /*!  WARNING:  If you perform surgery on a dataset and change its
01313                dimensions in the dataxes, you must also reflect
01314                this in the diskptr.  Otherwise, the .HEAD file
01315                will not have the correct dimensions!  The macro
01316                just below will do this for you.
01317 */
01318 
01319 #define DATAXES_TO_DISKPTR(ds)                             \
01320   ( (ds)->dblk->diskptr->dimsizes[0] = (ds)->daxes->nxx ,  \
01321     (ds)->dblk->diskptr->dimsizes[1] = (ds)->daxes->nyy ,  \
01322     (ds)->dblk->diskptr->dimsizes[2] = (ds)->daxes->nzz  )
01323 
01324 /*! Check if dax is a valid THD_dataxes struct. */
01325 
01326 #define ISVALID_DATAXES(dax) ( (dax) != NULL && (dax)->type == DATAXES_TYPE )
01327 
01328 /*! Check if two THD_dataxes are essential equivalent. */
01329 
01330 #define EQUIV_DATAXES(cax,dax)                     \
01331   ( ISVALID_DATAXES((cax))                      && \
01332     ISVALID_DATAXES((dax))                      && \
01333     (cax)->nxx == (dax)->nxx                    && \
01334     (cax)->nyy == (dax)->nyy                    && \
01335     (cax)->nzz == (dax)->nzz                    && \
01336     fabs( (cax)->xxorg - (dax)->xxorg ) < 0.01  && \
01337     fabs( (cax)->yyorg - (dax)->yyorg ) < 0.01  && \
01338     fabs( (cax)->zzorg - (dax)->zzorg ) < 0.01  && \
01339     fabs( (cax)->xxdel - (dax)->xxdel ) < 0.001 && \
01340     fabs( (cax)->yydel - (dax)->yydel ) < 0.001 && \
01341     fabs( (cax)->zzdel - (dax)->zzdel ) < 0.001 && \
01342     (cax)->xxorient == (dax)->xxorient          && \
01343     (cax)->yyorient == (dax)->yyorient          && \
01344     (cax)->zzorient == (dax)->zzorient    )
01345 
01346 extern void THD_edit_dataxes( float , THD_dataxes * , THD_dataxes * ) ;
01347 
01348 int THD_get_axis_direction( THD_dataxes *, int ) ; /* 19 Mar 2003 */
01349 
01350 /*---------------------------------------------------------------------*/
01351 /*--- data structure for information about time axis of 3D dataset ----*/
01352 
01353 #define TIMEAXIS_TYPE 907
01354 
01355 #define UNITS_MSEC_TYPE  77001
01356 #define UNITS_SEC_TYPE   77002
01357 #define UNITS_HZ_TYPE    77003
01358 
01359 static char * UNITS_TYPE_labelstring[] = { "ms" , "s" , "Hz" } ;
01360 
01361 /*! Return a string for the units of the uu-th time unit type. */
01362 
01363 #define UNITS_TYPE_LABEL(uu) UNITS_TYPE_labelstring[(uu)-UNITS_MSEC_TYPE]
01364 
01365 /*! Struct to hold information about the time axis of a 3D+time datset.
01366 
01367     For 3D+t datasets, there are ntt 3D times; the i-th one is centered
01368     at ttorg + ttdel*ii seconds, for ii=0..ntt-1.
01369     Also, ttdur = duration of each sample in time.
01370 
01371     If ( nsl > 0 && toff_sl != NULL), then the data was acquired as
01372     slices, not as a 3D block.  The slicing direction must be the
01373     dataset (not Dicom) z-axis.  The extra offset for the data at
01374     z is given by computing isl = (z - zorg_sl) / dz_sl + 0.5; the
01375     extra offset is then toff_sl[isl].  Note that dz_sl might be
01376     different from the dataxes zzdel because the dataset might actually
01377     be made up of duplicated slices (see program abut.c).
01378 
01379     All this is computed using the routine THD_timeof().
01380 
01381     When transformed, all the slice stuff will be ignored.  That's
01382     because the warped dataset z-direction will not be the same as the
01383     original dataset's z-direction.
01384 */
01385 
01386 typedef struct {
01387    int   type ;     /*!< TIMEAXIS_TYPE */
01388    int   ntt ;      /*!< Number of time points */
01389    float ttorg ;    /*!< Time origin (usually 0) */
01390    float ttdel ;    /*!< Fondly known as TR */
01391    float ttdur ;    /*!< Duration of image acquisition (usually not known) */
01392 
01393    int units_type ;  /*!< one of the UNITS_ codes */
01394 
01395    int     nsl ;      /*!< Number of slice-dependent time offsets */
01396    float * toff_sl ;  /*!< toff_sl[i] is time offset for slice #1 */
01397    float   zorg_sl ;  /*!< z-coordinate origin for slice offsets */
01398    float   dz_sl ;    /*!< z-coordinate spacing for slice offsets */
01399 } THD_timeaxis ;
01400 
01401 /*! Check if tax points to a valid THD_timeaxis struct. */
01402 
01403 #define ISVALID_TIMEAXIS(tax) ((tax) != NULL && (tax)->type == TIMEAXIS_TYPE)
01404 
01405 /*---------------------------------------------------------------------*/
01406 /*--------- data structure for statistics about a 3D dataset ----------*/
01407 
01408 #define STATISTICS_TYPE 17
01409 
01410 /*! Statistics about data in a sub-brick.
01411     (e.g., Used in the Define Function control panel in AFNI.)
01412 */
01413 
01414 typedef struct {
01415    float min ;      /*!< Smallest value in sub-brick */
01416    float max ;      /*!< Largest value in sub-brick */
01417 } THD_brick_stats ;
01418 
01419 /*! Collection of statistics about all sub-bricks. */
01420 
01421 typedef struct {
01422    int type ;                     /*!< STATISTICS_TYPE */
01423    int              nbstat ;      /*!< Number of entries below */
01424    THD_brick_stats * bstat ;      /*!< Array of entries for all sub-bricks */
01425    XtPointer parent ;             /*!< Owner of this object */
01426 } THD_statistics ;
01427 
01428 /*! Check if st is a valid THD_statistics struct. */
01429 
01430 #define ISVALID_STATISTIC(st) ( (st) != NULL && (st)->type == STATISTICS_TYPE )
01431 
01432 /*! Check if bst is a valid sub-brick statistic. */
01433 
01434 #define ISVALID_BSTAT(bst) ( (bst).min <= (bst).max )
01435 
01436 /*! Make bst have invalid data. */
01437 
01438 #define INVALIDATE_BSTAT(bst) ( (bst).min = 1.0 , (bst).max = -1.0 )
01439 
01440 /*! Destroy a THD_statistics struct. */
01441 
01442 #define KILL_STATISTIC(st)          \
01443   do{ if( ISVALID_STATISTIC(st) ){  \
01444         XtFree((char *)(st)->bstat) ; XtFree((char *)(st)) ; } } while(0)
01445 
01446 /*--------------------------------------------------------------------*/
01447 /*--------------------  Unique ID code for a 3D dataset  -------------*/
01448 
01449 #ifndef IDCODE_PREFIX
01450 #  define MCW_IDPREFIX "NIH_"
01451 #else
01452 #  define MCW_IDPREFIX IDCODE_PREFIX
01453 #endif
01454 
01455 /*! Size of ID code string. 27 Sep 2001: increased from 16 to 32. */
01456 #define MCW_IDSIZE 32
01457 
01458 /*! Size of ID date string. */
01459 #define MCW_IDDATE 48
01460 
01461 /*! Struct to hold ID code for a dataset. */
01462 
01463 typedef struct {
01464   char str[MCW_IDSIZE] ;    /*!< Unique ID code string */
01465   char date[MCW_IDDATE] ;   /*!< Date string was generated */
01466 } MCW_idcode ;
01467 
01468 extern MCW_idcode MCW_new_idcode (void) ;
01469 extern void       MCW_hash_idcode( char *, struct THD_3dim_dataset * ) ;
01470 
01471 /*! Check if 2 ID code strings are equal. */
01472 
01473 #define EQUIV_IDCODES(id,ie) (strncmp((id).str,(ie).str,MCW_IDSIZE) == 0)
01474 
01475 /*! Check if 2 AFNI dataset pointers point to the same dataset struct. */
01476 
01477 #define EQUIV_DSETS(ds,es) \
01478    ( (ds)==(es) ||         \
01479      ((ds)!=NULL && (es)!=NULL && EQUIV_IDCODES((ds)->idcode,(es)->idcode)) )
01480 
01481 /*! Check if 2 AFNI dataset pointers are different but have the same ID codes. */
01482 
01483 #define DUPLICATE_DSETS(ds,es)   \
01484    ( (ds) != (es) &&             \
01485      (ds) != NULL &&             \
01486      (es) != NULL && EQUIV_IDCODES((ds)->idcode,(es)->idcode) )
01487 
01488 /*! Zero out the ID code. */
01489 
01490 #define ZERO_IDCODE(id)   ((id).str[0] = (id).date[0] = '\0')
01491 
01492 /*! Check if the ID code is zero. */
01493 
01494 #define ISZERO_IDCODE(id) ((id).str[0] == '\0')
01495 
01496 #define ATRNAME_IDSTRING  "IDCODE_STRING"
01497 #define ATRNAME_IDDATE    "IDCODE_DATE"
01498 #define ATRNAME_IDANATPAR "IDCODE_ANAT_PARENT"
01499 #define ATRNAME_IDWARPPAR "IDCODE_WARP_PARENT"
01500 
01501 /*----------------------------------------------------------------------*/
01502 /*------------------- how to present the coordinates -------------------*/
01503 
01504 /*! How to present coordinates to the user (vs. the internal RAI/Dicom order). */
01505 
01506 typedef struct {
01507    int xxsign , yysign , zzsign ,
01508        first  , second , third  ,
01509        xxor   , yyor   , zzor    ;
01510    char orcode[4] ;
01511 } THD_coorder ;
01512 
01513 extern void THD_coorder_fill( char * , THD_coorder * ) ;
01514 extern void THD_dicom_to_coorder( THD_coorder *, float *, float *, float * ) ;
01515 extern void THD_coorder_to_dicom( THD_coorder *, float *, float *, float * ) ;
01516 
01517 /*----------------------------------------------------------------------*/
01518 /*-------------- internal data structure for a 3D dataset --------------*/
01519 
01520 /* dataset type codes and string */
01521 
01522 #define HEAD_ANAT_TYPE 0
01523 #define HEAD_ANAT_STR  "3DIM_HEAD_ANAT"
01524 
01525 #define HEAD_FUNC_TYPE 1
01526 #define HEAD_FUNC_STR  "3DIM_HEAD_FUNC"
01527 
01528 #define GEN_ANAT_TYPE  2
01529 #define GEN_ANAT_STR   "3DIM_GEN_ANAT"
01530 
01531 #define GEN_FUNC_TYPE  3
01532 #define GEN_FUNC_STR   "3DIM_GEN_FUNC"
01533 
01534 #define FIRST_3DIM_TYPE 0
01535 #define LAST_3DIM_TYPE  3
01536 
01537 #define LONGEST_3DIM_TYPESTR strlen(HEAD_ANAT_STR)
01538 
01539 static char * DATASET_typestr[] = {
01540    HEAD_ANAT_STR , HEAD_FUNC_STR , GEN_ANAT_STR , GEN_FUNC_STR
01541 } ;
01542 
01543 /* view type codes, string, and viewcodes */
01544 
01545 #define VIEW_ORIGINAL_TYPE    0
01546 #define VIEW_ORIGINAL_STR     "Original View"
01547 #define VIEW_ORIGINAL_CODE    "orig"
01548 
01549 #define VIEW_ACPCALIGNED_TYPE 1
01550 #define VIEW_ACPCALIGNED_STR  "AC-PC Aligned"
01551 #define VIEW_ACPCALIGNED_CODE "acpc"
01552 
01553 #define VIEW_TALAIRACH_TYPE   2
01554 #define VIEW_TALAIRACH_STR    "Talairach View"
01555 #define VIEW_TALAIRACH_CODE   "tlrc"
01556 
01557 #define VIEW_REGISTERED_TYPE  3
01558 #define VIEW_REGISTERED_STR   "Registered View"
01559 #define VIEW_REGISTERED_CODE  "rgst"
01560 
01561 #define FIRST_VIEW_TYPE 0
01562 #define LAST_VIEW_TYPE  2
01563 
01564 #define LONGEST_VIEW_TYPESTR strlen(VIEW_REGISTERED_STR)
01565 
01566 static char * VIEW_typestr[] = {
01567    VIEW_ORIGINAL_STR  , VIEW_ACPCALIGNED_STR ,
01568    VIEW_TALAIRACH_STR , VIEW_REGISTERED_STR
01569 } ;
01570 
01571 static char * VIEW_codestr[] = {
01572    VIEW_ORIGINAL_CODE  , VIEW_ACPCALIGNED_CODE ,
01573    VIEW_TALAIRACH_CODE , VIEW_REGISTERED_CODE
01574 } ;
01575 
01576 /* function type codes, string, and prefixes */
01577 
01578 #define FUNC_FIM_TYPE       0
01579 #define FUNC_FIM_STR        "Intensity"
01580 #define FUNC_FIM_PREFIX     "fim"
01581 #define FUNC_FIM_LABEL      "fim"
01582 #define FUNC_FIM_DESCRIPTOR "Functional Intensity"
01583 #define FUNC_FIM_MASK       (1 << FUNC_FIM_TYPE)
01584 
01585 /** old PAIR type retained for compatibility **/
01586 
01587 #define FUNC_PAIR_TYPE   1
01588 #define FUNC_PAIR_STR    "Inten+Thr"
01589 #define FUNC_PAIR_PREFIX "fith"
01590 
01591 #define FUNC_THR_TYPE          FUNC_PAIR_TYPE
01592 #define FUNC_THR_STR           FUNC_PAIR_STR
01593 #define FUNC_THR_PREFIX        FUNC_PAIR_PREFIX
01594 #define FUNC_THR_TOP           1.0        /* maximum true value               */
01595 #define FUNC_THR_SCALE_SHORT   10000      /* stored short = this * true value */
01596 #define FUNC_THR_SCALE_BYTE    100        /* stored byte  = this * true value */
01597 #define FUNC_THR_LABEL         "Thr "     /* <= 4 characters!                 */
01598 #define FUNC_THR_DESCRIPTOR    "Old style threshold"
01599 #define FUNC_THR_MASK          (1 << FUNC_PAIR_TYPE)
01600 
01601 #define FUNC_COR_TYPE          2
01602 #define FUNC_COR_STR           "Inten+Cor"
01603 #define FUNC_COR_PREFIX        "fico"
01604 #define FUNC_COR_TOP           1.0
01605 #define FUNC_COR_SCALE_SHORT   10000
01606 #define FUNC_COR_SCALE_BYTE    100
01607 #define FUNC_COR_LABEL         "Corr"
01608 #define FUNC_COR_DESCRIPTOR    "Correlation Coefficient"
01609 #define FUNC_COR_MASK          (1 << FUNC_COR_TYPE)
01610 
01611 #define FUNC_TT_TYPE           3
01612 #define FUNC_TT_STR            "Inten+Ttest"
01613 #define FUNC_TT_PREFIX         "fitt"
01614 #define FUNC_TT_TOP           10.0
01615 #define FUNC_TT_SCALE_SHORT   1000
01616 #define FUNC_TT_SCALE_BYTE    10
01617 #define FUNC_TT_LABEL         "T-t "
01618 #define FUNC_TT_DESCRIPTOR    "Student t-statistic"
01619 #define FUNC_TT_MASK          (1 << FUNC_TT_TYPE)
01620 
01621                                                     /* 30 Oct 1996 */
01622 #define FUNC_FT_TYPE           4
01623 #define FUNC_FT_STR            "Inten+Ftest"
01624 #define FUNC_FT_PREFIX         "fift"
01625 #define FUNC_FT_TOP           100.0
01626 #define FUNC_FT_SCALE_SHORT   100
01627 #define FUNC_FT_SCALE_BYTE    1
01628 #define FUNC_FT_LABEL         "F-t "
01629 #define FUNC_FT_DESCRIPTOR    "Fisher F-statistic"
01630 #define FUNC_FT_MASK          (1 << FUNC_FT_TYPE)
01631 
01632                                                     /* 22 Jul 1997 */
01633 #define FUNC_ZT_TYPE           5
01634 #define FUNC_ZT_STR            "Inten+Ztest"
01635 #define FUNC_ZT_PREFIX         "fizt"
01636 #define FUNC_ZT_TOP           10.0
01637 #define FUNC_ZT_SCALE_SHORT   1000
01638 #define FUNC_ZT_SCALE_BYTE    10
01639 #define FUNC_ZT_LABEL         "Z-t "
01640 #define FUNC_ZT_DESCRIPTOR    "Normal (Gaussian) Z"
01641 #define FUNC_ZT_MASK          (1 << FUNC_ZT_TYPE)
01642 
01643                                                     /* 22 Jul 1997 */
01644 #define FUNC_CT_TYPE           6
01645 #define FUNC_CT_STR            "Inten+ChiSq"
01646 #define FUNC_CT_PREFIX         "fict"
01647 #define FUNC_CT_TOP           100.0
01648 #define FUNC_CT_SCALE_SHORT   100
01649 #define FUNC_CT_SCALE_BYTE    1
01650 #define FUNC_CT_LABEL         "ChiS"
01651 #define FUNC_CT_DESCRIPTOR    "Chi-Squared statistic"
01652 #define FUNC_CT_MASK          (1 << FUNC_CT_TYPE)
01653 
01654                                                     /* 22 Jul 1997 */
01655 #define FUNC_BT_TYPE           7
01656 #define FUNC_BT_STR            "Inten+Beta"
01657 #define FUNC_BT_PREFIX         "fibt"
01658 #define FUNC_BT_TOP           1.0
01659 #define FUNC_BT_SCALE_SHORT   10000
01660 #define FUNC_BT_SCALE_BYTE    100
01661 #define FUNC_BT_LABEL         "Beta"
01662 #define FUNC_BT_DESCRIPTOR    "Beta Distribution"
01663 #define FUNC_BT_MASK          (1 << FUNC_BT_TYPE)
01664 
01665                                                     /* 22 Jul 1997 */
01666 #define FUNC_BN_TYPE           8
01667 #define FUNC_BN_STR            "Inten+Binom"
01668 #define FUNC_BN_PREFIX         "fibn"
01669 #define FUNC_BN_TOP           100.0
01670 #define FUNC_BN_SCALE_SHORT   100
01671 #define FUNC_BN_SCALE_BYTE    1
01672 #define FUNC_BN_LABEL         "Bino"
01673 #define FUNC_BN_DESCRIPTOR    "Binomial Distribution"
01674 #define FUNC_BN_MASK          (1 << FUNC_BN_TYPE)
01675 
01676                                                     /* 22 Jul 1997 */
01677 #define FUNC_GT_TYPE           9
01678 #define FUNC_GT_STR            "Inten+Gamma"
01679 #define FUNC_GT_PREFIX         "figt"
01680 #define FUNC_GT_TOP           10.0
01681 #define FUNC_GT_SCALE_SHORT   1000
01682 #define FUNC_GT_SCALE_BYTE    10
01683 #define FUNC_GT_LABEL         "Gam "
01684 #define FUNC_GT_DESCRIPTOR    "Gamma Distribution"
01685 #define FUNC_GT_MASK          (1 << FUNC_GT_TYPE)
01686 
01687                                                     /* 22 Jul 1997 */
01688 #define FUNC_PT_TYPE          10
01689 #define FUNC_PT_STR            "Inten+Poisson"
01690 #define FUNC_PT_PREFIX         "fipt"
01691 #define FUNC_PT_TOP           100.0
01692 #define FUNC_PT_SCALE_SHORT   100
01693 #define FUNC_PT_SCALE_BYTE    1
01694 #define FUNC_PT_LABEL         "Pois"
01695 #define FUNC_PT_DESCRIPTOR    "Poisson Distribution"
01696 #define FUNC_PT_MASK          (1 << FUNC_PT_TYPE)
01697 
01698                                                    /* 30 Nov 1997 */
01699 #define FUNC_BUCK_TYPE          11
01700 #define FUNC_BUCK_STR           "Func-Bucket"
01701 #define FUNC_BUCK_PREFIX        "fbuc"
01702 #define FUNC_BUCK_TOP           1.0
01703 #define FUNC_BUCK_SCALE_SHORT   1
01704 #define FUNC_BUCK_SCALE_BYTE    1
01705 #define FUNC_BUCK_LABEL         "Buck"
01706 #define FUNC_BUCK_DESCRIPTOR    "Function Bucket"
01707 #define FUNC_BUCK_MASK          (1 << FUNC_BUCK_TYPE)
01708 
01709 #define FIRST_FUNC_TYPE  0
01710 #define LAST_FUNC_TYPE  11
01711 
01712 #define FIRST_STAT_TYPE  2
01713 #define LAST_STAT_TYPE  10
01714 
01715 #define FUNC_ALL_MASK (FUNC_FIM_MASK | FUNC_THR_MASK |                \
01716                        FUNC_COR_MASK | FUNC_TT_MASK  | FUNC_FT_MASK | \
01717                        FUNC_ZT_MASK  | FUNC_CT_MASK  | FUNC_BT_MASK | \
01718                        FUNC_BN_MASK  | FUNC_GT_MASK  | FUNC_PT_MASK | \
01719                        FUNC_BUCK_MASK                                    )
01720 
01721 #define LONGEST_FUNC_TYPESTR strlen(FUNC_PT_STR)
01722 
01723 static char * FUNC_typestr[] = {
01724    FUNC_FIM_STR , FUNC_THR_STR , FUNC_COR_STR , FUNC_TT_STR , FUNC_FT_STR ,
01725    FUNC_ZT_STR  , FUNC_CT_STR  , FUNC_BT_STR  ,
01726    FUNC_BN_STR  , FUNC_GT_STR  , FUNC_PT_STR  , FUNC_BUCK_STR
01727 } ;
01728 
01729 static char * FUNC_prefixstr[] = {
01730    FUNC_FIM_PREFIX , FUNC_THR_PREFIX , FUNC_COR_PREFIX ,
01731    FUNC_TT_PREFIX  , FUNC_FT_PREFIX  ,
01732    FUNC_ZT_PREFIX  , FUNC_CT_PREFIX  , FUNC_BT_PREFIX  ,
01733    FUNC_BN_PREFIX  , FUNC_GT_PREFIX  , FUNC_PT_PREFIX  , FUNC_BUCK_PREFIX
01734 } ;
01735 
01736 static float FUNC_topval[] = {
01737   1.0 , FUNC_THR_TOP , FUNC_COR_TOP , FUNC_TT_TOP , FUNC_FT_TOP ,
01738         FUNC_ZT_TOP  , FUNC_CT_TOP  , FUNC_BT_TOP ,
01739         FUNC_BN_TOP  , FUNC_GT_TOP  , FUNC_PT_TOP , FUNC_BUCK_TOP
01740 } ;
01741 
01742 static int FUNC_scale_short[] = {
01743   1 , FUNC_THR_SCALE_SHORT , FUNC_COR_SCALE_SHORT ,
01744       FUNC_TT_SCALE_SHORT  , FUNC_FT_SCALE_SHORT  ,
01745       FUNC_ZT_SCALE_SHORT  , FUNC_CT_SCALE_SHORT  , FUNC_BT_SCALE_SHORT ,
01746       FUNC_BN_SCALE_SHORT  , FUNC_GT_SCALE_SHORT  , FUNC_PT_SCALE_SHORT ,
01747       FUNC_BUCK_SCALE_SHORT
01748 } ;
01749 
01750 static int FUNC_scale_byte[] = {
01751   1 , FUNC_THR_SCALE_BYTE , FUNC_COR_SCALE_BYTE ,
01752       FUNC_TT_SCALE_BYTE  , FUNC_FT_SCALE_BYTE  ,
01753       FUNC_ZT_SCALE_BYTE  , FUNC_CT_SCALE_BYTE  , FUNC_BT_SCALE_BYTE ,
01754       FUNC_BN_SCALE_BYTE  , FUNC_GT_SCALE_BYTE  , FUNC_PT_SCALE_BYTE ,
01755       FUNC_BUCK_SCALE_BYTE
01756 } ;
01757 
01758 static char * FUNC_label[] = {
01759   FUNC_FIM_LABEL , FUNC_THR_LABEL , FUNC_COR_LABEL , FUNC_TT_LABEL , FUNC_FT_LABEL ,
01760   FUNC_ZT_LABEL  , FUNC_CT_LABEL  , FUNC_BT_LABEL ,
01761   FUNC_BN_LABEL  , FUNC_GT_LABEL  , FUNC_PT_LABEL , FUNC_BUCK_LABEL
01762 } ;
01763 
01764 static char * FUNC_descriptor[] = {
01765   FUNC_FIM_DESCRIPTOR , FUNC_THR_DESCRIPTOR ,
01766   FUNC_COR_DESCRIPTOR , FUNC_TT_DESCRIPTOR  , FUNC_FT_DESCRIPTOR ,
01767   FUNC_ZT_DESCRIPTOR  , FUNC_CT_DESCRIPTOR  , FUNC_BT_DESCRIPTOR ,
01768   FUNC_BN_DESCRIPTOR  , FUNC_GT_DESCRIPTOR  , FUNC_PT_DESCRIPTOR ,
01769   FUNC_BUCK_DESCRIPTOR
01770 } ;
01771 
01772 #define AFNI_FIRST_STATCODE FUNC_COR_TYPE
01773 #define AFNI_LAST_STATCODE  FUNC_PT_TYPE
01774 
01775 static int FUNC_nvals[]    = {  1, 2,2,2,2,2,2,2,2,2,2, 1 } ; /* # in each dataset */
01776 static int FUNC_ival_fim[] = {  0, 0,0,0,0,0,0,0,0,0,0, 0 } ; /* index of fim      */
01777 
01778 #define FIMTHR 0   /* set = -1 to disable thresholding for FIM type - 06 Feb 2003 */
01779 
01780 static int FUNC_ival_thr[] = { FIMTHR, 1,1,1,1,1,1,1,1,1,1, 0 } ; /* index of thresh */
01781 
01782 #define FUNC_HAVE_FIM(ftyp)  ((ftyp) >= 0 && \
01783                               (ftyp) <= LAST_FUNC_TYPE && FUNC_ival_fim[(ftyp)] >= 0)
01784 
01785 #define FUNC_HAVE_THR(ftyp)  ((ftyp) >= 0 && \
01786                               (ftyp) <= LAST_FUNC_TYPE && FUNC_ival_thr[(ftyp)] >= 0)
01787 
01788 #define FUNC_IS_STAT(ftyp)   ((ftyp) >= FIRST_STAT_TYPE && (ftyp) <= LAST_STAT_TYPE)
01789 #define FUNC_HAVE_PVAL       FUNC_IS_STAT
01790 
01791 /******* dimension of auxiliary array for functional statistics *******/
01792 
01793 #define MAX_STAT_AUX 64
01794 
01795 /*! Number of statistical parameters needed for each statistic code. */
01796 
01797 static int FUNC_need_stat_aux[] = { 0 , 0 , 3 , 1 , 2 ,
01798                                     0 , 1 , 2 , 2 , 2 , 1 ,
01799                                     0 } ; /* # aux data needed */
01800 
01801 /*! Labels describing the parameters needed for each statistic code. */
01802 
01803 static char * FUNC_label_stat_aux[] = {
01804    "N/A" , "N/A" ,                                      /* fim, fith */
01805    "SAMPLES  FIT-PARAMETERS  ORT-PARAMETERS" ,          /* fico */
01806    "DEGREES-of-FREEDOM" ,                               /* fitt */
01807    "NUMERATOR and DENOMINATOR DEGREES-of-FREEDOM" ,     /* fift */
01808    "N/A" ,                                              /* fizt */
01809    "DEGREES-of-FREEDOM" ,                               /* fict */
01810    "A (numerator) and B (denominator)" ,                /* fibt */
01811    "NUMBER-of-TRIALS and PROBABILITY-per-TRIAL" ,       /* fibn */
01812    "SHAPE and SCALE" ,                                  /* figt */
01813    "MEAN" ,                                             /* fipt */
01814    "N/A"                                                /* fbuc */
01815 } ;
01816 
01817 /***  stat_aux values:
01818         FUNC_FIM_TYPE = not used
01819         FUNC_THR_TYPE = not used
01820         FUNC_COR_TYPE = # samples, # fit parameters, # ort parameters
01821         FUNC_TT_TYPE  = # degrees of freedom
01822         FUNC_FT_TYPE  = DOF for numerator and denominator
01823         FUNC_ZT_TYPE  = not used
01824         FUNC_CT_TYPE  = DOF
01825         FUNC_BT_TYPE  = a and b parameters
01826         FUNC_BN_TYPE  = number of trials, and probability per trial
01827         FUNC_GT_TYPE  = shape and scale parameters
01828         FUNC_PT_TYPE  = mean of Poisson distribution
01829       FUNC_BUCK_TYPE  = not used
01830 ***********************************************************************/
01831 
01832 /****   anatomy type codes, strings, and prefixes        ****/
01833 /* (these are not used much at present, but may be someday) */
01834 
01835 #define ANAT_SPGR_TYPE   0
01836 #define ANAT_SPGR_STR    "Spoiled GRASS"
01837 #define ANAT_SPGR_PREFIX "spgr"
01838 #define ANAT_SPGR_MASK   (1 << ANAT_SPGR_TYPE)
01839 
01840 #define ANAT_FSE_TYPE    1
01841 #define ANAT_FSE_STR     "Fast Spin Echo"
01842 #define ANAT_FSE_PREFIX  "fse"
01843 #define ANAT_FSE_MASK    (1 << ANAT_FSE_TYPE)
01844 
01845 #define ANAT_EPI_TYPE    2
01846 #define ANAT_EPI_STR     "Echo Planar"
01847 #define ANAT_EPI_PREFIX  "epan"
01848 #define ANAT_EPI_MASK    (1 << ANAT_EPI_TYPE)
01849 
01850 #define ANAT_MRAN_TYPE   3
01851 #define ANAT_MRAN_STR    "MRI Anatomy"
01852 #define ANAT_MRAN_PREFIX "anat"
01853 #define ANAT_MRAN_MASK   (1 << ANAT_MRAN_TYPE)
01854 
01855 #define ANAT_CT_TYPE     4
01856 #define ANAT_CT_STR      "CT Scan"
01857 #define ANAT_CT_PREFIX   "ct"
01858 #define ANAT_CT_MASK     (1 << ANAT_CT_TYPE)
01859 
01860 #define ANAT_SPECT_TYPE   5
01861 #define ANAT_SPECT_STR    "SPECT Anatomy"
01862 #define ANAT_SPECT_PREFIX "spct"
01863 #define ANAT_SPECT_MASK   (1 << ANAT_SPECT_TYPE)
01864 
01865 #define ANAT_PET_TYPE     6
01866 #define ANAT_PET_STR      "PET Anatomy"
01867 #define ANAT_PET_PREFIX   "pet"
01868 #define ANAT_PET_MASK     (1 << ANAT_PET_TYPE)
01869 
01870 #define ANAT_MRA_TYPE    7
01871 #define ANAT_MRA_STR     "MR Angiography"
01872 #define ANAT_MRA_PREFIX  "mra"
01873 #define ANAT_MRA_MASK    (1 << ANAT_MRA_TYPE)
01874 
01875 #define ANAT_BMAP_TYPE   8
01876 #define ANAT_BMAP_STR    "B-field Map"
01877 #define ANAT_BMAP_PREFIX "bmap"
01878 #define ANAT_BMAP_MASK   (1 << ANAT_BMAP_TYPE)
01879 
01880 #define ANAT_DIFF_TYPE   9
01881 #define ANAT_DIFF_STR    "Diffusion Map"
01882 #define ANAT_DIFF_PREFIX "diff"
01883 #define ANAT_DIFF_MASK   (1 << ANAT_DIFF_TYPE)
01884 
01885 #define ANAT_OMRI_TYPE   10
01886 #define ANAT_OMRI_STR    "Other MRI"
01887 #define ANAT_OMRI_PREFIX "omri"
01888 #define ANAT_OMRI_MASK   (1 << ANAT_OMRI_TYPE)
01889 
01890 #define ANAT_BUCK_TYPE   11
01891 #define ANAT_BUCK_STR    "Anat Bucket"
01892 #define ANAT_BUCK_PREFIX "abuc"
01893 #define ANAT_BUCK_MASK   (1 << ANAT_BUCK_TYPE)
01894 
01895 #define ANAT_MAPC_TYPE   12
01896 #define ANAT_MAPC_STR    "Mapped Color"
01897 #define ANAT_MAPC_PREFIX "mapc"
01898 #define ANAT_MAPC_MASK   (1 << ANAT_MAPC_TYPE)
01899 
01900 #define FIRST_ANAT_TYPE  0
01901 #define LAST_ANAT_TYPE   11
01902 
01903 #define ANAT_ALL_MASK ( ANAT_SPGR_MASK | ANAT_FSE_MASK | ANAT_EPI_MASK   | \
01904                         ANAT_MRAN_MASK | ANAT_CT_MASK  | ANAT_SPECT_MASK | \
01905                         ANAT_PET_MASK  | ANAT_MRA_MASK | ANAT_BMAP_MASK  | \
01906                         ANAT_DIFF_MASK | ANAT_OMRI_MASK| ANAT_BUCK_MASK  | \
01907                         ANAT_MAPC_MASK )
01908 
01909 #define NUM_DSET_TYPES (LAST_FUNC_TYPE + LAST_ANAT_TYPE + 2)
01910 
01911 #define LONGEST_ANAT_TYPESTR strlen(ANAT_MRA_STR)
01912 
01913 static char * ANAT_typestr[] = {
01914  ANAT_SPGR_STR , ANAT_FSE_STR   , ANAT_EPI_STR  , ANAT_MRAN_STR ,
01915  ANAT_CT_STR   , ANAT_SPECT_STR , ANAT_PET_STR  ,
01916  ANAT_MRA_STR  , ANAT_BMAP_STR  , ANAT_DIFF_STR , ANAT_OMRI_STR ,
01917  ANAT_BUCK_STR , ANAT_MAPC_STR
01918 } ;
01919 
01920 static char * ANAT_prefixstr[] = {
01921  ANAT_SPGR_PREFIX , ANAT_FSE_PREFIX   , ANAT_EPI_PREFIX  , ANAT_MRAN_PREFIX ,
01922  ANAT_CT_PREFIX   , ANAT_SPECT_PREFIX , ANAT_PET_PREFIX  ,
01923  ANAT_MRA_PREFIX  , ANAT_BMAP_PREFIX  , ANAT_DIFF_PREFIX , ANAT_OMRI_PREFIX ,
01924  ANAT_BUCK_PREFIX , ANAT_MAPC_PREFIX
01925 } ;
01926 
01927 /* Feb 1998: put all together */
01928 
01929 static char * DSET_prefixstr[NUM_DSET_TYPES] = {
01930    FUNC_FIM_PREFIX , FUNC_THR_PREFIX , FUNC_COR_PREFIX ,
01931    FUNC_TT_PREFIX  , FUNC_FT_PREFIX  ,
01932    FUNC_ZT_PREFIX  , FUNC_CT_PREFIX  , FUNC_BT_PREFIX  ,
01933    FUNC_BN_PREFIX  , FUNC_GT_PREFIX  , FUNC_PT_PREFIX  , FUNC_BUCK_PREFIX ,
01934    ANAT_SPGR_PREFIX , ANAT_FSE_PREFIX   , ANAT_EPI_PREFIX  , ANAT_MRAN_PREFIX ,
01935    ANAT_CT_PREFIX   , ANAT_SPECT_PREFIX , ANAT_PET_PREFIX  ,
01936    ANAT_MRA_PREFIX  , ANAT_BMAP_PREFIX  , ANAT_DIFF_PREFIX , ANAT_OMRI_PREFIX ,
01937    ANAT_BUCK_PREFIX
01938 } ;
01939 
01940 #define DSET_PREFIXSTR(ds) ( ISFUNC(ds) ? FUNC_prefixstr[(ds)->func_type]  \
01941                                         : ANAT_prefixstr[(ds)->func_type] )
01942 
01943 #define DSET_FUNCLABEL(ds) ( ISFUNC(ds) ? FUNC_label[(ds)->func_type]      \
01944                                         : ANAT_prefixstr[(ds)->func_type] )
01945 
01946 #define DSET_TYPESTR(ds)   ( ISFUNC(ds) ? FUNC_typestr[(ds)->func_type]     \
01947                                         : ANAT_typestr[(ds)->func_type] )
01948 
01949 static int ANAT_nvals[]     = { 1,1,1,1,1,1,1,1,1,1,1,1 , 1 } ;
01950 static int ANAT_ival_zero[] = { 0,0,0,0,0,0,0,0,0,0,0,0 , 0 } ;
01951 
01952 /* the data structure itself */
01953 
01954 struct THD_3dim_dataset_array ;  /* incomplete definition */
01955 
01956 /*! One AFNI dataset structure.
01957     Most elements are accessed via macros, and should only be changed via EDIT_dset_items(). */
01958 
01959 typedef struct THD_3dim_dataset {
01960       int type ;        /*!< type code: HEAD_ANAT_TYPE or HEAD_FUNC_TYPE or GEN_ANAT_TYPE or GEN_FUNC_TYPE */
01961 
01962       int view_type ;   /*!< view code: VIEW_ORIGINAL_TYPE or VIEW_ACPCALIGNED_TYPE or VIEW_TALAIRACH_TYPE */
01963       int func_type ;   /*!< dataset type: one of FUNC_*_TYPE or ANAT_*_TYPE codes */
01964 
01965       char label1[THD_MAX_LABEL] ;  /*!< short label #1: not used for anything anymore */
01966       char label2[THD_MAX_LABEL] ;  /*!< short label #2: even more obsolete */
01967 
01968       THD_datablock   * dblk ;      /*!< pointer to actual data */
01969       THD_dataxes     * daxes ;     /*!< info about axes (where dataset is) */
01970       THD_dataxes     * wod_daxes ; /*!< warp-on-demand axes (for viewing interpolated dataset) */
01971       int               wod_flag ;  /*!< if true, use wod_daxes, otherwise use daxes */
01972 
01973       THD_timeaxis    * taxis ;     /*!< non-NULL --> this is a 3D+t dataset */
01974 
01975       THD_marker_set  * markers ;   /*!< user set mark points (if non-NULL) */
01976 
01977       struct THD_3dim_dataset * warp_parent ; /*!< non-NULL --> this dataset is warped from that one */
01978       THD_warp                * warp ;        /*!< this is the coordinate-to-coordinate warp */
01979       THD_warp                * vox_warp ;    /*!< this is the index-to-index warp */
01980 
01981       struct THD_3dim_dataset * anat_parent ;   /*!< non-NULL --> linked to this as anatomical ref */
01982 
01983       THD_statistics          * stats ;      /*!< statistics about the sub-brick data */
01984 
01985       float stat_aux[MAX_STAT_AUX] ;         /*!< global auxiliary statistics info */
01986 
01987       char warp_parent_name[THD_MAX_NAME] ;  /*!< "name" of warp_parent dataset (no longer used) */
01988       char anat_parent_name[THD_MAX_NAME] ;  /*!< "name" of anat_parent dataset (no longer used) */
01989       char self_name[THD_MAX_NAME]        ;  /*!< my own "name" (no longer used) */
01990 
01991 #ifdef ALLOW_DATASET_VLIST
01992       THD_vector_list * pts ;     /*!< in dataset coords (not Dicom order!) - for Ted Deyoe */
01993       Boolean pts_original ;      /*!< true if was read from disk directly */
01994 #endif
01995 
01996       int death_mark ;            /*!< dataset is marked for destruction */
01997 
01998       MCW_idcode idcode ;              /*!< globally unique (I hope) ID code for this dataset */
01999       MCW_idcode anat_parent_idcode ;  /*!< ID code for warp_parent dataset */
02000       MCW_idcode warp_parent_idcode ;  /*!< ID code for anat_parent dataset */
02001 
02002       char * keywords ;           /*!< 30 Nov 1997: keyword list for dataset */
02003 
02004       THD_usertaglist * tagset ;  /*!< 23 Oct 1998: see plug_tag.c */
02005 
02006    /* pointers to other stuff */
02007 
02008       KILL_list kl ;              /*!< Stuff to delete if this dataset is deleted (see killer.h) */
02009       XtPointer parent ;          /*!< Somebody that "owns" this dataset */
02010 
02011    /* 26 Aug 2002: self warp (for w-o-d) */
02012 
02013       THD_warp *self_warp ;
02014 
02015    /* 03 Aug 2004: list of filenames to cat together (cf. THD_open_tcat) */
02016 
02017       char *tcat_list ;
02018       int   tcat_num ;
02019       int  *tcat_len ;
02020 
02021 } THD_3dim_dataset ;
02022 
02023 /*! A marker that defines a dataset that is about to be killed. */
02024 
02025 #define DOOMED 665
02026 
02027 /*! Mark a dataset to be eliminated by AFNI_mark_for_death() and AFNI_andersonville(). */
02028 
02029 #define DSET_MARK_FOR_DEATH(ds)                                         \
02030  do{ if( ISVALID_DSET(ds) && ds->death_mark >= 0 ) ds->death_mark = DOOMED ; } while(0)
02031 
02032 /*! Mark a dataset to be ineligible for elimination during AFNI_rescan_session(). */
02033 
02034 #define DSET_MARK_FOR_IMMORTALITY(ds)                                   \
02035  do{ if( ISVALID_DSET(ds) ) ds->death_mark = -1 ; } while(0)
02036 
02037 /*! Mark a dataset to be eligible for elimination if the need arises. */
02038 
02039 #define DSET_MARK_FOR_NORMAL(ds)                                        \
02040  do{ if( ISVALID_DSET(ds) ) ds->death_mark = 0 ; } while(0)
02041 
02042 /*! Dataset is tcat-ed? */
02043 
02044 #define DSET_IS_TCAT(ds) (ISVALID_DSET(ds) && (ds)->tcat_list != NULL)
02045 
02046 /*! Return pointer to current dataset axes (warp-on-demand or permanent). */
02047 
02048 #define CURRENT_DAXES(ds) (((ds)->wod_flag) ? ((ds)->wod_daxes) : ((ds)->daxes))
02049 
02050 /*! Determine if ds is a pointer to a valid dataset. */
02051 
02052 #define ISVALID_3DIM_DATASET(ds)                      \
02053    ( (ds) != NULL && (ds)->type >= FIRST_3DIM_TYPE && \
02054                      (ds)->type <= LAST_3DIM_TYPE  && \
02055       ISVALID_DATABLOCK((ds)->dblk)                  )
02056 
02057 /*! Determine if ds is a pointer to a valid dataset. */
02058 
02059 #define ISVALID_DSET ISVALID_3DIM_DATASET
02060 
02061 /*! Determine if nn is a functional dataset type code. */
02062 
02063 #define ISFUNCTYPE(nn) ( (nn) == HEAD_FUNC_TYPE || (nn) == GEN_FUNC_TYPE )
02064 
02065 /*! Determine if dset is a functional dataset. */
02066 
02067 #define ISFUNC(dset) ( ISVALID_DSET(dset) && ISFUNCTYPE((dset)->type) )
02068 
02069 /*! Determine if nn is an anatomical dataset type code. */
02070 
02071 #define ISANATTYPE(nn) ( (nn) == HEAD_ANAT_TYPE || (nn) == GEN_ANAT_TYPE )
02072 
02073 /*! Determine if dset is an anatomical dataset. */
02074 
02075 #define ISANAT(dset) ( ISVALID_DSET(dset) && ISANATTYPE((dset)->type) )
02076 
02077 /*! Determine if nn is a head dataset type code. */
02078 
02079 #define ISHEADTYPE(nn) ( (nn) == HEAD_ANAT_TYPE || (nn) == HEAD_FUNC_TYPE )  /* 09 Sep 2002: ==ugh */
02080 
02081 /*! Determine if dset is a head dataset (vs. non-head). */
02082 
02083 #define ISHEAD(dset) ( ISVALID_DSET(dset) && ISHEADTYPE((dset)->type) )
02084 
02085 /*! Determine if dset is an anatomical bucket dataset */
02086 
02087 #define ISANATBUCKET(dset) ( ISANAT(dset) && (dset)->func_type == ANAT_BUCK_TYPE )
02088 
02089 /*! Determine if dset is a functional bucket dataset */
02090 
02091 #define ISFUNCBUCKET(dset) ( ISFUNC(dset) && (dset)->func_type == FUNC_BUCK_TYPE )
02092 
02093 /*! Determine if dset is a bucket dataset (functional or anatomical) */
02094 
02095 #define ISBUCKET(dset) ( ISANATBUCKET(dset) || ISFUNCBUCKET(dset) )
02096 
02097 /*! Determine if dataset ds is actually stored on disk */
02098 
02099 #define DSET_ONDISK(ds) ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \
02100                           (ds)->dblk->diskptr->storage_mode!=STORAGE_UNDEFINED )
02101 
02102 /*! Determine if dataset ds is stored in a BRIK file on disk */
02103 
02104 #define DSET_IS_BRIK(ds) ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \
02105                            (ds)->dblk->diskptr->storage_mode == STORAGE_BY_BRICK )
02106 
02107 /*! Determine if datablock db is stored in a MINC file on disk */
02108 
02109 #define DBLK_IS_MINC(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \
02110                            (db)->diskptr->storage_mode == STORAGE_BY_MINC )
02111 
02112 /*! Determine if dataset ds is stored in a MINC file on disk */
02113 
02114 #define DSET_IS_MINC(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&       \
02115                            ISVALID_DISKPTR((ds)->dblk->diskptr) &&               \
02116                            (ds)->dblk->diskptr->storage_mode == STORAGE_BY_MINC )
02117 
02118 /*! Determine if datablock db is stored in a ANALYZE file on disk */
02119 
02120 #define DBLK_IS_ANALYZE(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \
02121                               (db)->diskptr->storage_mode == STORAGE_BY_ANALYZE )
02122 
02123 /*! Determine if dataset ds is stored in a ANALYZE file on disk */
02124 
02125 #define DSET_IS_ANALYZE(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&       \
02126                               ISVALID_DISKPTR((ds)->dblk->diskptr) &&               \
02127                               (ds)->dblk->diskptr->storage_mode == STORAGE_BY_ANALYZE )
02128 
02129 /*! Determine if datablock db is stored in a CTFMRI file on disk */
02130 
02131 #define DBLK_IS_CTFMRI(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \
02132                              (db)->diskptr->storage_mode == STORAGE_BY_CTFMRI )
02133 
02134 /*! Determine if dataset ds is stored in a CTFMRI file on disk */
02135 
02136 #define DSET_IS_CTFMRI(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&       \
02137                              ISVALID_DISKPTR((ds)->dblk->diskptr) &&               \
02138                              (ds)->dblk->diskptr->storage_mode == STORAGE_BY_CTFMRI )
02139 
02140 /*! Determine if datablock db is stored in a CTFSAM file on disk */
02141 
02142 #define DBLK_IS_CTFSAM(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \
02143                              (db)->diskptr->storage_mode == STORAGE_BY_CTFSAM )
02144 
02145 /*! Determine if dataset ds is stored in a CTFSAM file on disk */
02146 
02147 #define DSET_IS_CTFSAM(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&       \
02148                              ISVALID_DISKPTR((ds)->dblk->diskptr) &&               \
02149                              (ds)->dblk->diskptr->storage_mode == STORAGE_BY_CTFSAM )
02150 
02151 /*! Determine if datablock db is stored in a 1D file on disk */
02152 
02153 #define DBLK_IS_1D(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) &&     \
02154                          (db)->diskptr->storage_mode == STORAGE_BY_1D )
02155 
02156 /*! Determine if datablock db is stored in a 3D file on disk */
02157 
02158 #define DBLK_IS_3D(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) &&     \
02159                          (db)->diskptr->storage_mode == STORAGE_BY_3D )
02160 
02161 /*! Determine if datablock db is stored in a NIFTI file on disk */
02162 
02163 #define DBLK_IS_NIFTI(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) &&  \
02164                            (db)->diskptr->storage_mode == STORAGE_BY_NIFTI )
02165 
02166 /*! Determine if dataset ds is stored in a 1D file on disk */
02167 
02168 #define DSET_IS_1D(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&           \
02169                          ISVALID_DISKPTR((ds)->dblk->diskptr) &&                   \
02170                          (ds)->dblk->diskptr->storage_mode == STORAGE_BY_1D )
02171 
02172 /*! Determine if dataset ds is stored in a 3D file on disk */
02173 
02174 #define DSET_IS_3D(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&           \
02175                          ISVALID_DISKPTR((ds)->dblk->diskptr) &&                   \
02176                          (ds)->dblk->diskptr->storage_mode == STORAGE_BY_3D )
02177 
02178 /*! Determine if dataset ds is stored in a NIFTI file on disk */
02179 
02180 #define DSET_IS_NIFTI(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&        \
02181                             ISVALID_DISKPTR((ds)->dblk->diskptr) &&                \
02182                             (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NIFTI )
02183 
02184 /*! Determine if datablock db is stored by volume files rather than 1 big BRIK */
02185 
02186 #define DBLK_IS_VOLUMES(db) ( ISVALID_DBLK(db) &&                                \
02187                               ISVALID_DISKPTR((db)->diskptr) &&                  \
02188                               (db)->diskptr->storage_mode == STORAGE_BY_VOLUMES )
02189 
02190 /*! Determine if dataset ds is stored in volumes files rather than 1 big BRIK */
02191 
02192 #define DSET_IS_VOLUMES(ds) ( ISVALID_DSET(ds) &&                                    \
02193                               ISVALID_DBLK((ds)->dblk) &&                            \
02194                               ISVALID_DISKPTR((ds)->dblk->diskptr) &&                \
02195                               (ds)->dblk->diskptr->storage_mode == STORAGE_BY_VOLUMES )
02196 
02197 /*! Determine if datablock db is stored in a MPEG file on disk */
02198 
02199 #define DBLK_IS_MPEG(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \
02200                            (db)->diskptr->storage_mode == STORAGE_BY_MPEG )
02201 
02202 /*! Determine if dataset ds is stored in a MPEG file on disk */
02203 
02204 #define DSET_IS_MPEG(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) &&       \
02205                            ISVALID_DISKPTR((ds)->dblk->diskptr) &&               \
02206                            (ds)->dblk->diskptr->storage_mode == STORAGE_BY_MPEG )
02207 
02208 /*! Determine if AFNI is allowed to over-write dataset ds */
02209 
02210 #define DSET_WRITEABLE(ds)       \
02211  ( ISVALID_DSET(ds)          &&  \
02212    ISVALID_DBLK((ds)->dblk)  &&  \
02213    (ds)->warp_parent != NULL &&  \
02214    !DSET_IS_MINC(ds)         &&  \
02215    !DSET_IS_ANALYZE(ds)        )
02216 
02217 /*! Determine if dataset ds is stored in a compressed format */
02218 
02219 #define DSET_COMPRESSED(ds)                  \
02220    ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \
02221      (ds)->dblk->diskptr != NULL          && \
02222      COMPRESS_filecode((ds)->dblk->diskptr->brick_name) >= 0 )
02223 
02224 /*! Purge the data of dataset ds from memory (you can reload it later) */
02225 
02226 #define PURGE_DSET(ds)                                                  \
02227   do{ if( ISVALID_3DIM_DATASET(ds) && DSET_ONDISK(ds) )                 \
02228          (void) THD_purge_datablock( (ds)->dblk , DATABLOCK_MEM_ANY ) ; \
02229   } while(0)
02230 
02231 /*! Determine if dataset ds is loadable into memory */
02232 
02233 #define DSET_INMEMORY(ds)                                                        \
02234   ( ISVALID_DSET(ds) && (ds)->dblk!=NULL &&                                      \
02235     (ds)->dblk->malloc_type!=DATABLOCK_MEM_UNDEFINED &&                          \
02236     ( (ds)->dblk->diskptr->storage_mode!=STORAGE_UNDEFINED || DSET_LOADED(ds) ) )
02237 
02238 #define DBLK_BRICK(db,iv) ((db)->brick->imarr[(iv)])
02239 
02240 /*! Return the MRI_IMAGE * that is the iv-th volume of dataset ds */
02241 
02242 #define DSET_BRICK(ds,iv) DBLK_BRICK((ds)->dblk,(iv))
02243 
02244 #define DBLK_BRICK_TYPE(db,iv) (DBLK_BRICK((db),(iv))->kind)
02245 
02246 /*! Return the datum code (MRI_short, etc.) of the iv-th volume of dataset ds */
02247 
02248 #define DSET_BRICK_TYPE(ds,iv) DBLK_BRICK_TYPE((ds)->dblk,(iv))
02249 
02250 /*! Return the number of voxels in the iv-th volume of dataset ds */
02251 
02252 #define DBLK_BRICK_NVOX(db,iv) (DBLK_BRICK((db),(iv))->nvox)
02253 
02254 #define DBLK_ARRAY(db,iv) mri_data_pointer( DBLK_BRICK((db),(iv)) )
02255 
02256 /*! Return the pointer to the actual data in the iv-th volume of dataset ds */
02257 
02258 #define DSET_ARRAY(ds,iv) DBLK_ARRAY((ds)->dblk,(iv))
02259 
02260 #define DSET_BRICK_ARRAY DSET_ARRAY  /* Because I sometimes forget the  */
02261 #define DBLK_BRICK_ARRAY DBLK_ARRAY  /* correct names given above - RWC */
02262 
02263 #define DBLK_BRICK_FACTOR(db,iv) ((db)->brick_fac[(iv)])
02264 
02265 /*! Return the brick scaling factor of the iv-th volume of dataset ds.
02266 
02267     If the scale factor is 0, then the brick is used "as-is"; that is,
02268     the effective scale factor is 1.  You can assign to this macro
02269     as in "DSET_BRICK_FACTOR(ds,iv)=3.2;" but I don't recommend this.
02270     Instead, do something like "EDIT_BRICK_FACTOR(ds,iv,3.2);" (see editvol.h).
02271 */
02272 
02273 #define DSET_BRICK_FACTOR(ds,iv) DBLK_BRICK_FACTOR((ds)->dblk,(iv))
02274 
02275 extern int THD_need_brick_factor( THD_3dim_dataset * ) ;
02276 
02277 #define DBLK_BRICK_BYTES(db,iv) ((db)->brick_bytes[iv])
02278 
02279 /*! Return number of bytes stored in the iv-th volume of dataset ds */
02280 
02281 #define DSET_BRICK_BYTES(ds,iv) DBLK_BRICK_BYTES((ds)->dblk,(iv))
02282 
02283 /*! Return the volume index of the "most important" sub-brick in dataset ds.
02284 
02285     This is still used in places, but is fairly obsolete
02286 */
02287 #define DSET_PRINCIPAL_VALUE(ds) ( ISANAT(ds) ? ANAT_ival_zero[(ds)->func_type] \
02288                                               : FUNC_ival_fim[(ds)->func_type] )
02289 
02290 /*! Synonym for DSET_PRINCIPAL_VALUE */
02291 
02292 #define DSET_PRINCIPAL_INDEX DSET_PRINCIPAL_VALUE
02293 
02294 /*! Return the volume index of the "threshold" sub-brick in dataset ds.
02295 
02296     This is analogous to DSET_PRINCIPAL_VALUE, and is also sort-of-obsolete.
02297 */
02298 #define DSET_THRESH_VALUE(ds) (ISANAT((ds)) ? -1 : FUNC_ival_thr[(ds)->func_type])
02299 
02300 #define DSET_THRESH_INDEX DSET_THRESH_VALUE
02301 
02302 /*! Return a pointer to the prefix of dataset ds */
02303 
02304 #define DSET_PREFIX(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \
02305                        ? ((ds)->dblk->diskptr->prefix) : "\0" )
02306 
02307 extern char * THD_newprefix(THD_3dim_dataset * dset, char * suffix); /* 16 Feb 2001 */
02308 extern char * THD_deplus_prefix( char *prefix ) ;                    /* 22 Nov 2002 */
02309 
02310 /*! Return a pointer to the filecode of dataset ds (prefix+view) */
02311 
02312 #define DSET_FILECODE(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \
02313                          ? ((ds)->dblk->diskptr->filecode) : "\0" )
02314 
02315 /*! Return a pointer to the .HEAD filename of dataset ds */
02316 
02317 #define DSET_HEADNAME(ds) ( ((ds)->tcat_list != NULL) ? (ds)->tcat_list     \
02318                           : ((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \
02319                           ? ((ds)->dblk->diskptr->header_name) : "\0" )
02320 
02321 /*! Return a pointer to the .BRIK filename of dataset ds */
02322 
02323 #define DSET_BRIKNAME(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \
02324                          ? ((ds)->dblk->diskptr->brick_name) : "\0" )
02325 #define DSET_BRICKNAME DSET_BRIKNAME
02326 
02327 /*! Return a pointer to the directory name of dataset ds */
02328 
02329 #define DSET_DIRNAME(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \
02330                          ? ((ds)->dblk->diskptr->directory_name) : "\0" )
02331 
02332 #define DSET_SESSNAME DSET_DIRNAME
02333 
02334 /*! Return a pointer to the ID code of dataset ds */
02335 
02336 #define DSET_IDCODE(ds) (&((ds)->idcode))
02337 
02338 /*! Return the ID code string */
02339 
02340 #define DSET_IDCODE_STR(ds) ((ds)->idcode.str)
02341 
02342 /* 25 April 1998 */
02343 
02344 #define DBLK_BYTEORDER(db)  ((db)->diskptr->byte_order)
02345 
02346 /*! Return LSB_FIRST or MSB_FIRST for dataset ds */
02347 
02348 #define DSET_BYTEORDER(ds)  DBLK_BYTEORDER((ds)->dblk)
02349 
02350 /** macros for time-dependent datasets **/
02351 
02352 /*! Return number of time points in dataset ds.
02353 
02354     If value is 1, dataset is not time-dependent, but it still may have
02355     multiple sub-bricks (if it is a bucket dataset, for example)
02356 */
02357 #define DSET_NUM_TIMES(ds)       ( ((ds)->taxis == NULL) ? 1 : (ds)->taxis->ntt )
02358 
02359 /*! Check if have a 3D+time dataset. */
02360 
02361 #define HAS_TIMEAXIS(ds)         ( DSET_NUM_TIMES(ds) > 1 )
02362 
02363 /*! Return number of values stored at each time point for dataset ds.
02364 
02365     Will always be 1 in the current version of AFNI!
02366     (Except for bucket datasets, that is, damn it.)
02367 */
02368 #define DSET_NVALS_PER_TIME(ds)  ( (ds)->dblk->nvals / DSET_NUM_TIMES(ds) )
02369 
02370 /*! Return number of sub-bricks in dataset ds */
02371 
02372 #define DSET_NVALS(ds)           ( (ds)->dblk->nvals )
02373 
02374 /*! Return number of voxels in each sub-brick of dataset ds */
02375 
02376 #define DSET_NVOX(ds) ( (ds)->daxes->nxx * (ds)->daxes->nyy * (ds)->daxes->nzz )
02377 
02378 /*! Return number of voxels along x-axis of dataset ds */
02379 
02380 #define DSET_NX(ds) ((ds)->daxes->nxx)
02381 
02382 /*! Return number of voxels along y-axis of dataset ds */
02383 
02384 #define DSET_NY(ds) ((ds)->daxes->nyy)
02385 
02386 /*! Return number of voxels along z-axis of dataset ds */
02387 
02388 #define DSET_NZ(ds) ((ds)->daxes->nzz)
02389 
02390 /*! Return grid spacing (voxel size) along x-axis of dataset ds */
02391 
02392 #define DSET_DX(ds) ((ds)->daxes->xxdel)  /* added 17 Aug 1998 */
02393 
02394 /*! Return grid spacing (voxel size) along y-axis of dataset ds */
02395 
02396 #define DSET_DY(ds) ((ds)->daxes->yydel)
02397 
02398 /*! Return grid spacing (voxel size) along z-axis of dataset ds */
02399 
02400 #define DSET_DZ(ds) ((ds)->daxes->zzdel)
02401 
02402 /*! Return grid origin along x-axis of dataset ds */
02403 
02404 #define DSET_XORG(ds) ((ds)->daxes->xxorg)  /* 29 Aug 2001 */
02405 
02406 /*! Return grid origin along y-axis of dataset ds */
02407 
02408 #define DSET_YORG(ds) ((ds)->daxes->yyorg)
02409 
02410 /*! Return grid origin along y-axis of dataset ds */
02411 
02412 #define DSET_ZORG(ds) ((ds)->daxes->zzorg)
02413 
02414 /*! Return smallest x-coordinate of grid for dataset ds */
02415 
02416 #define DSET_XXMIN(ds) ((ds)->daxes->xxmin) /* 11 Sep 2001 */
02417 
02418 /*! Return largest x-coordinate of grid for dataset ds */
02419 
02420 #define DSET_XXMAX(ds) ((ds)->daxes->xxmax)
02421 
02422 /*! Return smallest y-coordinate of grid for dataset ds */
02423 
02424 #define DSET_YYMIN(ds) ((ds)->daxes->yymin)
02425 
02426 /*! Return largest y-coordinate of grid for dataset ds */
02427 
02428 #define DSET_YYMAX(ds) ((ds)->daxes->yymax)
02429 
02430 /*! Return smallest z-coordinate of grid for dataset ds */
02431 
02432 #define DSET_ZZMIN(ds) ((ds)->daxes->zzmin)
02433 
02434 /*! Return largest z-coordinate of grid for dataset ds */
02435 
02436 #define DSET_ZZMAX(ds) ((ds)->daxes->zzmax)
02437 
02438   /* these next 4 added 19 Aug 1999 */
02439 
02440 /*! Find the x-axis index of a 3D array index in dataset ds */
02441 
02442 #define DSET_index_to_ix(ds,ii)         (  (ii) % (ds)->daxes->nxx)
02443 
02444 /*! Find the y-axis index of a 3D array index in dataset ds */
02445 
02446 #define DSET_index_to_jy(ds,ii)         ( ((ii) / (ds)->daxes->nxx) % (ds)->daxes->nyy )
02447 
02448 /*! Find the z-axis index of a 3D array index in dataset ds */
02449 
02450 #define DSET_index_to_kz(ds,ii)         (  (ii) /((ds)->daxes->nxx * (ds)->daxes->nyy ))
02451 
02452 /*! Convert a triple-index (ix,jy,kz) to a single 3D index for dataset ds */
02453 
02454 #define DSET_ixyz_to_index(ds,ix,jy,kz) ((ix)+((jy)+(kz)*(ds)->daxes->nyy)*(ds)->daxes->nxx)
02455 
02456 /*! Determine if dataset ds has cubical voxels */
02457 
02458 #define DSET_CUBICAL(ds) ( fabs((ds)->daxes->xxdel) == fabs((ds)->daxes->yydel) && \
02459                            fabs((ds)->daxes->xxdel) == fabs((ds)->daxes->zzdel)   )
02460 
02461 #if 0  /* 22 Sep 2000 */
02462 #define DSET_GRAPHABLE(ds) ( ISVALID_3DIM_DATASET(ds) && DSET_INMEMORY(ds)      && \
02463                              (ds)->wod_flag == False  && DSET_NUM_TIMES(ds) > 1 && \
02464                              ( DSET_ONDISK(ds) || DSET_LOADED(ds) && DSET_LOCKED(ds) ) )
02465 #else
02466 /*! Determine if a graph window can be opened for dataset ds.
02467 
02468     Cannot graph warp-on-demand datasets.
02469 */
02470 #define DSET_GRAPHABLE(ds) ( ISVALID_3DIM_DATASET(ds) && DSET_INMEMORY(ds)      && \
02471                              (ds)->wod_flag == False                            && \
02472                              ( DSET_ONDISK(ds) || DSET_LOADED(ds) && DSET_LOCKED(ds) ) )
02473 #endif
02474 
02475 /*! Return the TR for dataset ts; will be 0 if not time-dependent. */
02476 
02477 #define DSET_TIMESTEP(ds)        ( ((ds)->taxis == NULL) ? 0.0 : (ds)->taxis->ttdel )
02478 
02479 #define DSET_TR                  DSET_TIMESTEP
02480 
02481 /*! Return the time origin for dataset ds.
02482 
02483     Is always 0 in current version of AFNI.
02484 */
02485 #define DSET_TIMEORIGIN(ds)      ( ((ds)->taxis == NULL) ? 0.0 : (ds)->taxis->ttorg )
02486 
02487 /*! Return the time duration of image acquisition for dataset ds.
02488 
02489     Is always 0 in current version of AFNI (was intended for true 3D echo-volume imaging).
02490 */
02491 #define DSET_TIMEDURATION(ds)    ( ((ds)->taxis == NULL) ? 0.0 : (ds)->taxis->ttdur )
02492 
02493 /*! Return the time-step units code for dataset ds.
02494 
02495     Will be one of
02496       - UNITS_MSEC_TYPE  milliseconds
02497       - UNITS_SEC_TYPE   seconds
02498       - UNITS_HZ_TYPE    Hertz
02499       - ILLEGAL_TYPE     not a time-dependent dataset (d'oh)
02500 */
02501 #define DSET_TIMEUNITS(ds)       ( ((ds)->taxis == NULL) ? ILLEGAL_TYPE             \
02502                                                          : (ds)->taxis->units_type )
02503 
02504 /*! Return number of time-axis slice offsets for datsaet ds.
02505 
02506     Will be zero for non-time-dependent datasets, and may be zero or positive
02507     for time-dependent datasets
02508 */
02509 #define DSET_NUM_TTOFF(ds)       ( ((ds)->taxis == NULL) ? 0 : (ds)->taxis->nsl )
02510 
02511 /** 30 Nov 1997 **/
02512 
02513 static char tmp_dblab[8] ;
02514 #define DBLK_BRICK_LAB(db,iv) ( ((db)->brick_lab != NULL) ? ((db)->brick_lab[iv]) : "?" )
02515 
02516 /*! Return the label string for sub-brick iv of dataset ds.
02517 
02518     This label is used on chooser menus, for example
02519 */
02520 #define DSET_BRICK_LAB(ds,iv) DBLK_BRICK_LAB((ds)->dblk,(iv))
02521 
02522 /*! Synonym for DSET_BRICK_LAB */
02523 
02524 #define DSET_BRICK_LABEL      DSET_BRICK_LAB
02525 
02526 #define DBLK_BRICK_STATCODE(db,iv)  \
02527  ( ((db)->brick_statcode != NULL) ? (db)->brick_statcode[iv] : ILLEGAL_TYPE )
02528 
02529 /*! Return the statistical type code for the iv-th volume of dataset ds.
02530 
02531     Will be -1 if this sub-brick is not tagged as being an SPM.
02532 */
02533 #define DSET_BRICK_STATCODE(ds,iv)                                         \
02534    ( ISBUCKET((ds)) ? DBLK_BRICK_STATCODE((ds)->dblk,(iv))                 \
02535                     : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \
02536                       ? (ds)->func_type : -1 )
02537 
02538 #define DBLK_BRICK_STATAUX(db,iv)  \
02539  ( ((db)->brick_stataux != NULL) ? (db)->brick_stataux[iv] : NULL )
02540 
02541 /*! Return float * pointer to statistical parameters for sub-brick iv in dataset ds.
02542 
02543     If return is NULL, there aren't any parameters for this sub-brick,
02544     otherwise the number of parameters is given by FUNC_need_stat_aux[code],
02545     where code = DSET_BRICK_STATCODE(ds,iv).
02546 */
02547 #define DSET_BRICK_STATAUX(ds,iv)                                          \
02548    ( ISBUCKET((ds)) ? DBLK_BRICK_STATAUX((ds)->dblk,(iv))                  \
02549                     : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \
02550                       ? (ds)->stat_aux : NULL )
02551 
02552 #define DBLK_BRICK_STATPAR(db,iv,jj) \
02553  ( ((db)->brick_stataux != NULL) ? (db)->brick_stataux[iv][jj] : 0.0 )
02554 
02555 /*! Return the jj-th statistical parameter for the iv-th volume of dataset ds. */
02556 
02557 #define DSET_BRICK_STATPAR(ds,iv,jj)                                       \
02558    ( ISBUCKET((ds)) ? DBLK_BRICK_STATPAR((ds)->dblk,(iv),(jj))             \
02559                     : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \
02560                       ? (ds)->stat_aux[jj] : 0.0 )
02561 
02562 #define DBLK_BRICK_KEYWORDS(db,iv) \
02563   ( ((db)->brick_keywords != NULL) ? ((db)->brick_keywords[iv]) : NULL )
02564 
02565 #define DSET_BRICK_KEYWORDS(ds,iv) DBLK_BRICK_KEYWORDS((ds)->dblk,(iv))
02566 
02567 #define DSET_KEYWORDS(ds) ((ds)->keywords)
02568 
02569 #define DSET_BRICK_KEYWORDS_HAS(ds,iv,ss) \
02570    THD_string_has( DSET_BRICK_KEYWORDS((ds),(iv)) , (ss) )
02571 
02572 #define DSET_KEYWORDS_HAS(ds,ss) \
02573    THD_string_has( DSET_KEYWORDS((ds)) , (ss) )
02574 
02575 /*! Macro to load the self_name and labels of a dataset
02576     with values computed from the filenames;
02577     replaces user control/input of these values in to3d
02578 */
02579 
02580 #define DSET_FIX_NAMES(ds)                                       \
02581   ( strcpy((ds)->self_name,(ds)->dblk->diskptr->directory_name), \
02582     strcat((ds)->self_name,(ds)->dblk->diskptr->filecode)      , \
02583     strcpy((ds)->label1   ,(ds)->dblk->diskptr->filecode)      , \
02584     strcpy((ds)->label2   ,THD_DEFAULT_LABEL) )
02585 
02586 /*! Macro to load brick statistics of a dataset if it
02587       - doesn't have statistics already, or
02588       - has bad statistics from the (very) old to3d bug
02589 */
02590 
02591 #define RELOAD_STATS(dset)                                                  \
02592   if( ISVALID_3DIM_DATASET((dset)) &&                                       \
02593       ( !ISVALID_STATISTIC((dset)->stats) ||                                \
02594         ( (dset)->dblk->nvals > 1 &&                                        \
02595           (dset)->stats->bstat[1].min > (dset)->stats->bstat[1].max ) ) ){  \
02596      THD_load_statistics((dset)) ; }
02597 
02598 /*! Determine if the ii-th volume of dataset dset has a valid brick statistic.
02599     Brick statistics are just the min and max values in the volume.
02600 */
02601 
02602 #define DSET_VALID_BSTAT(dset,ii)                 \
02603   ( ISVALID_3DIM_DATASET((dset))     &&           \
02604     ISVALID_STATISTIC((dset)->stats) &&           \
02605     (ii) < (dset)->stats->nbstat     &&           \
02606     ISVALID_BSTAT( (dset)->stats->bstat[(ii)] ) )
02607 
02608 /*! Mark the ii-th volume's brick statistics to be invalid in dataset dset. */
02609 
02610 #define DSET_CRUSH_BSTAT(dset,ii)                                 \
02611   do{ if( DSET_VALID_BSTAT(dset,ii) )                             \
02612          INVALIDATE_BSTAT((dset)->stats->bstat[(ii)]) ; } while(0)
02613 
02614 /*! Delete all the sub-brick statistics for dataset ds. */
02615 
02616 #define DSET_KILL_STATS(ds)                                \
02617   do{ if( (ds)->stats != NULL ){                           \
02618          REMOVEFROM_KILL( (ds)->kl, (ds)->stats->bstat ) ; \
02619          REMOVEFROM_KILL( (ds)->kl, (ds)->stats ) ;        \
02620          KILL_STATISTIC( (ds)->stats ) ;                   \
02621          (ds)->stats = NULL ; } } while(0)
02622 
02623 /*! Macro to initialize the global stat_aux data in a dataset.
02624 
02625     Note that each sub-brick now has its own stat_aux data, and this
02626     global data is only used for the older (non-bucket) functional
02627     dataset types such as "fico".
02628 */
02629 
02630 #define INIT_STAT_AUX(ds,nf,ff)               \
02631   do{ int is ;                                \
02632       for( is=0 ; is < MAX_STAT_AUX ; is++ )  \
02633          (ds)->stat_aux[is] = (is < (nf)) ? (ff)[is] : 0.0 ; } while(0)
02634 
02635 /*! Clear the global stat_aux data in a dataset. */
02636 
02637 #define ZERO_STAT_AUX(ds)                              \
02638   do{ int is ; for( is=0 ; is < MAX_STAT_AUX ; is++ )  \
02639                  (ds)->stat_aux[is] = 0.0 ; } while(0)
02640 
02641 /** macros to load and unload a dataset from memory **/
02642 
02643 /*! Load dataset ds's sub-bricks into memory.
02644 
02645     If it is already loaded, does nothing (so you can call this without much penalty).
02646 */
02647 #define DSET_load(ds)   THD_load_datablock( (ds)->dblk )
02648 
02649 /*! Unload dataset ds's sub-bricks from memory.
02650 
02651     Won't do anything if the dataset is locked into memory
02652 */
02653 #define DSET_unload(ds) THD_purge_datablock( (ds)->dblk , DATABLOCK_MEM_ANY )
02654 
02655 /*! Unload sub-brick iv in dataset ds from memory.
02656 
02657     Only does something if the dataset is malloc()-ed,
02658     not mmap()-ed, and not locked in memory
02659 */
02660 #define DSET_unload_one(ds,iv) THD_purge_one_brick( (ds)->dblk , (iv) )
02661 
02662 /*! Delete dataset ds's volumes and struct from memory.
02663 
02664     Does not delete from disk
02665 */
02666 #define DSET_delete(ds) THD_delete_3dim_dataset((ds),False)
02667 
02668 /*! Write dataset ds to disk.
02669 
02670     Also loads the sub-brick statistics
02671 */
02672 #define DSET_write(ds)  ( THD_load_statistics( (ds) ) ,                    \
02673                           THD_write_3dim_dataset( NULL,NULL , (ds),True ) )
02674 
02675 /*! Write only the dataset header to disk, for dataset ds */
02676 
02677 #define DSET_write_header(ds)  THD_write_3dim_dataset( NULL,NULL , (ds),False )
02678 
02679 /*! Check if dataset ds if fully loaded into memory.
02680 
02681     If return is 0 (false), you could try DSET_load(ds)
02682 */
02683 #define DSET_LOADED(ds) ( THD_count_databricks((ds)->dblk) == DSET_NVALS(ds) )
02684 
02685 /*! Lock dataset ds into memory */
02686 
02687 #define DSET_lock(ds)      DBLK_lock((ds)->dblk)       /* Feb 1998 */
02688 
02689 /*! Unlock dataset ds (so it can be purged) */
02690 
02691 #define DSET_unlock(ds)    DBLK_unlock((ds)->dblk)
02692 
02693 /*! Check if dataset ds is locked into memory */
02694 
02695 #define DSET_LOCKED(ds)    DBLK_LOCKED((ds)->dblk)
02696 
02697 /*! Force this dataset to be loaded into memory using malloc().
02698 
02699     If you are altering the dataset contents, this is required,
02700     since a mmap()-ed dataset is readonly.
02701 */
02702 #define DSET_mallocize(ds) DBLK_mallocize((ds)->dblk)
02703 
02704 /*! Force this dataset to be loaded into memory using mmap()
02705     You cannot alter any sub-brick data, since mmap() is done in
02706     readonly mode.
02707 */
02708 #define DSET_mmapize(ds)   DBLK_mmapize((ds)->dblk)
02709 
02710 /*! Force this dataset to be loaded into shared memory.
02711     You cannot alter any sub-brick data, since is done in
02712     readonly mode.
02713 */
02714 #define DSET_shareize(ds)  DBLK_shareize((ds)->dblk)
02715 
02716 /*! Let AFNI decide how to load a dataset into memory.
02717 
02718     May choose mmap() or malloc()
02719 */
02720 #define DSET_anyize(ds)    DBLK_anyize((ds)->dblk)
02721 
02722 /*! Super-lock dataset ds into memory.
02723 
02724     Super-locked datasets will not be unlocked by DSET_unlock
02725 */
02726 #define DSET_superlock(ds) DBLK_superlock((ds)->dblk)  /* 22 Mar 2001 */
02727 
02728 /*! Check if dataset ds is loaded into memory using malloc() */
02729 
02730 #define DSET_IS_MALLOC(ds)  DBLK_IS_MALLOC((ds)->dblk)
02731 
02732 /*! Check if dataset ds is loaded into memory using mmap() */
02733 
02734 #define DSET_IS_MMAP(ds)    DBLK_IS_MMAP((ds)->dblk)
02735 
02736 /*! Check if dataset ds is loaded into shared memory */
02737 
02738 #define DSET_IS_SHARED(ds)  DBLK_IS_SHARED((ds)->dblk)
02739 
02740 /*! Check if dataset ds is "mastered": gets its data from someone else.
02741 
02742     Mastered datasets are specified on the command line with the [a..b] syntax, etc.
02743 */
02744 #define DSET_IS_MASTERED(ds) DBLK_IS_MASTERED((ds)->dblk)
02745 
02746 /*-------------------------------------------------------------------*/
02747 #undef  TWOGIG
02748 #define TWOGIG 2147000000   /* 2 gigabytes, aboot */
02749 
02750 #define DBLK_mmapfix(db)                                                      \
02751   do{ if( (db)->malloc_type==DATABLOCK_MEM_MMAP && (db)->total_bytes>TWOGIG ) \
02752         (db)->malloc_type = DATABLOCK_MEM_MALLOC ; } while(0)
02753 
02754 /*------------- a dynamic array type for 3D datasets ---------------*/
02755 
02756 /*! A dynamic array type for AFNI datasets.
02757 
02758     This is used when collecting all the datasets in a directory into a THD_session.
02759 */
02760 
02761 typedef struct THD_3dim_dataset_array {
02762       int num ;                  /*!< Number of datasets stored */
02763       int nall ;                 /*!< Number of datasets slots allocated */
02764       THD_3dim_dataset **ar ;    /*!< Array of datasets: [0..num-1] are in use */
02765 } THD_3dim_dataset_array ;
02766 
02767 #define INC_3DARR 8
02768 
02769 /*! Initialize a new AFNI dataset array into variable "name".
02770 
02771     You should declare "THD_3dim_dataset_array *name;".
02772 */
02773 #define INIT_3DARR(name)                  \
02774    ( (name) = XtNew(THD_3dim_dataset_array) ,\
02775      (name)->num = (name)->nall = 0 ,     \
02776      (name)->ar  = NULL )
02777 
02778 /*! Add dataset ddset to AFNI dataset array "name" */
02779 
02780 #define ADDTO_3DARR(name,ddset)                                       \
02781    { if( (name)->num == (name)->nall ){                               \
02782       (name)->nall += INC_3DARR ;                                     \
02783       (name)->ar    = (THD_3dim_dataset **)                           \
02784                        XtRealloc( (char *) (name)->ar ,               \
02785                         sizeof(THD_3dim_dataset *) * (name)->nall ) ; \
02786      }                                                             \
02787      if( (ddset) != NULL ){               \
02788       (name)->ar[(name)->num] = (ddset) ; \
02789       ((name)->num)++ ;                  \
02790      } }
02791 
02792 /*! Free the AFNI dataset array (but don't kill the datasets).
02793 
02794     This would be used after the dataset pointers have been moved
02795     someplace else (e.g., into the THD_session structure).
02796 */
02797 
02798 #define FREE_3DARR(name)      \
02799    if( (name) != NULL ){      \
02800      myXtFree( (name)->ar ) ; \
02801      myXtFree( (name) ) ; }
02802 
02803 /*! Macro to access the nn-th dataset in AFNI dataset array name */
02804 
02805 #define DSET_IN_3DARR(name,nn) ((name)->ar[(nn)])
02806 
02807 /*! Determine if two datasets are properly ordered */
02808 
02809 #define DSET_ORDERED(d1,d2)                  \
02810   ( ( (d1)->view_type < (d2)->view_type ) || \
02811     ( (d1)->view_type==(d2)->view_type && (d1)->func_type<(d2)->func_type ) )
02812 
02813 /*! Swap 2 dataset pointers (thru pointer dt) */
02814 
02815 #define DSET_SWAP(d1,d2) (dt=(d1),(d1)=(d2),(d2)=dt)
02816 
02817 /*! Sort an AFNI dataset array */
02818 
02819 #define SORT_3DARR(name)                                               \
02820    if( (name) != NULL && (name)->num > 1 ){                            \
02821       int iid , jjd ; THD_3dim_dataset * dt ;                          \
02822       for( iid=0 ; iid < (name)->num ; iid++ ){                        \
02823          for( jjd=1 ; jjd < (name)->num ; jjd++ ){                     \
02824             if( !DSET_ORDERED( (name)->ar[jjd-1] , (name)->ar[jjd] ) ) \
02825                DSET_SWAP( (name)->ar[jjd-1] , (name)->ar[jjd] ) ;      \
02826    }}}
02827 
02828 /*-------------------------------------------------------------------*/
02829 /*--------        holds all data from a session!          -----------*/
02830 
02831 #define SESSION_TYPE 97
02832 
02833 /*! Holds all the datasets from a directory (session).
02834     [28 Jul 2003: modified to put elide distinction between anat and func]
02835     [20 Jan 2004: modified to put surfaces into here as well]
02836 */
02837 
02838 typedef struct {
02839       int type     ;                  /*!< code indicating this is a THD_session */
02840       int num_dsset ;                 /*!< Number of datasets. */
02841       char sessname[THD_MAX_NAME] ;   /*!< Name of directory datasets were read from */
02842       char lastname[THD_MAX_NAME] ;   /*!< Just/the/last/name of the directory */
02843 
02844       THD_3dim_dataset *dsset[THD_MAX_SESSION_SIZE][LAST_VIEW_TYPE+1] ;
02845                                       /*!< array of datasets */
02846 
02847       Htable *warptable ;       /*!< Table of inter-dataset warps [27 Aug 2002] */
02848 
02849       /* 20 Jan 2004: put surfaces here, rather than in the datasets */
02850 
02851       int su_num ;              /*!< Number of surfaces */
02852       SUMA_surface **su_surf ;  /*!< Surface array */
02853 
02854       int su_numgroup ;                  /*!< Number of surface groups */
02855       SUMA_surfacegroup **su_surfgroup ; /*!< Surface group array */
02856 
02857       XtPointer parent ;        /*!< generic pointer to "owner" of session */
02858 } THD_session ;
02859 
02860 /*! Determine if ss points to a valid THD_session. */
02861 
02862 #define ISVALID_SESSION(ss) ( (ss) != NULL && (ss)->type == SESSION_TYPE )
02863 
02864 /*! Initialize THD_session ss to hold nothing at all. */
02865 
02866 #define BLANK_SESSION(ss)                                                     \
02867   if( ISVALID_SESSION((ss)) ){                                                \
02868       int id , vv ;                                                           \
02869       for( id=0 ; id < THD_MAX_SESSION_SIZE ; id++ )                          \
02870         for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ) (ss)->dsset[id][vv] = NULL; \
02871       (ss)->num_dsset = 0 ;                                                   \
02872       (ss)->su_num    = 0 ; (ss)->su_surf = NULL ;                            \
02873       (ss)->su_numgroup = 0 ; (ss)->su_surfgroup = NULL ;                     \
02874       (ss)->warptable = NULL ; }
02875 
02876 /*! Determine if session has SUMA surface data attached. */
02877 
02878 #define SESSION_HAS_SUMA(ss) ( (ss)!=NULL           &&  \
02879                                (ss)->su_surf!=NULL  &&  \
02880                                (ss)->su_num > 0        )
02881 
02882 #define SESSIONLIST_TYPE 107
02883 
02884 /*! Array of THD_sessions.
02885 
02886     Holds all the datasets read into AFNI from all directories.
02887 */
02888 
02889 typedef struct {
02890       int type , num_sess ;
02891       THD_session * ssar[THD_MAX_NUM_SESSION] ;
02892       XtPointer parent ;
02893 } THD_sessionlist ;
02894 
02895 /*! Determine if sl is a valid THD_sessionlist */
02896 
02897 #define ISVALID_SESSIONLIST(sl) ( (sl)!=NULL && (sl)->type==SESSIONLIST_TYPE )
02898 
02899 /*! Initialize a THD_sessionlist to contain nothing. */
02900 
02901 #define BLANK_SESSIONLIST(sl) \
02902    if( ISVALID_SESSIONLIST((sl)) ){ \
02903       int is ; \
02904       for( is=0 ; is < THD_MAX_NUM_SESSION ; is++ ) (sl)->ssar[is] = NULL ; \
02905       (sl)->num_sess = 0 ; }
02906 
02907 /*! Return type for THD_sessionlist searching (see THD_dset_in_*).
02908 
02909     There are different ways to search for a dataset in THD_sessionlist
02910       - FIND_NAME    to find by the name field (is now obsolete)
02911       - FIND_IDCODE  to find by the dataset ID code (the best way)
02912       - FIND_PREFIX  to find by the dataset prefix (an OK way)
02913 */
02914 
02915 typedef struct {
02916    int sess_index ;            /*!< Session it was found in */
02917    int dset_index ;            /*!< Index it was found at (if >= 0) */
02918    int view_index ;            /*!< View index it was found at (if >= 0) */
02919    THD_3dim_dataset * dset ;   /*!< Pointer to found dataset itself */
02920 } THD_slist_find ;
02921 
02922 /*! Set the find codes to indicate a bad result */
02923 
02924 #define BADFIND(ff)                                       \
02925    ( (ff).sess_index=(ff).dset_index=(ff).view_index=-1 , \
02926      (ff).dset = NULL )
02927 
02928 #define FIND_NAME   1
02929 #define FIND_IDCODE 2
02930 #define FIND_PREFIX 3
02931 
02932 /*******************************************************************/
02933 /********************** attribute names ****************************/
02934 
02935 #define ATRNAME_DATANAME "DATASET_NAME"
02936 #define ATRNAME_LABEL1   "LABEL_1"
02937 #define ATRNAME_LABEL2   "LABEL_2"
02938 
02939 #define ATRNAME_ANATOMY_PARENT "ANATOMY_PARENTNAME"
02940 
02941 #define ATRNAME_ORIENT_SPECIFIC "ORIENT_SPECIFIC"
02942 #define ATRTYPE_ORIENT_SPECIFIC ATR_INT_TYPE
02943 #define ATRSIZE_ORIENT_SPECIFIC 3
02944 
02945 #define ATRNAME_ORIENT_GENERAL "ORIENT_GENERAL"   /*** not used yet  ***/
02946 #define ATRTYPE_ORIENT_GENERAL ATR_FLOAT_TYPE     /* (will someday be  */
02947 #define ATRSIZE_ORIENT_GENERAL 9                  /*  rotation matrix) */
02948 
02949 #define ATRNAME_ORIGIN "ORIGIN"
02950 #define ATRTYPE_ORIGIN ATR_FLOAT_TYPE
02951 #define ATRSIZE_ORIGIN 3
02952 
02953 #define ATRNAME_DELTA  "DELTA"
02954 #define ATRTYPE_DELTA  ATR_FLOAT_TYPE
02955 #define ATRSIZE_DELTA  3
02956 
02957 #define ATRNAME_SKIP   "SKIP"
02958 #define ATRTYPE_SKIP   ATR_FLOAT_TYPE
02959 #define ATRSIZE_SKIP   3
02960 
02961 #define ATRNAME_MARKSXYZ  "MARKS_XYZ"
02962 #define ATRTYPE_MARKSXYZ  ATR_FLOAT_TYPE
02963 #define ATRSIZE_MARKSXYZ  MARKS_FSIZE
02964 
02965 #define ATRNAME_MARKSLAB  "MARKS_LAB"
02966 #define ATRTYPE_MARKSLAB  ATR_STRING_TYPE
02967 #define ATRSIZE_MARKSLAB  MARKS_LSIZE
02968 
02969 #define ATRNAME_MARKSHELP "MARKS_HELP"
02970 #define ATRTYPE_MARKSHELP  ATR_STRING_TYPE
02971 #define ATRSIZE_MARKSHELP  MARKS_HSIZE
02972 
02973 #define ATRNAME_MARKSFLAG "MARKS_FLAGS"
02974 #define ATRTYPE_MARKSFLAG  ATR_INT_TYPE
02975 #define ATRSIZE_MARKSFLAG  MARKS_MAXFLAG
02976 
02977 #define ATRNAME_TYPESTRING "TYPESTRING"
02978 #define ATRTYPE_TYPESTRING ATR_STRING_TYPE
02979 #define ATRSIZE_TYPESTRING 0                /* 0 size means variable */
02980 
02981 #define ATRNAME_WARP_TYPE  "WARP_TYPE"
02982 #define ATRTYPE_WARP_TYPE  ATR_INT_TYPE
02983 #define ATRSIZE_WARP_TYPE  8           /* warp, resample (6 expansions) */
02984 
02985 #define ATRNAME_WARP_DATA  "WARP_DATA"
02986 #define ATRTYPE_WARP_DATA  ATR_FLOAT_TYPE
02987 #define ATRSIZE_WARP_DATA  0
02988 
02989 #define ATRNAME_WARP_PARENT "WARP_PARENTNAME"
02990 #define ATRTYPE_WARP_PARENT ATR_STRING_TYPE
02991 #define ATRSIZE_WARP_PARENT 0
02992 
02993 #define ATRNAME_SCENE_TYPE "SCENE_DATA"
02994 #define ATRTYPE_SCENE_TYPE ATR_INT_TYPE
02995 #define ATRSIZE_SCENE_TYPE 8           /* view, func, type (+5) */
02996 
02997 #define ATRNAME_DATASET_RANK "DATASET_RANK"
02998 #define ATRTYPE_DATASET_RANK ATR_INT_TYPE
02999 #define ATRSIZE_DATASET_RANK 8         /* # dims, # vals (+6) */
03000 
03001 #define ATRNAME_DATASET_DIMENSIONS "DATASET_DIMENSIONS"
03002 #define ATRTYPE_DATASET_DIMENSIONS ATR_INT_TYPE
03003 #define ATRSIZE_DATASET_DIMENSIONS THD_MAX_RANK_EVER
03004 
03005 #define ATRNAME_MINMAX "MINMAX"
03006 #define ATRTYPE_MINMAX ATR_INT_TYPE
03007 
03008 #if 0
03009 #   define ATRNAME_DATASET_PREFIX  "DATASET_PREFIX"
03010 #   define ATRTYPE_DATASET_PREFIX  ATR_STRING_TYPE
03011 #   define ATRSIZE_DATASET_PREFIX  THD_MAX_PREFIX
03012 
03013 #   define ATRNAME_DATASET_VIEWCODE  "DATASET_VIEWCODE"
03014 #   define ATRTYPE_DATASET_VIEWCODE  ATR_STRING_TYPE
03015 #   define ATRSIZE_DATASET_VIEWCODE  THD_MAX_VIEWCODE
03016 #endif
03017 
03018 /** additions 1995 Nov 15, for variable brick data types **/
03019 
03020 #define ATRNAME_BRICK_TYPES    "BRICK_TYPES"
03021 #define ATRTYPE_BRICK_TYPES    ATR_INT_TYPE
03022 #define ATRSIZE_BRICK_TYPES    0
03023 
03024 #define ATRNAME_BRICK_STATS    "BRICK_STATS"
03025 #define ATRTYPE_BRICK_STATS    ATR_FLOAT_TYPE
03026 #define ATRSIZE_BRICK_STATS    0
03027 
03028 #define ATRNAME_BRICK_FLTFAC   "BRICK_FLOAT_FACS"
03029 #define ATRTYPE_BRICK_FLTFAC   ATR_FLOAT_TYPE
03030 #define ATRSIZE_BRICK_FLTFAC   0
03031 
03032 /** 1996 Mar 26 **/
03033 
03034 #define ATRNAME_STAT_AUX       "STAT_AUX"
03035 #define ATRTYPE_STAT_AUX       ATR_FLOAT_TYPE
03036 #define ATRSIZE_STAT_AUX       0
03037 
03038 /** 1996 May 14 **/
03039 
03040 #define ATRNAME_TAXIS_NUMS     "TAXIS_NUMS"
03041 #define ATRSIZE_TAXIS_NUMS     8
03042 
03043 #define ATRNAME_TAXIS_FLOATS   "TAXIS_FLOATS"
03044 #define ATRSIZE_TAXIS_FLOATS   8
03045 
03046 #define ATRNAME_TAXIS_OFFSETS  "TAXIS_OFFSETS"
03047 #define ATRSIZE_TAXIS_OFFSETS  0
03048 
03049 /** 30 Nov 1997 **/
03050 
03051 #define ATRNAME_BRICK_LABS     "BRICK_LABS"
03052 #define ATRNAME_BRICK_STATAUX  "BRICK_STATAUX"
03053 #define ATRNAME_BRICK_KEYWORDS "BRICK_KEYWORDS"
03054 
03055 #define ATRNAME_KEYWORDS       "DATASET_KEYWORDS"
03056 
03057 /************************************************************************/
03058 /******************* rest of prototypes *********************************/
03059 
03060 #ifndef DONT_USE_SCANDIR
03061 #ifdef SCANDIR_WANTS_CONST
03062    extern int THD_select_dirent( const struct dirent * dp ) ;
03063 #else
03064    extern int THD_select_dirent( struct dirent * dp ) ;
03065 #endif
03066 #endif
03067 
03068 char * ig_strstr( char *, char *, char * ) ; /* 08 Aug 2002 */
03069 void freeup_strings( int n , char **sar ) ;
03070 int breakup_string( char *sin , char ***stok ) ;
03071 
03072 extern THD_string_array * THD_get_all_filenames( char * ) ;
03073 extern THD_string_array * THD_extract_regular_files( THD_string_array * ) ;
03074 extern THD_string_array * THD_extract_directories( THD_string_array * ) ;
03075 extern int THD_is_file     ( char * ) ;
03076 extern int THD_is_symlink  ( char * ) ;  /* 03 Mar 1999 */
03077 extern int THD_is_directory( char * ) ;
03078 extern int THD_is_ondisk   ( char * ) ;  /* 19 Dec 2002 */
03079 extern int THD_mkdir       ( char * ) ;  /* 19 Dec 2002 */
03080 extern int THD_cwd         ( char * ) ;  /* 19 Dec 2002 */
03081 extern int THD_equiv_files ( char * , char * ) ;
03082 extern unsigned long THD_filesize( char * pathname ) ;
03083 extern THD_string_array * THD_get_all_subdirs( int , char * ) ;
03084 extern THD_string_array * THD_normalize_flist( THD_string_array * ) ;
03085 extern THD_string_array * THD_get_wildcard_filenames( char * ) ;
03086 
03087 extern time_t THD_file_mtime( char * ) ; /* 05 Dec 2001 */
03088 
03089 extern THD_string_array * THD_get_all_executables( char * ) ;    /* 26 Jun 2001 */
03090 extern THD_string_array * THD_getpathprogs( THD_string_array * );
03091 extern int THD_is_executable( char * pathname ) ;
03092 extern char * THD_find_executable( char * ) ;
03093 
03094 extern int THD_is_dataset( char * , char * , int ) ; /* 17 Mar 2000 */
03095 extern char * THD_dataset_headname( char * , char * , int ) ;
03096 
03097 extern MRI_IMARR * THD_get_all_timeseries( char * ) ;
03098 extern MRI_IMARR * THD_get_many_timeseries( THD_string_array * ) ;
03099 extern char * THD_trailname( char * fname , int lev ) ;
03100 
03101 extern int THD_linecount( char * ) ;
03102 
03103 extern void THD_read_all_atr ( char * , THD_datablock * ) ;
03104 extern void THD_erase_all_atr( THD_datablock * ) ;
03105 extern void THD_erase_one_atr( THD_datablock * , char * ) ;
03106 extern void THD_read_niml_atr( char * , THD_datablock * ) ; /* 01 Jun 2005 */
03107 
03108 extern void THD_anonymize_dset ( THD_3dim_dataset * ) ;  /* 08 Jul 2005 */
03109 extern void THD_anonymize_write( int ) ;
03110 
03111 extern ATR_any    * THD_find_atr       ( THD_datablock * , char * ) ;
03112 extern ATR_float  * THD_find_float_atr ( THD_datablock * , char * ) ;
03113 extern ATR_int    * THD_find_int_atr   ( THD_datablock * , char * ) ;
03114 extern ATR_string * THD_find_string_atr( THD_datablock * , char * ) ;
03115 
03116 extern void THD_set_atr( THD_datablock * , char * , int,int, void * ) ;
03117 
03118 extern ATR_any * THD_copy_atr( ATR_any *atr ) ;  /* 03 Aug 2005 */
03119 extern void THD_insert_atr( THD_datablock *blk , ATR_any *atr ) ;
03120 
03121 extern void THD_store_dataset_keywords ( THD_3dim_dataset * , char * ) ;
03122 extern void THD_append_dataset_keywords( THD_3dim_dataset * , char * ) ;
03123 extern char * THD_dataset_info( THD_3dim_dataset * , int ) ;
03124 extern char * THD_zzprintf( char * sss , char * fmt , ... ) ;
03125 
03126 extern void THD_set_float_atr( THD_datablock * , char * , int , float * ) ;
03127 extern void THD_set_int_atr  ( THD_datablock * , char * , int , int   * ) ;
03128 extern void THD_set_char_atr ( THD_datablock * , char * , int , char  * ) ;
03129 
03130 /*! Macro to set a string attribute from a C string (vs. a char array). */
03131 
03132 #define THD_set_string_atr(blk,name,str) \
03133    THD_set_char_atr( (blk) , (name) , strlen(str)+1 , (str) )
03134 
03135 extern void THD_init_diskptr_names( THD_diskptr *, char *,char *,char * ,
03136                                     int, Boolean ) ;
03137 
03138 extern THD_datablock *       THD_init_one_datablock( char *,char * ) ;
03139 extern THD_datablock_array * THD_init_prefix_datablocks( char *, THD_string_array * ) ;
03140 
03141 extern XtPointer_array * THD_init_alldir_datablocks( char * ) ;
03142 
03143 extern THD_session * THD_init_session( char * ) ;
03144 extern void          THD_order_session( THD_session * ) ;   /* 29 Jul 2003 */
03145 
03146 extern THD_3dim_dataset * THD_open_one_dataset( char * ) ;
03147 extern THD_3dim_dataset * THD_open_dataset( char * ) ;      /* 11 Jan 1999 */
03148 extern THD_3dim_dataset * THD_open_minc( char * ) ;         /* 29 Oct 2001 */
03149 extern THD_3dim_dataset * THD_open_analyze( char * ) ;      /* 27 Aug 2002 */
03150 extern THD_3dim_dataset * THD_open_ctfmri( char * ) ;       /* 04 Dec 2002 */
03151 extern THD_3dim_dataset * THD_open_ctfsam( char * ) ;       /* 04 Dec 2002 */
03152 extern THD_3dim_dataset * THD_open_1D( char * ) ;           /* 04 Mar 2003 */
03153 extern THD_3dim_dataset * THD_open_3D( char * ) ;           /* 21 Mar 2003 */
03154 extern THD_3dim_dataset * THD_open_nifti( char * ) ;        /* 28 Aug 2003 */
03155 extern THD_3dim_dataset * THD_open_mpeg( char * ) ;         /* 03 Dec 2003 */
03156 extern THD_3dim_dataset * THD_open_tcat( char * ) ;         /* 04 Aug 2004 */
03157 
03158 extern void THD_datablock_apply_atr( THD_3dim_dataset * ) ; /* 09 May 2005 */
03159 
03160 extern THD_3dim_dataset * THD_fetch_dataset      (char *) ; /* 23 Mar 2001 */
03161 extern XtPointer_array *  THD_fetch_many_datasets(char *) ;
03162 extern MRI_IMAGE *        THD_fetch_1D           (char *) ; /* 26 Mar 2001 */
03163 
03164 extern void THD_set_storage_mode( THD_3dim_dataset *,int ); /* 21 Mar 2003 */
03165 
03166 extern int * MCW_get_intlist( int , char * ) ;
03167 extern void MCW_intlist_allow_negative( int ) ;             /* 22 Nov 1999 */
03168 
03169 /* copy a dataset, given a list of sub-bricks          [rickr] 26 Jul 2004 */
03170 extern THD_3dim_dataset * THD_copy_dset_subs( THD_3dim_dataset * , int * ) ;
03171 
03172 /*! Help string to explain dataset "mastering" briefly. */
03173 
03174 #define MASTER_SHORTHELP_STRING                                                 \
03175  "INPUT DATASET NAMES\n"                                                        \
03176  "-------------------\n"                                                        \
03177  "This program accepts datasets that are modified on input according to the\n"  \
03178  "following schemes:\n"                                                         \
03179  "  'r1+orig[3..5]'                                    {sub-brick selector}\n"  \
03180  "  'r1+orig<100.200>'                                 {sub-range selector}\n"  \
03181  "  'r1+orig[3..5]<100..200>'                          {both selectors}\n"      \
03182  "  '3dcalc( -a r1+orig -b r2+orig -expr 0.5*(a+b) )'  {calculation}\n"         \
03183  "For the gruesome details, see the output of 'afni -help'.\n"
03184 
03185 /*! Help string to explain dataset "mastering" at length. */
03186 
03187 #define MASTER_HELP_STRING                                                    \
03188     "INPUT DATASET NAMES\n"                                                   \
03189     "-------------------\n"                                                   \
03190     " An input dataset is specified using one of these forms:\n"              \
03191     "    'prefix+view', 'prefix+view.HEAD', or 'prefix+view.BRIK'.\n"         \
03192     " You can also add a sub-brick selection list after the end of the\n"     \
03193     " dataset name.  This allows only a subset of the sub-bricks to be\n"     \
03194     " read in (by default, all of a dataset's sub-bricks are input).\n"       \
03195     " A sub-brick selection list looks like one of the following forms:\n"    \
03196     "   fred+orig[5]                     ==> use only sub-brick #5\n"         \
03197     "   fred+orig[5,9,17]                ==> use #5, #9, and #12\n"           \
03198     "   fred+orig[5..8]     or [5-8]     ==> use #5, #6, #7, and #8\n"        \
03199     "   fred+orig[5..13(2)] or [5-13(2)] ==> use #5, #7, #9, #11, and #13\n"  \
03200     " Sub-brick indexes start at 0.  You can use the character '$'\n"         \
03201     " to indicate the last sub-brick in a dataset; for example, you\n"        \
03202     " can select every third sub-brick by using the selection list\n"         \
03203     "   fred+orig[0..$(3)]\n"                                                 \
03204     "\n"                                                                      \
03205     " N.B.: The sub-bricks are read in the order specified, which may\n"      \
03206     " not be the order in the original dataset.  For example, using\n"        \
03207     "   fred+orig[0..$(2),1..$(2)]\n"                                         \
03208     " will cause the sub-bricks in fred+orig to be input into memory\n"       \
03209     " in an interleaved fashion.  Using\n"                                    \
03210     "   fred+orig[$..0]\n"                                                    \
03211     " will reverse the order of the sub-bricks.\n"                            \
03212     "\n"                                                                      \
03213     " N.B.: You may also use the syntax <a..b> after the name of an input \n" \
03214     " dataset to restrict the range of values read in to the numerical\n"     \
03215     " values in a..b, inclusive.  For example,\n"                             \
03216     "    fred+orig[5..7]<100..200>\n"                                         \
03217     " creates a 3 sub-brick dataset with values less than 100 or\n"           \
03218     " greater than 200 from the original set to zero.\n"                      \
03219     " If you use the <> sub-range selection without the [] sub-brick\n"       \
03220     " selection, it is the same as if you had put [0..$] in front of\n"       \
03221     " the sub-range selection.\n"                                             \
03222     "\n"                                                                      \
03223     " N.B.: Datasets using sub-brick/sub-range selectors are treated as:\n"   \
03224     "  - 3D+time if the dataset is 3D+time and more than 1 brick is chosen\n" \
03225     "  - otherwise, as bucket datasets (-abuc or -fbuc)\n"                    \
03226     "    (in particular, fico, fitt, etc datasets are converted to fbuc!)\n"  \
03227     "\n"                                                                      \
03228     " N.B.: The characters '$ ( ) [ ] < >'  are special to the shell,\n"      \
03229     " so you will have to escape them.  This is most easily done by\n"        \
03230     " putting the entire dataset plus selection list inside forward\n"        \
03231     " single quotes, as in 'fred+orig[5..7,9]', or double quotes \"x\".\n"
03232 
03233 /*! Help string to explain calculated datasets. */
03234 
03235 #define CALC_HELP_STRING                                                   \
03236    "CALCULATED DATASETS\n"                                                 \
03237    "-------------------\n"                                                 \
03238    " Datasets may also be specified as runtime-generated results from\n"   \
03239    " program 3dcalc.  This type of dataset specifier is enclosed in\n"     \
03240    " quotes, and starts with the string '3dcalc(':\n"                      \
03241    "    '3dcalc( opt opt ... opt )'\n"                                     \
03242    " where each 'opt' is an option to program 3dcalc; this program\n"      \
03243    " is run to generate a dataset in the directory given by environment\n" \
03244    " variable TMPDIR (default=/tmp).  This dataset is then read into\n"    \
03245    " memory, locked in place, and deleted from disk.  For example\n"       \
03246    "    afni -dset '3dcalc( -a r1+orig -b r2+orig -expr 0.5*(a+b) )'\n"    \
03247    " will let you look at the average of datasets r1+orig and r2+orig.\n"  \
03248    " N.B.: using this dataset input method will use lots of memory!\n"
03249 
03250 /*! Help string to explain 1D column and row selection. [01 May 2003] */
03251 
03252 #define TS_HELP_STRING                                                        \
03253    "TIMESERIES (1D) INPUT\n"                                                  \
03254    "---------------------\n"                                                  \
03255    "A timeseries file is in the form of a 1D or 2D table of ASCII numbers;\n" \
03256    "for example:   3 5 7\n"                                                   \
03257    "               2 4 6\n"                                                   \
03258    "               0 3 3\n"                                                   \
03259    "               7 2 9\n"                                                   \
03260    "This example has 3 rows and 4 columns.  Each column is considered as\n"   \
03261    "a timeseries in AFNI.  The convention is to store this type of data\n"    \
03262    "in a filename ending in '.1D'.\n"                                         \
03263    "\n"                                                                       \
03264    "When specifying a timeseries file to an command-line AFNI program, you\n" \
03265    "can select a subset of columns using the '[...]' notation:\n"             \
03266    "  'fred.1D[5]'            ==> use only column #5\n"                       \
03267    "  'fred.1D[5,9,17]'       ==> use columns #5, #9, and #12\n"              \
03268    "  'fred.1D[5..8]'         ==> use columns #5, #6, #7, and #8\n"           \
03269    "  'fred.1D[5..13(2)]'     ==> use columns #5, #7, #9, #11, and #13\n"     \
03270    "Sub-brick indexes start at 0.  You can use the character '$'\n"           \
03271    "to indicate the last sub-brick in a dataset; for example, you\n"          \
03272    "can select every third sub-brick by using the selection list\n"           \
03273    "  'fred.1D[0..$(3)]'      ==> use columns #0, #3, #6, #9, ....\n"         \
03274    "Similarly, you select a subset of the rows using the '{...}' notation:\n" \
03275    "  'fred.1D{0..$(2)}'      ==> use rows #0, #2, #4, ....\n"                \
03276    "You can also use both notations together, as in\n"                        \
03277    "  'fred.1D[1,3]{1..$(2)}' ==> columns #1 and #3; rows #1, #3, #5, ....\n" \
03278    "\n"                                                                       \
03279    "You can also input a 1D time series 'dataset' directly on the command\n"  \
03280    "line, without an external file. The 'filename' for such input has the\n"  \
03281    "general format\n"                                                         \
03282    "  '1D:n_1@val_1,n_2@val_2,n_3@val_3,...'\n"                               \
03283    "where each 'n_i' is an integer and each 'val_i' is a float.  For\n"       \
03284    "example\n"                                                                \
03285    "   -a '1D:5@0,10@1,5@0,10@1,5@0'\n"                                       \
03286    "specifies that variable 'a' be assigned to a 1D time series of 35,\n"     \
03287    "alternating in blocks between values 0 and value 1.\n"
03288 
03289 extern void THD_delete_3dim_dataset( THD_3dim_dataset * , Boolean ) ;
03290 extern THD_3dim_dataset * THD_3dim_from_block( THD_datablock * ) ;
03291 extern void THD_allow_empty_dataset( int ) ; /* 23 Mar 2001 */
03292 extern THD_3dim_dataset_array *
03293    THD_array_3dim_from_block( THD_datablock_array * blk_arr ) ;
03294 
03295 extern Boolean THD_write_3dim_dataset( char *,char * ,
03296                                        THD_3dim_dataset * , Boolean );
03297 
03298 extern void THD_use_3D_format   ( int ) ;  /* 21 Mar 2003 */
03299 extern void THD_use_NIFTI_format( int ) ;  /* 06 Apr 2005 */
03300 
03301 extern Boolean THD_write_datablock( THD_datablock * , Boolean ) ;
03302 extern Boolean THD_write_atr( THD_datablock * ) ;
03303 extern Boolean THD_write_nimlatr( THD_datablock * ) ;  /* 01 Jun 2005 */
03304 extern void THD_set_write_compression( int mm ) ;
03305 extern int THD_enviro_write_compression(void) ;
03306 extern int THD_get_write_compression(void) ;
03307 
03308 extern void THD_set_write_order( int ) ;
03309 extern void THD_enviro_write_order(void) ;
03310 extern int THD_get_write_order(void) ;
03311 
03312 extern int TRUST_host(char *) ;
03313 #define OKHOST(hh) TRUST_host(hh) ;
03314 extern void TRUST_addhost(char *) ;      /* 21 Feb 2001 */
03315 
03316 extern Boolean THD_load_datablock( THD_datablock * ) ;
03317 extern void    THD_load_datablock_verbose(int) ;             /* 21 Aug 2002 */
03318 extern void    THD_set_freeup( generic_func * ) ;            /* 18 Oct 2001 */
03319 extern Boolean THD_purge_datablock( THD_datablock * , int ) ;
03320 extern Boolean THD_purge_one_brick( THD_datablock * , int ) ;
03321 extern void    THD_force_malloc_type( THD_datablock * , int ) ;
03322 extern int     THD_count_databricks( THD_datablock * dblk ) ;
03323 extern void    THD_load_minc( THD_datablock * ) ;            /* 29 Oct 2001 */
03324 extern void    THD_load_analyze( THD_datablock * ) ;         /* 27 Aug 2002 */
03325 extern void    THD_load_ctfmri ( THD_datablock * ) ;         /* 04 Dec 2002 */
03326 extern void    THD_load_ctfsam ( THD_datablock * ) ;         /* 04 Dec 2002 */
03327 extern void    THD_load_1D     ( THD_datablock * ) ;         /* 04 Mar 2003 */
03328 extern void    THD_load_3D     ( THD_datablock * ) ;         /* 21 Mar 2003 */
03329 extern void    THD_load_nifti  ( THD_datablock * ) ;         /* 28 Aug 2003 */
03330 extern void    THD_load_mpeg   ( THD_datablock * ) ;         /* 03 Dec 2003 */
03331 extern void    THD_load_tcat   ( THD_datablock * ) ;         /* 04 Aug 2004 */
03332 
03333 extern void    THD_zerofill_dataset( THD_3dim_dataset * ) ;  /* 18 Mar 2005 */
03334 
03335 extern int THD_datum_constant( THD_datablock * ) ;           /* 30 Aug 2002 */
03336 #define DSET_datum_constant(ds) THD_datum_constant((ds)->dblk)
03337 
03338 #define ALLOW_FSL_FEAT  /* 27 Aug 2002 */
03339 
03340 #define MINC_FLOATIZE_MASK 1
03341 extern int THD_write_minc( char *, THD_3dim_dataset * , int ) ; /* 11 Apr 2002 */
03342 
03343 extern void THD_write_1D ( char *, char *, THD_3dim_dataset *); /* 04 Mar 2003 */
03344 extern void THD_write_3D ( char *, char *, THD_3dim_dataset *); /* 21 Mar 2003 */
03345 
03346 extern void THD_reconcile_parents( THD_sessionlist * ) ;
03347 extern THD_slist_find THD_dset_in_sessionlist( int,void *, THD_sessionlist *, int ) ;
03348 extern THD_slist_find THD_dset_in_session( int,void * , THD_session * ) ;
03349 
03350 extern void THD_check_idcodes( THD_sessionlist * ) ; /* 08 Jun 1999 */
03351 
03352 extern void THD_load_statistics( THD_3dim_dataset * ) ;
03353 extern void THD_update_statistics( THD_3dim_dataset * ) ;
03354 extern THD_brick_stats THD_get_brick_stats( MRI_IMAGE * ) ;
03355 extern void THD_update_one_bstat( THD_3dim_dataset * , int ) ; /* 29 Mar 2005 */
03356 
03357 extern THD_fvec3 THD_3dind_to_3dmm( THD_3dim_dataset * , THD_ivec3 ) ;
03358 extern THD_fvec3 THD_3dind_to_3dmm_no_wod( THD_3dim_dataset * , THD_ivec3 ) ;
03359 extern THD_ivec3 THD_3dmm_to_3dind( THD_3dim_dataset * , THD_fvec3 ) ;
03360 extern THD_ivec3 THD_3dmm_to_3dind_no_wod( THD_3dim_dataset * , THD_fvec3 ) ;
03361                                                    /* 28 Sep 2004  [rickr] */
03362 
03363 extern THD_fvec3 THD_3dfind_to_3dmm( THD_3dim_dataset * , THD_fvec3 ) ;
03364 extern THD_fvec3 THD_3dmm_to_3dfind( THD_3dim_dataset * , THD_fvec3 ) ;
03365 
03366 extern THD_fvec3 THD_3dmm_to_dicomm( THD_3dim_dataset * , THD_fvec3 ) ;
03367 extern THD_fvec3 THD_dicomm_to_3dmm( THD_3dim_dataset * , THD_fvec3 ) ;
03368 
03369 extern THD_fvec3 THD_tta_to_mni( THD_fvec3 ) ;  /* 29 Apr 2002 */
03370 extern THD_fvec3 THD_mni_to_tta( THD_fvec3 ) ;
03371 extern void THD_3mni_to_3tta( float *, float *, float *) ;
03372 extern void THD_3tta_to_3mni( float *, float *, float *) ;
03373 
03374 extern float THD_timeof      ( int , float , THD_timeaxis * ) ;
03375 extern float THD_timeof_vox  ( int , int , THD_3dim_dataset * ) ;
03376 extern float THD_timeof_slice( int , int , THD_3dim_dataset * ) ;  /* BDW */
03377 
03378 extern THD_fvec3 THD_dataset_center( THD_3dim_dataset * ) ;  /* 01 Feb 2001 */
03379 extern int THD_dataset_mismatch(THD_3dim_dataset *, THD_3dim_dataset *) ;
03380 
03381 extern int THD_dataset_tshift( THD_3dim_dataset * , int ) ; /* 15 Feb 2001 */
03382 
03383 #define MISMATCH_CENTER  (1<<0)  /* within 0.2 voxel */
03384 #define MISMATCH_DELTA   (1<<1)  /* within 0.001 voxel */
03385 #define MISMATCH_ORIENT  (1<<2)
03386 #define MISMATCH_DIMEN   (1<<3)
03387 
03388 /*----------------------------------------------------------------*/
03389 /*--------  FD_brick type: for rapid extraction of slices --------*/
03390 
03391 /*! This type is to hold information needed for the rapid extraction
03392            of slices from an AFNI dataset (THD_3dim_dataset struct).
03393 
03394     It exists primarily as a historical artifact.  The earliest version
03395     of AFNI was to be called FD3, as a successor to FD2.  The FD_brick
03396     was conceived as part of FD3.  However, FD3 morphed into AFNI within
03397     a few weeks, but by then I didn't want to throw away the code that
03398     had already been structured around this (primarily the imseq.c stuff).
03399 */
03400 
03401 typedef struct FD_brick {
03402 
03403    THD_ivec3 nxyz ;     /*!< actual dimensions as read in */
03404    THD_ivec3 sxyz ;     /*!< starting indices in each dataset dimen */
03405    THD_ivec3 a123 ;     /*!< axis codes as supplied in THD_3dim_dataset_to_brick */
03406 
03407    int n1 ;             /*!< ni = length in direction i */
03408    int d1 ;             /*!< di = stride in direction i */
03409    int e1 ;             /*!< ei = last index in direc i */
03410    int n2 ;             /*!< ni = length in direction i */
03411    int d2 ;             /*!< di = stride in direction i */
03412    int e2 ;             /*!< ei = last index in direc i */
03413    int n3 ;             /*!< ni = length in direction i */
03414    int d3 ;             /*!< di = stride in direction i */
03415    int start ;          /*!< start = offset of 1st elem */
03416 
03417    float del1 ;         /*!< voxel dimensions */
03418    float del2 ;         /*!< voxel dimensions */
03419    float del3 ;         /*!< voxel dimensions */
03420 
03421    THD_3dim_dataset * dset ;    /*!< pointer to parent dataset */
03422    int resam_code ;             /*!< how to resample normal sub-bricks */
03423    int thr_resam_code ;         /*!< how to resample statistical sub-bricks */
03424 
03425    char namecode[32] ;          /*!< June 1997 */
03426 
03427    XtPointer parent ;           /*!< struct owner */
03428 } FD_brick ;
03429 
03430 /*! rotate the three numbers (a,b,c) to (b,c,a) into (na,nb,nc) */
03431 
03432 #define ROT3(a,b,c,na,nb,nc) ((na)=(b),(nb)=(c),(nc)=(a))
03433 
03434 /*! Determine if this FD_brick can be drawn (in an image or graph) */
03435 
03436 #define BRICK_DRAWABLE(br)  ((br)->n1 >  1 && (br)->n2 >  1)
03437 #define BRICK_GRAPHABLE(br) ((br)->n1 >= 1 && (br)->n2 >= 1)
03438 
03439 extern FD_brick * THD_3dim_dataset_to_brick( THD_3dim_dataset * ,
03440                                              int,int,int ) ;
03441 
03442 extern MRI_IMAGE * FD_brick_to_mri( int,int , FD_brick * br ) ;
03443 extern MRI_IMAGE * FD_brick_to_series( int , FD_brick * br ) ;
03444 
03445 extern float THD_get_voxel( THD_3dim_dataset *dset , int ijk , int ival ) ;
03446 
03447 extern MRI_IMAGE * THD_extract_series( int , THD_3dim_dataset * , int ) ;
03448 extern MRI_IMARR * THD_extract_many_series( int, int *, THD_3dim_dataset * );
03449 
03450 extern int THD_extract_array( int, THD_3dim_dataset *, int, void * ) ;
03451 
03452 extern MRI_IMAGE * THD_extract_float_brick( int , THD_3dim_dataset * ) ;
03453 
03454 extern void THD_insert_series( int, THD_3dim_dataset *, int, int, void *, int );
03455 
03456 /*--------------- routines that are in thd_detrend.c ---------------*/
03457 
03458 extern void get_linear_trend     ( int, float *, float *, float * ) ;
03459 extern void THD_linear_detrend   ( int, float *, float *, float * ) ;
03460 extern void get_quadratic_trend  ( int, float *, float *, float *, float * ) ;
03461 extern void THD_quadratic_detrend( int, float *, float *, float *, float * ) ;
03462 extern void THD_normalize        ( int, float * ) ;
03463 extern void THD_cubic_detrend    ( int, float * ) ;  /* 15 Nov 1999 */
03464 
03465 extern void THD_const_detrend    ( int, float *, float * ); /* 24 Aug 2001 */
03466 
03467 extern void THD_generic_detrend( int, float *, int, int, float ** ) ;
03468 
03469 #define DETREND_linear(n,f)    THD_linear_detrend(n,f,NULL,NULL)
03470 #define DETREND_quadratic(n,f) THD_quadratic_detrend(n,f,NULL,NULL,NULL)
03471 #define DETREND_cubic(n,f)     THD_cubic_detrend(n,f)
03472 #define DETREND_const(n,f)     THD_const_detrend(n,f,NULL)
03473 
03474 /*! Macro to detrend a time series array in to various polynomial orders. */
03475 
03476 #define DETREND_polort(p,n,f)                            \
03477  do{ switch(p){ default:                         break;  \
03478                  case 0: DETREND_const(n,f)    ; break;  \
03479                  case 1: DETREND_linear(n,f)   ; break;  \
03480                  case 2: DETREND_quadratic(n,f); break;  \
03481                  case 3: DETREND_cubic(n,f)    ; break; } } while(0)
03482 
03483 /*------------------------------------------------------------------*/
03484 
03485 extern THD_ivec3 THD_fdind_to_3dind( FD_brick * , THD_ivec3 ) ;
03486 extern THD_ivec3 THD_3dind_to_fdind( FD_brick * , THD_ivec3 ) ;
03487 
03488 extern THD_fvec3 THD_fdfind_to_3dfind( FD_brick *, THD_fvec3) ; /* 30 Aug 2001 */
03489 extern THD_fvec3 THD_3dfind_to_fdfind( FD_brick *, THD_fvec3) ;
03490 
03491 extern FD_brick ** THD_setup_bricks( THD_3dim_dataset * ) ;
03492 
03493 extern FD_brick * THD_oriented_brick( THD_3dim_dataset *, char *) ; /* 07 Dec 2001 */
03494 
03495 extern int thd_floatscan  ( int , float *   ) ; /* 30 Jul 1999 */
03496 extern int thd_complexscan( int , complex * ) ; /* 14 Sep 1999 */
03497 
03498 extern byte * THD_makemask( THD_3dim_dataset *, int,float,float) ;
03499 extern int    THD_countmask( int , byte * ) ;
03500 extern byte * THD_automask( THD_3dim_dataset * ) ;         /* 13 Aug 2001 */
03501 extern void   THD_automask_verbose( int ) ;                /* 28 Oct 2003 */
03502 extern void   THD_automask_extclip( int ) ;
03503 extern byte * mri_automask_image( MRI_IMAGE * ) ;          /* 05 Mar 2003 */
03504 extern byte * mri_automask_imarr( MRI_IMARR * ) ;          /* 18 Nov 2004 */
03505 
03506 extern void THD_autobbox( THD_3dim_dataset * ,             /* 06 Jun 2002 */
03507                           int *, int * , int *, int * , int *, int * ) ;
03508 extern void MRI_autobbox( MRI_IMAGE * ,
03509                           int *, int * , int *, int * , int *, int * ) ;
03510 
03511 extern int THD_mask_fillin_completely( int,int,int, byte *, int ) ; /* 19 Apr 2002 */
03512 extern int THD_mask_fillin_once      ( int,int,int, byte *, int ) ;
03513 
03514 extern int THD_mask_clip_neighbors( int,int,int, byte *, float,float,float *) ; /* 28 Oct 2003 */
03515 
03516 extern void THD_mask_clust( int nx, int ny, int nz, byte *mmm ) ;
03517 extern void THD_mask_erode( int nx, int ny, int nz, byte *mmm ) ;
03518 
03519 extern int THD_peel_mask( int nx, int ny, int nz , byte *mmm, int pdepth ) ;
03520 
03521 extern void THD_mask_dilate( int, int, int, byte *, int ) ;  /* 30 Aug 2002 */
03522 
03523 extern float THD_cliplevel( MRI_IMAGE * , float ) ;          /* 12 Aug 2001 */
03524 extern MRI_IMAGE * THD_median_brick( THD_3dim_dataset * ) ;  /* 12 Aug 2001 */
03525 extern MRI_IMAGE * THD_mean_brick  ( THD_3dim_dataset * ) ;  /* 15 Apr 2005 */
03526 extern MRI_IMAGE * THD_rms_brick   ( THD_3dim_dataset * ) ;  /* 15 Apr 2005 */
03527 
03528  /* 08 Mar 2001 - functions for dealing with rows */
03529 
03530 extern int THD_get_dset_rowcount( THD_3dim_dataset *, int ) ;
03531 extern void * THD_get_dset_row( THD_3dim_dataset *, int, int, int,int,int ) ;
03532 extern void THD_put_dset_row( THD_3dim_dataset *, int,
03533                               int, int,int,int, void * row ) ;
03534 extern int THD_dataset_rowfillin( THD_3dim_dataset *, int, int, int ) ;
03535 extern int THD_dataset_zfillin( THD_3dim_dataset *, int, int, int ) ; /* 03 Jul 2001 */
03536 
03537 /*------------------------------------------------------------------*/
03538 /*-- October 1998: routines for 3D volume rotation and alignment. --*/
03539 
03540 #define DELTA_AFTER  1
03541 #define DELTA_BEFORE 2
03542 #define DELTA_FIXED  3
03543 
03544   /*-- see thd_rotangles.c --*/
03545 
03546 extern void THD_rotangle_user_to_dset( THD_3dim_dataset * ,
03547                                        float,char, float,char, float,char,
03548                                        float*,int* , float*,int* , float*,int* );
03549 
03550 extern int THD_axcode( THD_3dim_dataset * , char ) ; /* promoted from static */
03551 extern int THD_handedness( THD_3dim_dataset * ) ;    /* on 06 Feb 2001 - RWCox */
03552 
03553 extern THD_dmat33 DBLE_mat_to_dicomm( THD_3dim_dataset * ) ; /* 14 Feb 2001 */
03554 extern THD_mat33  SNGL_mat_to_dicomm( THD_3dim_dataset * ) ; /* 28 Aug 2002 */
03555 
03556 extern THD_dvecmat THD_rotcom_to_matvec( THD_3dim_dataset * , char * ) ;
03557 
03558   /*-- see thd_rot3d.c for these routines --*/
03559 
03560 extern void THD_rota_method( int ) ;
03561 
03562 extern void THD_rota_setpad( int,int,int ) ; /* 02 Feb 2001 */
03563 extern void THD_rota_clearpad(void) ;
03564 
03565 extern void THD_rota_vol( int, int, int, float, float, float, float *,
03566                           int,float, int,float, int,float,
03567                           int,float,float,float ) ;
03568 
03569 extern MRI_IMAGE * THD_rota3D( MRI_IMAGE * ,
03570                                int,float, int,float, int,float,
03571                                int,float,float,float ) ;
03572 
03573 extern MRI_IMAGE * THD_rota3D_matvec( MRI_IMAGE *, THD_dmat33,THD_dfvec3 ) ;
03574 
03575   /* routines below added to thd_rot3d.c on 16 Jul 2000 */
03576 
03577 extern void THD_rota_vol_matvec( int, int, int, float, float, float, float *,
03578                                  THD_dmat33 , THD_dfvec3 ) ;
03579 
03580 extern THD_dvecmat DLSQ_rot_trans( int, THD_dfvec3 *, THD_dfvec3 *, double * );
03581 extern THD_dvecmat DLSQ_affine   ( int, THD_dfvec3 *, THD_dfvec3 *           );
03582 extern THD_dvecmat DLSQ_rotscl   ( int, THD_dfvec3 *, THD_dfvec3 *, int      );
03583 
03584 extern THD_dvecmat THD_read_dvecmat( char * , int ) ;  /* THD_read_vecmat.c */
03585 
03586   /* cf. thd_tmask.c */
03587 
03588 #define TM_IXY 2  /* fixdir-1 for each plane */
03589 #define TM_IYZ 0
03590 #define TM_IZX 1
03591 
03592 /*! Struct used in cox_render.c to indicate which lines in a volume are all zero. */
03593 
03594 typedef struct {
03595    int   nmask[3] ;
03596    byte * mask[3] ;
03597 } Tmask ;
03598 
03599 extern void free_Tmask( Tmask * ) ;
03600 extern Tmask * create_Tmask_byte( int, int, int, byte * ) ;
03601 extern Tmask * create_Tmask_rgba( int, int, int, rgba * ) ;
03602 
03603 #define TM_ZLINE(tm,i) (tm==NULL || tm->mask[TM_IXY][i])
03604 #define TM_YLINE(tm,i) (tm==NULL || tm->mask[TM_IZX][i])
03605 #define TM_XLINE(tm,i) (tm==NULL || tm->mask[TM_IYZ][i])
03606 
03607   /* routines below created in thd_rot3d_byte.c on 23 Oct 2000 */
03608 
03609 extern void THD_rota_vol_byte( int, int, int, float, float, float, byte *,
03610                                int,float, int,float, int,float,
03611                                int,float,float,float , Tmask * ) ;
03612 
03613 extern void THD_rota_byte_mode( int ) ; /* 07 Nov 2000 */
03614 
03615 extern void THD_rota_vol_matvec_byte( int, int, int, float, float, float, byte *,
03616                                       THD_mat33 , THD_fvec3 , Tmask * ) ;
03617 
03618   /*-- see thd_shift2.c for these routines --*/
03619 
03620 extern void SHIFT_set_method( int ) ;
03621 extern int  SHIFT_get_method( void ) ;
03622 extern void SHIFT_two_rows( int , int , float , float *, float , float *) ;
03623 
03624 extern void fft_shift2  ( int , int , float , float *, float , float *) ;
03625 extern void hept_shift2 ( int , int , float , float *, float , float *) ;
03626 extern void quint_shift2( int , int , float , float *, float , float *) ;
03627 extern void cub_shift2  ( int , int , float , float *, float , float *) ;
03628 extern void lin_shift2  ( int , int , float , float *, float , float *) ;
03629 extern void nn_shift2   ( int , int , float , float *, float , float *) ;
03630 extern void ts_shift2   ( int , int , float , float *, float , float *) ;
03631 
03632 extern void hept_shift ( int , float , float *) ;
03633 extern void nn_shift   ( int , float , float *) ;
03634 extern void lin_shift  ( int , float , float *) ;
03635 extern void cub_shift  ( int , float , float *) ;
03636 extern void quint_shift( int , float , float *) ;
03637 
03638 extern void THD_fftshift( THD_3dim_dataset *, float,float,float, int ) ;
03639 
03640   /*-- see mri_3dalign.c for these routines --*/
03641 
03642 /*! Struct that holds information used during 3D registration. */
03643 
03644 typedef struct {
03645    MRI_IMARR * fitim ;    /*!< Regression basis images */
03646    double * chol_fitim ;  /*!< Choleski decomposition of the normal equations */
03647    int xa,xb , ya,yb , za,zb ; /* trim box */
03648 } MRI_3dalign_basis ;
03649 
03650 extern void mri_3dalign_edging( int , int , int ) ;
03651 extern void mri_3dalign_edging_default( int , int , int ) ;
03652 extern void mri_3dalign_force_edging( int ) ;
03653 extern void mri_3dalign_wtrimming( int ) ;
03654 extern void mri_3dalign_wproccing( int ) ;
03655 extern void mri_3dalign_scaleinit( float ) ;  /* 22 Mar 2004 */
03656 
03657 extern void mri_3dalign_params( int , float , float , float ,
03658                                 int , int , int , int ) ;
03659 
03660 extern void mri_3dalign_method( int , int , int , int ) ;
03661 
03662 extern void mri_3dalign_final_regmode( int ) ;
03663 
03664 extern MRI_3dalign_basis * mri_3dalign_setup( MRI_IMAGE * , MRI_IMAGE * ) ;
03665 extern MRI_IMAGE * mri_3dalign_one( MRI_3dalign_basis * , MRI_IMAGE * ,
03666                                     float *, float *, float *,
03667                                     float *, float *, float * ) ;
03668 extern MRI_IMARR * mri_3dalign_many( MRI_IMAGE *, MRI_IMAGE * , MRI_IMARR *,
03669                                     float *, float *, float *,
03670                                     float *, float *, float * ) ;
03671 extern void mri_3dalign_cleanup( MRI_3dalign_basis * ) ;
03672 
03673 extern void mri_3dalign_initvals( float,float,float,float,float,float ) ;
03674 
03675 /*---------------------------------------------------------------------*/
03676 
03677   /*-- see mri_warp3D_align.c for these routines --*/
03678 
03679 typedef struct {
03680   float min, max, ident, delta, toler ;
03681   float val_init , val_out , val_fixed ;
03682   int fixed ;
03683   char name[32] ;
03684 } MRI_warp3D_param_def ;
03685 
03686   /*! Struct that holds information used during warp3D registration. */
03687 
03688 typedef struct {
03689 
03690    /*- this stuff is to be set by the user -*/
03691 
03692    int nparam ;
03693    MRI_warp3D_param_def *param ;
03694    float scale_init , scale_out ;
03695    float delfac , tolfac ;
03696    float twoblur ;
03697 
03698    int regmode , verb , max_iter , num_iter , wtproc ;
03699    int xedge , yedge , zedge ;
03700    int regfinal ;
03701 
03702    MRI_IMAGE *imbase , *imwt ;
03703 
03704    void (*vwfor)(float,float,float,float *,float *,float *) ;
03705    void (*vwinv)(float,float,float,float *,float *,float *) ;
03706    void (*vwset)(int,float *) ;
03707    float (*vwdet)(float,float,float) ;
03708 
03709    /*- below here is not to be touched by the user! -*/
03710 
03711    int        nfree ;
03712    MRI_IMAGE *imww ;
03713    MRI_IMAGE *imap ;
03714    MRI_IMAGE *imps ;
03715    MRI_IMAGE *imsk ;
03716    MRI_IMAGE *imps_blur ;
03717 
03718 } MRI_warp3D_align_basis ;
03719 
03720 extern int         mri_warp3D_align_setup  ( MRI_warp3D_align_basis * ) ;
03721 extern MRI_IMAGE * mri_warp3d_align_one    ( MRI_warp3D_align_basis *, MRI_IMAGE * );
03722 extern void        mri_warp3D_align_cleanup( MRI_warp3D_align_basis * ) ;
03723 
03724 /*---------------------------------------------------------------------*/
03725 
03726 #if 0
03727 extern float THD_thresh_to_pval( float thr , THD_3dim_dataset * dset ) ;
03728 #endif
03729 
03730 extern float THD_stat_to_pval  ( float thr , int statcode , float * stataux ) ;
03731 extern float THD_pval_to_stat  ( float pval, int statcode , float * stataux ) ;
03732 extern float THD_stat_to_zscore( float thr , int statcode , float * stataux ) ;
03733 
03734 extern int THD_filename_ok( char * ) ;   /* 24 Apr 1997 */
03735 extern int THD_filename_pure( char * ) ; /* 28 Feb 2001 */
03736 extern int THD_freemegabytes( char * ) ; /* 28 Mar 2005 */
03737 
03738 extern THD_warp * AFNI_make_voxwarp( THD_warp * , THD_3dim_dataset * ,
03739                                                   THD_3dim_dataset *  ) ;
03740 
03741 extern THD_linear_mapping * AFNI_make_voxmap( THD_linear_mapping * ,
03742                                               THD_dataxes * , THD_dataxes * ) ;
03743 
03744 extern void AFNI_concatenate_warp( THD_warp * , THD_warp * ) ;
03745 
03746 extern THD_linear_mapping * AFNI_concatenate_lmap( THD_linear_mapping * ,
03747                                                    THD_linear_mapping *  ) ;
03748 
03749 extern THD_warp * AFNI_make_affwarp_12(float,float,float,float,
03750                                        float,float,float,float,
03751                                        float,float,float,float ); /* 27 Aug 2002 */
03752 
03753 extern THD_warp * AFNI_make_affwarp_mat   ( THD_mat33 ) ;         /* 28 Aug 2002 */
03754 extern THD_warp * AFNI_make_affwarp_matvec( THD_mat33 , THD_fvec3 ) ;
03755 
03756 extern THD_ivec3 THD_matrix_to_orientation( THD_mat33 R ) ;       /* 27 Aug 2003 */
03757 
03758 extern THD_3dim_dataset * WINsorize( THD_3dim_dataset * ,
03759                                      int,int,int, float, char *, int,int,byte * );
03760 
03761 #define ZPAD_EMPTY (1<<0)
03762 #define ZPAD_PURGE (1<<1)
03763 #define ZPAD_MM    (1<<2)
03764 
03765 extern THD_3dim_dataset * THD_zeropad( THD_3dim_dataset * ,
03766                                        int,int,int,int,int,int, char *, int );
03767 
03768 extern THD_3dim_dataset * THD_warp3D(    /* cf. mri_warp3D.c - 18 May 2003 */
03769                      THD_3dim_dataset *,
03770                      void w_in2out(float,float,float,float *,float *,float *),
03771                      void w_out2in(float,float,float,float *,float *,float *),
03772                      void * , char *, int , int ) ;
03773 
03774 extern THD_3dim_dataset * THD_warp3D_affine(
03775                      THD_3dim_dataset *, THD_vecmat, void *, char *, int, int );
03776 
03777 extern THD_3dim_dataset * THD_warp3D_mni2tta( THD_3dim_dataset *, void *,
03778                                               char *, int, int );
03779 extern THD_3dim_dataset * THD_warp3D_tta2mni( THD_3dim_dataset *, void *,
03780                                               char *, int, int );
03781 
03782 #define WARP3D_NEWGRID  1
03783 #define WARP3D_NEWDSET  2
03784 #define WARP3D_GRIDMASK 7
03785 
03786 /*-- 02 Mar 2001: thd_entropy16.c --*/
03787 
03788 extern void   ENTROPY_setup     (void) ;
03789 extern void   ENTROPY_setdown   (void) ;
03790 extern void   ENTROPY_accumulate(int , void *) ;
03791 extern double ENTROPY_compute   (void) ;
03792 extern double ENTROPY_dataset   (THD_3dim_dataset *) ;
03793 extern double ENTROPY_datablock (THD_datablock *) ;
03794 
03795 /*--------------------------------------------------------------------------*/
03796 
03797 /*--- Stuff for Tom Ross's NOTES ---*/
03798 
03799 #define MAX_DSET_NOTES 999
03800 #define MAX_NOTE_SIZE  4000
03801 
03802 extern void   tross_Add_Note   (THD_3dim_dataset *, char *) ;
03803 extern void   tross_Delete_Note(THD_3dim_dataset *, int   ) ;
03804 
03805 extern char * tross_Expand_String( char * ) ;
03806 extern char * tross_Encode_String( char * ) ;
03807 extern void tross_Dont_Encode_Slash( int ) ;  /* 13 Mar 2003 */
03808 
03809 extern void   tross_Store_Note   ( THD_3dim_dataset * , int , char * ) ;
03810 extern char * tross_Get_Note     ( THD_3dim_dataset * , int ) ;
03811 extern char * tross_Get_Notedate ( THD_3dim_dataset * , int ) ;
03812 extern int    tross_Get_Notecount( THD_3dim_dataset * ) ;
03813 
03814 extern void tross_Addto_History( THD_3dim_dataset *, THD_3dim_dataset *) ;
03815 
03816 extern char * tross_datetime(void) ;
03817 extern char * tross_username(void) ;
03818 extern char * tross_hostname(void) ;
03819 extern char * tross_commandline( char * , int , char ** ) ;
03820 
03821 extern int AFNI_logger( char * , int , char ** ) ; /* 13 Aug 2001 */
03822 extern void AFNI_sleep( int ) ;
03823 #define AFNI_log_string(ss) AFNI_logger(ss,0,NULL)
03824 
03825 extern void AFNI_serverlog( char * ) ;             /* 24 Mar 2005 */
03826 
03827 void THD_outlier_count( THD_3dim_dataset *, float, int **, int * ) ; /* 15 Aug 2001 */
03828 
03829 extern void   tross_Append_History ( THD_3dim_dataset * , char * ) ;
03830 extern char * tross_Get_History    ( THD_3dim_dataset * ) ;
03831 extern void   tross_Make_History   ( char *, int, char **, THD_3dim_dataset * ) ;
03832 extern void   tross_Copy_History   ( THD_3dim_dataset *, THD_3dim_dataset * ) ;
03833 extern void   tross_Replace_History( THD_3dim_dataset * , char * ) ;
03834 
03835 #define tross_Erase_History(ds) THD_erase_one_atr((ds)->dblk,"HISTORY_NOTE")
03836 
03837 extern char * tross_breakup_string( char *, int , int ) ;
03838 
03839 #include <stdarg.h>
03840 void tross_multi_Append_History( THD_3dim_dataset * , ... ) ;
03841 
03842 /*-----------------------------------------------------------------------*/
03843 
03844 extern void B64_to_binary( int, byte *, int *, byte ** ) ; /* thd_base64.c */
03845 extern void B64_to_base64( int, byte *, int *, byte ** ) ;
03846 extern void B64_set_linelen( int ) ;
03847 extern void B64_set_crlf( int ) ;
03848 
03849 extern char * MD5_static_array ( int , char * ) ;          /* thd_md5.c */
03850 extern char * MD5_malloc_array ( int , char * ) ;
03851 extern char * MD5_static_string(char *) ;
03852 extern char * MD5_malloc_string(char *) ;
03853 extern char * MD5_static_file  (char *) ;
03854 extern char * MD5_malloc_file  (char *) ;
03855 
03856 extern char * MD5_B64_array ( int , char * ) ;
03857 extern char * MD5_B64_string( char * ) ;
03858 extern char * MD5_B64_file  (char * ) ;
03859 extern char * UNIQ_idcode(void) ;            /* 27 Sep 2001 */
03860 extern void   UNIQ_idcode_fill(char *) ;
03861 
03862 /*------------------------------------------------------------------------*/
03863 
03864 extern char * TT_whereami( float , float , float ) ;
03865 extern int  TT_load_atlas (void);
03866 extern void TT_purge_atlas(void);
03867 extern THD_3dim_dataset * TT_retrieve_atlas(void) ;
03868 
03869 extern THD_3dim_dataset * TT_retrieve_atlas_big(void) ; /* 01 Aug 2001 */
03870 extern void TT_purge_atlas_big(void);
03871 
03872 extern THD_3dim_dataset * TT_retrieve_atlas_either(void); /* 22 Aug 2001 */
03873 
03874 #define TT_ATLAS_NZ_SMALL 141 /* 01 Aug 2001 */
03875 #define TT_ATLAS_NZ_BIG   151
03876 
03877 #define TT_retrieve_atlas_nz(nz)                                \
03878  ( ((nz)==TT_ATLAS_NZ_SMALL)                                    \
03879     ? TT_retrieve_atlas()                                       \
03880     : ((nz)==TT_ATLAS_NZ_BIG) ? TT_retrieve_atlas_big() : NULL )
03881 
03882 /*------------------------------------------------------------------------*/
03883 
03884 extern float THD_spearman_corr( int,float *,float *) ;  /* 23 Aug 2001 */
03885 extern float THD_quadrant_corr( int,float *,float *) ;
03886 extern float THD_pearson_corr ( int,float *,float *) ;
03887 
03888 extern THD_fvec3 THD_autonudge( THD_3dim_dataset *dsepi, int ivepi,
03889                                 THD_3dim_dataset *dsant, int ivant,
03890                                 float step,
03891                                 int xstep, int ystep, int zstep, int code ) ;
03892 
03893 extern MRI_IMAGE * mri_brainormalize( MRI_IMAGE *, int,int,int , MRI_IMAGE **, MRI_IMAGE **) ; /* 05 Apr 2004 */
03894 extern void mri_brainormalize_verbose( int ) ;
03895 extern void brainnormalize_coord( float  ispat, float  jspat, float  kspat ,
03896                            float *iorig, float *jorig, float *korig ,
03897                            THD_3dim_dataset *origset,
03898                            float *xrai_orig, float *yrai_orig, float *zrai_orig); /* ZSS */
03899 extern MRI_IMAGE * mri_watershedize( MRI_IMAGE * , float ) ;
03900 extern void mri_brainormalize_initialize(float dx, float dy, float dz);
03901 extern float THD_BN_dxyz(void);
03902 extern int THD_BN_nx(void);
03903 extern int THD_BN_ny(void);
03904 extern int THD_BN_nz(void);
03905 /*------------------------------------------------------------------------*/
03906 /* 09 May 2005: stuff for converting a dataset to from a NIML group.      */
03907 
03908 extern NI_group * THD_nimlize_dsetatr( THD_3dim_dataset *) ;
03909 extern void       THD_dblkatr_from_niml( NI_group *, THD_datablock * ) ;
03910 extern void       THD_set_dataset_attributes( THD_3dim_dataset * ) ;
03911 
03912 extern THD_3dim_dataset * THD_niml_to_dataset( NI_group * , int ) ;
03913 extern int THD_add_bricks( THD_3dim_dataset * , void * ) ;
03914 
03915 #define SBFLAG_INDEX    (1<<0)
03916 #define SBFLAG_FACTOR   (1<<1)
03917 #define SBFLAG_STATCODE (1<<2)
03918 
03919 extern NI_element * THD_subbrick_to_niml( THD_3dim_dataset *, int , int ) ;
03920 extern NI_group * THD_dataset_to_niml( THD_3dim_dataset * ) ;
03921 
03922 extern MRI_IMAGE  * niml_to_mri( NI_element * ) ;
03923 extern NI_element * mri_to_niml( MRI_IMAGE *  ) ;
03924 
03925 #endif /* _MCW_3DDATASET_ */
 

Powered by Plone

This site conforms to the following standards: