Attributes in the AFNI Dataset Header ===================================== Each attribute is an array of values. There are three kinds of attributes allowed: float, int, and string (array of char). Each attribute has a name, which by convention is all caps. All the attributes are read in at once when a dataset .HEAD file is opened. The software searches for the attributes it wants, by name, when it needs them. Attributes that are not wanted by the programs are thus simply ignored. For example, the HISTORY_NOTE attribute is only used by functions in the thd_notes.c source file. -------------------- Format of Attributes -------------------- The format of attributes is a little clunky and non-robust, but that's the way it is for now. The .HEAD file structure was "designed" in 1994, and has not changed at all since then. Here is an example of an int attribute in the .HEAD file: type = integer-attribute name = ORIENT_SPECIFIC count = 3 3 5 1 The first line of the attribute is the "type =" line, which can take values "integer-attribute", "float-attribute", or "string-attribute". The second line is the "name =" line; the name that follows must not contain any blanks. The third line is the "count =" line; the value that follows is the number of entries in the attribute array. These 3 lines are read with the code below: char aname[THD_MAX_NAME] , atypestr[THD_MAX_NAME] ; int acount ; fscanf( header_file , " type = %s name = %s count = %d" , atypestr , aname , &acount ) ; Recall that a blank in a format matches any amount of whitespace in the input stream; for example, "name =" and "name =" are both acceptable second lines in an attribute (as are a number of other bizarre things that are too painful to elucidate). Following the third line is the list of values for the attribute array. For float and int attributes, these values are separated by blanks (or other C "whitespace"). If the .HEAD file is generated by an AFNI program, then a maximum of 5 values per line will be written. However, this is not required -- it is just there to make the .HEAD file easy to edit manually. For string attributes, the entire array of "count" characters follows on the fourth line, right after a single opening quote ' character. For example: type = string-attribute name = TYPESTRING count = 15 '3DIM_HEAD_ANAT~ Note that the starting ' is not part of the attribute value and is not included in the count. Also note that ASCII NUL characters '\0' are replaced with tilde ~ characters when the header is written. (This is to make it easy to edit the file manually). They will be replaced with NULs (not to be confused with NULL) when the attribute is read in. If a string actually contains a tilde, then the tilde will be replaced with an asterisk * when the attribute is written out. However, asterisks will NOT be replaced with tildes on input -- that is, there is no way for an attribute string to contain a tilde. Some of the attributes described below may contain more array entries in the .HEAD file than are listed. These entries are "reserves" for future expansion. In most cases, the expansions never happened. --------------------------------------- Extracting Attributes in a Shell Script --------------------------------------- Program 3dAttribute can be used to extract attributes from a dataset .HEAD file. For example 3dAttribute TYPESTRING anat+orig might produce (on stdout) the value "3DIM_HEAD_ANAT". This could be captured in a shell variable and used to make some decisions. For usage details, type the command 3dAttribute -help -------------------- Mandatory Attributes -------------------- All these attributes must be present for a dataset to be recognized from a .HEAD file. DATASET_RANK = Two values that determine the dimensionality of the (int) dataset: [0] = Number of spatial dimensions (must be 3) [1] = Number of sub-bricks in the dataset (in most programs, this is called "nvals") At one time I thought I might extend AFNI to support n-dimensional datasets, but as time went one, I decided to support the fourth dimension not by increasing the "rank" of a dataset, but by adding the time axis instead. Thus, the dataset rank is always set to 3. DATASET_DIMENSIONS = Three values that determine the size of each (int) spatial axis of the dataset: [0] = number of voxels along the x-axis (nx) [1] = number of voxels along the y-axis (ny) [2] = number of voxels along the z-axis (nz) The voxel with 3-index (i,j,k) in a sub-brick is located at position (i+j*nx+k*nx*ny), for i=0..nx-1, j=0..ny-1, k=0..nz-1. Each axis must have at least 2 points! TYPESTRING = One of "3DIM_HEAD_ANAT" or "3DIM_HEAD_FUNC" or (string) "3DIM_GEN_ANAT" or "3DIM_GEN_FUNC". Determines if the dataset is of Anat or Func type (grayscale underlay or color overlay). If Anat type, and if it is a _HEAD_ dataset in the +orig view, then Talairach markers might be attached to it (if it was created by to3d). SCENE_DATA = Three integer codes describing the dataset type (int) [0] = view type: 0=+orig, 1=+acpc, 2=+tlrc [1] = func type: If dataset is Anat type, then this is one of the following codes: #define ANAT_SPGR_TYPE 0 #define ANAT_FSE_TYPE 1 #define ANAT_EPI_TYPE 2 #define ANAT_MRAN_TYPE 3 #define ANAT_CT_TYPE 4 #define ANAT_SPECT_TYPE 5 #define ANAT_PET_TYPE 6 #define ANAT_MRA_TYPE 7 #define ANAT_BMAP_TYPE 8 #define ANAT_DIFF_TYPE 9 #define ANAT_OMRI_TYPE 10 #define ANAT_BUCK_TYPE 11 At this time, Anat codes 0..10 are treated identically by all AFNI programs. Code 11 marks the dataset as a "bucket" type, which is treated differently in the display; the "Define Function" control panel will have a chooser that allows you to specify which sub-brick from the bucket should be used to make the underlay image. If dataset is Func type, then this is one of the following codes: #define FUNC_FIM_TYPE 0 /* 1 value */ #define FUNC_THR_TYPE 1 /* obsolete */ #define FUNC_COR_TYPE 2 /* fico: correlation */ #define FUNC_TT_TYPE 3 /* fitt: t-statistic */ #define FUNC_FT_TYPE 4 /* fift: F-statistic */ #define FUNC_ZT_TYPE 5 /* fizt: z-score */ #define FUNC_CT_TYPE 6 /* fict: Chi squared */ #define FUNC_BT_TYPE 7 /* fibt: Beta stat */ #define FUNC_BN_TYPE 8 /* fibn: Binomial */ #define FUNC_GT_TYPE 9 /* figt: Gamma */ #define FUNC_PT_TYPE 10 /* fipt: Poisson */ #define FUNC_BUCK_TYPE 11 /* fbuc: bucket */ These types are defined more fully in README.func_types. Unfortunately, the func type codes overlap for Func and Anat datasets. This means that one cannot tell the contents of a dataset from a single attribute. However, this bad design choice (from 1994) is now enshrined in the .HEAD files of thousands of datasets, so it will be hard to change. [2] = 0 or 1 or 2 or 3, corresponding to the TYPESTRING values given above. If this value does not match the typestring value, then the dataset is malformed and AFNI will reject it! ORIENT_SPECIFIC = Three integer codes describing the spatial orientation (int) of the dataset axes; [0] for the x-axis, [1] for the y-axis, and [2] for the z-axis. The possible codes are: #define ORI_R2L_TYPE 0 /* Right to Left */ #define ORI_L2R_TYPE 1 /* Left to Right */ #define ORI_P2A_TYPE 2 /* Posterior to Anterior */ #define ORI_A2P_TYPE 3 /* Anterior to Posterior */ #define ORI_I2S_TYPE 4 /* Inferior to Superior */ #define ORI_S2I_TYPE 5 /* Superior to Inferior */ Note that these codes must make sense (e.g., they can't all be 4). Only program to3d enforces this restriction, but if you create a nonsensical dataset, then bad things will happen at some point. Spatial xyz-coordinates in AFNI are sometimes used in dataset order, which refers to the order given here. They are also sometimes used in Dicom order, in which x=R-L, y=A-P, and z=I-S (R,A,I are < 0; L,P,S are > 0). There are utility functions for converting dataset ordered 3-vectors to and from Dicom ordered 3-vectors -- see the functions in file thd_coords.c. Distances in AFNI are always encoded in millimeters. ORIGIN = Three numbers giving the xyz-coordinates of the center of (float) the (0,0,0) voxel in the dataset. The order of these numbers is the same as the order of the xyz-axes (cf. ORIENT_SPECIFIC). However, the AFNI convention is that R-L, A-P, and I-S are negative-to-positive. Thus, if the y-axis is P-A (say), then the y-origin is likely to be positive (and the y-delta, below, would be negative). These numbers are usually computed from the centering controls in to3d. DELTA = Three numbers giving the (x,y,z) voxel sizes, in the same order as ORIENT_SPECIFIC. That is, [0] = x-delta, [1] = y-delta, and [2] = z-delta. These values may be negative; in the example above, where the y-axis is P-A, then y-delta would be negative. The center of the (i,j,k) voxel is located at xyz-coordinates ORIGIN[0]+i*DELTA[0], ORIGIN[1]+j*DELTA[1], ORIGIN[2]+k*DELTA[2] --------------------------------- Time-Dependent Dataset Attributes --------------------------------- These attributes are mandatory if the .HEAD file describes a 3D+time dataset. TAXIS_NUMS = [0] = Number of points in time (at present, must be equal (int) to nvals=DATASET_RANK[1], or AFNI programs will not be happy; that is, each time point can only have a single numerical value per voxel). [1] = Number of slices with time offsets. If zero, then no slice-dependent time offsets are present (all slices are presumed to be acquired at the same time). If positive, specifies the number of values to read from TAXIS_OFFSETS. Normally, this would either be 0 or be equal to DATASET_DIMENSIONS[2]. [2] = Units codes for TAXIS_FLOATS[1]; one of the following #define UNITS_MSEC_TYPE 77001 /* don't ask me */ #define UNITS_SEC_TYPE 77002 /* where these */ #define UNITS_HZ_TYPE 77003 /* came from! */ TAXIS_FLOATS = [0] = Time origin (in units given by TAXIS_NUMS[2]). (float) This is 0 in datasets created by to3d (at present). [1] = Time step (TR). [2] = Duration of acquisition. This is 0 in datasets created by to3d (at present) [3] = If TAXIS_NUMS[1] > 0, then this is the z-axis offset for the slice-dependent time offsets. This will be equal to ORIGIN[2] in datasets created by to3d.c. [4] = If TAXIS_NUMS[1] > 0, then this is the z-axis step for the slice-dependent time offsets. This will be equal to DELTA[2] in datasets created by to3d.c. TAXIS_OFFSETS = If TAXIS_NUMS[1] > 0, then this array gives the time (floats) offsets of the slices defined by TAXIS_FLOATS[3..4]. The time offset at z = TAXIS_FLOATS[3] + k*TAXIS_FLOATS[4] is TAXIS_OFFSETS[k], for k=0..TAXIS_NUMS[1]-1. If TAXIS_NUMS[1] == 0, then this attribute is not used. The functions in thd_timeof.c are used to compute the time for any given voxel, taking into account the slice-dependent offsets. --------------------------- Almost Mandatory Attributes --------------------------- The following useful attributes are present in most AFNI datasets created by AFNI package programs. However, if they are not present, then the function that assembles a dataset struct will get by. IDCODE_STRING = 15 character string (plus NUL) giving a (hopefully) (string) unique identifier for the dataset, independent of the filename assigned by the user. If this attribute is not present, the input routine will make one up for the dataset. ID codes are used to provide links between datasets; see IDCODE_ANAT_PARENT for an example. (ID codes are generated in file thd_idcode.c.) IDCODE_DATE = Maximum of 47 characters giving the creation date for (string) the dataset. (Antedates the History Note, which contains the same information and more.) Not used anywhere except in 3dinfo. BYTEORDER_STRING = If this attribute is present, describes the byte- (string) ordering of the data in the .BRIK file. Its value must be one of the strings "LSB_FIRST" or "MSB_FIRST". If this attribute is not present, AFNI will assume that the brick is in the "native" order for the CPU on which the program is running. If this attribute is present, and it is different from the native CPU order, then short sub-bricks are 2-swapped (AB->BA) and float or complex sub-bricks are 4-swapped (ABCD->DCBA) when the .BRIK file is read into memory. BRICK_STATS = There should be 2*nvals values here. For the p-th (float) sub-brick, BRICK_STATS[2*p] is the minimum value stored in the brick, and BRICK_STATS[2*p+1] is the maximum value stored in the brick. If the brick is scaled, then these values refer to the scaled values, NOT to the actual values stored in the .BRIK file. Most AFNI programs create this attribute as they write the dataset to disk (e.g., by using the DSET_write macro, or by calling THD_load_statistics). The main function of this attribute is to provide the display of the dataset numerical ranges on the "Define Function" control panel. BRICK_TYPES = There should be nvals=DATASET_RANK[1] values here. For (int) the p-th sub-brick, BRICK_TYPES[p] is a code that tells the type of data stored in the .BRIK file for that sub-brick. (Although it is possible to create a dataset that has varying sub-brick types, I do not recommend it. That is, I recommend that all BRICK_TYPE[p] values be the same.) The legal types for AFNI datasets are 0 = byte (unsigned char; 1 byte) 1 = short (2 bytes, signed) 3 = float (4 bytes, assumed to be IEEE format) 5 = complex (8 bytes: real+imaginary parts) Future versions of AFNI may support 2=int, 4=double, and 6=rgb, or other extensions (but don't hold your breath). Relatively few AFNI programs support complex-valued datasets. If this attribute is not present, then the sub-bricks will all be assumed to be shorts (which was the only datum type supported in AFNI 1.0). The p-th sub-brick will have nx*ny*nz*sz bytes from the .BRIK file, where nx,ny,nz are from DATASET_DIMENSIONS and sz=sizeof(datum type). BRICK_FLOAT_FACS = There should be nvals=DATASET_RANK[1] values here. For (float) the p-th sub-brick, if f=BRICK_FLOAT_FACS[p] is positive, then the values in the .BRIK should be scaled by f to give their "true" values. Normally, this would only be used with byte or short types (to save disk space), but it is legal to use f > 0 for float type sub-bricks as well (although pointless and confusing). If f==0, then the values are unscaled. Possible uses for f < 0 are reserved for the future. If this attribute is not present, then all brick factors are taken to be 0 (i.e., no scaling). BRICK_LABS = These are labels for the sub-bricks, and are used in the (string) choosers for sub-brick display when the dataset is a bucket type. This attribute should contain nvals sub-strings, separated by NUL characters. If this attribute is not present, then the input routine will make up some labels of the form "#0", "#1", etc. BRICK_STATAUX = This stores auxiliary statistical information about (float) sub-bricks that contain statistical parameters. Each unit of this array contains the following iv = sub-brick index (0..nvals-1) jv = statistical code (see below) nv = number of parameters that follow (may be 0) and then nv more numbers. That is, there are nv+3 numbers for each unit of this array, starting at location [0]. After the first unit is read out (from BRICK_STATAUX[0] up to BRICK_STATAUX[2+BRICK_STATAUX[2]]), then the next one starts immediately with the next value of iv. jv should be one of the 9 statistical types supported by AFNI, and described in README.func_types, and below: ------------- ----------------- ------------------------------ Type Index=jv Distribution Auxiliary Parameters [stataux] ------------- ----------------- ------------------------------ FUNC_COR_TYPE Correlation Coeff # Samples, # Fit Param, # Orts FUNC_TT_TYPE Student t Degrees-of-Freedom (DOF) FUNC_FT_TYPE F ratio Numerator DOF, Denominator DOF FUNC_ZT_TYPE Standard Normal -- none -- FUNC_CT_TYPE Chi-Squared DOF FUNC_BT_TYPE Incomplete Beta Parameters "a" and "b" FUNC_BN_TYPE Binomial # Trials, Probability per trial FUNC_GT_TYPE Gamma Shape, Scale FUNC_PT_TYPE Poisson Mean The main function of this attribute is to let the "Define Function" threshold slider show a p-value. This attribute also allows various other statistical calculations, such as the "-1zscore" option to 3dmerge. STAT_AUX = The BRICK_STATAUX attribute allows you to attach statistical (float) distribution information to arbitrary sub-bricks of a bucket dataset. The older STAT_AUX attribute is for the Func type datasets of the following types: fico = FUNC_COR_TYPE fitt = FUNC_TT_TYPE fift = FUNC_FT_TYPE fict = FUNC_CT_TYPE fibt = FUNC_BT_TYPE fibn = FUNC_BN_TYPE figt = FUNC_GT_TYPE fipt = FUNC_PT_TYPE These parameters apply to the second sub-brick (#1) of the dataset. (Datasets of these types must have exactly 2 sub-bricks.) The number and definition of these parameters is the same as the BRICK_STATAUX cases, above. ---------------- Notes Attributes ---------------- Special characters in these strings are escaped. For example, the newline character is stored in the header as the two character combination "\n", but will be displayed as a newline when the Notes are printed (e.g., in 3dinfo). The characters that are escaped are '\r' '\n' '\"' '\t' '\a' '\v' '\b' CR LF quote TAB BEL VTAB BS For details, see function tross_Encode_String() in file thd_notes.c. HISTORY_NOTE = A multi-line string giving the history of the dataset. (string) Can be read with 3dinfo, the Notes plugin, or 3dNotes. Written functions in thd_notes.c, including tross_Copy_History: copies dataset histories tross_Make_History: adds a history line from argc,argv NOTES_COUNT = The number of auxiliary notes attached to the dataset (int) (from 0 to 999). NOTE_NUMBER_001 = The first auxiliary note attached to the dataset. (string) Can be read/written with the Notes plugin, or 3dNotes. (You have to guess what the attribute name for the 237th Note will be.) ----------------------- Registration Attributes ----------------------- Note that the MATVEC attributes are transformations of Dicom-ordered coordinates, and so have to be permuted to transform dataset-ordered xyz-coordinates. The MATVEC attributes describe the transformation of coordinates from input dataset to the output dataset in the form [xyz_out] = [mat] ([xyz_in]-[xyz_cen]) + [vec] + [xyz_cen] where [mat] is a 3x3 orthogonal matrix; [vec] is a 3-vector; [xyz_in] is the input vector; [xyz_cen] is the center of rotation (usually the center of the dataset); [xyz_out] is the output vector. Dicom coordinate order is used for these matrices and vectors, which means that they need to be permuted to dataset order for application. For examples of how this is done, see 3drotate.c and 3dvolreg.c. TAGALIGN_MATVEC = 12 numbers giving the 3x3 matrix and 3-vector of the (float) transformation derived in 3dTagalign. The matrix-vector are loaded from the following elements of the attribute: [ 0 1 2 ] [ 3 ] [mat] = [ 4 5 6 ] [vec] = [ 7 ] [ 8 9 10 ] [ 11 ] This is used by 3drotate with the -matvec_dset option, and is written by 3dTagalign. VOLREG_MATVEC_xxxxxx = For sub-brick #xxxxxx (so a max of 999,999 (float) sub-bricks can be used), this stores the 12 numbers for the matrix-vector of the transformation from 3dvolreg. This is used by the -rotparent options of 3drotate and 3dvolreg, and is written into the output dataset of 3dvolreg. The value of xxxxxx is printf("%06d",k) for k=0..VOLREG_ROTCOM_NUM-1. VOLREG_ROTCOM_xxxxxx = The -rotate/-ashift options to 3drotate that are (string) equivalent to the above matrix-vector transformation. It is not actually used anywhere, but is there for reference. VOLREG_CENTER_OLD = The xyz-coordinates (Dicom order) of the center of (float) the input dataset to 3dvolreg; this is written to 3dvolreg's output dataset, and is used by the -rotparent options to 3dvolreg and 3drotate. VOLREG_CENTER_BASE = The xyz-coordinates (Dicom order) of the center of the base dataset to 3dvolreg; this is written to 3dvolreg's output dataset, and is used by the -rotparent options to 3dvolreg and 3drotate. VOLREG_ROTPARENT_IDCODE = If a 3dvolreg run uses the -rotparent option, (string) then this value in the header of the output dataset tells which dataset was the rotparent. VOLREG_ROTPARENT_NAME = The .HEAD filename of the -rotparent. (string) VOLREG_GRIDPARENT_IDCODE = Similar to the above, but for a 3dvolreg (string) output dataset that was created using a -gridparent option. VOLREG_GRIDPARENT_NAME = The .HEAD filename of the -gridparent. (string) VOLREG_INPUT_IDCODE = In the 3dvolreg output dataset header, this (string) tells which dataset was the input to 3dvolreg. VOLREG_INPUT_NAME = The .HEAD filename of the 3dvolreg input dataset. (string) VOLREG_BASE_IDCODE = In the 3dvolreg output dataset header, this (string) tells which dataset was the base for registration. VOLREG_BASE_NAME = The .HEAD filename of the 3dvolreg base dataset. (string) VOLREG_ROTCOM_NUM = The single value in here tells how many sub-bricks (int) were registered by 3dvolreg. (The only reason this might be different than nvals is that someone might later tack extra sub-bricks onto this dataset using 3dTcat.) This is how many VOLREG_MATVEC_xxxxx and VOLREG_ROTCOM_xxxxxx attributes are present in the dataset. ------------------------ Miscellaneous Attributes ------------------------ IDCODE_ANAT_PARENT = ID code for the "anatomy parent" of this dataset (string) (if it has one). TO3D_ZPAD = 3 integers specifying how much zero-padding to3d applied (int) when it created the dataset (x,y,z axes). At this time, only the [2] component could be nonzero. If this attribute is not present, then no zero-padding was done by to3d. ------------------ Warping Attributes ------------------ IDCODE_WARP_PARENT = ID code for the "warp parent" of this dataset (string) (if it has one). This will normally be a dataset in the +orig view, even for datasets transformed from +acpc to +tlrc. That is, the transformation chain +orig to +acpc to +tlrc is symbolic; when you transform a dataset from +acpc to +tlrc, AFNI catenates that transformation onto the +orig to +acpc transformation and stores the result, which is the direct transformation from +orig to +tlrc. WARP_TYPE = [0] = Integer code describing the type of warp: (int) #define WARP_AFFINE_TYPE 0 #define WARP_TALAIRACH_12_TYPE 1 [1] = No longer used (was the resampling type, but that is now set separately by the user). WARP_DATA = Data that define the transformation from the warp parent (float) to the current dataset. Each basic linear transformation (BLT) takes 30 numbers. For WARP_AFFINE_TYPE, there is one BLT per warp; for WARP_TALAIRACH_12_TYPE, there are 12 BLTs per warp. Thus, for WARP_AFFINE_TYPE there should be 30 numbers in WARP_DATA, and for WARP_TALAIRACH_12_TYPE there should be 360 numbers. (WARP_AFFINE_TYPE is used for the +orig to +acpc transformation; WARP_TALAIRACH_12_TYPE is used for the +orig to +tlrc transformation - duh.) Each BLT is defined by a struct that contains two 3x3 matrices and four 3-vectors (2*3*3+4*3 = the 30 numbers). These values are: [mfor] = 3x3 forward transformation matrix [0..8] } range of [mbac] = 3x3 backward transformation matrix [9..17] } indexes [bvec] = 3-vector for forward transformation [18..20] } in the [svec] = 3-vector for backward transformation [21..23] } WARP_DATA [bot] } two more 3-vectors that [24..26] } BLT [top] } are described below [27..29] } array (the matrices are stored in row-major order; e.g., [ 0 1 2 ] [mfor] = [ 3 4 5 ] [ 6 7 8 ] -- the indices of the [mfor] matrix). The forward transformation is [x_map] = [mfor] [x_in] - [bvec]; The backward transformation is [x_in] = [mbac] [x_map] - [svec] (which implies [svec] = -[mbac] [bvec] and [mbac] = Inverse{[mfor]}). The forward transformation is the transformation of Dicom order coordinates from the warp parent dataset (usually in the +orig view) to the warped dataset (usually +acpc or +tlrc). The backward transformation is just the inverse of the forward transformation, and is stored for convenience (it could be recomputed from the forward transformation whenever it was needed, but that would be too much like work). The identity BLT would be stored as these 30 numbers: 1 0 0 } 0 1 0 } [mfor] = I 0 0 1 } 1 0 0 } 0 1 0 } [mbac] = I 0 0 1 } 0 0 0 } [bvec] = 0 0 0 0 } [svec] = 0 botx boty botz } these numbers are described below, topx topy topz } and depend on the application. If the transformation is WARP_TALAIRACH_12_TYPE, then each BLT only applies to a bounded region of 3-space. The [bot] and [top] vectors define the limits for each BLT, in the warped [x_map] coordinates. These values are used in the function AFNI_transform_vector() to compute the transformation of a 3-vector between +orig and +tlrc coordinates. For example, to compute the transformation from +tlrc back to +orig of a vector [x_tlrc], the code must scan all 12 [bot]..[top] regions to see which BLT to use. Similarly, to transform [x_orig] from +orig to +tlrc, the vector must be transformed with each BLT and then the result tested to see if it lies within the BLT's [bot]..[top] region. (If a lower bound is supposed to be -infinity, then that element of [bot] is -9999; if an upper bound is supposed to be +infinity, then that element of [top] is +9999 -- there is an implicit assumption that AFNI won't be applied to species with heads more than 10 meters in size.) For the +orig to +acpc transformation (of WARP_AFFINE_TYPE), the [bot] and [top] vectors store the bounding box of the transformed dataset. However, this fact isn't used much (only when the new dataset is created when the user presses the "Define Markers->Transform Data" button, which is when the +acpc.HEAD file would be created). If you were to manually edit the +acpc.HEAD file and change [bot] and [top], nothing would happen. This is not true for a +tlrc.HEAD file, since the [bot] and [top] vectors actually mean something for WARP_TALAIRACH_12_TYPE. ---------------------------- Talairach Markers Attributes ---------------------------- These are used to define the transformations from +orig to +acpc coordinates, and from +acpc to +tlrc. If they are present, then opening the "Define Markers" panel in AFNI will show a list of the markers and let you edit their locations. MARKSET_ALIGN (+orig to +acpc) markers are attached to 3DIM_HEAD_ANAT +orig datasets created by to3d (if there is no time axis). An empty set of such markers can also be attached to such datasets using the "-markers" option to 3drefit. (The label and help strings for the 2 types of marker sets are defined in 3ddata.h.) MARKS_XYZ = 30 values giving the xyz-coordinates (Dicom order) of (float) the markers for this dataset. (A maximum of 10 markers can be defined for a dataset.) MARKS_XYZ[0] = x0, MARKS_XYZ[1] = y0, MARKS_XYZ[2] = z0, MARKS_XYZ[3] = x1, etc. If a marker's xyz-coordinates are outside the bounding box of the dataset, it is considered not to be set. For this purpose, the bounding box of the dataset extends to the edges of the outermost voxels (not just their centers). MARKS_LAB = 200 characters giving the labels for the markers (20 chars (string) per marker, EXACTLY, including the NULs). A marker whose string is empty (all NUL characters) will not be defined or shown by AFNI. MARKS_HELP = 2560 characters giving the help strings for the markers (string) (256 chars per marker, EXACTLY, including the NULs). MARKS_FLAGS = [0] = Type of markers; one of the following: (int) #define MARKSET_ALIGN 1 /* +orig to +acpc */ #define MARKSET_BOUNDING 2 /* +acpc to +tlrc */ [1] = This should always be 1 (it is an "action code", but the only action ever defined was warping). -------------------------------- Attributes for User-Defined Tags -------------------------------- These tags defined and set by plug_tag.c; their original purpose was to aid in 3D alignment by having the user mark homologous points that would then be aligned with 3dTagalign. This application has pretty much been superseded with the advent of "3dvolreg -twopass" (but you never know, do you?). TAGSET_NUM = [0] = ntag = number of tags defined in the dataset (max=100) (int) [1] = nfper = number of floats stored per tag (should be 5) TAGSET_FLOATS = ntag*nfper values; for tag #i: (float) [nfper*i+0] = x-coordinate (Dicom order) [nfper*i+1] = y-coordinate (Dicom order) [nfper*i+2] = z-coordinate (Dicom order) [nfper*i+3] = tag numerical value [nfper*i+4] = sub-brick index of tag (if >= 0), or "not set" flag (if < 0) TAGSET_LABELS = ntag sub-strings (separated by NULs) with the labels (string) for each tag. ------------------------- Nearly Useless Attributes ------------------------- These attributes are leftovers from the early days of AFNI, but never became useful for anything. LABEL_1 = A short label describing the dataset. (string) LABEL_2 = Another short label describing the dataset. (string) DATASET_NAME = A longer name describing the dataset contents. (string) DATASET_KEYWORDS = List of keywords for this dataset. By convention, (string) keywords are separated by " ; ". (However, no program at this time uses the keywords or this convention!) BRICK_KEYWORDS = List of keywords for each sub-brick of the dataset. (string) Should contain nvals sub-strings (separated by NULs). Again, by convention, separate keywords for the same sub-brick would be separated by " ; " within the sub-brick's keyword string. -------------------------- Programming Considerations -------------------------- When a new dataset is created, it is usually made with one of the library functions EDIT_empty_copy() or EDIT_full_copy(). These make a copy of a dataset struct in memory. They do NOT preserve attributes. Various struct elements will be translated to attributes when the dataset is written to disk (see thd_writedset.c), but other attributes in the "parent" dataset are not automatically copied. This means that if you attach some extra information to a dataset in a plugin using an attribute, say, and write it out using the DSET_write_header() macro, that information will not be preserved in "descendants" of that dataset. For example, if you did 3dcalc -a old+orig -expr "a" -prefix new then any plugin-defined attributes attached to old+orig.HEAD will not be reproduced in new+orig.HEAD. (In fact, this would be a good way to see exactly what attributes are generated by AFNI.) ==================================== Robert W Cox, PhD National Institute of Mental Health ====================================