1 /***************************************************************************** 2 Major portions of this software are copyrighted by the Medical College 3 of Wisconsin, 1994-2000, and are released under the Gnu General Public 4 License, Version 2. See the file README.Copyright for details. 5 ******************************************************************************/ 6 7 /*! \file 8 This file contains the definition of the structs, macros, etc. for AFNI datasets. 9 */ 10 11 #ifndef _MCW_3DDATASET_ 12 #define _MCW_3DDATASET_ 13 14 /** yyyy-mm-dd **/ 15 #define DSET_VERSION_LATEST "1996-07-10" 16 #define DSET_VERSION_COMPARE(v1,v2) strcmp(v1,v2) 17 18 /** #include <dirent.h> **/ 19 #include <unistd.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <string.h> 23 #include <math.h> 24 #include <errno.h> 25 #include <ctype.h> 26 #include <time.h> 27 #include <sys/types.h> 28 29 #include "replaceXt.h" /* 09 Nov 2018 */ 30 31 /*----------------------------------------------------------------------------*/ 32 33 #include "mcw_malloc.h" 34 35 #include "killer.h" 36 #include "vecmat.h" 37 #include "machdep.h" 38 #include "mrilib.h" 39 #include "tagset.h" 40 41 #include "thd_compress.h" 42 43 #include "nifti2_io.h" /* 06 Dec 2005 */ 44 45 /* cast int to pointer and vice-versa without warning messages */ 46 47 #ifndef SOLARIS_OLD 48 #include <stdint.h> 49 #endif 50 #undef ITOP 51 #define ITOP(qw) ((void *)(intptr_t)(qw)) 52 #undef PTOI 53 #define PTOI(qw) ((int)(intptr_t)(qw)) 54 55 struct THD_3dim_dataset ; /* incomplete definition */ 56 57 #include "niml.h" /* NIML */ 58 #include "afni_suma.h" /* SUrface MApper */ 59 60 #ifdef __cplusplus 61 extern "C" { 62 #endif 63 64 /*! Macro to check if string ss ends in string suf. */ 65 66 #define STRING_HAS_SUFFIX(ss,suf) \ 67 ((ss != NULL) && (suf != NULL) && \ 68 (strlen(ss) >= strlen(suf)) && \ 69 (strcmp(ss+strlen(ss)-strlen(suf),suf) == 0)) 70 71 #define STRING_HAS_SUFFIX_CASE(ss,suf) \ 72 ((ss != NULL) && (suf != NULL) && \ 73 (strlen(ss) >= strlen(suf)) && \ 74 (strcasecmp(ss+strlen(ss)-strlen(suf),suf) == 0)) 75 76 #define PREFIX_IS_NIFTI(ss) ( STRING_HAS_SUFFIX(ss,".nii") || \ 77 STRING_HAS_SUFFIX(ss,".nii.gz") || \ 78 STRING_HAS_SUFFIX(ss,".hdr") ) 79 80 /***************************** dimensions ***************************/ 81 82 /*! Max length of a dataset label. */ 83 84 #define THD_MAX_LABEL 38 85 86 /*! Max length of a dataset sub-brick label. */ 87 88 #define THD_MAX_SBLABEL 64 /* added 11/03/2011 drg */ 89 90 /*! Max length of a dataset prefix. [increased to 999 by RWCox 17 Oct 2016] */ 91 92 #define THD_MAX_PREFIX (999+1) /* must be more than THD_MAX_LABEL 93 ( ZSS Jan 07 need room for path specified 94 with prefix on command line ) */ 95 96 /*! Max length of a "name" of a file, or stuff like that. */ 97 98 #define THD_MAX_NAME (4096+THD_MAX_PREFIX) /* (ZSS Jan 07)*/ 99 100 /*! Max length of a dataset view code (+orig, etc). */ 101 102 #define THD_MAX_VIEWCODE (4+1) 103 104 /*! Max length of a dataset suffix (BRIK, etc). */ 105 106 #define THD_MAX_SUFFIX (4+1) 107 108 /*! Max length of a dataset filecode (prefix+view). */ 109 110 #define THD_MAX_FILECODE (THD_MAX_PREFIX+THD_MAX_VIEWCODE) 111 112 /*! Default label for a dataset. 113 114 Labels aren't really used anymore, since the stupid users didn't like them 115 */ 116 #define THD_DEFAULT_LABEL "Viggo!" 117 118 /*! Max num datasets per session. */ 119 120 #define THD_MAX_SESSION_SIZE 8192 121 122 /*! Max number of directories. */ 123 124 #define THD_MAX_NUM_SESSION 199 125 126 #define THD_MAX_CHOICES THD_MAX_SESSION_SIZE 127 128 #define THD_MAX_MARKSET 5 129 130 #define FAIL -1 131 #define SUCCESS 1 132 133 /*! General "type code" for invalid data. 134 135 Various things are labeled with non-negative type codes (e.g., statistics types). 136 Negative type codes indicate something is not valid. 137 */ 138 139 #define ILLEGAL_TYPE -666 140 141 /* define the max length of a string input to realpath() */ 142 143 #undef RPMAX 144 #define RPMAX 4096 145 #if defined(PATH_MAX) && PATH_MAX > RPMAX 146 # undef RPMAX 147 # define RPMAX PATH_MAX 148 #endif 149 #if defined(MAXPATHLEN) && MAXPATHLEN > RPMAX 150 # undef RPMAX 151 # define RPMAX MAXPATHLEN 152 #endif 153 154 #undef isnumeric 155 #define isnumeric(c) (isdigit(c) || (c) == '-' || (c) == '+' || (c) == '.') 156 157 /* define what angular difference constitues a "real" difference 158 * (allow for truncation artifacts) 22 May 2015 [rickr] */ 159 #undef OBLIQ_ANGLE_THRESH 160 #define OBLIQ_ANGLE_THRESH 0.01 161 162 /*************** generic function with no return value **********************/ 163 164 /*! Generic function type returning void. */ 165 166 typedef void generic_func() ; 167 168 /*! Generic function type returning float. */ 169 170 typedef float float_func() ; 171 172 /*! Stores a list of "registered" functions (e.g., "Transforms") */ 173 174 typedef struct { 175 int num ; /*!< number of functions */ 176 int * flags ; /*!< flags[i] = bitmask flag for function #i */ 177 char ** labels ; /*!< labels[i] = string name for function #i */ 178 generic_func ** funcs ; /*!< funcs[i] = function #i */ 179 180 void ** func_data ; /*!< 30 Jan 2000 */ 181 int * func_code ; 182 183 generic_func ** func_init ; /*!< 21 Jul 2003 */ 184 } MCW_function_list ; 185 186 /*! MCW_function_list possible bitmask flag */ 187 #define RETURNS_STRING 1 188 189 /*! MCW_function_list possible bitmask flag */ 190 #define NEEDS_DSET_INDEX 2 191 192 /*! MCW_function_list possible bitmask flag */ 193 #define PROCESS_MRI_IMAGE 4 194 195 /*! MCW_function_list possible bitmask flag */ 196 #define SET_DPLOT_OVERLAY 8 197 198 /*! MCW_function_list possible func_code */ 199 #define FUNC_0D 0 200 /*! MCW_function_list possible func_code */ 201 #define FUNC_1D 1 202 /*! MCW_function_list possible func_code */ 203 #define FUNC_2D 2 204 /*! MCW_function_list possible func_code */ 205 #define FUNC_3D 3 206 207 /*! MCW_function_list possible func_code */ 208 #define FUNC_FIM 71 209 210 /******************************** macros ******************************/ 211 212 /*! First part of TWO_TWO macro. */ 213 214 #define TWO_ONE(x,y) x ## y 215 216 /*! Combine two interpreted tokens into one using TWO_TWO. */ 217 218 #define TWO_TWO(x,y) TWO_ONE(x,y) 219 220 /*! Zero out a variable */ 221 222 #undef ZZME 223 #define ZZME(x) memset(&(x),0,sizeof(x)) 224 225 /*! Copy n units of the given type "type * ptr", into a structure "str", 226 starting at byte offset "off"; 227 N.B.: str is the structure itself, not a pointer to it 228 off is most easily computed with RwcOffsetOf */ 229 230 #define COPY_INTO_STRUCT(str,off,type,ptr,n) \ 231 AAmemcpy( (char *)(&(str))+(off), (char *)(ptr), (n)*sizeof(type) ) 232 233 /*! Copy n units of the given type "type * ptr", from a structure "str", 234 starting at byte offset "off"; 235 N.B.: str is the structure itself, not a pointer to it 236 off is most easily computed with RwcOffsetOf */ 237 238 #define COPY_FROM_STRUCT(str,off,type,ptr,n) \ 239 AAmemcpy( (char *)(ptr), (char *)(&(str))+(off), (n)*sizeof(type) ) 240 241 /*! Safe version of strncpy, which always leaves a NUL at the end. 242 243 The standard stupid strncpy(dest,src,n) might not leave a NUL character 244 at the end if the src string is too long. This criminal behavior is 245 reformed by this macro. 246 */ 247 248 #ifndef MCW_strncpy 249 #define MCW_strncpy(dest,src,n) \ 250 ( (void) strncpy( (dest) , (src) , (n)-1 ) , (dest)[(n)-1] = '\0' ) 251 #endif 252 253 /*********************** dynamic array of RwcPointers **********************/ 254 255 #define IC_DSET 44301 256 #define IC_FLIM 55402 257 258 /*! Dynamically extendable array of RwcPointer. */ 259 260 typedef struct { 261 int num ; /*!< Number currently in use */ 262 int nall ; /*!< Number currently allocated */ 263 RwcPointer *ar ; /*!< Array of pointers: [0..num-1] are valid */ 264 int *ic ; /*!< added 26 Mar 2001 */ 265 } RwcPointer_array ; 266 267 /*! Increment for extending RwcPointer_array allocation */ 268 269 #define INC_XTARR 8 270 271 /*! Initialize dynamic RwcPointer array named "name". 272 273 You must declare "RwcPointer_array *name;". 274 */ 275 #define INIT_XTARR(name) \ 276 ( (name) = RwcNew(RwcPointer_array) , \ 277 (name)->num = (name)->nall = 0 , \ 278 (name)->ar = NULL , \ 279 (name)->ic = NULL ) 280 281 /*! Add a pointer to a dynamic RwcPointer array. */ 282 283 #define ADDTO_XTARR(name,bblk) \ 284 do{ if( (name)->num == (name)->nall ){ \ 285 (name)->nall += INC_XTARR + (name)->nall/8 ; \ 286 (name)->ar = (RwcPointer *) \ 287 RwcRealloc( (char *) (name)->ar , \ 288 sizeof(RwcPointer) * (name)->nall ) ; \ 289 (name)->ic = (int *) RwcRealloc( (char *) (name)->ic , \ 290 sizeof(int) * (name)->nall ) ; \ 291 } \ 292 (name)->ar[(name)->num] = (RwcPointer)(bblk) ; \ 293 (name)->ic[(name)->num] = 0 ; \ 294 ((name)->num)++ ; \ 295 } while(0) 296 297 /*! Number of good entries in a dynamic RwcPointer array. */ 298 299 #define XTARR_NUM(name) ((name)->num) 300 301 /*! i-th entry in a dynamic RwcPointer array. */ 302 303 #define XTARR_XT(name,i) ((name)->ar[i]) 304 305 #define XTARR_IC(name,i) ((name)->ic[i]) 306 307 /*! Free a dynamic RwcPointer array. 308 But not what the pointers point to - that is a completely separate matter. 309 */ 310 311 #define FREE_XTARR(name) \ 312 if( (name) != NULL ){ \ 313 myRwcFree( (name)->ar ) ; \ 314 myRwcFree( (name)->ic ) ; \ 315 myRwcFree( (name) ) ; \ 316 (name) = NULL ; } 317 318 /*! Duplicate definition for FREE_XTARR */ 319 #define DESTROY_XTARR FREE_XTARR 320 321 /************************* help utilities *************************/ 322 323 /* Flags & macros for shpinx string formatting */ 324 typedef enum { TFORM_NOT_SET, NO_FORMAT, TXT, SPX , ASPX, WEB } TFORM; 325 326 #define CHECK_HELP(opt,fun) {\ 327 if( strcmp(argv[iarg],"-h_spx") == 0 ){ \ 328 fun(SPX, 2); RETURN(0);} \ 329 else if( strcmp(argv[iarg],"-h_raw") == 0 ){ \ 330 fun(NO_FORMAT,2); RETURN(0);} \ 331 else if( strcmp(argv[iarg],"-help") == 0 ){ \ 332 fun(TXT,1); RETURN(0);} \ 333 else if( strcmp(argv[iarg],"-h") == 0 ){ \ 334 fun(TXT,0); RETURN(0);} \ 335 } 336 337 #define sphinx_printf(targ, ...) (sphinx_offprintf( targ, 0, NULL, __VA_ARGS__)) 338 #define sphinx_fprintf(targ, fout, ...) \ 339 (sphinx_offprintf( targ, 0, fout, __VA_ARGS__)) 340 #include "suma_string_manip.h" 341 342 /************************* string array stuff *************************/ 343 344 /*! Dynamic array of character strings. */ 345 346 typedef struct { 347 int num ; /*!< Number of strings currently stored */ 348 int nall ; /*!< Number of strings space is set aside for */ 349 char ** ar ; /*!< Array of pointers to strings */ 350 KILL_list kl ; /*!< For semi-automatic memory cleanup */ 351 } THD_string_array ; 352 353 /*! Return pointer to qq-th string in dynamic string array ss. */ 354 355 #define SARR_STRING(ss,qq) ((ss)->ar[(qq)]) 356 357 /*! Return number of strings stored in dynamic string array ss. */ 358 359 #define SARR_NUM(ss) ((ss)->num) 360 361 #define INC_SARR 64 362 363 /*! Initialize an empty dynamic string array named "name". 364 365 You must declare "THD_string_array *name;". 366 */ 367 368 #define INIT_SARR(name) \ 369 ( (name) = RwcNew(THD_string_array) , \ 370 (name)->num = (name)->nall = 0 , \ 371 (name)->ar = NULL , \ 372 INIT_KILL((name)->kl) ) 373 374 /*! Add string str to dynamic string array "name". */ 375 376 #define ADDTO_SARR(name,str) \ 377 do{ if( (name)->num == (name)->nall ){ \ 378 (name)->nall += INC_SARR + (name)->nall/8 ; \ 379 (name)->ar = (char **) RwcRealloc( (char *) (name)->ar , \ 380 sizeof(char *) * (name)->nall ) ; \ 381 } \ 382 if( (str) != NULL ){ \ 383 (name)->ar[(name)->num] = (char *) RwcMalloc( strlen((str))+1 ); \ 384 strcpy( (name)->ar[(name)->num] , (str) ) ; \ 385 ADDTO_KILL((name)->kl,(name)->ar[(name)->num]) ; \ 386 ((name)->num)++ ; \ 387 } } while(0) 388 389 /*! Add string str to dynamic string array "name" if str is not in there yet. */ 390 #define ADDUTO_SARR(name,str) \ 391 do{ if (SARR_find_string(name, str, 0)<0) ADDTO_SARR(name,str); \ 392 } while(0) 393 394 /*! Remove the ijk-th string from dynamic string array "name". */ 395 396 #define REMOVEFROM_SARR(name,ijk) \ 397 do{ SINGLE_KILL((name)->kl,(name)->ar[(ijk)]) ; \ 398 (name)->ar[(ijk)] = NULL ; } while(0) 399 400 /*! Kill all entries in the dynamic string array "name". */ 401 402 #define DESTROY_SARR(name) \ 403 do{ if( (name) != NULL ){ \ 404 KILL_KILL((name)->kl) ; \ 405 myRwcFree( (name)->ar ) ; \ 406 myRwcFree( (name) ) ; } } while(0) 407 408 /*! Print all entries in a dynamic string array */ 409 410 #define PRINTF_SARR(name,lll) \ 411 do{ int qq ; printf("%s:",(lll)) ; \ 412 for( qq=0; qq < (name)->num; qq++ ) printf(" '%s'",(name)->ar[qq]); \ 413 printf("\n") ; } while(0) 414 415 extern int SARR_find_string( THD_string_array * sar , char * str , byte ci) ; 416 extern int SARR_find_substring( THD_string_array * sar , char * sub , byte ci) ; 417 418 extern int SARR_lookfor_string ( THD_string_array * sar , char * str , int nstart , byte ci) ; 419 extern int SARR_lookfor_substring( THD_string_array * sar , char * sub , int nstart , byte ci) ; 420 421 /*! Concatenate strings p1 and p2 into string pout, making them a filesystem path. 422 423 If p1 doesn't end in a '/', the '/' between p1/p2 will be added. 424 The pout array must be previously allocated. 425 */ 426 427 #define PATH_CONCAT(pout,p1,p2) \ 428 do{ int zq ; strcpy((pout),(p1)) ; zq = strlen((pout)) ; \ 429 if( (pout)[zq-1] != '/' ) strcat((pout),"/") ; \ 430 strcat((pout),(p2)) ; } while(0) 431 432 /*************** dynamic array of sorted (x,y,z) points *************/ 433 434 #undef ALLOW_DATASET_VLIST 435 #ifdef ALLOW_DATASET_VLIST 436 437 /*! Dynamic array of xyz and ijk points. */ 438 439 typedef struct { 440 int num ; /*!< Number of points currently in use */ 441 int nall ; /*!< Number of points currently allocated */ 442 THD_fvec3 *xyz ; /*!< Array of xyz coordinates in parent */ 443 THD_ivec3 *ijk ; /*!< Array of ijk indexes in parent */ 444 struct THD_3dim_dataset *parent ; /*!< Dataset these things come from */ 445 } THD_vector_list ; 446 447 #define INC_VLIST 64 448 449 /*! Initialize a dynamic array of xyz points, attached to datset ddd. */ 450 451 #define INIT_VLIST(name,ddd) \ 452 ( (name) = RwcNew(THD_vector_list) , \ 453 (name)->num = (name)->nall = 0 , \ 454 (name)->xyz = NULL , (name)->ijk = NULL , \ 455 (name)->parent = (ddd) ) 456 457 /*! Add 1 xyz-vector to the array of xyz points. 458 459 The ijk-vector will be converted from the xyz coordinates, 460 using the parent dataset for this array. 461 */ 462 463 #define ADD_FVEC_TO_VLIST(name,vec) \ 464 { if( (name)->num == (name)->nall ){ \ 465 (name)->nall += INC_VLIST ; \ 466 (name)->xyz = (THD_fvec3 * ) RwcRealloc( (char *) (name)->xyz , \ 467 sizeof(THD_fvec3) * (name)->nall ) ; \ 468 (name)->ijk = (THD_ivec3 * ) RwcRealloc( (char *) (name)->ijk , \ 469 sizeof(THD_ivec3) * (name)->nall ) ; \ 470 } \ 471 (name)->xyz[(name)->num] = (vec); \ 472 (name)->ijk[(name)->num] = THD_3dmm_to_3dind((name)->parent,(vec)) ; \ 473 ((name)->num)++; } 474 475 /*! Add one ijk-vector to the array of xyz points. 476 477 The xyz-vector will be converted from the ijk indexes, using 478 the parent dataset for this array. 479 */ 480 481 #define ADD_IVEC_TO_VLIST(name,vec) \ 482 { if( (name)->num == (name)->nall ){ \ 483 (name)->nall += INC_VLIST ; \ 484 (name)->xyz = (THD_fvec3 * ) RwcRealloc( (char *) (name)->xyz , \ 485 sizeof(THD_fvec3) * (name)->nall ) ; \ 486 (name)->ijk = (THD_ivec3 * ) RwcRealloc( (char *) (name)->ijk , \ 487 sizeof(THD_ivec3) * (name)->nall ) ; \ 488 } \ 489 (name)->ijk[(name)->num] = (vec); \ 490 (name)->xyz[(name)->num] = THD_3dind_to_3dmm((name)->parent,(vec)) ; \ 491 ((name)->num)++; } 492 493 /*! Destroy an array of xyz points. */ 494 495 #define DESTROY_VLIST(name) \ 496 { if( (name) != NULL ){ \ 497 myRwcFree( (name)->xyz ) ; \ 498 myRwcFree( (name)->ijk ) ; \ 499 myRwcFree( (name) ) ; } } 500 501 #endif /* ALLOW_DATASET_VLIST */ 502 503 /**************************** typedefs ******************************/ 504 505 /*---------- structure to hold attributes from disk files ----------*/ 506 507 #define ATR_STRING_TYPE 0 508 #define ATR_FLOAT_TYPE 1 509 #define ATR_INT_TYPE 2 510 511 #define FIRST_ATR_TYPE 0 512 #define LAST_ATR_TYPE 2 513 514 /*! Things to look for in the .HEAD file; these define start of an attribute. */ 515 516 static char * ATR_typestr[] = { 517 "string-attribute" , "float-attribute" , "integer-attribute" 518 } ; 519 520 /*! Stores an integer-attribute (array of ints). */ 521 522 typedef struct { 523 int type ; /*!< should be ATR_INT_TYPE */ 524 char * name ; /*!< name of attribute, read from HEAD file */ 525 int nin ; /*!< number of ints stored here */ 526 int * in ; /*!< array of ints stored here */ 527 } ATR_int ; 528 529 /*! Stores a float-attribute (array of floats). */ 530 531 typedef struct { 532 int type ; /*!< should be ATR_FLOAT_TYPE */ 533 char * name ; /*!< name of attribute, read from HEAD file */ 534 int nfl ; /*!< number of floats stored here */ 535 float * fl ; /*!< array of floats stored here */ 536 } ATR_float ; 537 538 /*! Stores a string-attribute (array of strings). */ 539 540 typedef struct { 541 int type ; /*!< should be ATR_STRING_TYPE */ 542 char * name ; /*!< name of attribute, read from HEAD file */ 543 int nch ; /*!< number of characters in string */ 544 char * ch ; /*!< array of characters (may not be NUL terminated) */ 545 } ATR_string ; 546 547 #define ZBLOCK 126 548 #define ZSBLOCK 59 /* kurukuru pa */ 549 extern void THD_zblock(int,char *) ; /* replace zeros with ZBLOCKs */ 550 extern void THD_unzblock(int,char *) ; /* undo the above */ 551 extern void THD_zblock_ch(int,char *,char) ; /* 12 Jul 2006 [rickr] */ 552 extern void THD_unzblock_ch(int,char *,char) ; /* undo the above */ 553 554 /*! Union type to hold an arbitrary attribute. */ 555 556 typedef union { 557 int type ; /*!< Determines type of data here */ 558 ATR_string str_atr ; 559 ATR_float flo_atr ; 560 ATR_int int_atr ; 561 } ATR_any ; 562 563 #undef ATR_COUNT 564 #define ATR_COUNT(aap) \ 565 ( ((aap)==NULL) ? 0 \ 566 :((aap)->type==ATR_FLOAT_TYPE) ? ((ATR_float *)(aap))->nfl \ 567 :((aap)->type==ATR_STRING_TYPE) ? ((ATR_string *)(aap))->nch \ 568 :((aap)->type==ATR_INT_TYPE) ? ((ATR_int *)(aap))->nin \ 569 :0 ) 570 571 /*---------------------------------------------------------------------*/ 572 /*-------------------- structure for linear mapping -------------------*/ 573 574 #define MAPPING_LINEAR_TYPE 0 575 #define MAPPING_LINEAR_STR "LINEAR_MAPPING" 576 577 #define FIRST_MAPPING_TYPE 0 578 #define LAST_MAPPING_TYPE 0 579 580 static char * MAPPING_typestr[] = { 581 MAPPING_LINEAR_STR 582 } ; 583 584 /*! Structure to hold a linear mapping between coordinate systems. */ 585 586 typedef struct { 587 int type ; /*!< type code: only type now is MAPPING_LINEAR_TYPE */ 588 589 THD_mat33 mfor ; /*!< x_map = [mfor] * x_in - bvec */ 590 THD_mat33 mbac ; /*!< x_in = [mbac] * x_map - svec */ 591 592 THD_fvec3 bvec; /* x_map = [mfor] * x_in - bvec */ 593 THD_fvec3 svec; /* svec = - [mbac] * bvec */ 594 THD_fvec3 bot ; /* lower bound for transformation use */ 595 THD_fvec3 top ; /* upper bound for transformation use */ 596 } THD_linear_mapping ; 597 598 /*! Copy the .bot and .top bounds between two THD_linear_mapping structs. */ 599 600 #define COPY_LMAP_BOUNDS(m1,m2) ( (m1).bot=(m2).bot , (m1).top=(m2).top ) 601 602 /*! Use the matrix operations to define a macro 603 to load the inverse to a THD_linear_mapping once the forward is done. */ 604 605 #define LOAD_INVERSE_LMAP(map) \ 606 ( (map).mbac = MAT_INV((map).mfor) , \ 607 (map).svec = MATVEC((map).mbac,(map).bvec) ,\ 608 NEGATE_FVEC3((map).svec) ) 609 610 #define MAPPING_LINEAR_FSTART RwcOffsetOf(THD_linear_mapping,mfor) 611 #define MAPPING_LINEAR_FEND (RwcOffsetOf(THD_linear_mapping,top)+sizeof(THD_fvec3)) 612 #define MAPPING_LINEAR_FSIZE ((MAPPING_LINEAR_FEND-MAPPING_LINEAR_FSTART)/sizeof(float)) 613 614 /*! Debugging printout of a THD_linear_mapping struct. */ 615 616 #define DUMP_LMAP(m) \ 617 ( printf("THD_linear_mapping:\n") , \ 618 printf(" mfor = %8.4f %8.4f %8.4f\n", \ 619 (m).mfor.mat[0][0], (m).mfor.mat[0][1], (m).mfor.mat[0][2] ) , \ 620 printf(" %8.4f %8.4f %8.4f\n", \ 621 (m).mfor.mat[1][0], (m).mfor.mat[1][1], (m).mfor.mat[1][2] ) , \ 622 printf(" %8.4f %8.4f %8.4f\n", \ 623 (m).mfor.mat[2][0], (m).mfor.mat[2][1], (m).mfor.mat[2][2] ) , \ 624 printf(" mbac = %8.4f %8.4f %8.4f\n", \ 625 (m).mbac.mat[0][0], (m).mbac.mat[0][1], (m).mbac.mat[0][2] ) , \ 626 printf(" %8.4f %8.4f %8.4f\n", \ 627 (m).mbac.mat[1][0], (m).mbac.mat[1][1], (m).mbac.mat[1][2] ) , \ 628 printf(" %8.4f %8.4f %8.4f\n", \ 629 (m).mbac.mat[2][0], (m).mbac.mat[2][1], (m).mbac.mat[2][2] ) , \ 630 printf(" bvec = %8.4f %8.4f %8.4f\n", \ 631 (m).bvec.xyz[0] , (m).bvec.xyz[1] , (m).bvec.xyz[2] ) , \ 632 printf(" svec = %8.4f %8.4f %8.4f\n", \ 633 (m).svec.xyz[0] , (m).svec.xyz[1] , (m).svec.xyz[2] ) , \ 634 printf(" bot = %8.4f %8.4f %8.4f\n", \ 635 (m).bot.xyz[0] , (m).bot.xyz[1] , (m).bot.xyz[2] ) , \ 636 printf(" top = %8.4f %8.4f %8.4f\n\n", \ 637 (m).top.xyz[0] , (m).top.xyz[1] , (m).top.xyz[2] ) ) 638 639 /*-----------------------------------------------------------------*/ 640 /*--------------- structure for user placed markers ---------------*/ 641 642 #define MARKS_MAXNUM 10 643 #define MARKS_MAXLAB 20 644 #define MARKS_MAXHELP 256 645 #define MARKS_MAXFLAG 8 646 647 /*! Structure for user placed markers. */ 648 649 typedef struct { 650 int numdef ; /*!< Number of markers defined */ 651 int numset ; /*!< Number of markers now set */ 652 653 char label[MARKS_MAXNUM][MARKS_MAXLAB] ; /*!< Names for these marks */ 654 655 char help[MARKS_MAXNUM][MARKS_MAXHELP] ; /*!< Help for these marks */ 656 657 int ovcolor[MARKS_MAXNUM] ; /*!< Overlay color index; -1 --> use defaults */ 658 659 RwcBoolean valid[MARKS_MAXNUM] ; /*!< True if actually set */ 660 661 float xyz[MARKS_MAXNUM][3] ; /*!< Coordinates (3dmm, not DICOM) */ 662 663 int aflags[MARKS_MAXFLAG] ; /*!< Action flags */ 664 665 int type ; /*!< Type of markers (same as aflags[0]) */ 666 char name[MARKS_MAXLAB] ; /*!< Name of this type of markers */ 667 } THD_marker_set ; 668 669 #define MARKS_FSIZE (MARKS_MAXNUM*3) 670 #define MARKS_FSTART RwcOffsetOf(THD_marker_set,xyz) 671 672 #define MARKS_LSIZE (MARKS_MAXNUM*MARKS_MAXLAB) 673 #define MARKS_LSTART RwcOffsetOf(THD_marker_set,label) 674 675 #define MARKS_HSIZE (MARKS_MAXNUM*MARKS_MAXHELP) 676 #define MARKS_HSTART RwcOffsetOf(THD_marker_set,help) 677 678 #define MARKS_ASIZE MARKS_MAXFLAG 679 #define MARKS_ASTART RwcOffsetOf(THD_marker_set,aflags) 680 681 /*--------------- definitions for markers I know about now ---------------*/ 682 683 #define MARKSET_ALIGN 1 /* types of marker sets */ 684 #define MARKSET_BOUNDING 2 685 686 #define MARKACTION_NONE 0 /* action codes for marker sets */ 687 #define MARKACTION_WARP 1 688 #define MARKACTION_REGISTER 2 /* not used at present */ 689 690 /*........................................................................*/ 691 692 /*! Number of orig->acpc markers. */ 693 694 #define NMARK_ALIGN 5 695 696 static int THD_align_aflags[MARKS_MAXFLAG] = { 697 MARKSET_ALIGN , MARKACTION_WARP 698 } ; 699 700 #define IMARK_ACSE 0 701 #define IMARK_ACPM 1 702 #define IMARK_PCIE 2 703 #define IMARK_MSA1 3 704 #define IMARK_MSA2 4 705 706 /*! Labels for orig->acpc markers. */ 707 708 static char * THD_align_label[NMARK_ALIGN] = { 709 "AC superior edge" , 710 "AC posterior margin" , 711 "PC inferior edge" , 712 "First mid-sag pt" , 713 "Another mid-sag pt" 714 } ; 715 716 /*! Help for orig->acpc markers. */ 717 718 static char * THD_align_help[NMARK_ALIGN] = { 719 "This is the uppermost point\n" 720 "on the anterior commisure,\n" 721 "in the mid-sagittal plane." , 722 723 "This is the rearmost point\n" 724 "on the anterior commisure,\n" 725 "in the mid-sagittal plane.\n" 726 "[Just a couple mm behind and\n" 727 " below the AC superior edge.]" , 728 729 "This is the bottommost point\n" 730 "on the posterior commissure,\n" 731 "in the mid-sagittal plane." , 732 733 "You must also specify two other points in the\n" 734 "mid-sagittal plane, ABOVE the corpus callosum\n" 735 "(i.e., in the longitudinal fissure). These\n" 736 "points are needed to define the vertical plane." , 737 738 "You must also specify two other points in the\n" 739 "mid-sagittal plane, ABOVE the corpus callosum\n" 740 "(i.e., in the longitudinal fissure). These\n" 741 "points are needed to define the vertical plane." , 742 743 } ; 744 745 /*.....................................................................*/ 746 747 /*! Number of acpc->tlrc markers. */ 748 749 #define NMARK_BOUNDING 6 750 751 static int THD_bounding_aflags[MARKS_MAXFLAG] = { 752 MARKSET_BOUNDING , MARKACTION_WARP 753 } ; 754 755 #define IMARK_MANT 0 756 #define IMARK_MPOS 1 757 #define IMARK_MSUP 2 758 #define IMARK_MINF 3 759 #define IMARK_MLEF 4 760 #define IMARK_MRIG 5 761 762 /*! Atlas distances for acpc->tlrc markers. 763 If you change these, change the helps below too */ 764 765 #define ATLAS_FRONT_TO_AC 70.0 766 #define ATLAS_AC_TO_PC 23.0 767 #define ATLAS_PC_TO_BACK 79.0 768 769 #define ATLAS_BOT_TO_AC 42.0 770 #define ATLAS_AC_TO_TOP 74.0 771 #define ATLAS_AC_TO_LAT 68.0 772 773 #define ATLAS_BBOX_LAT 80.0 /* dimensions used for */ 774 #define ATLAS_BBOX_ANT 80.0 /* Talairach view clipping box */ 775 #define ATLAS_BBOX_POS 110.0 776 #define ATLAS_BBOX_INF 55.0 777 #define ATLAS_BBOX_SUP 85.0 778 779 #define ATLAS_BBOX_INF_NEW 65.0 /* 3/06/96: extra 10 mm for cerebellum */ 780 781 #define ATLAS_ALIGNBOX_LAT 95.0 /* dimensions used for AC-PC */ 782 #define ATLAS_ALIGNBOX_ANT 95.0 /* aligned view clipping box */ 783 #define ATLAS_ALIGNBOX_POS 140.0 /* (3/25/95) */ 784 #define ATLAS_ALIGNBOX_SUP 100.0 785 #define ATLAS_ALIGNBOX_INF 70.0 786 787 #define MAX_ALLOWED_DEVIATION 2.0 788 #define MIN_ALLOWED_DEVIATION 0.5 789 790 /*! Labels for acpc->tlrc markers. */ 791 792 static char * THD_bounding_label[NMARK_BOUNDING] = { 793 "Most anterior point" , 794 "Most posterior point" , 795 "Most superior point" , 796 "Most inferior point" , 797 "Most left point" , 798 "Most right point" 799 } ; 800 801 /*! Help for acpc->tlrc markers. */ 802 803 static char * THD_bounding_help[NMARK_BOUNDING] = { 804 "The frontmost point of the frontal cortex;\n" 805 "needed for brain length [atlas y = -70 mm]" , 806 807 "The hindmost point of the occipital cortex;\n" 808 "needed for brain length [atlas y = +102 mm]" , 809 810 "The topmost point of the parietal cortex;\n" 811 "needed for brain height [atlas z = +74 mm]" , 812 813 "The lowest point of the temporal cortex;\n" 814 "needed for brain height [atlas z = -42 mm]" , 815 816 "The most lateral (left) point of the parietotemporal cortex;\n" 817 "needed for brain width [atlas x = +68 mm]" , 818 819 "The most lateral (right) point of the parietotemporal cortex;\n" 820 "needed for brain width [atlas x = -68 mm]" 821 822 } ; 823 824 /*---------------------------------------------------------------------*/ 825 /*---------------------- structures to hold warps ---------------------*/ 826 827 #define WARP_AFFINE_TYPE 0 828 #define WARP_AFFINE_STR "WARP_AFFINE" 829 830 #define WARP_TALAIRACH_12_TYPE 1 831 #define WARP_TALAIRACH_12_STR "WARP_TALAIRACH_12" 832 833 #define FIRST_WARP_TYPE 0 834 #define LAST_WARP_TYPE 1 835 836 static char * WARP_typestr[] = { 837 WARP_AFFINE_STR , WARP_TALAIRACH_12_STR 838 } ; 839 840 /*----------------------- resample types -----------------------*/ 841 842 #define RESAM_NN_TYPE 0 843 #define RESAM_NN_STR "Nearest Neighbor" 844 845 #define RESAM_LINEAR_TYPE 1 846 #define RESAM_LINEAR_STR "Linear Interpolation" 847 848 #define RESAM_CUBIC_TYPE 2 849 #define RESAM_CUBIC_STR "Cubic Interpolation" 850 851 #define RESAM_BLOCK_TYPE 3 852 #define RESAM_BLOCK_STR "Blocky Interpolation" 853 854 #define FIRST_RESAM_TYPE 0 855 #define LAST_RESAM_TYPE 3 856 857 static char * RESAM_typestr[] = { 858 RESAM_NN_STR , RESAM_LINEAR_STR , RESAM_CUBIC_STR , RESAM_BLOCK_STR 859 } ; 860 861 #define NSTR_SHORT_RESAM 2 862 static char * RESAM_shortstr[] = { "NN" , "Li" , "Cu" , "Bk" } ; 863 864 /*! 12-piece Warp struct for orig/acpc -> tlrc coordinates. */ 865 866 typedef struct { 867 int type ; /*!< type code: WARP_TALAIRACH_12_TYPE */ 868 int resam_type ; /*!< Resampling method */ 869 870 THD_linear_mapping warp[12] ; /* The 12 pieces of the transformation */ 871 } THD_talairach_12_warp ; 872 873 #define W_RAS 0 /* right-anterior -superior mapping index */ 874 #define W_LAS 1 /* left -anterior -superior */ 875 #define W_RMS 2 /* right-medial -superior */ 876 #define W_LMS 3 /* left -medial -superior */ 877 #define W_RPS 4 /* right-posterior-superior */ 878 #define W_LPS 5 /* left -posterior-superior */ 879 #define W_RAI 6 /* right-anterior -inferior */ 880 #define W_LAI 7 /* left -anterior -inferior */ 881 #define W_RMI 8 /* right-medial -inferior */ 882 #define W_LMI 9 /* left -medial -inferior */ 883 #define W_RPI 10 /* right-posterior-inferior */ 884 #define W_LPI 11 /* left -posterior-inferior */ 885 886 #define WARP_TALAIRACH_12_SIZE (12*MAPPING_LINEAR_FSIZE) 887 888 /*! Debug printout for 1 piece of a Talairach warp. */ 889 890 #define DUMP_T12_MAP(t12,xx,yy,zz) \ 891 ( printf("\n--- submap " # xx # yy # zz "\n" ) , \ 892 DUMP_LMAP( (t12).warp[W_ ## xx ## yy ## zz] ) ) 893 894 /*! Debug printout for all 12 pieces of a Talairach warp. */ 895 896 #define DUMP_T12_WARP(t12) \ 897 ( printf("\n12 region Talairach warp:") , \ 898 DUMP_T12_MAP((t12),R,A,S) , DUMP_T12_MAP((t12),L,A,S) , \ 899 DUMP_T12_MAP((t12),R,M,S) , DUMP_T12_MAP((t12),L,M,S) , \ 900 DUMP_T12_MAP((t12),R,P,S) , DUMP_T12_MAP((t12),L,P,S) , \ 901 DUMP_T12_MAP((t12),R,A,I) , DUMP_T12_MAP((t12),L,A,I) , \ 902 DUMP_T12_MAP((t12),R,M,I) , DUMP_T12_MAP((t12),L,M,I) , \ 903 DUMP_T12_MAP((t12),R,P,I) , DUMP_T12_MAP((t12),L,P,I) ) 904 905 /*! Struct to hold a simple affine warp (orig -> acpc). */ 906 907 typedef struct { 908 int type ; /*!< type code: WARP_AFFINE_TYPE */ 909 int resam_type ; /*!< Resampling method */ 910 911 THD_linear_mapping warp ; /*!< The single affine mapping */ 912 } THD_affine_warp ; 913 914 #define WARP_AFFINE_SIZE (MAPPING_LINEAR_FSIZE) 915 916 /*! Union type to hold all possible warp types. */ 917 918 typedef union { 919 int type ; /*!< WARP_AFFINE_TYPE or WARP_TALAIRACH_12_TYPE */ 920 THD_affine_warp rig_bod ; 921 THD_talairach_12_warp tal_12 ; 922 } THD_warp ; 923 924 /*! Check if ww is a good warp. */ 925 926 #define ISVALID_WARP(ww) ( (ww) != NULL && \ 927 (ww)->type >= FIRST_WARP_TYPE && \ 928 (ww)->type <= LAST_WARP_TYPE ) 929 930 /*! Temporary warp. */ 931 932 static THD_warp tempA_warp ; 933 934 /*! Return value is an affine warp set to the identity transformation. */ 935 936 #define IDENTITY_WARP \ 937 ( tempA_warp.rig_bod.type = WARP_AFFINE_TYPE , \ 938 tempA_warp.rig_bod.resam_type = RESAM_NN_TYPE , \ 939 tempA_warp.rig_bod.warp.type = MAPPING_LINEAR_TYPE , \ 940 LOAD_DIAG_MAT( tempA_warp.rig_bod.warp.mfor , 1, 1, 1 ) ,\ 941 LOAD_DIAG_MAT( tempA_warp.rig_bod.warp.mbac , 1, 1, 1 ) ,\ 942 LOAD_FVEC3( tempA_warp.rig_bod.warp.bvec , 0, 0, 0 ) ,\ 943 LOAD_FVEC3( tempA_warp.rig_bod.warp.svec , 0, 0, 0 ) ,\ 944 LOAD_FVEC3( tempA_warp.rig_bod.warp.bot , -9999,-9999,-9999 ) ,\ 945 LOAD_FVEC3( tempA_warp.rig_bod.warp.top , 9999, 9999, 9999 ) ,\ 946 tempA_warp ) 947 948 /*! Return values is a warp of angle th about axis ff, in aa-bb plane. */ 949 950 #define ROTGEN_WARP(th,ff,aa,bb) \ 951 ( tempA_warp.rig_bod.type = WARP_AFFINE_TYPE , \ 952 tempA_warp.rig_bod.resam_type = RESAM_NN_TYPE , \ 953 tempA_warp.rig_bod.warp.type = MAPPING_LINEAR_TYPE , \ 954 LOAD_ROTGEN_MAT(tempA_warp.rig_bod.warp.mfor, th,ff,aa,bb) , \ 955 LOAD_ROTGEN_MAT(tempA_warp.rig_bod.warp.mbac,-th,ff,aa,bb) , \ 956 LOAD_FVEC3( tempA_warp.rig_bod.warp.bvec, 0, 0, 0 ) ,\ 957 LOAD_FVEC3( tempA_warp.rig_bod.warp.svec, 0, 0, 0 ) ,\ 958 LOAD_FVEC3( tempA_warp.rig_bod.warp.bot , -9999,-9999,-9999 ) ,\ 959 LOAD_FVEC3( tempA_warp.rig_bod.warp.top , 9999, 9999, 9999 ) ,\ 960 tempA_warp ) 961 962 #define ROTX_WARP(th) ROTGEN_WARP(th,0,1,2) 963 #define ROTY_WARP(th) ROTGEN_WARP(th,1,2,0) 964 #define ROTZ_WARP(th) ROTGEN_WARP(th,2,0,1) 965 966 /*! Make the affine warp map point (xin,yin,zin) to (xout,yout,zout). */ 967 968 #define CEN_WARP(ww,xin,yin,zin,xout,yout,zout) \ 969 do{ THD_fvec3 tv , uv ; \ 970 LOAD_FVEC3(tv,xin,yin,zin) ; \ 971 uv = MATVEC((ww).rig_bod.warp.mfor,tv) ; \ 972 LOAD_FVEC3(tv,xout,yout,zout) ; \ 973 (ww).rig_bod.warp.bvec = SUB_FVEC3(uv,tv) ; \ 974 (ww).rig_bod.warp.svec = \ 975 MATVEC((ww).rig_bod.warp.mbac,(ww).rig_bod.warp.bvec) ; \ 976 NEGATE_FVEC3((ww).rig_bod.warp.svec) ; \ 977 } while(0) 978 979 extern THD_fvec3 AFNI_backward_warp_vector( THD_warp * , THD_fvec3 ) ; 980 extern THD_fvec3 AFNI_forward_warp_vector ( THD_warp * , THD_fvec3 ) ; 981 982 /*---------------------------------------------------------------------*/ 983 /*----------- structure to hold pointer to data on disk ---------------*/ 984 985 #define DISKPTR_TYPE 47 986 987 #define THD_MAX_RANK 3 988 #define THD_MIN_RANK 3 989 #define THD_MAX_RANK_EVER 5 990 991 /* none of these should be over 4 characters! */ 992 993 #define DATASET_HEADER_SUFFIX "HEAD" 994 #define DATASET_BRICK_SUFFIX "BRIK" 995 #define DATASET_NOTES_SUFFIX "NOTE" 996 997 /* for strstr searches, include the '.' 17 Jun 2016 [rickr,DRG] */ 998 #define DATASET_DOT_HEADER_SUFFIX ".HEAD" 999 #define DATASET_DOT_BRICK_SUFFIX ".BRIK" 1000 1001 /*** 1002 The following codes define how the data is stored on disk. 1003 At one time, I started to support more than one storage 1004 type, but that is history. Data either isn't stored 1005 (i.e., is warped-on-demand), or is stored in one big 1006 brick file. 1007 1008 Later: OK, now we have more than one type. However, type #1 1009 was never implemented (the ill-fated STORAGE_BY_SLICES). 1010 1011 see also: thd_opendset.c: storage_mode_from_filename() 1012 ***/ 1013 1014 #define STORAGE_UNDEFINED 0 1015 #define STORAGE_BY_BRICK 2 1016 #define STORAGE_BY_MINC 3 1017 #define STORAGE_BY_VOLUMES 4 /* 20 Jun 2002 */ 1018 #define STORAGE_BY_ANALYZE 5 1019 #define STORAGE_BY_CTFMRI 6 /* 04 Dec 2002 */ 1020 #define STORAGE_BY_CTFSAM 7 1021 #define STORAGE_BY_1D 8 /* 04 Mar 2003 */ 1022 #define STORAGE_BY_3D 9 /* 21 Mar 2003 */ 1023 #define STORAGE_BY_NIFTI 10 /* 28 Aug 2003 */ 1024 #define STORAGE_BY_MPEG 11 /* 03 Dec 2003 */ 1025 #define STORAGE_BY_NIML 12 /* NIML AFNI dset 25 May 2006 [rickr] */ 1026 #define STORAGE_BY_NI_SURF_DSET 13 /* NIML surface dset */ 1027 #define STORAGE_BY_GIFTI 14 /* GIFTI surface dset */ 1028 #define STORAGE_BY_NI_TRACT 15 /* NIML tract dset */ 1029 #define STORAGE_BY_IMAGE_FILE 16 /* 06 Jul 2016 */ 1030 1031 #define LAST_STORAGE_MODE 16 1032 1033 /*! Contains information about where/how dataset is stored on disk. 1034 1035 The filenames in this structure are really path names 1036 (that is, they have the directory name prependend). 1037 */ 1038 1039 typedef struct { 1040 int type ; /*!< must be DISKPTR_TYPE */ 1041 int rank ; /*!< must be 3 */ 1042 int nvals ; /*!< number of 3D volumes; must agree with THD_datablock */ 1043 int dimsizes[THD_MAX_RANK] ; /*!< size of each dimension of 3D array */ 1044 int storage_mode ; /*!< one of the STORAGE_ codes */ 1045 1046 int byte_order ; /*!< LSB_FIRST or MSB_FIRST [25 Apr 1998] */ 1047 1048 char prefix[THD_MAX_PREFIX] ; /*!< prefix part of filename */ 1049 char viewcode[THD_MAX_VIEWCODE] ; /*!< viewcode part of filename */ 1050 char filecode[THD_MAX_FILECODE] ; /*!< filecode = prefix+viewcode */ 1051 1052 char directory_name[THD_MAX_NAME] ; /*!< contain all files for this dataset */ 1053 char header_name[THD_MAX_NAME] ; /*!< contains attributes */ 1054 char brick_name[THD_MAX_NAME] ; /*!< THIS contains actual data volumes */ 1055 1056 int allow_directwrite ; /* 08 May 2009 -- Star Trek Day! */ 1057 } THD_diskptr ; 1058 1059 #define ATRNAME_BYTEORDER "BYTEORDER_STRING" 1060 1061 extern void THD_delete_diskptr( THD_diskptr * ) ; 1062 1063 /*! Determine if THD_diskptr dk is valid. */ 1064 1065 #define ISVALID_DISKPTR(dk) ( (dk)!=NULL && (dk)->type==DISKPTR_TYPE ) 1066 1067 /*! Convert a file prefix and viewcode into a filecode (prefix+view). */ 1068 1069 #define PREFIX_VIEW_TO_FILECODE(pr,vv,fc) sprintf( (fc),"%s+%s",(pr),(vv) ) 1070 1071 /*! Extract the prefix from a filecode (prefix+view). 1072 1073 - If there is no '+', puts an empty string into pr 1074 - Otherwise, scans backward from end to find last '+'; everything before that is the prefix 1075 - Space for pr must be allocated beforehand 1076 1077 Made strstr check for +orig, +acpc, and +tlrc instead of just 1078 "+". Names like aseg+aparc.nii were getting butchered 1079 ZSS: Dec 2011 1080 */ 1081 1082 #define FILECODE_TO_PREFIX(fc,pr) \ 1083 do{ char *qq , *ff , *pp ; \ 1084 if( strstr((fc),"+orig") == NULL &&\ 1085 strstr((fc),"+acpc") == NULL &&\ 1086 strstr((fc),"+tlrc") == NULL ){ \ 1087 (pr)[0] = '\0' ; \ 1088 } else { \ 1089 for( qq=fc+strlen((fc)) ; *qq != '+' ; qq-- ) ; \ 1090 for( ff=(fc) , (pp)=(pr) ; ff < qq ; ff++,pp++ ) *pp = *ff ; \ 1091 *pp = '\0' ; } break ; } while(1) 1092 1093 #if 0 1094 #define FILECODE_TO_PREFIX(fc,pr) \ 1095 do{ char *qq , *ff , *pp ; \ 1096 if( (qq=strstr((fc),"+")) == NULL ){ \ 1097 (pr)[0] = '\0' ; \ 1098 } else { \ 1099 for( ff=(fc) , (pp)=(pr) ; ff < qq ; ff++,pp++ ) *pp = *ff ; \ 1100 *pp = '\0' ; } break ; } while(1) 1101 #endif 1102 1103 /*! Extract the prefix from a filename. */ 1104 1105 #define FILENAME_TO_PREFIX(fn,pr) \ 1106 do{ int ii ; \ 1107 for( ii=strlen((fn)) ; ii >= 0 ; ii-- ) \ 1108 if( (fn)[ii] == '/' ) break ; \ 1109 FILECODE_TO_PREFIX( (fn)+(ii+1) , (pr) ) ; break ; } while(1) 1110 1111 /*---------------------------------------------------------------------*/ 1112 /*------- structure to hold actual 3D data, or pointers thereto -------*/ 1113 1114 #define DATABLOCK_TYPE 37 1115 1116 #define DATABLOCK_MEM_UNDEFINED 1 1117 #define DATABLOCK_MEM_MALLOC 2 1118 #define DATABLOCK_MEM_MMAP 4 1119 #define DATABLOCK_MEM_ANY (DATABLOCK_MEM_MALLOC | DATABLOCK_MEM_MMAP) 1120 #define DATABLOCK_MEM_SHARED 8 /* 02 May 2003 */ 1121 1122 /*! Determine if mm is a valid memory allocation code. */ 1123 1124 #define ISVALID_MEM_CODE(mm) \ 1125 ( (mm) == DATABLOCK_MEM_MALLOC || (mm) == DATABLOCK_MEM_MMAP \ 1126 || (mm) == DATABLOCK_MEM_ANY \ 1127 || (mm) == DATABLOCK_MEM_SHARED ) 1128 1129 #ifndef MMAP_THRESHOLD /* if not previously defined in machdep.h */ 1130 /*! A brick file should have this many bytes before we try to use mmap */ 1131 # define MMAP_THRESHOLD 999999 1132 #endif 1133 1134 /*------------------------------------------------------------------*/ 1135 /* Stuff for volume-editing on demand. [05 Sep 2006] */ 1136 1137 #define VEDIT_NPARAM 9 1138 typedef struct { 1139 int code , ival , flags ; 1140 float param[VEDIT_NPARAM] ; 1141 void *exinfo ; 1142 } VEDIT_settings ; 1143 1144 #define VEDIT_CLUST 1 /* param= ithr,thr,rmm,vmul exinfo=NULL */ 1145 #define VEDIT_LASTCODE 1 /* no other options besides clustering!? */ 1146 1147 #define VEDIT_IVAL(vv) ((vv).ival) 1148 #define DBLK_VEDIT_IVAL(db) VEDIT_IVAL((db)->vedset) 1149 #define DSET_VEDIT_IVAL(ds) DBLK_VEDIT_IVAL((ds)->dblk) 1150 1151 #define VEDIT_CODE(vv) ((vv).code) 1152 #define DBLK_VEDIT_CODE(db) VEDIT_CODE((db)->vedset) 1153 #define DSET_VEDIT_CODE(ds) DBLK_VEDIT_CODE((ds)->dblk) 1154 1155 #define VEDIT_FLAGS(vv) ((vv).flags) 1156 #define DBLK_VEDIT_FLAGS(db) VEDIT_FLAGS((db)->vedset) 1157 #define DSET_VEDIT_FLAGS(db) DBLK_VEDIT_FLAGS((ds)->dblk) 1158 1159 #define VEDIT_good(vv) \ 1160 ( (vv).code > 0 && (vv).code <= VEDIT_LASTCODE ) 1161 #define DBLK_VEDIT_good(db) \ 1162 ( VEDIT_good((db)->vedset) && (db)->vedset.ival >= 0 && \ 1163 (db)->vedset.ival < (db)->nvals ) 1164 #define DSET_VEDIT_good(ds) DBLK_VEDIT_good((ds)->dblk) 1165 /*------------------------------------------------------------------*/ 1166 1167 /*! All subvolumes are stored in an array of MRI_IMAGE (the "brick"). 1168 - If mmap is used, then the whole external file is mmap()-ed in one 1169 block and the data pointers for each image computed from this base. 1170 - If malloc() is used, then each image is separately allocated and input. 1171 - Each datablock has a brick, even if it doesn't actually contain 1172 data (is only warp-on-demand). 1173 - Whether or not a datablock contains actual voxel data can be 1174 determined by examining the "malloc_type". 1175 \date Feb 1996 1176 */ 1177 1178 typedef struct { 1179 int type ; /*!< type code: DATABLOCK_TYPE */ 1180 1181 int nvals ; /*!< number of 3D bricks */ 1182 1183 MRI_IMARR * brick ; /*!< array of pointers to each 3D brick */ 1184 float * brick_fac ; /*!< array of scale factors to convert sub-bricks to floats */ 1185 int64_t *brick_bytes ; /*!< array of data size of each sub-brick */ 1186 1187 /* These fields added for "bucket" datasets: */ 1188 1189 char ** brick_lab ; /*!< labels for all sub-bricks */ 1190 char ** brick_keywords ; /*!< keywords strings for all sub-bricks */ 1191 int * brick_statcode ; /*!< a FUNC_*_TYPE ==> kind of statistic here */ 1192 float ** brick_stataux ; /*!< stat_aux parameters for each sub-brick with brick_statcode[iv] > 0 */ 1193 1194 int64_t total_bytes ; /*!< totality of data storage needed */ 1195 int malloc_type ; /*!< memory allocation method */ 1196 int locked ; /*!< Feb 1998: locked in memory (un-purgeable) */ 1197 1198 /* Jan 1999: for datasets that are extracted from a master dataset */ 1199 int master_nvals ; /*!< Number of nvals in master dataset */ 1200 int * master_ival ; /*!< master_ival[i] = sub-brick index in master of sub-brick #i here */ 1201 int64_t *master_bytes ; /*!< master_bytes[i] = size of sub-brick #i in master */ 1202 1203 float master_bot ; /*!< range of data values to keep from master - bottom */ 1204 float master_top ; /*!< range of data values to keep from master - top */ 1205 1206 /* for angle bracket selectors - input restricted to an integer list of */ 1207 /* CSV (comma separated values) - akin to master_bot and master_top, */ 1208 /* but a list, not a range 21 Nov 2016 [rickr] */ 1209 /* --> of course, this will probably change to a list of float ranges...*/ 1210 int master_ncsv ; /*!< Number of values in master_csv */ 1211 int * master_csv ; /*!< list of non-zero values that can be stored */ 1212 1213 THD_diskptr * diskptr ; /*!< where the data is on disk (if anywhere!) */ 1214 1215 int natr ; /*!< number of attributes read from disk (or to write to disk) */ 1216 int natr_alloc ; /*!< number of attributes allocated in atr below */ 1217 ATR_any * atr ; /*!< array of attributes (from the header) */ 1218 1219 int nnodes ; /*!< number of node indices [25 May 2006 rickr] */ 1220 int * node_list ; /*!< index array for STORAGE_BY_NI_SURF_DSET */ 1221 1222 /* pointers to other stuff */ 1223 1224 KILL_list kl ; /*!< Stuff to delete if this struct is deleted */ 1225 RwcPointer parent ; /*!< Somebody who "owns" me */ 1226 1227 char shm_idcode[32] ; /*!< Idcode for shared memory buffer, if any [02 May 2003]. */ 1228 int shm_idint ; /*!< Integer id for shared memory buffer. */ 1229 1230 VEDIT_settings vedset ; /*!< Volume edit-on-the-fly settings */ 1231 MRI_IMAGE *vedim ; /*!< Volume edit-on-the-fly result */ 1232 1233 floatvec **brick_fdrcurve ; /*!< FDR z(q) as a function of statistic */ 1234 floatvec **brick_mdfcurve ; /*!< FDR mdf as a function of log10(p) */ 1235 1236 } THD_datablock ; 1237 1238 /*! Force bricks to be allocated with malloc(). */ 1239 1240 #define DBLK_mallocize(db) THD_force_malloc_type((db),DATABLOCK_MEM_MALLOC) 1241 1242 /*! Force bricks to be allocated with mmap(). */ 1243 1244 #define DBLK_mmapize(db) THD_force_malloc_type((db),DATABLOCK_MEM_MMAP) 1245 1246 /*! Don't care how bricks are allocated. */ 1247 1248 #define DBLK_anyize(db) THD_force_malloc_type((db),DATABLOCK_MEM_ANY) 1249 1250 /*! Test if brick is set to be malloc()-ed. */ 1251 1252 #define DBLK_IS_MALLOC(db) ((db)->malloc_type == DATABLOCK_MEM_MALLOC) 1253 1254 /*! Test if brick is set to be mmap()-ed. */ 1255 1256 #define DBLK_IS_MMAP(db) ((db)->malloc_type == DATABLOCK_MEM_MMAP) 1257 1258 /*! Test if brick is set to be shared. */ 1259 1260 #define DBLK_IS_SHARED(db) ((db)->malloc_type == DATABLOCK_MEM_SHARED) 1261 1262 /*! Force bricks to be allocated in shared memory. */ 1263 1264 #define DBLK_shareize(db) THD_force_malloc_type((db),DATABLOCK_MEM_SHARED) 1265 1266 /*! Lock bricks in memory. */ 1267 1268 #define DBLK_lock(db) ((db)->locked = 1) 1269 1270 /*! Unlock bricks from memory, if they aren't "superlocked". */ 1271 1272 #define DBLK_unlock(db) ((db)->locked = ((db)->locked<2) ? 0 : 2) 1273 1274 /*! Test if brick is locked into memory. */ 1275 1276 #define DBLK_LOCKED(db) ((db)->locked) 1277 1278 /*! Superlock brick in memory. Can only be undone by explicit access to db->locked. */ 1279 #define DBLK_superlock(db) ((db)->locked = 2) 1280 1281 /*! Check if brick is mastered from another dataset. */ 1282 1283 #define DBLK_IS_MASTERED(db) \ 1284 ((db)->master_nvals > 0 && (db)->master_ival != NULL && (db)->master_bytes != NULL) 1285 1286 /*! Check if brick is mastered and has subranges to be applied */ 1287 1288 #define DBLK_IS_MASTER_SUBRANGED(db) \ 1289 (DBLK_IS_MASTERED(db) && \ 1290 ( ((db)->master_bot <= (db)->master_top) || \ 1291 ((db)->master_ncsv > 0 && (db)->master_csv != NULL) )) 1292 1293 extern void THD_delete_datablock ( THD_datablock * ) ; 1294 extern void THD_init_datablock_brick ( THD_datablock * , int , void * ) ; 1295 extern void THD_init_datablock_labels ( THD_datablock * ) ; 1296 extern void THD_init_datablock_keywords ( THD_datablock * ) ; 1297 extern void THD_copy_datablock_auxdata ( THD_datablock * , THD_datablock * ) ; 1298 extern void THD_init_datablock_stataux ( THD_datablock * ) ; 1299 extern void THD_store_datablock_stataux ( THD_datablock *,int,int,int,float * ); 1300 extern void THD_store_datablock_label ( THD_datablock * , int , char * ) ; 1301 extern void THD_store_datablock_keywords ( THD_datablock * , int , char * ) ; 1302 extern void THD_append_datablock_keywords( THD_datablock * , int , char * ) ; 1303 extern int THD_datablock_from_atr ( THD_datablock *, char *, char * ) ; 1304 extern void atr_print( ATR_any * atr, char *ssep , char *spsep, char quote, int do_name) ; 1305 1306 /*! Initialize all sub-bricks auxiliary data to nothing. */ 1307 1308 #define THD_null_datablock_auxdata(blk) ( (blk)->brick_lab = NULL , \ 1309 (blk)->brick_keywords = NULL , \ 1310 (blk)->brick_statcode = NULL , \ 1311 (blk)->brick_stataux = NULL ) 1312 1313 extern int THD_string_has( char * , char * ) ; 1314 1315 /*! Check if datablock is OK. */ 1316 1317 #define ISVALID_DATABLOCK(bk) ( (bk) != NULL && (bk)->type == DATABLOCK_TYPE ) 1318 1319 /*! Synonym for ISVALID_DATABLOCK. */ 1320 1321 #define ISVALID_DBLK ISVALID_DATABLOCK /* 26 Mar 2001 */ 1322 1323 /*------------- a dynamic array type for datablocks --------------*/ 1324 1325 /*! A dynamic array type for datablocks - used when assembling datasets. */ 1326 1327 typedef struct { 1328 int num ; /*!< Number of datablocks stored */ 1329 int nall ; /*!< Number of datablocks space allocated for */ 1330 THD_datablock **ar ; /*!< Array of datablocks */ 1331 } THD_datablock_array ; 1332 1333 #define INC_DBARR 8 1334 1335 /*! Initialize a THD_datablock_array. */ 1336 1337 #define INIT_DBARR(name) \ 1338 ( (name) = RwcNew(THD_datablock_array) ,\ 1339 (name)->num = (name)->nall = 0 , \ 1340 (name)->ar = NULL ) 1341 1342 /*! Add a datablock to a THD_datablock_array. */ 1343 1344 #define ADDTO_DBARR(name,bblk) \ 1345 { if( (name)->num == (name)->nall ){ \ 1346 (name)->nall += INC_DBARR + (name)->nall/8 ; \ 1347 (name)->ar = (THD_datablock **) \ 1348 RwcRealloc( (char *) (name)->ar , \ 1349 sizeof(THD_datablock *) * (name)->nall ) ; \ 1350 } \ 1351 if( (bblk) != NULL ){ \ 1352 (name)->ar[(name)->num] = (bblk) ; \ 1353 ((name)->num)++ ; \ 1354 } } 1355 1356 /*! Free the space used by a THD_datablock_array (but not the datablocks themselves). */ 1357 1358 #define FREE_DBARR(name) \ 1359 if( (name) != NULL ){ \ 1360 myRwcFree( (name)->ar ) ; \ 1361 myRwcFree( (name) ) ; } 1362 1363 /*--------------------------------------------------------------------*/ 1364 /*---------- stuff to hold axes information for 3D dataset -----------*/ 1365 1366 #define DATAXES_TYPE 27 1367 1368 /*! Default resampling grid size (in mm). */ 1369 1370 #define DEFAULT_RESAMPLE_VOX 1.0 1371 1372 /*--- orientation types ---*/ 1373 1374 #define ORI_R2L_TYPE 0 1375 #define ORI_R2L_STR "Right-to-Left" 1376 1377 #define ORI_L2R_TYPE 1 1378 #define ORI_L2R_STR "Left-to-Right" 1379 1380 #define ORI_P2A_TYPE 2 1381 #define ORI_P2A_STR "Posterior-to-Anterior" 1382 1383 #define ORI_A2P_TYPE 3 1384 #define ORI_A2P_STR "Anterior-to-Posterior" 1385 1386 #define ORI_I2S_TYPE 4 1387 #define ORI_I2S_STR "Inferior-to-Superior" 1388 1389 #define ORI_S2I_TYPE 5 1390 #define ORI_S2I_STR "Superior-to-Inferior" 1391 1392 #define ORI_GEN_TYPE 6 1393 #define ORI_GEN_STR "General" /* not used at present */ 1394 1395 #define FIRST_ORIENT_TYPE 0 1396 #define LAST_ORIENT_TYPE 5 1397 1398 #define LONGEST_ORIENT_TYPESTR strlen(ORI_P2A_STR) 1399 1400 static char * ORIENT_typestr[] = { 1401 ORI_R2L_STR , ORI_L2R_STR , ORI_P2A_STR , 1402 ORI_A2P_STR , ORI_I2S_STR , ORI_S2I_STR , ORI_GEN_STR 1403 } ; 1404 1405 static char * ORIENT_shortstr[] = { 1406 "R-L" , "L-R" , "P-A" , "A-P" , "I-S" , "S-I" , "GEN" 1407 } ; 1408 1409 static char * ORIENT_tinystr[] = { 1410 "RL" , "LR" , "PA" , "AP" , "IS" , "SI" , "??" 1411 } ; 1412 1413 static char ORIENT_xyz[] = "xxyyzzg" ; /* DICOM directions are 1414 x = R->L , y = A->P , z = I->S */ 1415 1416 /*! Determines if orientation code (0..5) is DICOM positive or negative. */ 1417 1418 static char ORIENT_sign[] = "+--++-" ; 1419 1420 static char ORIENT_first[] = "RLPAIS" ; 1421 1422 static int ORIENT_xyzint[] = { 1,1 , 2,2 , 3,3 , 666 } ; 1423 1424 #define ORIENT_OPPOSITE(orc) \ 1425 ( ((orc) % 2 == 0) ? ((orc)+1) : ((orc)-1) ) 1426 1427 /*! Struct to hold information about 3D brick grid in space. 1428 Voxel center x[i] is at xxorg + i * xxdel, et cetera. 1429 */ 1430 1431 typedef struct { 1432 int type ; /*!< type code: DATAXES_TYPE */ 1433 1434 int nxx ; /*!< Number of points in grid in x direction */ 1435 int nyy ; /*!< Number of points in grid in y direction */ 1436 int nzz ; /*!< Number of points in grid in z direction */ 1437 1438 float xxorg ; /*!< Center of (0,0,0) voxel */ 1439 float yyorg ; /*!< Center of (0,0,0) voxel */ 1440 float zzorg ; /*!< center of (0,0,0) voxel */ 1441 float xxdel ; /*!< Spacings between voxel centers (mm) - may be negative */ 1442 float yydel ; /*!< Spacings between voxel centers (mm) - may be negative */ 1443 float zzdel ; /*!< Spacings between voxel centers (mm) - may be negative */ 1444 1445 float xxmin ; /*!< Bounding box for grid [cf THD_set_daxes_bbox()] */ 1446 float xxmax ; /*!< Bounding box for grid */ 1447 float yymin ; /*!< Bounding box for grid */ 1448 float yymax ; /*!< Bounding box for grid */ 1449 float zzmin ; /*!< Bounding box for grid */ 1450 float zzmax ; /*!< Bounding box for grid */ 1451 1452 int xxorient ; /*!< Orientation code */ 1453 int yyorient ; /*!< Orientation code */ 1454 int zzorient ; /*!< Orientation code */ 1455 1456 THD_mat33 to_dicomm ; /*!< Orthogonal matrix transforming from 1457 dataset coordinates to DICOM coordinates */ 1458 1459 /*** 06 Dec 2005: extensions to allow arbitrarily oriented volumes [cf thd_matdaxes.c] ***/ 1460 1461 mat44 ijk_to_dicom ; /* matrix taking ijk indexes to DICOM xyz coords */ 1462 mat44 dicom_to_ijk ; /* inverse of above */ 1463 float dicom_xxmin , dicom_yymin , dicom_zzmin ; 1464 float dicom_xxmax , dicom_yymax , dicom_zzmax ; 1465 /*** 18 May 2007: obliquity */ 1466 mat44 ijk_to_dicom_real ; /* matrix to convert ijk to DICOM for obliquity*/ 1467 /* pointers to other stuff */ 1468 1469 RwcPointer parent ; /*!< Dataset that "owns" this struct */ 1470 } THD_dataxes ; 1471 1472 #define DAXES_CMAT(dax,rrr) \ 1473 ( ( rrr && ISVALID_MAT44((dax)->ijk_to_dicom_real) ) \ 1474 ? (dax)->ijk_to_dicom_real \ 1475 : (dax)->ijk_to_dicom ) 1476 1477 #define DSET_CMAT(ds,rrr) DAXES_CMAT( (ds)->daxes , (rrr) ) 1478 1479 #define DAXES_COPYOVER_REAL(dax) \ 1480 (dax)->ijk_to_dicom_real = (dax)->ijk_to_dicom /* 27 Jun 2014 */ 1481 1482 #define DSET_COPYOVER_REAL(ds) \ 1483 do{ if( ISVALID_DSET(ds) && ISVALID_DATAXES((ds)->daxes) ) \ 1484 DAXES_COPYOVER_REAL((ds)->daxes) ; \ 1485 } while(0) 1486 1487 #define DSET_CHECKAXES_REAL(ds) \ 1488 do{ if( ISVALID_DSET(ds) && ISVALID_DATAXES((ds)->daxes) ){ \ 1489 float dif = MAT44_FLDIF((ds)->daxes->ijk_to_dicom,(ds)->daxes->ijk_to_dicom_real); \ 1490 if( dif > 0.001f ) \ 1491 WARNING_message("-*-*-*- ijk_to_dicom and ijk_to_dicom_real differ for dataset %s", \ 1492 DSET_HEADNAME(ds) ) ; \ 1493 } } while(0) 1494 1495 /*! Center of grid in x-direction. */ 1496 #define DAXES_XCEN(dax) ((dax)->xxorg + 0.5*((dax)->nxx - 1) * (dax)->xxdel) 1497 1498 /*! Center of grid in y-direction. */ 1499 #define DAXES_YCEN(dax) ((dax)->yyorg + 0.5*((dax)->nyy - 1) * (dax)->yydel) 1500 1501 /*! Center of grid in z-direction. */ 1502 #define DAXES_ZCEN(dax) ((dax)->zzorg + 0.5*((dax)->nzz - 1) * (dax)->zzdel) 1503 1504 #define DSET_XCEN(ds) DAXES_XCEN((ds)->daxes) 1505 #define DSET_YCEN(ds) DAXES_YCEN((ds)->daxes) 1506 #define DSET_ZCEN(ds) DAXES_ZCEN((ds)->daxes) 1507 1508 #if 1 1509 #define DAXES_NUM(dax,ori) \ 1510 ( (ORIENT_xyzint[(ori)] == ORIENT_xyzint[(dax)->xxorient]) ? (dax)->nxx : \ 1511 (ORIENT_xyzint[(ori)] == ORIENT_xyzint[(dax)->yyorient]) ? (dax)->nyy : \ 1512 (ORIENT_xyzint[(ori)] == ORIENT_xyzint[(dax)->zzorient]) ? (dax)->nzz : 0 ) 1513 #else 1514 #define DAXES_NUM(dax,ori) ( ( ORIENT_xyzint[(ori)] == 1 ) ? (dax)->nxx : \ 1515 ( ORIENT_xyzint[(ori)] == 2 ) ? (dax)->nyy : \ 1516 ( ORIENT_xyzint[(ori)] == 3 ) ? (dax)->nzz : 0 ) 1517 #endif 1518 1519 /*! WARNING: If you perform surgery on a dataset and change its 1520 dimensions in the dataxes, you must also reflect 1521 this in the diskptr. Otherwise, the .HEAD file 1522 will not have the correct dimensions! The macro 1523 just below will do this for you. 1524 */ 1525 1526 #define DATAXES_TO_DISKPTR(ds) \ 1527 ( (ds)->dblk->diskptr->dimsizes[0] = (ds)->daxes->nxx , \ 1528 (ds)->dblk->diskptr->dimsizes[1] = (ds)->daxes->nyy , \ 1529 (ds)->dblk->diskptr->dimsizes[2] = (ds)->daxes->nzz ) 1530 1531 /*! Check if dax is a valid THD_dataxes struct. */ 1532 1533 #define ISVALID_DATAXES(dax) ( (dax) != NULL && (dax)->type == DATAXES_TYPE ) 1534 1535 /*! Check if two THD_dataxes are essential equivalent. 1536 ***** SEE ALSO ******** 1537 THD_dataset_mismatch () */ 1538 1539 #define EQUIV_DATAXES(cax,dax) \ 1540 ( ISVALID_DATAXES((cax)) && \ 1541 ISVALID_DATAXES((dax)) && \ 1542 (cax)->nxx == (dax)->nxx && \ 1543 (cax)->nyy == (dax)->nyy && \ 1544 (cax)->nzz == (dax)->nzz && \ 1545 fabs( (cax)->xxorg - (dax)->xxorg ) < 0.01 && \ 1546 fabs( (cax)->yyorg - (dax)->yyorg ) < 0.01 && \ 1547 fabs( (cax)->zzorg - (dax)->zzorg ) < 0.01 && \ 1548 fabs( (cax)->xxdel - (dax)->xxdel ) < 0.001 && \ 1549 fabs( (cax)->yydel - (dax)->yydel ) < 0.001 && \ 1550 fabs( (cax)->zzdel - (dax)->zzdel ) < 0.001 && \ 1551 (cax)->xxorient == (dax)->xxorient && \ 1552 (cax)->yyorient == (dax)->yyorient && \ 1553 (cax)->zzorient == (dax)->zzorient ) 1554 1555 #define EQUIV_DATAXYZ(cax,dax) \ 1556 ( ISVALID_DATAXES((cax)) && \ 1557 ISVALID_DATAXES((dax)) && \ 1558 (cax)->nxx == (dax)->nxx && \ 1559 (cax)->nyy == (dax)->nyy && \ 1560 (cax)->nzz == (dax)->nzz && \ 1561 fabs( (cax)->xxdel - (dax)->xxdel ) < 0.001 && \ 1562 fabs( (cax)->yydel - (dax)->yydel ) < 0.001 && \ 1563 fabs( (cax)->zzdel - (dax)->zzdel ) < 0.001 && \ 1564 (cax)->xxorient == (dax)->xxorient && \ 1565 (cax)->yyorient == (dax)->yyorient && \ 1566 (cax)->zzorient == (dax)->zzorient ) 1567 1568 #define EQUIV_DATADELTAXYZ(cax,dax) \ 1569 ( ISVALID_DATAXES((cax)) && \ 1570 ISVALID_DATAXES((dax)) && \ 1571 fabs( (cax)->xxdel - (dax)->xxdel ) < 0.001 && \ 1572 fabs( (cax)->yydel - (dax)->yydel ) < 0.001 && \ 1573 fabs( (cax)->zzdel - (dax)->zzdel ) < 0.001 && \ 1574 (cax)->xxorient == (dax)->xxorient && \ 1575 (cax)->yyorient == (dax)->yyorient && \ 1576 (cax)->zzorient == (dax)->zzorient ) 1577 1578 #define EQUIV_GRIDS(d1,d2) \ 1579 ( ISVALID_DSET(d1) && ISVALID_DSET(d2) && EQUIV_DATAXES((d1)->daxes,(d2)->daxes) ) 1580 1581 #define EQUIV_GRIDXYZ(d1,d2) \ 1582 ( ISVALID_DSET(d1) && ISVALID_DSET(d2) && EQUIV_DATAXYZ((d1)->daxes,(d2)->daxes) ) 1583 1584 #define EQUIV_DELTAXYZ(d1,d2) \ 1585 ( ISVALID_DSET(d1) && ISVALID_DSET(d2) && EQUIV_DATADELTAXYZ((d1)->daxes,(d2)->daxes) ) 1586 1587 #define EQUIV_DATA_NXYZ(cax,dax) \ 1588 ( ISVALID_DATAXES((cax)) && \ 1589 ISVALID_DATAXES((dax)) && \ 1590 (cax)->nxx == (dax)->nxx && \ 1591 (cax)->nyy == (dax)->nyy && \ 1592 (cax)->nzz == (dax)->nzz ) 1593 1594 #define EQUIV_GRIDS_NXYZ(d1,d2) \ 1595 ( ISVALID_DSET(d1) && ISVALID_DSET(d2) && EQUIV_DATA_NXYZ((d1)->daxes,(d2)->daxes) ) 1596 1597 extern void THD_edit_dataxes( float , THD_dataxes * , THD_dataxes * ) ; 1598 1599 extern void THD_set_daxes_bbox ( THD_dataxes * ) ; /* 20 Dec 2005 */ 1600 extern void THD_set_daxes_to_dicomm( THD_dataxes * ) ; 1601 1602 int THD_get_axis_direction( THD_dataxes *, int ) ; /* 19 Mar 2003 */ 1603 int THD_fill_orient_int_3_rlpais( THD_dataxes *, int [3] ); // [PT: Nov 2, 2020] 1604 int THD_fill_orient_str_3( THD_dataxes *, char [4] );/* 23 Jan 2013 [rickr] */ 1605 int THD_fill_orient_str_6( THD_dataxes *, char [7] );/* 23 Jan 2013 [rickr] */ 1606 1607 1608 extern int THD_daxes_to_mat44 ( THD_dataxes *dax ) ; /* 07 Dec 2005 */ 1609 extern int THD_daxes_from_mat44( THD_dataxes *dax ) ; 1610 extern void THD_set_dicom_box ( THD_dataxes *dax ) ; /* 15 Dec 2005 */ 1611 extern mat44 THD_resample_mat44( mat44 , int,int,int , 1612 float,float,float , int *,int *,int *) ; 1613 1614 /*---------------------------------------------------------------------*/ 1615 /* Macros and functions for dealing with mat44 structs. */ 1616 1617 /******* 1618 Useful mat33 and mat44 functions in nifti1_io.c: 1619 mat44 nifti_mat44_inverse( mat44 R ) ; == matrix inverse 1620 mat33 nifti_mat33_inverse( mat33 R ) ; == matrix inverse 1621 mat33 nifti_mat33_polar ( mat33 A ) ; == polar decomp 1622 float nifti_mat33_rownorm( mat33 A ) ; == max row sum 1623 float nifti_mat33_colnorm( mat33 A ) ; == max col sum 1624 float nifti_mat33_determ ( mat33 R ) ; == determinant 1625 mat33 nifti_mat33_mul ( mat33 A, mat33 B ) ; == matrix multiply 1626 *******/ 1627 1628 /******* Function below is not in nifti1_io.c, due to some oversight ******/ 1629 1630 extern mat44 THD_mat44_mul( mat44 A , mat44 B ) ; /* matrix multiply */ 1631 1632 static mat44 tempA_mat44 ; /* temp storage for matrices */ 1633 static mat33 tempZ_mat33 ; 1634 1635 extern mat44 THD_mat44_sqrt( mat44 A ) ; /* matrix square root [30 Jul 2007] */ 1636 1637 /* function to return rotation matrix of angle 1638 theta (radians) about unit vector (ax,ay,az) [05 Nov 2020] */ 1639 1640 extern mat33 THD_mat33_generic_rotation( float theta, float ax, float ay, float az ) ; 1641 1642 typedef struct { /* holds a matrix plus 3D grid dimensions */ 1643 mat44 mat ; 1644 int nx,ny,nz ; 1645 } mat44_nxyz ; 1646 1647 extern float MAT44_angle( mat44 amat , mat44 bmat ) ; 1648 extern mat44 MAT44_to_rotation( mat44 amat ) ; 1649 1650 #undef MAT44_MUL 1651 #define MAT44_MUL THD_mat44_mul 1652 1653 #undef MAT33_MUL 1654 #define MAT33_MUL nifti_mat33_mul 1655 1656 #undef MAT44_SQRT 1657 #define MAT44_SQRT THD_mat44_sqrt 1658 1659 #undef MAT44_INV 1660 #define MAT44_INV nifti_mat44_inverse 1661 1662 #undef MAT33_INV 1663 #define MAT33_INV nifti_mat33_inverse 1664 1665 #undef ISVALID_MAT44 1666 #define ISVALID_MAT44(AA) ((AA).m[3][3] != 0.0f) 1667 1668 #undef INVALIDATE_MAT44 1669 #define INVALIDATE_MAT44(AA) ((AA).m[3][3] = 0.0f) 1670 1671 #undef ISZERO_MAT44 1672 #define ISZERO_MAT44(AA) \ 1673 ((AA.m[0][0] == 0.0f) && \ 1674 (AA.m[0][1] == 0.0f) && \ 1675 (AA.m[0][2] == 0.0f) && \ 1676 (AA.m[0][3] == 0.0f) && \ 1677 (AA.m[1][0] == 0.0f) && \ 1678 (AA.m[1][1] == 0.0f) && \ 1679 (AA.m[1][2] == 0.0f) && \ 1680 (AA.m[1][3] == 0.0f) && \ 1681 (AA.m[2][0] == 0.0f) && \ 1682 (AA.m[2][1] == 0.0f) && \ 1683 (AA.m[2][2] == 0.0f) && \ 1684 (AA.m[2][3] == 0.0f) ) 1685 1686 #undef ISZERO_MAT33 1687 #define ISZERO_MAT33(AA) \ 1688 ((AA.m[0][0] == 0.0f) && \ 1689 (AA.m[0][1] == 0.0f) && \ 1690 (AA.m[0][2] == 0.0f) && \ 1691 (AA.m[1][0] == 0.0f) && \ 1692 (AA.m[1][1] == 0.0f) && \ 1693 (AA.m[1][2] == 0.0f) && \ 1694 (AA.m[2][0] == 0.0f) && \ 1695 (AA.m[2][1] == 0.0f) && \ 1696 (AA.m[2][2] == 0.0f) ) 1697 1698 #undef NORM_MAT33 1699 #define NORM_MAT33(MM) (fabsf(MM.m[0][0])+fabsf(MM.m[0][1])+fabsf(MM.m[0][2]) \ 1700 +fabsf(MM.m[1][0])+fabsf(MM.m[1][1])+fabsf(MM.m[1][2]) \ 1701 +fabsf(MM.m[2][0])+fabsf(MM.m[2][1])+fabsf(MM.m[2][2]) ) 1702 1703 #undef ISIDENT_MAT44 1704 #define ISIDENT_MAT44(AA) \ 1705 ((AA.m[0][0] == 1.0f) && \ 1706 (AA.m[0][1] == 0.0f) && \ 1707 (AA.m[0][2] == 0.0f) && \ 1708 (AA.m[0][3] == 0.0f) && \ 1709 (AA.m[1][0] == 0.0f) && \ 1710 (AA.m[1][1] == 1.0f) && \ 1711 (AA.m[1][2] == 0.0f) && \ 1712 (AA.m[1][3] == 0.0f) && \ 1713 (AA.m[2][0] == 0.0f) && \ 1714 (AA.m[2][1] == 0.0f) && \ 1715 (AA.m[2][2] == 1.0f) && \ 1716 (AA.m[2][3] == 0.0f) ) 1717 1718 #undef ISIDENT_MAT33 1719 #define ISIDENT_MAT33(AA) \ 1720 ((AA.m[0][0] == 1.0f) && \ 1721 (AA.m[0][1] == 0.0f) && \ 1722 (AA.m[0][2] == 0.0f) && \ 1723 (AA.m[1][0] == 0.0f) && \ 1724 (AA.m[1][1] == 1.0f) && \ 1725 (AA.m[1][2] == 0.0f) && \ 1726 (AA.m[2][0] == 0.0f) && \ 1727 (AA.m[2][1] == 0.0f) && \ 1728 (AA.m[2][2] == 1.0f) ) 1729 1730 /* check if 2 mat44 matrices are equal-ish */ 1731 1732 #undef FLEQ 1733 #define FLEQ(a,b) (fabsf((a)-(b)) < 0.0001f) 1734 1735 #undef MAT44_FLEQ 1736 #define MAT44_FLEQ(AA,BB) \ 1737 ( FLEQ(AA.m[0][0],BB.m[0][0]) && FLEQ(AA.m[0][1],BB.m[0][1]) && \ 1738 FLEQ(AA.m[0][2],BB.m[0][2]) && FLEQ(AA.m[0][3],BB.m[0][3]) && \ 1739 FLEQ(AA.m[1][0],BB.m[1][0]) && FLEQ(AA.m[1][1],BB.m[1][1]) && \ 1740 FLEQ(AA.m[1][2],BB.m[1][2]) && FLEQ(AA.m[1][3],BB.m[1][3]) && \ 1741 FLEQ(AA.m[2][0],BB.m[2][0]) && FLEQ(AA.m[2][1],BB.m[2][1]) && \ 1742 FLEQ(AA.m[2][2],BB.m[2][2]) && FLEQ(AA.m[2][3],BB.m[2][3]) && \ 1743 FLEQ(AA.m[3][0],BB.m[3][0]) && FLEQ(AA.m[3][1],BB.m[3][1]) && \ 1744 FLEQ(AA.m[3][2],BB.m[3][2]) && FLEQ(AA.m[3][3],BB.m[3][3]) ) 1745 1746 /* compute sum of diffs of 2 mat44 matrices */ 1747 1748 #undef FLDIF 1749 #define FLDIF(a,b) fabsf((a)-(b)) 1750 1751 #undef MAT44_FLDIF 1752 #define MAT44_FLDIF(AA,BB) \ 1753 ( FLDIF(AA.m[0][0],BB.m[0][0]) + FLDIF(AA.m[0][1],BB.m[0][1]) + \ 1754 FLDIF(AA.m[0][2],BB.m[0][2]) + FLDIF(AA.m[0][3],BB.m[0][3]) + \ 1755 FLDIF(AA.m[1][0],BB.m[1][0]) + FLDIF(AA.m[1][1],BB.m[1][1]) + \ 1756 FLDIF(AA.m[1][2],BB.m[1][2]) + FLDIF(AA.m[1][3],BB.m[1][3]) + \ 1757 FLDIF(AA.m[2][0],BB.m[2][0]) + FLDIF(AA.m[2][1],BB.m[2][1]) + \ 1758 FLDIF(AA.m[2][2],BB.m[2][2]) + FLDIF(AA.m[2][3],BB.m[2][3]) + \ 1759 FLDIF(AA.m[3][0],BB.m[3][0]) + FLDIF(AA.m[3][1],BB.m[3][1]) + \ 1760 FLDIF(AA.m[3][2],BB.m[3][2]) + FLDIF(AA.m[3][3],BB.m[3][3]) ) 1761 1762 /* load the top 3 rows of a mat44 matrix, 1763 and set the 4th row to [ 0 0 0 1], as required */ 1764 1765 #undef LOAD_MAT44 1766 #define LOAD_MAT44(AA,a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34) \ 1767 ( AA.m[0][0]=a11 , AA.m[0][1]=a12 , AA.m[0][2]=a13 , AA.m[0][3]=a14 , \ 1768 AA.m[1][0]=a21 , AA.m[1][1]=a22 , AA.m[1][2]=a23 , AA.m[1][3]=a24 , \ 1769 AA.m[2][0]=a31 , AA.m[2][1]=a32 , AA.m[2][2]=a33 , AA.m[2][3]=a34 , \ 1770 AA.m[3][0]=AA.m[3][1]=AA.m[3][2]=0.0f , AA.m[3][3]=1.0f ) 1771 1772 #undef LOAD_DIAG_MAT44 1773 #define LOAD_DIAG_MAT44(AA,a,b,c) \ 1774 LOAD_MAT44( AA , (a),0,0,0 , 0,(b),0,0 , 0,0,(c),0 ) 1775 1776 #undef LOAD_IDENT_MAT44 1777 #define LOAD_IDENT_MAT44(AA) \ 1778 LOAD_MAT44( AA , 1,0,0,0 , 0,1,0,0 , 0,0,1,0 ) 1779 1780 #undef ZERO_MAT44 1781 #define ZERO_MAT44(AA) LOAD_DIAG_MAT44(AA,0.0,0.0,0.0) 1782 #undef LOAD_ZERO_MAT44 1783 #define LOAD_ZERO_MAT44 ZERO_MAT44 1784 1785 #undef LOAD_MAT44_VEC 1786 #define LOAD_MAT44_VEC(AA,x,y,z) ( AA.m[0][3]=(x) , AA.m[1][3]=(y) , AA.m[2][3]=(z) ) 1787 1788 #undef UNLOAD_MAT44_VEC 1789 #define UNLOAD_MAT44_VEC(AA,x,y,z) ( (x)=AA.m[0][3] , (y)=AA.m[1][3] , (z)=AA.m[2][3] ) 1790 1791 #undef UNLOAD_MAT44 1792 #define UNLOAD_MAT44(AA,a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34) \ 1793 ( a11=AA.m[0][0] , a12=AA.m[0][1] , a13=AA.m[0][2] , a14=AA.m[0][3] , \ 1794 a21=AA.m[1][0] , a22=AA.m[1][1] , a23=AA.m[1][2] , a24=AA.m[1][3] , \ 1795 a31=AA.m[2][0] , a32=AA.m[2][1] , a33=AA.m[2][2] , a34=AA.m[2][3] ) 1796 1797 #undef UNLOAD_MAT44_AR 1798 #define UNLOAD_MAT44_AR(AA,vv) \ 1799 UNLOAD_MAT44(AA,(vv)[0],(vv)[1],(vv)[2],(vv)[3],(vv)[4 ],(vv)[5 ], \ 1800 (vv)[6],(vv)[7],(vv)[8],(vv)[9],(vv)[10],(vv)[11] ) 1801 1802 #undef LOAD_MAT44_AR 1803 #define LOAD_MAT44_AR(AA,vv) \ 1804 LOAD_MAT44(AA,(vv)[0],(vv)[1],(vv)[2],(vv)[3],(vv)[4 ],(vv)[5 ], \ 1805 (vv)[6],(vv)[7],(vv)[8],(vv)[9],(vv)[10],(vv)[11] ) 1806 1807 #undef UNLOAD_MAT33 1808 #define UNLOAD_MAT33(AA,a11,a12,a13,a21,a22,a23,a31,a32,a33) \ 1809 ( a11=AA.m[0][0] , a12=AA.m[0][1] , a13=AA.m[0][2] , \ 1810 a21=AA.m[1][0] , a22=AA.m[1][1] , a23=AA.m[1][2] , \ 1811 a31=AA.m[2][0] , a32=AA.m[2][1] , a33=AA.m[2][2] ) 1812 1813 #undef UNLOAD_MAT33_AR 1814 #define UNLOAD_MAT33_AR(AA,vv) \ 1815 UNLOAD_MAT33(AA,(vv)[0],(vv)[1],(vv)[2],(vv)[3], \ 1816 (vv)[4],(vv)[5],(vv)[6],(vv)[7],(vv)[8] ) 1817 1818 /* negate the top 2 rows of a mat44 matrix 1819 (for transforming between NIfTI-1 and DICOM coord systems) */ 1820 1821 #undef XYINVERT_MAT44 1822 #define XYINVERT_MAT44(AA) \ 1823 ( AA.m[0][0] = -AA.m[0][0] , AA.m[0][1] = -AA.m[0][1] , \ 1824 AA.m[0][2] = -AA.m[0][2] , AA.m[0][3] = -AA.m[0][3] , \ 1825 AA.m[1][0] = -AA.m[1][0] , AA.m[1][1] = -AA.m[1][1] , \ 1826 AA.m[1][2] = -AA.m[1][2] , AA.m[1][3] = -AA.m[1][3] ) 1827 1828 #undef MAT44_SUB 1829 #define MAT44_SUB(AA,BB) \ 1830 ( tempA_mat44.m[0][0] = (AA).m[0][0] - (BB).m[0][0] , \ 1831 tempA_mat44.m[1][0] = (AA).m[1][0] - (BB).m[1][0] , \ 1832 tempA_mat44.m[2][0] = (AA).m[2][0] - (BB).m[2][0] , \ 1833 tempA_mat44.m[3][0] = (AA).m[3][0] - (BB).m[3][0] , \ 1834 tempA_mat44.m[0][1] = (AA).m[0][1] - (BB).m[0][1] , \ 1835 tempA_mat44.m[1][1] = (AA).m[1][1] - (BB).m[1][1] , \ 1836 tempA_mat44.m[2][1] = (AA).m[2][1] - (BB).m[2][1] , \ 1837 tempA_mat44.m[3][1] = (AA).m[3][1] - (BB).m[3][1] , \ 1838 tempA_mat44.m[0][2] = (AA).m[0][2] - (BB).m[0][2] , \ 1839 tempA_mat44.m[1][2] = (AA).m[1][2] - (BB).m[1][2] , \ 1840 tempA_mat44.m[2][2] = (AA).m[2][2] - (BB).m[2][2] , \ 1841 tempA_mat44.m[3][2] = (AA).m[3][2] - (BB).m[3][2] , \ 1842 tempA_mat44.m[0][3] = (AA).m[0][3] - (BB).m[0][3] , \ 1843 tempA_mat44.m[1][3] = (AA).m[1][3] - (BB).m[1][3] , \ 1844 tempA_mat44.m[2][3] = (AA).m[2][3] - (BB).m[2][3] , \ 1845 tempA_mat44.m[3][3] = (AA).m[3][3] - (BB).m[3][3] , tempA_mat44 ) 1846 1847 #undef MAT44_NORM 1848 #define MAT44_NORM(AA) \ 1849 sqrt( (AA).m[0][0]*(AA).m[0][0] + \ 1850 (AA).m[0][1]*(AA).m[0][1] + \ 1851 (AA).m[0][2]*(AA).m[0][2] + \ 1852 (AA).m[0][3]*(AA).m[0][3] + \ 1853 (AA).m[1][0]*(AA).m[1][0] + \ 1854 (AA).m[1][1]*(AA).m[1][1] + \ 1855 (AA).m[1][2]*(AA).m[1][2] + \ 1856 (AA).m[1][3]*(AA).m[1][3] + \ 1857 (AA).m[2][0]*(AA).m[2][0] + \ 1858 (AA).m[2][1]*(AA).m[2][1] + \ 1859 (AA).m[2][2]*(AA).m[2][2] + \ 1860 (AA).m[2][3]*(AA).m[2][3] + \ 1861 (AA).m[3][0]*(AA).m[3][0] + \ 1862 (AA).m[3][1]*(AA).m[3][1] + \ 1863 (AA).m[3][2]*(AA).m[3][2] + \ 1864 (AA).m[3][3]*(AA).m[3][3] ) 1865 1866 #undef MAT44_COLNORM 1867 #define MAT44_COLNORM(AA,j) \ 1868 sqrt( (AA).m[0][(j)]*(AA).m[0][(j)] + \ 1869 (AA).m[1][(j)]*(AA).m[1][(j)] + \ 1870 (AA).m[2][(j)]*(AA).m[2][(j)] ) 1871 1872 #undef MAT44_ROWNORM 1873 #define MAT44_ROWNORM(i) \ 1874 sqrt( (AA).m[(i)][0]*(AA).m[(i)][0] + \ 1875 (AA).m[(i)][1]*(AA).m[(i)][1] + \ 1876 (AA).m[(i)][2]*(AA).m[(i)][2] ) 1877 1878 /* load a mat33 matrix */ 1879 1880 #undef LOAD_MAT33 1881 #define LOAD_MAT33(AA,a11,a12,a13,a21,a22,a23,a31,a32,a33) \ 1882 ( AA.m[0][0]=a11 , AA.m[0][1]=a12 , AA.m[0][2]=a13 , \ 1883 AA.m[1][0]=a21 , AA.m[1][1]=a22 , AA.m[1][2]=a23 , \ 1884 AA.m[2][0]=a31 , AA.m[2][1]=a32 , AA.m[2][2]=a33 ) 1885 1886 /* fill a mat33 with zeros */ 1887 1888 #undef LOAD_ZERO_MAT33 1889 #define LOAD_ZERO_MAT33(AA) LOAD_MAT33(AA,0,0,0,0,0,0,0,0,0) 1890 1891 /* fill a mat33 with the identity matrix */ 1892 1893 #undef LOAD_IDENT_MAT33 1894 #define LOAD_IDENT_MAT33(AA) \ 1895 LOAD_MAT33( AA , 1,0,0, 0,1,0 , 0,0,1 ) 1896 1897 /* copy the upper left corner of a mat44 struct into a mat33 struct */ 1898 1899 #undef MAT44_TO_MAT33 1900 #define MAT44_TO_MAT33(AA,BB) \ 1901 LOAD_MAT33(BB,AA.m[0][0],AA.m[0][1],AA.m[0][2], \ 1902 AA.m[1][0],AA.m[1][1],AA.m[1][2], \ 1903 AA.m[2][0],AA.m[2][1],AA.m[2][2] ) 1904 1905 /* the reverse: copy mat33 to mat44 upper left corner */ 1906 1907 #undef MAT33_TO_MAT44 1908 #define MAT33_TO_MAT44(AA,BB) \ 1909 LOAD_MAT44(BB,AA.m[0][0],AA.m[0][1],AA.m[0][2],0.0f, \ 1910 AA.m[1][0],AA.m[1][1],AA.m[1][2],0.0f, \ 1911 AA.m[2][0],AA.m[2][1],AA.m[2][2],0.0f ) 1912 1913 /* cf. vecmat.h */ 1914 1915 #undef VECMAT_TO_MAT44 1916 #define VECMAT_TO_MAT44(vm,AA) \ 1917 LOAD_MAT44(AA,vm.mm.mat[0][0],vm.mm.mat[0][1],vm.mm.mat[0][2],vm.vv.xyz[0], \ 1918 vm.mm.mat[1][0],vm.mm.mat[1][1],vm.mm.mat[1][2],vm.vv.xyz[1], \ 1919 vm.mm.mat[2][0],vm.mm.mat[2][1],vm.mm.mat[2][2],vm.vv.xyz[2] ) 1920 1921 #undef MAT44_TO_VECMAT 1922 #define MAT44_TO_VECMAT(AA,vm) \ 1923 UNLOAD_MAT44(AA,vm.mm.mat[0][0],vm.mm.mat[0][1],vm.mm.mat[0][2],vm.vv.xyz[0], \ 1924 vm.mm.mat[1][0],vm.mm.mat[1][1],vm.mm.mat[1][2],vm.vv.xyz[1], \ 1925 vm.mm.mat[2][0],vm.mm.mat[2][1],vm.mm.mat[2][2],vm.vv.xyz[2] ) 1926 1927 /* apply a mat44 matrix to a 3 vector (x,y,z) to produce (a,b,c) */ 1928 1929 #undef MAT44_VEC 1930 #define MAT44_VEC(AA,x,y,z,a,b,c) \ 1931 ( (a) = AA.m[0][0]*(x) + AA.m[0][1]*(y) + AA.m[0][2]*(z) + AA.m[0][3] , \ 1932 (b) = AA.m[1][0]*(x) + AA.m[1][1]*(y) + AA.m[1][2]*(z) + AA.m[1][3] , \ 1933 (c) = AA.m[2][0]*(x) + AA.m[2][1]*(y) + AA.m[2][2]*(z) + AA.m[2][3] ) 1934 1935 /* apply a mat33 matrix to a 3 vector (x,y,z) to produce (a,b,c); 1936 could also be used to apply the upper left 3x3 1937 corner of a mat44 matrix to (x,y,z), if you insist */ 1938 1939 #undef MAT33_VEC 1940 #define MAT33_VEC(AA,x,y,z,a,b,c) \ 1941 ( (a) = AA.m[0][0]*(x) + AA.m[0][1]*(y) + AA.m[0][2]*(z) , \ 1942 (b) = AA.m[1][0]*(x) + AA.m[1][1]*(y) + AA.m[1][2]*(z) , \ 1943 (c) = AA.m[2][0]*(x) + AA.m[2][1]*(y) + AA.m[2][2]*(z) ) 1944 1945 /* L2 norm of i-th column of a matrix (3x3 or 4x4) */ 1946 1947 #undef MAT33_CLEN 1948 #define MAT33_CLEN(AA,i) \ 1949 sqrt(AA.m[0][i]*AA.m[0][i]+AA.m[1][i]*AA.m[1][i]+AA.m[2][i]*AA.m[2][i]) 1950 1951 #undef MAT44_CLEN 1952 #define MAT44_CLEN MAT33_CLEN 1953 1954 /* print a mat44 struct to stdout (with a string) */ 1955 1956 #undef DUMP_MAT44 1957 #define DUMP_MAT44(SS,AA) \ 1958 printf("# mat44 %s:\n" \ 1959 " %13.6f %13.6f %13.6f %13.6f\n" \ 1960 " %13.6f %13.6f %13.6f %13.6f\n" \ 1961 " %13.6f %13.6f %13.6f %13.6f\n" , \ 1962 SS, AA.m[0][0], AA.m[0][1], AA.m[0][2], AA.m[0][3], \ 1963 AA.m[1][0], AA.m[1][1], AA.m[1][2], AA.m[1][3], \ 1964 AA.m[2][0], AA.m[2][1], AA.m[2][2], AA.m[2][3] ) 1965 1966 // vecmat.h oddly already contains a DUMP_MAT33, but I want one with 1967 // less formatting. 1968 #undef DUMP_MAT33b 1969 #define DUMP_MAT33b(SS,AA) \ 1970 printf("# mat33 %s:\n" \ 1971 " %13.6f %13.6f %13.6f\n" \ 1972 " %13.6f %13.6f %13.6f\n" \ 1973 " %13.6f %13.6f %13.6f\n" , \ 1974 SS, AA.m[0][0], AA.m[0][1], AA.m[0][2], \ 1975 AA.m[1][0], AA.m[1][1], AA.m[1][2], \ 1976 AA.m[2][0], AA.m[2][1], AA.m[2][2] ) 1977 1978 #undef DUMP_MAT44_ONELINE 1979 #define DUMP_MAT44_ONELINE(AA) \ 1980 printf(" %13.6f %13.6f %13.6f %13.6f" \ 1981 " %13.6f %13.6f %13.6f %13.6f" \ 1982 " %13.6f %13.6f %13.6f %13.6f " , \ 1983 AA.m[0][0], AA.m[0][1], AA.m[0][2], AA.m[0][3], \ 1984 AA.m[1][0], AA.m[1][1], AA.m[1][2], AA.m[1][3], \ 1985 AA.m[2][0], AA.m[2][1], AA.m[2][2], AA.m[2][3] ) 1986 1987 /* modify the last column of a mat44 struct so that the 1988 same spatial coords apply to an image with pp,qq,rr 1989 elements added at the lower edges [01 Sep 2006 - RWCox] */ 1990 1991 #undef MAT44_EXTEND_IJK 1992 #define MAT44_EXTEND_IJK(AA,pp,qq,rr) \ 1993 ( AA.m[0][3] -= AA.m[0][0]*(pp)+AA.m[0][1]*(qq)+AA.m[0][2]*(rr) , \ 1994 AA.m[1][3] -= AA.m[1][0]*(pp)+AA.m[1][1]*(qq)+AA.m[1][2]*(rr) , \ 1995 AA.m[2][3] -= AA.m[2][0]*(pp)+AA.m[2][1]*(qq)+AA.m[2][2]*(rr) ) 1996 1997 /* elementary rotation matrices: 1998 rotate about axis #ff, from axis #aa toward #bb, 1999 where ff, aa, and bb are a permutation of {0,1,2} */ 2000 2001 #undef LOAD_ROTGEN_MAT44 2002 #define LOAD_ROTGEN_MAT44(AA,th,ff,aa,bb) \ 2003 ( AA.m[aa][aa] = AA.m[bb][bb] = cos((th)) , \ 2004 AA.m[aa][bb] = sin((th)) , \ 2005 AA.m[bb][aa] = -AA.m[aa][bb] , \ 2006 AA.m[ff][ff] = 1.0f , \ 2007 AA.m[aa][ff] = AA.m[bb][ff] = AA.m[ff][aa] = AA.m[ff][bb] = 0.0f , \ 2008 AA.m[0][3] = AA.m[1][3] = AA.m[2][3] = \ 2009 AA.m[3][0] = AA.m[3][1] = AA.m[3][2] = 0.0f , AA.m[3][3]=1.0f ) 2010 2011 2012 /* rotations about x,y,z axes, respectively */ 2013 2014 #undef LOAD_ROTX_MAT44 2015 #undef LOAD_ROTY_MAT44 2016 #undef LOAD_ROTZ_MAT44 2017 #define LOAD_ROTX_MAT44(A,th) LOAD_ROTGEN_MAT44(A,th,0,1,2) 2018 #define LOAD_ROTY_MAT44(A,th) LOAD_ROTGEN_MAT44(A,th,1,2,0) 2019 #define LOAD_ROTZ_MAT44(A,th) LOAD_ROTGEN_MAT44(A,th,2,0,1) 2020 2021 /* rotation about axis #i, for i=0,1,2 (x,y,z) */ 2022 2023 #undef LOAD_ROT_MAT44 2024 #define LOAD_ROT_MAT44(A,th,i) \ 2025 do{ switch( (i) ){ \ 2026 case 0: LOAD_ROTX_MAT44(A,th) ; break ; \ 2027 case 1: LOAD_ROTY_MAT44(A,th) ; break ; \ 2028 case 2: LOAD_ROTZ_MAT44(A,th) ; break ; \ 2029 default: LOAD_DIAG_MAT44(A,1,1,1); break ; \ 2030 } } while(0) 2031 2032 /* determinant (could be used on a mat44 or mat33 struct) */ 2033 2034 #undef MAT44_DET 2035 #define MAT44_DET(AA) \ 2036 ( AA.m[0][0]*AA.m[1][1]*AA.m[2][2] - AA.m[0][0]*AA.m[1][2]*AA.m[2][1] \ 2037 - AA.m[1][0]*AA.m[0][1]*AA.m[2][2] + AA.m[1][0]*AA.m[0][2]*AA.m[2][1] \ 2038 + AA.m[2][0]*AA.m[0][1]*AA.m[1][2] - AA.m[2][0]*AA.m[0][2]*AA.m[1][1] ) 2039 2040 /* trace */ 2041 2042 #undef MAT44_TRACE 2043 #define MAT44_TRACE(AA) ( AA.m[0][0] + AA.m[1][1] + AA.m[2][2] ) 2044 2045 /* scale */ 2046 2047 #undef MAT44_SCALE 2048 #define MAT44_SCALE(AA,ff) \ 2049 ( (AA).m[0][0] *= (ff), (AA).m[0][1] *= (ff), (AA).m[0][2] *= (ff), (AA).m[0][3] *= (ff), \ 2050 (AA).m[1][0] *= (ff), (AA).m[1][1] *= (ff), (AA).m[1][2] *= (ff), (AA).m[1][3] *= (ff), \ 2051 (AA).m[2][0] *= (ff), (AA).m[2][1] *= (ff), (AA).m[2][2] *= (ff), (AA).m[2][3] *= (ff) ) 2052 2053 /* scale */ 2054 2055 #undef MAT33_SCALE 2056 #define MAT33_SCALE(AA,ff) \ 2057 ( (AA).m[0][0] *= (ff), (AA).m[0][1] *= (ff), (AA).m[0][2] *= (ff), \ 2058 (AA).m[1][0] *= (ff), (AA).m[1][1] *= (ff), (AA).m[1][2] *= (ff), \ 2059 (AA).m[2][0] *= (ff), (AA).m[2][1] *= (ff), (AA).m[2][2] *= (ff) ) 2060 2061 /* add */ 2062 2063 #undef MAT44_SUM 2064 #define MAT44_SUM(AA,ff,BB,gg) \ 2065 ( tempA_mat44.m[0][0] = (AA).m[0][0]*(ff) + (BB).m[0][0]*(gg) , \ 2066 tempA_mat44.m[0][1] = (AA).m[0][1]*(ff) + (BB).m[0][1]*(gg) , \ 2067 tempA_mat44.m[0][2] = (AA).m[0][2]*(ff) + (BB).m[0][2]*(gg) , \ 2068 tempA_mat44.m[0][3] = (AA).m[0][3]*(ff) + (BB).m[0][3]*(gg) , \ 2069 tempA_mat44.m[1][0] = (AA).m[1][0]*(ff) + (BB).m[1][0]*(gg) , \ 2070 tempA_mat44.m[1][1] = (AA).m[1][1]*(ff) + (BB).m[1][1]*(gg) , \ 2071 tempA_mat44.m[1][2] = (AA).m[1][2]*(ff) + (BB).m[1][2]*(gg) , \ 2072 tempA_mat44.m[1][3] = (AA).m[1][3]*(ff) + (BB).m[1][3]*(gg) , \ 2073 tempA_mat44.m[2][0] = (AA).m[2][0]*(ff) + (BB).m[2][0]*(gg) , \ 2074 tempA_mat44.m[2][1] = (AA).m[2][1]*(ff) + (BB).m[2][1]*(gg) , \ 2075 tempA_mat44.m[2][2] = (AA).m[2][2]*(ff) + (BB).m[2][2]*(gg) , \ 2076 tempA_mat44.m[2][3] = (AA).m[2][3]*(ff) + (BB).m[2][3]*(gg) , tempA_mat44 ) 2077 2078 /* add */ 2079 2080 #undef MAT33_SUM 2081 #define MAT33_SUM(AA,ff,BB,gg) \ 2082 ( tempZ_mat33.m[0][0] = (AA).m[0][0]*(ff) + (BB).m[0][0]*(gg) , \ 2083 tempZ_mat33.m[0][1] = (AA).m[0][1]*(ff) + (BB).m[0][1]*(gg) , \ 2084 tempZ_mat33.m[0][2] = (AA).m[0][2]*(ff) + (BB).m[0][2]*(gg) , \ 2085 tempZ_mat33.m[1][0] = (AA).m[1][0]*(ff) + (BB).m[1][0]*(gg) , \ 2086 tempZ_mat33.m[1][1] = (AA).m[1][1]*(ff) + (BB).m[1][1]*(gg) , \ 2087 tempZ_mat33.m[1][2] = (AA).m[1][2]*(ff) + (BB).m[1][2]*(gg) , \ 2088 tempZ_mat33.m[2][0] = (AA).m[2][0]*(ff) + (BB).m[2][0]*(gg) , \ 2089 tempZ_mat33.m[2][1] = (AA).m[2][1]*(ff) + (BB).m[2][1]*(gg) , \ 2090 tempZ_mat33.m[2][2] = (AA).m[2][2]*(ff) + (BB).m[2][2]*(gg) , tempZ_mat33 ) 2091 2092 /*---------------------------------------------------------------------*/ 2093 /*--- Macros to work on augmented ([4][4]) affine transforms ----*/ 2094 #undef AFF44_IDENT 2095 #define AFF44_IDENT( M ) {\ 2096 M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1.0; \ 2097 M[0][1] = M[0][2] = M[0][3] = \ 2098 M[1][0] = M[1][2] = M[1][3] = \ 2099 M[2][0] = M[2][1] = M[2][3] = \ 2100 M[3][0] = M[3][1] = M[3][2] = 0.0;\ 2101 } 2102 2103 #undef AFF44_ZERO 2104 #define AFF44_ZERO( M ) {\ 2105 M[0][0] = M[1][1] = M[2][2] = M[3][3] = \ 2106 M[0][1] = M[0][2] = M[0][3] = \ 2107 M[1][0] = M[1][2] = M[1][3] = \ 2108 M[2][0] = M[2][1] = M[2][3] = \ 2109 M[3][0] = M[3][1] = M[3][2] = 0.0;\ 2110 } 2111 2112 #undef AFF44_CARD_LOAD 2113 #define AFF44_CARD_LOAD( M , d0, d1, d2) {\ 2114 M[0][0] = d0; M[1][1] = d1; M[2][2] = d2; M[3][3] = 1.0;\ 2115 M[0][1] = M[0][2] = M[0][3] = \ 2116 M[1][0] = M[1][2] = M[1][3] = \ 2117 M[2][0] = M[2][1] = M[2][3] = \ 2118 M[3][0] = M[3][1] = M[3][2] = 0.0;\ 2119 } 2120 2121 #undef AFF44_TO_V12 2122 #define AFF44_TO_V12( V, M ) { \ 2123 V[0] = M[0][0]; V[1] = M[0][1]; V[2] = M[0][2]; V[3] = M[0][3]; \ 2124 V[4] = M[1][0]; V[5] = M[1][1]; V[6] = M[1][2]; V[7] = M[1][3]; \ 2125 V[8] = M[2][0]; V[9] = M[2][1]; V[10] = M[2][2]; V[11] = M[2][3]; \ 2126 } 2127 2128 #undef V12_TO_AFF44 2129 #define V12_TO_AFF44( M, V) { \ 2130 M[0][0] = V[0]; M[0][1] = V[1]; M[0][2] = V[2]; M[0][3] = V[3]; \ 2131 M[1][0] = V[4]; M[1][1] = V[5]; M[1][2] = V[6]; M[1][3] = V[7]; \ 2132 M[2][0] = V[8]; M[2][1] = V[9]; M[2][2] = V[10]; M[2][3] = V[11]; \ 2133 M[3][0] = 0.0; M[3][1] = 0.0; M[3][2] = 0.0; M[3][3] = 1.0; \ 2134 } 2135 2136 #undef AFF44_MULT_I 2137 #define AFF44_MULT_I( X, M, I ) { \ 2138 X[0] = M[0][0]*I[0] + M[0][1]*I[1] + M[0][2]*I[2] + M[0][3]; \ 2139 X[1] = M[1][0]*I[0] + M[1][1]*I[1] + M[1][2]*I[2] + M[1][3]; \ 2140 X[2] = M[2][0]*I[0] + M[2][1]*I[1] + M[2][2]*I[2] + M[2][3]; \ 2141 } 2142 2143 /* This macro is for transforming a direction D, rather than 2144 a point in I */ 2145 #undef AFF44_MULT_D 2146 #define AFF44_MULT_D( X, M, D ) { \ 2147 X[0] = M[0][0]*D[0] + M[0][1]*D[1] + M[0][2]*D[2]; \ 2148 X[1] = M[1][0]*D[0] + M[1][1]*D[1] + M[1][2]*D[2]; \ 2149 X[2] = M[2][0]*D[0] + M[2][1]*D[1] + M[2][2]*D[2]; \ 2150 } 2151 2152 #undef AFF44_MULT 2153 #define AFF44_MULT( M, A, B ) {\ 2154 int i,j ; \ 2155 for( i=0 ; i < 3 ; i++ ) \ 2156 for( j=0 ; j < 4 ; j++ ) \ 2157 M[i][j] = A[i][0] * B[0][j] + A[i][1] * B[1][j] \ 2158 + A[i][2] * B[2][j] + A[i][3] * B[3][j] ; \ 2159 M[3][0] = M[3][1] = M[3][2] = 0.0 ; M[3][3] = 1.0 ; \ 2160 } 2161 2162 #undef MAT44_COPY 2163 #define MAT44_COPY( C, A ) {\ 2164 int i,j ; \ 2165 for( i=0 ; i < 4 ; i++ ) \ 2166 for( j=0 ; j < 4 ; j++ ) \ 2167 C.m[i][j] = A.m[i][j] ; \ 2168 } 2169 2170 #undef AFF44_COPY 2171 #define AFF44_COPY( C, A ) {\ 2172 int i,j ; \ 2173 for( i=0 ; i < 4 ; i++ ) \ 2174 for( j=0 ; j < 4 ; j++ ) \ 2175 C[i][j] = A[i][j] ; \ 2176 } 2177 2178 #undef MAT44_TO_AFF44 2179 #define MAT44_TO_AFF44( A, M ) {\ 2180 int i,j ; \ 2181 for( i=0 ; i < 4 ; i++ ) \ 2182 for( j=0 ; j < 4 ; j++ ) \ 2183 A[i][j] = M.m[i][j] ; \ 2184 } 2185 2186 #undef AFF44_TO_MAT44 2187 #define AFF44_TO_MAT44( M, A ) {\ 2188 int i,j ; \ 2189 for( i=0 ; i < 4 ; i++ ) \ 2190 for( j=0 ; j < 4 ; j++ ) \ 2191 M.m[i][j] = A[i][j] ; \ 2192 } 2193 2194 #undef AFF44_INV 2195 #define AFF44_INV( Ai, A ) {\ 2196 mat44 M, Mi; \ 2197 AFF44_TO_MAT44( M, A ); \ 2198 Mi = MAT44_INV( M ); \ 2199 MAT44_TO_AFF44 ( Ai, Mi ); \ 2200 } 2201 2202 2203 #undef AFF44_LOAD 2204 #define AFF44_LOAD( C, a,b,c,d, e,f,g,h, i,j,k,l ) {\ 2205 C[0][0]=a; C[0][1]=b; C[0][2]=c; C[0][3]=d; \ 2206 C[1][0]=e; C[1][1]=f; C[1][2]=g; C[1][3]=h; \ 2207 C[2][0]=i; C[2][1]=j; C[2][2]=k; C[2][3]=l; \ 2208 C[3][0]=0; C[3][1]=0; C[3][2]=0; C[3][3]=1; \ 2209 } 2210 2211 /* Change transform matrix so that it applies to RAI space 2212 rather than LPI or vice versa. */ 2213 #undef AFF44_LPI_RAI_FLIP 2214 #define AFF44_LPI_RAI_FLIP( M , A ) { \ 2215 double F[4][4], T[4][4]; \ 2216 AFF44_LOAD( F , -1,0,0,0 , 0,-1,0,0 , 0,0,1,0 ); \ 2217 AFF44_MULT( T , F , A ); \ 2218 AFF44_MULT( M , T , F ); \ 2219 } 2220 2221 /* Show the matrix */ 2222 #undef AFF44_SHOW 2223 #define AFF44_SHOW( A , str) { \ 2224 if (str) fprintf(stderr,"%s\n", str); \ 2225 fprintf(stderr,"%f\t%f\t%f\t%f\n" \ 2226 "%f\t%f\t%f\t%f\n" \ 2227 "%f\t%f\t%f\t%f\n" \ 2228 "%f\t%f\t%f\t%f\n", \ 2229 A[0][0], A[0][1], A[0][2], A[0][3], \ 2230 A[1][0], A[1][1], A[1][2], A[1][3], \ 2231 A[2][0], A[2][1], A[2][2], A[2][3], \ 2232 A[3][0], A[3][1], A[3][2], A[3][3]); \ 2233 } 2234 2235 /*---------------------------------------------------------------------*/ 2236 /*--- data structure for information about time axis of 3D dataset ----*/ 2237 2238 #define TIMEAXIS_TYPE 907 2239 2240 #define UNITS_MSEC_TYPE 77001 2241 #define UNITS_SEC_TYPE 77002 2242 #define UNITS_HZ_TYPE 77003 2243 2244 static char * UNITS_TYPE_labelstring[] = { "ms" , "s" , "Hz" } ; 2245 2246 /*! Return a string for the units of the uu-th time unit type. */ 2247 2248 #define UNITS_TYPE_LABEL(uu) ( ((uu)<UNITS_MSEC_TYPE || (uu)>UNITS_HZ_TYPE) ? \ 2249 "none" : \ 2250 UNITS_TYPE_labelstring[(uu)-UNITS_MSEC_TYPE] ) 2251 2252 /*! Struct to hold information about the time axis of a 3D+time datset. 2253 2254 For 3D+t datasets, there are ntt 3D times; the i-th one is centered 2255 at ttorg + ttdel*ii seconds, for ii=0..ntt-1. 2256 Also, ttdur = duration of each sample in time. 2257 2258 If ( nsl > 0 && toff_sl != NULL), then the data was acquired as 2259 slices, not as a 3D block. The slicing direction must be the 2260 dataset (not DICOM) z-axis. The extra offset for the data at 2261 z is given by computing isl = (z - zorg_sl) / dz_sl + 0.5; the 2262 extra offset is then toff_sl[isl]. Note that dz_sl might be 2263 different from the dataxes zzdel because the dataset might actually 2264 be made up of duplicated slices (see program abut.c). 2265 2266 All this is computed using the routine THD_timeof(). 2267 2268 When transformed, all the slice stuff will be ignored. That's 2269 because the warped dataset z-direction will not be the same as the 2270 original dataset's z-direction. 2271 */ 2272 2273 typedef struct { 2274 int type ; /*!< TIMEAXIS_TYPE */ 2275 int ntt ; /*!< Number of time points */ 2276 float ttorg ; /*!< Time origin (usually 0) */ 2277 float ttdel ; /*!< Fondly known as TR */ 2278 float ttdur ; /*!< Duration of image acquisition (usually not known) */ 2279 2280 int units_type ; /*!< one of the UNITS_ codes */ 2281 2282 int nsl ; /*!< Number of slice-dependent time offsets */ 2283 float * toff_sl ; /*!< toff_sl[i] is time offset for slice #1 */ 2284 float zorg_sl ; /*!< z-coordinate origin for slice offsets */ 2285 float dz_sl ; /*!< z-coordinate spacing for slice offsets */ 2286 } THD_timeaxis ; 2287 2288 /*! Check if tax points to a valid THD_timeaxis struct. */ 2289 2290 #define ISVALID_TIMEAXIS(tax) ((tax) != NULL && (tax)->type == TIMEAXIS_TYPE) 2291 2292 /*---------------------------------------------------------------------*/ 2293 /*--------- data structure for statistics about a 3D dataset ----------*/ 2294 2295 #define STATISTICS_TYPE 17 2296 2297 /*! Statistics about data in a sub-brick. 2298 (e.g., Used in the Define Function control panel in AFNI.) 2299 */ 2300 2301 typedef struct { 2302 float min ; /*!< Smallest value in sub-brick */ 2303 float max ; /*!< Largest value in sub-brick */ 2304 } THD_brick_stats ; 2305 2306 /*! Collection of statistics about all sub-bricks. */ 2307 2308 typedef struct { 2309 int type ; /*!< STATISTICS_TYPE */ 2310 int nbstat ; /*!< Number of entries below */ 2311 THD_brick_stats *bstat ; /*!< Array of entries for all sub-bricks */ 2312 RwcPointer parent ; /*!< Owner of this object */ 2313 } THD_statistics ; 2314 2315 /*! Check if st is a valid THD_statistics struct. */ 2316 2317 #define ISVALID_STATISTIC(st) ( (st) != NULL && (st)->type == STATISTICS_TYPE ) 2318 2319 /*! Check if bst is a valid sub-brick statistic. */ 2320 2321 #define ISVALID_BSTAT(bst) ( (bst).min <= (bst).max ) 2322 2323 /*! Make bst have invalid data. */ 2324 2325 #define INVALIDATE_BSTAT(bst) ( (bst).min = 1.0 , (bst).max = -1.0 ) 2326 2327 /*! Destroy a THD_statistics struct. */ 2328 2329 #define KILL_STATISTIC(st) \ 2330 do{ if( ISVALID_STATISTIC(st) ){ \ 2331 RwcFree((char *)(st)->bstat) ; RwcFree((char *)(st)) ; } } while(0) 2332 2333 /*--------------------------------------------------------------------*/ 2334 2335 typedef struct { 2336 float hbot , htop , hdel ; int nbin ; 2337 int *hist ; 2338 } THD_histogram ; 2339 2340 #define HISTOGRAM_SET_TYPE 1743 2341 2342 typedef struct { 2343 int type ; 2344 int nbhist ; 2345 THD_histogram *bhist ; 2346 RwcPointer parent ; 2347 } THD_histogram_set ; 2348 2349 /*--------------------------------------------------------------------*/ 2350 /*-------------------- Unique ID code for a 3D dataset -------------*/ 2351 2352 #ifndef IDCODE_PREFIX 2353 # define MCW_IDPREFIX "NIH_" 2354 #else 2355 # define MCW_IDPREFIX IDCODE_PREFIX 2356 #endif 2357 2358 /*! Size of ID code string. 27 Sep 2001: increased from 16 to 32. */ 2359 #define MCW_IDSIZE 32 2360 2361 /*! Size of ID date string. */ 2362 #define MCW_IDDATE 48 2363 2364 /*! Struct to hold ID code for a dataset. */ 2365 2366 typedef struct { 2367 char str[MCW_IDSIZE] ; /*!< Unique ID code string */ 2368 char date[MCW_IDDATE] ; /*!< Date string was generated */ 2369 } MCW_idcode ; 2370 2371 extern MCW_idcode MCW_new_idcode (void) ; 2372 extern void MCW_hash_idcode( char *, struct THD_3dim_dataset * ) ; 2373 2374 /*! Check if 2 ID code strings are equal. */ 2375 2376 #define EQUIV_IDCODES(id,ie) (strncmp((id).str,(ie).str,MCW_IDSIZE) == 0) 2377 2378 /*! Check if 2 AFNI dataset pointers point to the same dataset struct. */ 2379 2380 #define EQUIV_DSETS(ds,es) \ 2381 ( (ds)==(es) || \ 2382 ((ds)!=NULL && (es)!=NULL && EQUIV_IDCODES((ds)->idcode,(es)->idcode)) ) 2383 2384 /*! Check if 2 AFNI dataset pointers are different but have the same ID codes. */ 2385 2386 #define DUPLICATE_DSETS(ds,es) \ 2387 ( (ds) != (es) && \ 2388 (ds) != NULL && \ 2389 (es) != NULL && EQUIV_IDCODES((ds)->idcode,(es)->idcode) ) 2390 2391 /*! Zero out the ID code. */ 2392 2393 #define ZERO_IDCODE(id) ((id).str[0] = (id).date[0] = '\0') 2394 2395 /*! Check if the ID code is zero. */ 2396 2397 #define ISZERO_IDCODE(id) ((id).str[0] == '\0') 2398 2399 #define ATRNAME_IDSTRING "IDCODE_STRING" 2400 #define ATRNAME_IDDATE "IDCODE_DATE" 2401 #define ATRNAME_IDANATPAR "IDCODE_ANAT_PARENT" 2402 #define ATRNAME_IDWARPPAR "IDCODE_WARP_PARENT" 2403 2404 /*----------------------------------------------------------------------*/ 2405 /*------------------- how to present the coordinates -------------------*/ 2406 2407 /*! How to present coordinates to the user (vs. the internal RAI/DICOM order). */ 2408 2409 typedef struct { 2410 int xxsign , yysign , zzsign , 2411 first , second , third , 2412 xxor , yyor , zzor ; 2413 char orcode[4] ; 2414 } THD_coorder ; 2415 2416 extern void THD_coorder_fill( char * , THD_coorder * ) ; 2417 extern void THD_dicom_to_coorder( THD_coorder *, float *, float *, float * ) ; 2418 extern void THD_coorder_to_dicom( THD_coorder *, float *, float *, float * ) ; 2419 2420 /*----------------------------------------------------------------------*/ 2421 /*-------------- internal data structure for a 3D dataset --------------*/ 2422 2423 /* dataset type codes and string */ 2424 2425 #define HEAD_ANAT_TYPE 0 2426 #define HEAD_ANAT_STR "3DIM_HEAD_ANAT" 2427 2428 #define HEAD_FUNC_TYPE 1 2429 #define HEAD_FUNC_STR "3DIM_HEAD_FUNC" 2430 2431 #define GEN_ANAT_TYPE 2 2432 #define GEN_ANAT_STR "3DIM_GEN_ANAT" 2433 2434 #define GEN_FUNC_TYPE 3 2435 #define GEN_FUNC_STR "3DIM_GEN_FUNC" 2436 2437 #define FIRST_3DIM_TYPE 0 2438 #define LAST_3DIM_TYPE 3 2439 2440 #define LONGEST_3DIM_TYPESTR strlen(HEAD_ANAT_STR) 2441 2442 static char * DATASET_typestr[] = { 2443 HEAD_ANAT_STR , HEAD_FUNC_STR , GEN_ANAT_STR , GEN_FUNC_STR 2444 } ; 2445 2446 /* view type codes, string, and viewcodes */ 2447 2448 #define VIEW_ORIGINAL_TYPE 0 2449 #define VIEW_ORIGINAL_STR "Original View" 2450 #define VIEW_ORIGINAL_CODE "orig" 2451 2452 #define VIEW_ACPCALIGNED_TYPE 1 2453 #define VIEW_ACPCALIGNED_STR "AC-PC Aligned" 2454 #define VIEW_ACPCALIGNED_CODE "acpc" 2455 2456 #define VIEW_TALAIRACH_TYPE 2 2457 #define VIEW_TALAIRACH_STR "Talairach View" 2458 #define VIEW_TALAIRACH_CODE "tlrc" 2459 2460 #define VIEW_REGISTERED_TYPE 3 2461 #define VIEW_REGISTERED_STR "Registered View" 2462 #define VIEW_REGISTERED_CODE "rgst" 2463 2464 /*#define oldsessions 1*/ 2465 #undef oldsessions 2466 #ifdef oldsessions 2467 #define FIRST_VIEW_TYPE 0 2468 #define LAST_VIEW_TYPE 2 2469 #define MAX_LAST_VIEW_TYPE 2 2470 #else 2471 #define FIRST_VIEW_TYPE 0 2472 #define LAST_VIEW_TYPE \ 2473 (int)((int)get_nspaces()-1) 2474 #define MAX_LAST_VIEW_TYPE 10 2475 #endif 2476 #define LONGEST_VIEW_TYPESTR strlen(VIEW_REGISTERED_STR) 2477 2478 static char * VIEW_typestr[] = { 2479 VIEW_ORIGINAL_STR , VIEW_ACPCALIGNED_STR , 2480 VIEW_TALAIRACH_STR , VIEW_REGISTERED_STR 2481 } ; 2482 2483 static char * VIEW_codestr[] = { 2484 VIEW_ORIGINAL_CODE , VIEW_ACPCALIGNED_CODE , 2485 VIEW_TALAIRACH_CODE , VIEW_REGISTERED_CODE 2486 } ; 2487 2488 /* function type codes, string, and prefixes */ 2489 2490 #define FUNC_FIM_TYPE 0 2491 #define FUNC_FIM_STR "Intensity" 2492 #define FUNC_FIM_PREFIX "fim" 2493 #define FUNC_FIM_LABEL "fim" 2494 #define FUNC_FIM_DESCRIPTOR "Functional Intensity" 2495 #define FUNC_FIM_MASK (1 << FUNC_FIM_TYPE) 2496 2497 /** old PAIR type retained for compatibility **/ 2498 2499 #define FUNC_PAIR_TYPE 1 2500 #define FUNC_PAIR_STR "Inten+Thr" 2501 #define FUNC_PAIR_PREFIX "fith" 2502 2503 #define FUNC_THR_TYPE FUNC_PAIR_TYPE 2504 #define FUNC_THR_STR FUNC_PAIR_STR 2505 #define FUNC_THR_PREFIX FUNC_PAIR_PREFIX 2506 #define FUNC_THR_TOP 1.0 /* maximum true value */ 2507 #define FUNC_THR_SCALE_SHORT 10000 /* stored short = this * true value */ 2508 #define FUNC_THR_SCALE_BYTE 100 /* stored byte = this * true value */ 2509 #define FUNC_THR_LABEL "Thr " /* <= 4 characters! */ 2510 #define FUNC_THR_DESCRIPTOR "Old style threshold" 2511 #define FUNC_THR_MASK (1 << FUNC_PAIR_TYPE) 2512 2513 #define FUNC_COR_TYPE 2 2514 #define FUNC_COR_STR "Inten+Cor" 2515 #define FUNC_COR_PREFIX "fico" 2516 #define FUNC_COR_TOP 1.0 2517 #define FUNC_COR_SCALE_SHORT 10000 2518 #define FUNC_COR_SCALE_BYTE 100 2519 #define FUNC_COR_LABEL "Corr" 2520 #define FUNC_COR_DESCRIPTOR "Correlation Coefficient" 2521 #define FUNC_COR_MASK (1 << FUNC_COR_TYPE) 2522 2523 #define FUNC_TT_TYPE 3 2524 #define FUNC_TT_STR "Inten+Ttest" 2525 #define FUNC_TT_PREFIX "fitt" 2526 #define FUNC_TT_TOP 10.0 2527 #define FUNC_TT_SCALE_SHORT 1000 2528 #define FUNC_TT_SCALE_BYTE 10 2529 #define FUNC_TT_LABEL "T-t " 2530 #define FUNC_TT_DESCRIPTOR "Student t-statistic" 2531 #define FUNC_TT_MASK (1 << FUNC_TT_TYPE) 2532 2533 /* 30 Oct 1996 */ 2534 #define FUNC_FT_TYPE 4 2535 #define FUNC_FT_STR "Inten+Ftest" 2536 #define FUNC_FT_PREFIX "fift" 2537 #define FUNC_FT_TOP 100.0 2538 #define FUNC_FT_SCALE_SHORT 100 2539 #define FUNC_FT_SCALE_BYTE 1 2540 #define FUNC_FT_LABEL "F-t " 2541 #define FUNC_FT_DESCRIPTOR "Fisher F-statistic" 2542 #define FUNC_FT_MASK (1 << FUNC_FT_TYPE) 2543 2544 /* 22 Jul 1997 */ 2545 #define FUNC_ZT_TYPE 5 2546 #define FUNC_ZT_STR "Inten+Ztest" 2547 #define FUNC_ZT_PREFIX "fizt" 2548 #define FUNC_ZT_TOP 10.0 2549 #define FUNC_ZT_SCALE_SHORT 1000 2550 #define FUNC_ZT_SCALE_BYTE 10 2551 #define FUNC_ZT_LABEL "Z-t " 2552 #define FUNC_ZT_DESCRIPTOR "Normal (Gaussian) Z" 2553 #define FUNC_ZT_MASK (1 << FUNC_ZT_TYPE) 2554 2555 /* 22 Jul 1997 */ 2556 #define FUNC_CT_TYPE 6 2557 #define FUNC_CT_STR "Inten+ChiSq" 2558 #define FUNC_CT_PREFIX "fict" 2559 #define FUNC_CT_TOP 100.0 2560 #define FUNC_CT_SCALE_SHORT 100 2561 #define FUNC_CT_SCALE_BYTE 1 2562 #define FUNC_CT_LABEL "ChiS" 2563 #define FUNC_CT_DESCRIPTOR "Chi-Squared statistic" 2564 #define FUNC_CT_MASK (1 << FUNC_CT_TYPE) 2565 2566 /* 22 Jul 1997 */ 2567 #define FUNC_BT_TYPE 7 2568 #define FUNC_BT_STR "Inten+Beta" 2569 #define FUNC_BT_PREFIX "fibt" 2570 #define FUNC_BT_TOP 1.0 2571 #define FUNC_BT_SCALE_SHORT 10000 2572 #define FUNC_BT_SCALE_BYTE 100 2573 #define FUNC_BT_LABEL "Beta" 2574 #define FUNC_BT_DESCRIPTOR "Beta Distribution" 2575 #define FUNC_BT_MASK (1 << FUNC_BT_TYPE) 2576 2577 /* 22 Jul 1997 */ 2578 #define FUNC_BN_TYPE 8 2579 #define FUNC_BN_STR "Inten+Binom" 2580 #define FUNC_BN_PREFIX "fibn" 2581 #define FUNC_BN_TOP 100.0 2582 #define FUNC_BN_SCALE_SHORT 100 2583 #define FUNC_BN_SCALE_BYTE 1 2584 #define FUNC_BN_LABEL "Bino" 2585 #define FUNC_BN_DESCRIPTOR "Binomial Distribution" 2586 #define FUNC_BN_MASK (1 << FUNC_BN_TYPE) 2587 2588 /* 22 Jul 1997 */ 2589 #define FUNC_GT_TYPE 9 2590 #define FUNC_GT_STR "Inten+Gamma" 2591 #define FUNC_GT_PREFIX "figt" 2592 #define FUNC_GT_TOP 10.0 2593 #define FUNC_GT_SCALE_SHORT 1000 2594 #define FUNC_GT_SCALE_BYTE 10 2595 #define FUNC_GT_LABEL "Gam " 2596 #define FUNC_GT_DESCRIPTOR "Gamma Distribution" 2597 #define FUNC_GT_MASK (1 << FUNC_GT_TYPE) 2598 2599 /* 22 Jul 1997 */ 2600 #define FUNC_PT_TYPE 10 2601 #define FUNC_PT_STR "Inten+Poisson" 2602 #define FUNC_PT_PREFIX "fipt" 2603 #define FUNC_PT_TOP 100.0 2604 #define FUNC_PT_SCALE_SHORT 100 2605 #define FUNC_PT_SCALE_BYTE 1 2606 #define FUNC_PT_LABEL "Pois" 2607 #define FUNC_PT_DESCRIPTOR "Poisson Distribution" 2608 #define FUNC_PT_MASK (1 << FUNC_PT_TYPE) 2609 2610 /* 30 Nov 1997 */ 2611 #define FUNC_BUCK_TYPE 11 2612 #define FUNC_BUCK_STR "Func-Bucket" 2613 #define FUNC_BUCK_PREFIX "fbuc" 2614 #define FUNC_BUCK_TOP 1.0 2615 #define FUNC_BUCK_SCALE_SHORT 1 2616 #define FUNC_BUCK_SCALE_BYTE 1 2617 #define FUNC_BUCK_LABEL "Buck" 2618 #define FUNC_BUCK_DESCRIPTOR "Function Bucket" 2619 #define FUNC_BUCK_MASK (1 << FUNC_BUCK_TYPE) 2620 2621 #define FIRST_FUNC_TYPE 0 2622 #define LAST_FUNC_TYPE 11 2623 2624 #define FIRST_STAT_TYPE 2 2625 #define LAST_STAT_TYPE 10 2626 2627 #define FUNC_ALL_MASK (FUNC_FIM_MASK | FUNC_THR_MASK | \ 2628 FUNC_COR_MASK | FUNC_TT_MASK | FUNC_FT_MASK | \ 2629 FUNC_ZT_MASK | FUNC_CT_MASK | FUNC_BT_MASK | \ 2630 FUNC_BN_MASK | FUNC_GT_MASK | FUNC_PT_MASK | \ 2631 FUNC_BUCK_MASK ) 2632 2633 #define LONGEST_FUNC_TYPESTR strlen(FUNC_PT_STR) 2634 2635 static char * FUNC_typestr[] = { 2636 FUNC_FIM_STR , FUNC_THR_STR , FUNC_COR_STR , FUNC_TT_STR , FUNC_FT_STR , 2637 FUNC_ZT_STR , FUNC_CT_STR , FUNC_BT_STR , 2638 FUNC_BN_STR , FUNC_GT_STR , FUNC_PT_STR , FUNC_BUCK_STR 2639 } ; 2640 2641 static char * FUNC_prefixstr[] = { 2642 FUNC_FIM_PREFIX , FUNC_THR_PREFIX , FUNC_COR_PREFIX , 2643 FUNC_TT_PREFIX , FUNC_FT_PREFIX , 2644 FUNC_ZT_PREFIX , FUNC_CT_PREFIX , FUNC_BT_PREFIX , 2645 FUNC_BN_PREFIX , FUNC_GT_PREFIX , FUNC_PT_PREFIX , FUNC_BUCK_PREFIX 2646 } ; 2647 2648 static float FUNC_topval[] = { 2649 1.0 , FUNC_THR_TOP , FUNC_COR_TOP , FUNC_TT_TOP , FUNC_FT_TOP , 2650 FUNC_ZT_TOP , FUNC_CT_TOP , FUNC_BT_TOP , 2651 FUNC_BN_TOP , FUNC_GT_TOP , FUNC_PT_TOP , FUNC_BUCK_TOP 2652 } ; 2653 2654 static int FUNC_scale_short[] = { 2655 1 , FUNC_THR_SCALE_SHORT , FUNC_COR_SCALE_SHORT , 2656 FUNC_TT_SCALE_SHORT , FUNC_FT_SCALE_SHORT , 2657 FUNC_ZT_SCALE_SHORT , FUNC_CT_SCALE_SHORT , FUNC_BT_SCALE_SHORT , 2658 FUNC_BN_SCALE_SHORT , FUNC_GT_SCALE_SHORT , FUNC_PT_SCALE_SHORT , 2659 FUNC_BUCK_SCALE_SHORT 2660 } ; 2661 2662 static int FUNC_scale_byte[] = { 2663 1 , FUNC_THR_SCALE_BYTE , FUNC_COR_SCALE_BYTE , 2664 FUNC_TT_SCALE_BYTE , FUNC_FT_SCALE_BYTE , 2665 FUNC_ZT_SCALE_BYTE , FUNC_CT_SCALE_BYTE , FUNC_BT_SCALE_BYTE , 2666 FUNC_BN_SCALE_BYTE , FUNC_GT_SCALE_BYTE , FUNC_PT_SCALE_BYTE , 2667 FUNC_BUCK_SCALE_BYTE 2668 } ; 2669 2670 static char * FUNC_label[] = { 2671 FUNC_FIM_LABEL , FUNC_THR_LABEL , FUNC_COR_LABEL , FUNC_TT_LABEL , FUNC_FT_LABEL , 2672 FUNC_ZT_LABEL , FUNC_CT_LABEL , FUNC_BT_LABEL , 2673 FUNC_BN_LABEL , FUNC_GT_LABEL , FUNC_PT_LABEL , FUNC_BUCK_LABEL 2674 } ; 2675 2676 static char * FUNC_descriptor[] = { 2677 FUNC_FIM_DESCRIPTOR , FUNC_THR_DESCRIPTOR , 2678 FUNC_COR_DESCRIPTOR , FUNC_TT_DESCRIPTOR , FUNC_FT_DESCRIPTOR , 2679 FUNC_ZT_DESCRIPTOR , FUNC_CT_DESCRIPTOR , FUNC_BT_DESCRIPTOR , 2680 FUNC_BN_DESCRIPTOR , FUNC_GT_DESCRIPTOR , FUNC_PT_DESCRIPTOR , 2681 FUNC_BUCK_DESCRIPTOR 2682 } ; 2683 2684 #define AFNI_FIRST_STATCODE FUNC_COR_TYPE 2685 #define AFNI_LAST_STATCODE FUNC_PT_TYPE 2686 2687 static int FUNC_nvals[] = { 1, 2,2,2,2,2,2,2,2,2,2, 1 } ; /* # in each dataset */ 2688 static int FUNC_ival_fim[] = { 0, 0,0,0,0,0,0,0,0,0,0, 0 } ; /* index of fim */ 2689 2690 #define FIMTHR 0 /* set = -1 to disable thresholding for FIM type - 06 Feb 2003 */ 2691 2692 static int FUNC_ival_thr[] = { FIMTHR, 1,1,1,1,1,1,1,1,1,1, 0 } ; /* index of thresh */ 2693 2694 #define FUNC_HAVE_FIM(ftyp) ((ftyp) >= 0 && \ 2695 (ftyp) <= LAST_FUNC_TYPE && FUNC_ival_fim[(ftyp)] >= 0) 2696 2697 #define FUNC_HAVE_THR(ftyp) ((ftyp) >= 0 && \ 2698 (ftyp) <= LAST_FUNC_TYPE && FUNC_ival_thr[(ftyp)] >= 0) 2699 2700 #define FUNC_IS_STAT(ftyp) ((ftyp) >= FIRST_STAT_TYPE && (ftyp) <= LAST_STAT_TYPE) 2701 #define FUNC_HAVE_PVAL FUNC_IS_STAT 2702 2703 #define STAT_SIDES(fcod) \ 2704 ( !FUNC_IS_STAT(fcod) ? 0 \ 2705 : ((fcod)==FUNC_COR_TYPE || (fcod)==FUNC_TT_TYPE || (fcod)==FUNC_ZT_TYPE) ? 2 : 1 ) 2706 2707 /******* dimension of auxiliary array for functional statistics *******/ 2708 2709 #define MAX_STAT_AUX 64 2710 2711 /*! Number of statistical parameters needed for each statistic code. */ 2712 2713 static int FUNC_need_stat_aux[] = { 0 , 0 , 3 , 1 , 2 , 2714 0 , 1 , 2 , 2 , 2 , 1 , 2715 0 } ; /* # aux data needed */ 2716 2717 /*! Labels describing the parameters needed for each statistic code. */ 2718 2719 static char * FUNC_label_stat_aux[] = { 2720 "N/A" , "N/A" , /* fim, fith */ 2721 "SAMPLES FIT-PARAMETERS ORT-PARAMETERS" , /* fico */ 2722 "DEGREES-of-FREEDOM" , /* fitt */ 2723 "NUMERATOR and DENOMINATOR DEGREES-of-FREEDOM" , /* fift */ 2724 "N/A" , /* fizt */ 2725 "DEGREES-of-FREEDOM" , /* fict */ 2726 "A (numerator) and B (denominator)" , /* fibt */ 2727 "NUMBER-of-TRIALS and PROBABILITY-per-TRIAL" , /* fibn */ 2728 "SHAPE and SCALE" , /* figt */ 2729 "MEAN" , /* fipt */ 2730 "N/A" /* fbuc */ 2731 } ; 2732 2733 /*** stat_aux values: 2734 FUNC_FIM_TYPE = not used 2735 FUNC_THR_TYPE = not used 2736 FUNC_COR_TYPE = # samples, # fit parameters, # ort parameters 2737 FUNC_TT_TYPE = # degrees of freedom 2738 FUNC_FT_TYPE = DOF for numerator and denominator 2739 FUNC_ZT_TYPE = not used 2740 FUNC_CT_TYPE = DOF 2741 FUNC_BT_TYPE = a and b parameters 2742 FUNC_BN_TYPE = number of trials, and probability per trial 2743 FUNC_GT_TYPE = shape and scale parameters 2744 FUNC_PT_TYPE = mean of Poisson distribution 2745 FUNC_BUCK_TYPE = not used 2746 ***********************************************************************/ 2747 2748 /**** anatomy type codes, strings, and prefixes ****/ 2749 /* (these are not used much at present, but may be someday) */ 2750 2751 #define ANAT_SPGR_TYPE 0 2752 #define ANAT_SPGR_STR "Spoiled GRASS" 2753 #define ANAT_SPGR_PREFIX "spgr" 2754 #define ANAT_SPGR_MASK (1 << ANAT_SPGR_TYPE) 2755 2756 #define ANAT_FSE_TYPE 1 2757 #define ANAT_FSE_STR "Fast Spin Echo" 2758 #define ANAT_FSE_PREFIX "fse" 2759 #define ANAT_FSE_MASK (1 << ANAT_FSE_TYPE) 2760 2761 #define ANAT_EPI_TYPE 2 2762 #define ANAT_EPI_STR "Echo Planar" 2763 #define ANAT_EPI_PREFIX "epan" 2764 #define ANAT_EPI_MASK (1 << ANAT_EPI_TYPE) 2765 2766 #define ANAT_MRAN_TYPE 3 2767 #define ANAT_MRAN_STR "MRI Anatomy" 2768 #define ANAT_MRAN_PREFIX "anat" 2769 #define ANAT_MRAN_MASK (1 << ANAT_MRAN_TYPE) 2770 2771 #define ANAT_CT_TYPE 4 2772 #define ANAT_CT_STR "CT Scan" 2773 #define ANAT_CT_PREFIX "ct" 2774 #define ANAT_CT_MASK (1 << ANAT_CT_TYPE) 2775 2776 #define ANAT_SPECT_TYPE 5 2777 #define ANAT_SPECT_STR "SPECT Anatomy" 2778 #define ANAT_SPECT_PREFIX "spct" 2779 #define ANAT_SPECT_MASK (1 << ANAT_SPECT_TYPE) 2780 2781 #define ANAT_PET_TYPE 6 2782 #define ANAT_PET_STR "PET Anatomy" 2783 #define ANAT_PET_PREFIX "pet" 2784 #define ANAT_PET_MASK (1 << ANAT_PET_TYPE) 2785 2786 #define ANAT_MRA_TYPE 7 2787 #define ANAT_MRA_STR "MR Angiography" 2788 #define ANAT_MRA_PREFIX "mra" 2789 #define ANAT_MRA_MASK (1 << ANAT_MRA_TYPE) 2790 2791 #define ANAT_BMAP_TYPE 8 2792 #define ANAT_BMAP_STR "B-field Map" 2793 #define ANAT_BMAP_PREFIX "bmap" 2794 #define ANAT_BMAP_MASK (1 << ANAT_BMAP_TYPE) 2795 2796 #define ANAT_DIFF_TYPE 9 2797 #define ANAT_DIFF_STR "Diffusion Map" 2798 #define ANAT_DIFF_PREFIX "diff" 2799 #define ANAT_DIFF_MASK (1 << ANAT_DIFF_TYPE) 2800 2801 #define ANAT_OMRI_TYPE 10 2802 #define ANAT_OMRI_STR "Other MRI" 2803 #define ANAT_OMRI_PREFIX "omri" 2804 #define ANAT_OMRI_MASK (1 << ANAT_OMRI_TYPE) 2805 2806 #define ANAT_BUCK_TYPE 11 2807 #define ANAT_BUCK_STR "Anat Bucket" 2808 #define ANAT_BUCK_PREFIX "abuc" 2809 #define ANAT_BUCK_MASK (1 << ANAT_BUCK_TYPE) 2810 2811 #define ANAT_MAPC_TYPE 12 2812 #define ANAT_MAPC_STR "Mapped Color" 2813 #define ANAT_MAPC_PREFIX "mapc" 2814 #define ANAT_MAPC_MASK (1 << ANAT_MAPC_TYPE) 2815 2816 #define FIRST_ANAT_TYPE 0 2817 #define LAST_ANAT_TYPE 11 2818 2819 #define ANAT_ALL_MASK ( ANAT_SPGR_MASK | ANAT_FSE_MASK | ANAT_EPI_MASK | \ 2820 ANAT_MRAN_MASK | ANAT_CT_MASK | ANAT_SPECT_MASK | \ 2821 ANAT_PET_MASK | ANAT_MRA_MASK | ANAT_BMAP_MASK | \ 2822 ANAT_DIFF_MASK | ANAT_OMRI_MASK| ANAT_BUCK_MASK | \ 2823 ANAT_MAPC_MASK ) 2824 2825 #define NUM_DSET_TYPES (LAST_FUNC_TYPE + LAST_ANAT_TYPE + 2) 2826 2827 #define LONGEST_ANAT_TYPESTR strlen(ANAT_MRA_STR) 2828 2829 static char * ANAT_typestr[] = { 2830 ANAT_SPGR_STR , ANAT_FSE_STR , ANAT_EPI_STR , ANAT_MRAN_STR , 2831 ANAT_CT_STR , ANAT_SPECT_STR , ANAT_PET_STR , 2832 ANAT_MRA_STR , ANAT_BMAP_STR , ANAT_DIFF_STR , ANAT_OMRI_STR , 2833 ANAT_BUCK_STR , ANAT_MAPC_STR 2834 } ; 2835 2836 static char * ANAT_prefixstr[] = { 2837 ANAT_SPGR_PREFIX , ANAT_FSE_PREFIX , ANAT_EPI_PREFIX , ANAT_MRAN_PREFIX , 2838 ANAT_CT_PREFIX , ANAT_SPECT_PREFIX , ANAT_PET_PREFIX , 2839 ANAT_MRA_PREFIX , ANAT_BMAP_PREFIX , ANAT_DIFF_PREFIX , ANAT_OMRI_PREFIX , 2840 ANAT_BUCK_PREFIX , ANAT_MAPC_PREFIX 2841 } ; 2842 2843 /* Feb 1998: put all together */ 2844 2845 static char * DSET_prefixstr[NUM_DSET_TYPES] = { 2846 FUNC_FIM_PREFIX , FUNC_THR_PREFIX , FUNC_COR_PREFIX , 2847 FUNC_TT_PREFIX , FUNC_FT_PREFIX , 2848 FUNC_ZT_PREFIX , FUNC_CT_PREFIX , FUNC_BT_PREFIX , 2849 FUNC_BN_PREFIX , FUNC_GT_PREFIX , FUNC_PT_PREFIX , FUNC_BUCK_PREFIX , 2850 ANAT_SPGR_PREFIX , ANAT_FSE_PREFIX , ANAT_EPI_PREFIX , ANAT_MRAN_PREFIX , 2851 ANAT_CT_PREFIX , ANAT_SPECT_PREFIX , ANAT_PET_PREFIX , 2852 ANAT_MRA_PREFIX , ANAT_BMAP_PREFIX , ANAT_DIFF_PREFIX , ANAT_OMRI_PREFIX , 2853 ANAT_BUCK_PREFIX 2854 } ; 2855 2856 #define DSET_PREFIXSTR(ds) ( ISFUNC(ds) ? FUNC_prefixstr[(ds)->func_type] \ 2857 : ANAT_prefixstr[(ds)->func_type] ) 2858 2859 #define DSET_FUNCLABEL(ds) ( ISFUNC(ds) ? FUNC_label[(ds)->func_type] \ 2860 : ANAT_prefixstr[(ds)->func_type] ) 2861 2862 #define DSET_TYPESTR(ds) ( ISFUNC(ds) ? FUNC_typestr[(ds)->func_type] \ 2863 : ANAT_typestr[(ds)->func_type] ) 2864 2865 static int ANAT_nvals[] = { 1,1,1,1,1,1,1,1,1,1,1,1 , 1 } ; 2866 static int ANAT_ival_zero[] = { 0,0,0,0,0,0,0,0,0,0,0,0 , 0 } ; 2867 2868 /* the data structure itself */ 2869 2870 /*! One AFNI dataset structure. 2871 Most elements are accessed via macros, and should only be changed via EDIT_dset_items(). */ 2872 2873 typedef struct THD_3dim_dataset { 2874 int type ; /*!< type code: HEAD_ANAT_TYPE or HEAD_FUNC_TYPE or GEN_ANAT_TYPE or GEN_FUNC_TYPE */ 2875 2876 int view_type ; /*!< view code: VIEW_ORIGINAL_TYPE or VIEW_ACPCALIGNED_TYPE or VIEW_TALAIRACH_TYPE */ 2877 int func_type ; /*!< dataset type: one of FUNC_*_TYPE or ANAT_*_TYPE codes */ 2878 2879 char label1[THD_MAX_LABEL] ; /*!< short label #1: not used for anything anymore */ 2880 char label2[THD_MAX_LABEL] ; /*!< short label #2: even more obsolete */ 2881 2882 THD_datablock * dblk ; /*!< pointer to actual data */ 2883 THD_dataxes * daxes ; /*!< info about axes (where dataset is) */ 2884 THD_dataxes * wod_daxes ; /*!< warp-on-demand axes (for viewing interpolated dataset) */ 2885 int wod_flag ; /*!< if true, use wod_daxes, otherwise use daxes */ 2886 2887 THD_timeaxis * taxis ; /*!< non-NULL --> this is a 3D+t dataset */ 2888 2889 THD_marker_set * markers ; /*!< user set mark points (if non-NULL) */ 2890 2891 struct THD_3dim_dataset * warp_parent ; /*!< non-NULL --> this dataset is warped from that one */ 2892 THD_warp * warp ; /*!< this is the coordinate-to-coordinate warp */ 2893 THD_warp * vox_warp ; /*!< this is the index-to-index warp */ 2894 2895 struct THD_3dim_dataset * anat_parent ; /*!< non-NULL --> linked to this as anatomical ref */ 2896 2897 THD_statistics * stats ; /*!< statistics about the sub-brick data */ 2898 2899 float stat_aux[MAX_STAT_AUX] ; /*!< global auxiliary statistics info */ 2900 2901 char warp_parent_name[THD_MAX_NAME] ; /*!< "name" of warp_parent dataset (no longer used) */ 2902 char anat_parent_name[THD_MAX_NAME] ; /*!< "name" of anat_parent dataset (no longer used) */ 2903 char self_name[THD_MAX_NAME] ; /*!< my own "name" (no longer used) */ 2904 2905 #ifdef ALLOW_DATASET_VLIST 2906 THD_vector_list * pts ; /*!< in dataset coords (not DICOM order!) - for Ted Deyoe */ 2907 RwcBoolean pts_original ; /*!< true if was read from disk directly */ 2908 #endif 2909 2910 int death_mark ; /*!< dataset is marked for destruction */ 2911 2912 MCW_idcode idcode ; /*!< globally unique (I hope) ID code for this dataset */ 2913 MCW_idcode anat_parent_idcode ; /*!< ID code for warp_parent dataset */ 2914 MCW_idcode warp_parent_idcode ; /*!< ID code for anat_parent dataset */ 2915 2916 char * keywords ; /*!< 30 Nov 1997: keyword list for dataset */ 2917 2918 THD_usertaglist * tagset ; /*!< 23 Oct 1998: see plug_tag.c */ 2919 2920 /* pointers to other stuff */ 2921 2922 KILL_list kl ; /*!< Stuff to delete if this dataset is deleted (see killer.h) */ 2923 RwcPointer parent ; /*!< Somebody that "owns" this dataset */ 2924 2925 /* 26 Aug 2002: self warp (for w-o-d) */ 2926 2927 THD_warp *self_warp ; 2928 2929 /* 03 Aug 2004: list of filenames to cat together (cf. THD_open_tcat) */ 2930 2931 char *tcat_list ; 2932 int tcat_num ; 2933 int *tcat_len ; 2934 2935 /* 26 Feb 2010: Pointer to VALUE_LABEL_DTABLE for ROI drawing labels*/ 2936 void *Label_Dtable; 2937 /* 13 Mar 2009: atlas space */ 2938 char atlas_space[THD_MAX_NAME] ; 2939 /* 18 Nov 2010: Pointer to ATLAS_LABEL_TABLE for atlas segmentation */ 2940 /* atlas_point_list *atlas_label_table;*/ 2941 2942 /* 31 Mar 2009: integer colormap for ROIs and atlases */ 2943 int int_cmap ; 2944 /* 04 Jul 2010: temporary index to say which space the dataset is in */ 2945 int space_index; 2946 2947 } THD_3dim_dataset ; 2948 2949 /*! A marker that defines a dataset that is about to be killed. */ 2950 2951 #define DOOMED 665 2952 2953 /*! Mark a dataset to be eliminated by AFNI_mark_for_death() and AFNI_andersonville(). */ 2954 2955 #define DSET_MARK_FOR_DEATH(ds) \ 2956 do{ if( ISVALID_DSET(ds) && ds->death_mark >= 0 ) ds->death_mark = DOOMED ; } while(0) 2957 2958 /*! Mark a dataset to be ineligible for elimination during AFNI_rescan_session(). */ 2959 2960 #define DSET_MARK_FOR_IMMORTALITY(ds) \ 2961 do{ if( ISVALID_DSET(ds) ) ds->death_mark = -1 ; } while(0) 2962 2963 /*! Mark a dataset to be eligible for elimination if the need arises. */ 2964 2965 #define DSET_MARK_FOR_NORMAL(ds) \ 2966 do{ if( ISVALID_DSET(ds) ) ds->death_mark = 0 ; } while(0) 2967 2968 /*! Dataset is tcat-ed? */ 2969 2970 #define DSET_IS_TCAT(ds) (ISVALID_DSET(ds) && (ds)->tcat_list != NULL && (ds)->tcat_num > 0) 2971 2972 /*! Return pointer to current dataset axes (warp-on-demand or permanent). */ 2973 2974 #define CURRENT_DAXES(ds) (((ds)->wod_flag) ? ((ds)->wod_daxes) : ((ds)->daxes)) 2975 2976 /*! Determine if ds is a pointer to a valid dataset. */ 2977 2978 #define ISVALID_3DIM_DATASET(ds) \ 2979 ( (ds) != NULL && (ds)->type >= FIRST_3DIM_TYPE && \ 2980 (ds)->type <= LAST_3DIM_TYPE && \ 2981 (ds)->view_type >= FIRST_VIEW_TYPE && \ 2982 (ds)->view_type <= LAST_VIEW_TYPE && \ 2983 ISVALID_DATABLOCK((ds)->dblk) ) 2984 2985 /*! Determine if ds is a pointer to a valid dataset. */ 2986 2987 #define ISVALID_DSET ISVALID_3DIM_DATASET 2988 2989 /*! Determine if nn is a functional dataset type code. */ 2990 2991 #define ISFUNCTYPE(nn) ( (nn) == HEAD_FUNC_TYPE || (nn) == GEN_FUNC_TYPE ) 2992 2993 /*! Determine if dset is a functional dataset. */ 2994 2995 #define ISFUNC(dset) ( ISVALID_DSET(dset) && ISFUNCTYPE((dset)->type) ) 2996 2997 /*! Determine if nn is an anatomical dataset type code. */ 2998 2999 #define ISANATTYPE(nn) ( (nn) == HEAD_ANAT_TYPE || (nn) == GEN_ANAT_TYPE ) 3000 3001 /*! Determine if dset is an anatomical dataset. */ 3002 3003 #define ISANAT(dset) ( ISVALID_DSET(dset) && ISANATTYPE((dset)->type) ) 3004 3005 /*! Determine if nn is a head dataset type code. */ 3006 3007 #define ISHEADTYPE(nn) ( (nn) == HEAD_ANAT_TYPE || (nn) == HEAD_FUNC_TYPE ) /* 09 Sep 2002: ==ugh */ 3008 3009 /*! Determine if dset is a head dataset (vs. non-head). */ 3010 3011 #define ISHEAD(dset) ( ISVALID_DSET(dset) && ISHEADTYPE((dset)->type) ) 3012 3013 /*! Determine if dset is an anatomical bucket dataset */ 3014 3015 #define ISANATBUCKET(dset) ( ISANAT(dset) && (dset)->func_type == ANAT_BUCK_TYPE ) 3016 3017 /*! Determine if dset is a functional bucket dataset */ 3018 3019 #define ISFUNCBUCKET(dset) ( ISFUNC(dset) && (dset)->func_type == FUNC_BUCK_TYPE ) 3020 3021 /*! Determine if dset is a bucket dataset (functional or anatomical) */ 3022 3023 #define ISBUCKET(dset) ( ISANATBUCKET(dset) || ISFUNCBUCKET(dset) ) 3024 3025 /*! Determine if dataset ds is actually stored on disk */ 3026 3027 #define DSET_ONDISK(ds) ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \ 3028 (ds)->dblk->diskptr->storage_mode!=STORAGE_UNDEFINED ) 3029 3030 /*! Determine if dataset ds is stored in a BRIK file on disk */ 3031 3032 #define DSET_IS_BRIK(ds) ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \ 3033 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_BRICK ) 3034 3035 /*! Determine if datablock db is stored in a MINC file on disk */ 3036 3037 #define DBLK_IS_MINC(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3038 (db)->diskptr->storage_mode == STORAGE_BY_MINC ) 3039 3040 /*! Determine if dataset ds is stored in a MINC file on disk */ 3041 3042 #define DSET_IS_MINC(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3043 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3044 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_MINC ) 3045 3046 /*! Determine if datablock db is stored in a ANALYZE file on disk */ 3047 3048 #define DBLK_IS_ANALYZE(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3049 (db)->diskptr->storage_mode == STORAGE_BY_ANALYZE ) 3050 3051 /*! Determine if dataset ds is stored in a ANALYZE file on disk */ 3052 3053 #define DSET_IS_ANALYZE(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3054 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3055 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_ANALYZE ) 3056 3057 /*! Determine if datablock db is stored in a CTFMRI file on disk */ 3058 3059 #define DBLK_IS_CTFMRI(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3060 (db)->diskptr->storage_mode == STORAGE_BY_CTFMRI ) 3061 3062 /*! Determine if dataset ds is stored in a CTFMRI file on disk */ 3063 3064 #define DSET_IS_CTFMRI(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3065 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3066 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_CTFMRI ) 3067 3068 /*! Determine if datablock db is stored in a CTFSAM file on disk */ 3069 3070 #define DBLK_IS_CTFSAM(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3071 (db)->diskptr->storage_mode == STORAGE_BY_CTFSAM ) 3072 3073 /*! Determine if dataset ds is stored in a CTFSAM file on disk */ 3074 3075 #define DSET_IS_CTFSAM(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3076 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3077 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_CTFSAM ) 3078 3079 /*! Determine if datablock db is stored in a 1D file on disk */ 3080 3081 #define DBLK_IS_1D(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3082 (db)->diskptr->storage_mode == STORAGE_BY_1D ) 3083 3084 /*! Determine if datablock db is stored in a 3D file on disk */ 3085 3086 #define DBLK_IS_3D(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3087 (db)->diskptr->storage_mode == STORAGE_BY_3D ) 3088 3089 /*! Determine if datablock db is stored in a NIFTI file on disk */ 3090 3091 #define DBLK_IS_NIFTI(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3092 (db)->diskptr->storage_mode == STORAGE_BY_NIFTI ) 3093 3094 /*! Determine if datablock db is stored in a NIML file on disk 26 May 2006 */ 3095 3096 #define DBLK_IS_NIML(db) ( ISVALID_DBLK(db) && \ 3097 ISVALID_DISKPTR((db)->diskptr) && \ 3098 (db)->diskptr->storage_mode == STORAGE_BY_NIML ) 3099 3100 /*! Determine if datablock db is stored in a NI_SURF_DSET file on disk */ 3101 3102 #define DBLK_IS_NI_SURF_DSET(db) ( ISVALID_DBLK(db) && \ 3103 ISVALID_DISKPTR((db)->diskptr) && \ 3104 (db)->diskptr->storage_mode == STORAGE_BY_NI_SURF_DSET ) 3105 3106 /*! Determine if datablock db is stored in a NI_SURF_DSET file on disk */ 3107 3108 #define DBLK_IS_GIFTI(db) ( ISVALID_DBLK(db) && \ 3109 ISVALID_DISKPTR((db)->diskptr) && \ 3110 (db)->diskptr->storage_mode == STORAGE_BY_GIFTI ) 3111 3112 /*! Determine if dataset ds is stored in a 1D file on disk */ 3113 3114 #define DSET_IS_1D(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3115 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3116 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_1D ) 3117 3118 /*! Determine if dataset ds is stored in a 3D file on disk */ 3119 3120 #define DSET_IS_3D(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3121 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3122 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_3D ) 3123 3124 /*! Determine if dataset ds is stored in a NIFTI file on disk */ 3125 3126 #define DSET_IS_NIFTI(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3127 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3128 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NIFTI ) 3129 3130 /*! Determine if dataset ds is stored in a NIML file on disk 26 May 2006 */ 3131 3132 #define DSET_IS_NIML(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3133 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3134 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NIML ) 3135 3136 /*! Determine if dataset ds is stored in a NI_SURF_DSET file on disk */ 3137 3138 #define DSET_IS_NI_SURF_DSET(ds) (ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) \ 3139 && ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3140 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NI_SURF_DSET ) 3141 3142 /*! Determine if dataset ds is stored in a GIFTI file on disk */ 3143 3144 #define DSET_IS_GIFTI(ds) (ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) \ 3145 && ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3146 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_GIFTI ) 3147 3148 /*! Determine if datablock db is stored by volume files rather than 1 big BRIK */ 3149 3150 #define DBLK_IS_VOLUMES(db) ( ISVALID_DBLK(db) && \ 3151 ISVALID_DISKPTR((db)->diskptr) && \ 3152 (db)->diskptr->storage_mode == STORAGE_BY_VOLUMES ) 3153 3154 /*! Determine if dataset ds is stored in volumes files rather than 1 big BRIK */ 3155 3156 #define DSET_IS_VOLUMES(ds) ( ISVALID_DSET(ds) && \ 3157 ISVALID_DBLK((ds)->dblk) && \ 3158 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3159 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_VOLUMES ) 3160 3161 /*! Determine if datablock db is stored in a MPEG file on disk */ 3162 3163 #define DBLK_IS_MPEG(db) ( ISVALID_DBLK(db) && ISVALID_DISKPTR((db)->diskptr) && \ 3164 (db)->diskptr->storage_mode == STORAGE_BY_MPEG ) 3165 3166 /*! Determine if dataset ds is stored in a MPEG file on disk */ 3167 3168 #define DSET_IS_MPEG(ds) ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3169 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3170 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_MPEG ) 3171 3172 /*! Determine if dataset is valid, but has a non-AFNI storage mode */ 3173 3174 #define IS_VALID_NON_AFNI_DSET(ds) \ 3175 ( ISVALID_DSET(ds) && ISVALID_DBLK((ds)->dblk) && \ 3176 ISVALID_DISKPTR((ds)->dblk->diskptr) && \ 3177 ( (ds)->dblk->diskptr->storage_mode == STORAGE_BY_MINC || \ 3178 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_ANALYZE || \ 3179 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_CTFMRI || \ 3180 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_CTFSAM || \ 3181 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_1D || \ 3182 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_3D || \ 3183 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NIFTI || \ 3184 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_MPEG || \ 3185 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NIML || \ 3186 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NI_SURF_DSET || \ 3187 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_NI_TRACT || \ 3188 (ds)->dblk->diskptr->storage_mode == STORAGE_BY_GIFTI \ 3189 ) ) 3190 3191 /*! Determine if AFNI is allowed to over-write dataset ds */ 3192 3193 #define DSET_WRITEABLE(ds) \ 3194 ( ISVALID_DSET(ds) && \ 3195 ISVALID_DBLK((ds)->dblk) && \ 3196 !DSET_IS_MINC(ds) && \ 3197 !DSET_IS_ANALYZE(ds) && \ 3198 ( (ds)->warp_parent != NULL || (ds)->dblk->diskptr->allow_directwrite==1 ) ) 3199 3200 /*! Determine if dataset ds is stored in a compressed format */ 3201 3202 #define DSET_COMPRESSED(ds) \ 3203 ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \ 3204 (ds)->dblk->diskptr != NULL && \ 3205 COMPRESS_filecode((ds)->dblk->diskptr->brick_name) >= 0 ) 3206 3207 /*! Purge the data of dataset ds from memory (you can reload it later) */ 3208 3209 #define PURGE_DSET(ds) \ 3210 do{ if( ISVALID_3DIM_DATASET(ds) && DSET_ONDISK(ds) ) \ 3211 (void) THD_purge_datablock( (ds)->dblk , DATABLOCK_MEM_ANY ) ; \ 3212 } while(0) 3213 3214 /*! Determine if dataset ds is loadable into memory */ 3215 3216 #define DSET_INMEMORY(ds) \ 3217 ( ISVALID_DSET(ds) && (ds)->dblk!=NULL && \ 3218 (ds)->dblk->malloc_type!=DATABLOCK_MEM_UNDEFINED && \ 3219 ( (ds)->dblk->diskptr->storage_mode!=STORAGE_UNDEFINED || DSET_LOADED(ds) ) ) 3220 3221 #define DBLK_BRICK(db,iv) ((db)->brick->imarr[(iv)]) 3222 3223 /*! Return the MRI_IMAGE * that is the iv-th volume of dataset ds */ 3224 3225 #define DSET_BRICK(ds,iv) DBLK_BRICK((ds)->dblk,(iv)) 3226 3227 /*! See if the iv-th volume is purged to disk at this moment */ 3228 3229 #define DSET_BRICK_IS_PURGED(ds,iv) MRI_IS_PURGED(DSET_BRICK((ds),(iv))) 3230 3231 #define DBLK_BRICK_TYPE(db,iv) (DBLK_BRICK((db),(iv))->kind) 3232 3233 /*! Return the datum code (MRI_short, etc.) of the iv-th volume of dataset ds */ 3234 3235 #define DSET_BRICK_TYPE(ds,iv) DBLK_BRICK_TYPE((ds)->dblk,(iv)) 3236 3237 /*! Return the number of voxels in the iv-th volume of dataset ds */ 3238 3239 #define DBLK_BRICK_NVOX(db,iv) (DBLK_BRICK((db),(iv))->nvox) 3240 3241 #define DBLK_ARRAY(db,iv) mri_data_pointer( DBLK_BRICK((db),(iv)) ) 3242 3243 /*! Return the pointer to the actual data in the iv-th volume of dataset ds */ 3244 3245 #define DSET_ARRAY(ds,iv) DBLK_ARRAY((ds)->dblk,(iv)) 3246 3247 /* set a sub-brick pointer to null ZSS May 08 2012 */ 3248 #define DSET_NULL_ARRAY(ds,iv) \ 3249 mri_clear_data_pointer(DBLK_BRICK((ds)->dblk,(iv))) 3250 /* free then set a sub-brick pointer to null ZSS May 08 2012 */ 3251 #define DSET_FREE_ARRAY(ds,iv) { \ 3252 if (DSET_ARRAY((ds),(iv))) {\ 3253 free(DSET_ARRAY((ds),(iv))); \ 3254 mri_clear_data_pointer(DBLK_BRICK((ds)->dblk,(iv))); \ 3255 } \ 3256 } 3257 3258 #define DSET_BRICK_ARRAY DSET_ARRAY /* Because I sometimes forget the */ 3259 #define DBLK_BRICK_ARRAY DBLK_ARRAY /* correct names given above - RWC */ 3260 3261 #define DBLK_BRICK_FACTOR(db,iv) ((db)->brick_fac[(iv)]) 3262 3263 /*! Return the brick scaling factor of the iv-th volume of dataset ds. 3264 3265 If the scale factor is 0, then the brick is used "as-is"; that is, 3266 the effective scale factor is 1. You can assign to this macro 3267 as in "DSET_BRICK_FACTOR(ds,iv)=3.2;" but I don't recommend this. 3268 Instead, do something like "EDIT_BRICK_FACTOR(ds,iv,3.2);" (see editvol.h). 3269 */ 3270 3271 #define DSET_BRICK_FACTOR(ds,iv) DBLK_BRICK_FACTOR((ds)->dblk,(iv)) 3272 3273 extern int THD_need_brick_factor( THD_3dim_dataset * ) ; 3274 3275 #define DBLK_BRICK_BYTES(db,iv) ((db)->brick_bytes[iv]) 3276 3277 /*! Return number of bytes stored in the iv-th volume of dataset ds */ 3278 3279 #define DSET_BRICK_BYTES(ds,iv) DBLK_BRICK_BYTES((ds)->dblk,(iv)) 3280 3281 /*! Return the volume index of the "most important" sub-brick in dataset ds. 3282 3283 This is still used in places, but is fairly obsolete 3284 */ 3285 #define DSET_PRINCIPAL_VALUE(ds) ( ISANAT(ds) ? ANAT_ival_zero[(ds)->func_type] \ 3286 : FUNC_ival_fim[(ds)->func_type] ) 3287 3288 /*! Synonym for DSET_PRINCIPAL_VALUE */ 3289 3290 #define DSET_PRINCIPAL_INDEX DSET_PRINCIPAL_VALUE 3291 3292 /*! Return the volume index of the "threshold" sub-brick in dataset ds. 3293 3294 This is analogous to DSET_PRINCIPAL_VALUE, and is also sort-of-obsolete. 3295 */ 3296 #define DSET_THRESH_VALUE(ds) (ISANAT((ds)) ? -1 : FUNC_ival_thr[(ds)->func_type]) 3297 3298 #define DSET_THRESH_INDEX DSET_THRESH_VALUE 3299 3300 /*! Return a pointer to the prefix of dataset ds */ 3301 #define DSET_PREFIX(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \ 3302 ? ((ds)->dblk->diskptr->prefix) : "\0" ) 3303 extern char *DSET_prefix_noext(THD_3dim_dataset *dset); 3304 3305 extern char * THD_newprefix(THD_3dim_dataset * dset, char * suffix); /* 16 Feb 2001 */ 3306 extern char * THD_deplus_prefix( char *prefix ) ; /* 22 Nov 2002 */ 3307 extern int THD_deconflict_prefix( THD_3dim_dataset * ) ; /* 23 Mar 2007 */ 3308 3309 /*! Return a pointer to the filecode of dataset ds (prefix+view) */ 3310 3311 #define DSET_FILECODE(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \ 3312 ? ((ds)->dblk->diskptr->filecode) : "\0" ) 3313 3314 /*! Return a pointer to the .HEAD filename of dataset ds */ 3315 3316 #define DSET_HEADNAME(ds) ( ((ds)->tcat_list != NULL) ? (ds)->tcat_list \ 3317 : ((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \ 3318 ? ((ds)->dblk->diskptr->header_name) : "\0" ) 3319 3320 /*! Return a pointer to the .BRIK filename of dataset ds */ 3321 3322 #define DSET_BRIKNAME(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \ 3323 ? ((ds)->dblk->diskptr->brick_name) : "\0" ) 3324 #define DSET_BRICKNAME DSET_BRIKNAME 3325 3326 /*! Return a pointer to the directory name of dataset ds */ 3327 3328 #define DSET_DIRNAME(ds) (((ds)->dblk!=NULL && (ds)->dblk->diskptr!=NULL) \ 3329 ? ((ds)->dblk->diskptr->directory_name) : "\0" ) 3330 3331 #define DSET_SESSNAME DSET_DIRNAME 3332 3333 /*! Return a pointer to the ID code of dataset ds */ 3334 3335 #define DSET_IDCODE(ds) (&((ds)->idcode)) 3336 3337 /*! Return the ID code string */ 3338 3339 #define DSET_IDCODE_STR(ds) ((ds)->idcode.str) 3340 3341 /*! Return the storage mode 5 Mar 2012 [rickr] */ 3342 #define DSET_STORAGE_MODE(ds) ( ((ds) && (ds)->dblk && (ds)->dblk->diskptr)\ 3343 ? (ds)->dblk->diskptr->storage_mode:STORAGE_UNDEFINED ) 3344 3345 /*! Return the storage mode string */ 3346 #define DSET_STORAGE_MODE_STR(ds) ( ((ds) && (ds)->dblk && (ds)->dblk->diskptr)\ 3347 ? storage_mode_str((ds)->dblk->diskptr->storage_mode):"NULL" ) 3348 3349 /* 25 April 1998 */ 3350 3351 #define DBLK_BYTEORDER(db) ((db)->diskptr->byte_order) 3352 3353 /*! Return LSB_FIRST or MSB_FIRST for dataset ds */ 3354 3355 #define DSET_BYTEORDER(ds) DBLK_BYTEORDER((ds)->dblk) 3356 3357 /** macros for time-dependent datasets **/ 3358 3359 /*! Return number of time points in dataset ds. 3360 3361 If value is 1, dataset is not time-dependent, but it still may have 3362 multiple sub-bricks (if it is a bucket dataset, for example) 3363 */ 3364 #define DSET_NUM_TIMES(ds) ( ((ds)->taxis == NULL) ? 1 : (ds)->taxis->ntt ) 3365 3366 /*! Check if have a 3D+time dataset. */ 3367 3368 #define HAS_TIMEAXIS(ds) ( DSET_NUM_TIMES(ds) > 1 ) 3369 #define DSET_HAS_TIMEAXIS HAS_TIMEAXIS 3370 3371 /*! Return number of values stored at each time point for dataset ds. 3372 3373 Will always be 1 in the current version of AFNI! 3374 (Except for bucket datasets, that is, damn it.) 3375 */ 3376 #define DSET_NVALS_PER_TIME(ds) ( (ds)->dblk->nvals / DSET_NUM_TIMES(ds) ) 3377 3378 /*! Return number of sub-bricks in dataset ds */ 3379 3380 #define DSET_NVALS(ds) ( (ds)->dblk->nvals ) 3381 3382 /*! Return number of voxels in each sub-brick of dataset ds */ 3383 3384 #define DSET_NVOX(ds) ( (ds)->daxes->nxx * (ds)->daxes->nyy * (ds)->daxes->nzz ) 3385 3386 /*! Find the largest node index in dset (for surface-based dsets) */ 3387 #define DSET_MAX_NODE(ds, MM) {\ 3388 int i; \ 3389 MM = -1; \ 3390 if ((ds) && (ds)->dblk && (ds)->dblk->node_list) {\ 3391 for (i=0; i<(ds)->dblk->nnodes; ++i) {\ 3392 if ((ds)->dblk->node_list[i]>MM) MM = (ds)->dblk->node_list[i];\ 3393 } \ 3394 } \ 3395 } 3396 3397 /*! Return total size of dataset in bytes. */ 3398 3399 #define DSET_TOTALBYTES(ds) ((ds)->dblk->total_bytes) 3400 3401 /*! Return number of voxels along x-axis of dataset ds */ 3402 3403 #define DSET_NX(ds) ((ds)->daxes->nxx) 3404 3405 /*! Return number of voxels along y-axis of dataset ds */ 3406 3407 #define DSET_NY(ds) ((ds)->daxes->nyy) 3408 3409 /*! Return number of voxels along z-axis of dataset ds */ 3410 3411 #define DSET_NZ(ds) ((ds)->daxes->nzz) 3412 3413 /*! Return number of voxels in a slice of dataset ds */ 3414 3415 #define DSET_NXY(ds) ((ds)->daxes->nxx * (ds)->daxes->nyy) 3416 3417 /*! Is dataset 3D? [12 May 2020] */ 3418 3419 #define DSET_HAS_3D(ds) \ 3420 ( (ds)->daxes->nxx > 1 && (ds)->daxes->nyy > 1 && (ds)->daxes->nzz > 1 ) 3421 3422 /*! Is dataset 2D? [12 May 2020] */ 3423 3424 #define DSET_HAS_2D(ds) \ 3425 ( (ds)->daxes->nxx > 1 && (ds)->daxes->nyy > 1 && (ds)->daxes->nzz == 1 ) 3426 3427 /*! Is dataset 1D? [12 May 2020] */ 3428 3429 #define DSET_HAS_1D(ds) \ 3430 ( (ds)->daxes->nxx > 1 && (ds)->daxes->nyy == 1 && (ds)->daxes->nzz == 1 ) 3431 3432 /*! Return grid spacing (voxel size) along x-axis of dataset ds */ 3433 3434 #define DSET_DX(ds) ((ds)->daxes->xxdel) /* added 17 Aug 1998 */ 3435 3436 /*! Return grid spacing (voxel size) along y-axis of dataset ds */ 3437 3438 #define DSET_DY(ds) ((ds)->daxes->yydel) 3439 3440 /*! Return grid spacing (voxel size) along z-axis of dataset ds */ 3441 3442 #define DSET_DZ(ds) ((ds)->daxes->zzdel) 3443 3444 /*! Return 1 if dset is on a volume grid, as opposed to 1D or surface-based */ 3445 3446 #define DSET_IS_VOL(ds) (((ds)->daxes->nzz == 1 && (ds)->daxes->nyy == 1) ? 0:1) 3447 3448 /*! Return volume of a voxel */ 3449 3450 #define DSET_VOXVOL(ds) \ 3451 fabsf((ds)->daxes->xxdel*(ds)->daxes->yydel*(ds)->daxes->zzdel) 3452 3453 /*! Return minimum grid spacing in 2 dimensions for dataset ds */ 3454 #define DSET_MIN_DELXY(ds) ((fabs(DSET_DX(ds)) < (fabs(DSET_DY(ds))) ) ? \ 3455 fabs(DSET_DX(ds)) : fabs(DSET_DY(ds)) ) 3456 3457 /*! Return minimum grid spacing in 3 dimensions for dataset ds */ 3458 #define DSET_MIN_DEL(ds) ((DSET_MIN_DELXY(ds)<fabs(DSET_DZ(ds))) ? \ 3459 DSET_MIN_DELXY(ds) : fabs(DSET_DZ(ds))) 3460 3461 /*! Return grid origin along x-axis of dataset ds */ 3462 3463 #define DSET_XORG(ds) ((ds)->daxes->xxorg) /* 29 Aug 2001 */ 3464 3465 /*! Return grid origin along y-axis of dataset ds */ 3466 3467 #define DSET_YORG(ds) ((ds)->daxes->yyorg) 3468 3469 /*! Return grid origin along y-axis of dataset ds */ 3470 3471 #define DSET_ZORG(ds) ((ds)->daxes->zzorg) 3472 3473 /*! Return smallest x-coordinate of grid for dataset ds */ 3474 3475 #define DSET_XXMIN(ds) ((ds)->daxes->xxmin) /* 11 Sep 2001 */ 3476 3477 /*! Return largest x-coordinate of grid for dataset ds */ 3478 3479 #define DSET_XXMAX(ds) ((ds)->daxes->xxmax) 3480 3481 /*! Return smallest y-coordinate of grid for dataset ds */ 3482 3483 #define DSET_YYMIN(ds) ((ds)->daxes->yymin) 3484 3485 /*! Return largest y-coordinate of grid for dataset ds */ 3486 3487 #define DSET_YYMAX(ds) ((ds)->daxes->yymax) 3488 3489 /*! Return smallest z-coordinate of grid for dataset ds */ 3490 3491 #define DSET_ZZMIN(ds) ((ds)->daxes->zzmin) 3492 3493 /*! Return largest z-coordinate of grid for dataset ds */ 3494 3495 #define DSET_ZZMAX(ds) ((ds)->daxes->zzmax) 3496 3497 /* these next 4 added 19 Aug 1999 */ 3498 3499 /*! Find the x-axis index of a 3D array index in dataset ds */ 3500 3501 #define DSET_index_to_ix(ds,ii) ( (ii) % (ds)->daxes->nxx) 3502 3503 /*! Find the y-axis index of a 3D array index in dataset ds */ 3504 3505 #define DSET_index_to_jy(ds,ii) ( ((ii) / (ds)->daxes->nxx) % (ds)->daxes->nyy ) 3506 3507 /*! Find the z-axis index of a 3D array index in dataset ds */ 3508 3509 #define DSET_index_to_kz(ds,ii) ( (ii) /((ds)->daxes->nxx * (ds)->daxes->nyy )) 3510 3511 /*! Convert a triple-index (ix,jy,kz) to a single 3D index for dataset ds */ 3512 3513 #define DSET_ixyz_to_index(ds,ix,jy,kz) ((ix)+((jy)+(kz)*(ds)->daxes->nyy)*(ds)->daxes->nxx) 3514 3515 #define DAXES_index_to_ix(da,ii) ( (ii) % (da)->nxx) 3516 #define DAXES_index_to_jy(da,ii) ( ((ii) / (da)->nxx) % (da)->nyy ) 3517 #define DAXES_index_to_kz(da,ii) ( (ii) /((da)->nxx * (da)->nyy )) 3518 #define DAXES_ixyz_to_index(da,ix,jy,kz) ((ix)+((jy)+(kz)*(da)->nyy)*(da)->nxx) 3519 3520 /*! Determine if dataset ds has cubical voxels */ 3521 3522 #define DSET_CUBICAL(ds) ( fabs((ds)->daxes->xxdel) == fabs((ds)->daxes->yydel) && \ 3523 fabs((ds)->daxes->xxdel) == fabs((ds)->daxes->zzdel) ) 3524 3525 /*! Determine if a graph window can be opened for dataset ds. 3526 Cannot graph warp-on-demand datasets. 3527 */ 3528 #define DSET_GRAPHABLE(ds) ( ISVALID_3DIM_DATASET(ds) && DSET_INMEMORY(ds) && \ 3529 (ds)->wod_flag == False && \ 3530 ( DSET_ONDISK(ds) || DSET_LOADED(ds) || DSET_LOCKED(ds) ) ) 3531 3532 /*! Return the TR for dataset ts; will be 0 if not time-dependent. */ 3533 3534 #define DSET_TIMESTEP(ds) ( ((ds)->taxis == NULL) ? 0.0 : (ds)->taxis->ttdel ) 3535 3536 #define DSET_TR DSET_TIMESTEP 3537 3538 #define DSET_TR_SEC(ds) ( \ 3539 (DSET_TIMEUNITS(ds) == UNITS_SEC_TYPE) ? DSET_TR(ds) : \ 3540 ((DSET_TIMEUNITS(ds) == UNITS_MSEC_TYPE) ? DSET_TR(ds)*0.001 : 0.0 ) ) 3541 3542 /*! Return the time origin for dataset ds. 3543 3544 Is always 0 in current version of AFNI. 3545 */ 3546 #define DSET_TIMEORIGIN(ds) ( ((ds)->taxis == NULL) ? 0.0 : (ds)->taxis->ttorg ) 3547 3548 /*! Return the time duration of image acquisition for dataset ds. 3549 3550 Is always 0 in current version of AFNI (was intended for true 3D echo-volume imaging). 3551 */ 3552 #define DSET_TIMEDURATION(ds) ( ((ds)->taxis == NULL) ? 0.0 : (ds)->taxis->ttdur ) 3553 3554 /*! Return the time-step units code for dataset ds. 3555 3556 Will be one of 3557 - UNITS_MSEC_TYPE milliseconds 3558 - UNITS_SEC_TYPE seconds 3559 - UNITS_HZ_TYPE Hertz 3560 - ILLEGAL_TYPE not a time-dependent dataset (d'oh) 3561 */ 3562 #define DSET_TIMEUNITS(ds) ( ((ds)->taxis == NULL) ? ILLEGAL_TYPE \ 3563 : (ds)->taxis->units_type ) 3564 3565 /*! Alter a dataset's time units from MSEC to SEC, if need be. */ 3566 3567 #define DSET_UNMSEC(ds) \ 3568 do{ int zz ; \ 3569 if( (ds)!=NULL && (ds)->taxis!=NULL && (ds)->taxis->units_type==UNITS_MSEC_TYPE ){ \ 3570 (ds)->taxis->units_type = UNITS_SEC_TYPE ; \ 3571 (ds)->taxis->ttdel *= 0.001 ; \ 3572 (ds)->taxis->ttorg *= 0.001 ; \ 3573 (ds)->taxis->ttdur *= 0.001 ; \ 3574 if( (ds)->taxis->toff_sl != NULL ) \ 3575 for( zz=0 ; zz < (ds)->taxis->nsl ; zz++ ) (ds)->taxis->toff_sl[zz] *= 0.001 ; \ 3576 } } while(0) 3577 3578 /*! Return number of time-axis slice offsets for datsaet ds. 3579 3580 Will be zero for non-time-dependent datasets, and may be zero or positive 3581 for time-dependent datasets 3582 */ 3583 #define DSET_NUM_TTOFF(ds) ( ((ds)->taxis == NULL) ? 0 : (ds)->taxis->nsl ) 3584 /*! Return whether the dataset has slice timing. 6 May 2013 [rickr] */ 3585 #define DSET_HAS_SLICE_TIMING(ds) \ 3586 (((ds) != NULL) && (DSET_NUM_TTOFF(ds) > 0) && ((ds)->taxis->toff_sl != NULL)) 3587 3588 /** 30 Nov 1997 **/ 3589 3590 #define NO_LAB_FLAG "?" 3591 #define DBLK_BRICK_LAB(db,iv) ( ((db)->brick_lab != NULL) ? ((db)->brick_lab[iv]) \ 3592 : NO_LAB_FLAG ) 3593 3594 /*! Return the label string for sub-brick iv of dataset ds. 3595 3596 This label is used on chooser menus, for example 3597 */ 3598 #define DSET_BRICK_LAB(ds,iv) DBLK_BRICK_LAB((ds)->dblk,(iv)) 3599 3600 /*! Synonym for DSET_BRICK_LAB */ 3601 3602 #define DSET_BRICK_LABEL DSET_BRICK_LAB 3603 3604 /*! Check if sub-brick has label March 2010 ZSS */ 3605 #define DSET_HAS_LABEL(ds,iv) ( strcmp (DSET_BRICK_LABEL(ds,iv), NO_LAB_FLAG) ) 3606 3607 #define DBLK_BRICK_STATCODE(db,iv) \ 3608 ( ((db)->brick_statcode != NULL) ? (db)->brick_statcode[iv] : ILLEGAL_TYPE ) 3609 3610 /*! Return the statistical type code for the iv-th volume of dataset ds. 3611 3612 Will be -1 if this sub-brick is not tagged as being an SPM. 3613 */ 3614 #if 1 /* 18 Dec 2017 */ 3615 3616 #define DSET_BRICK_STATCODE(ds,iv) \ 3617 ( (((ds)->dblk->brick_statcode != NULL) && (iv >= 0)) \ 3618 ? (ds)->dblk->brick_statcode[iv] \ 3619 : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \ 3620 ? (ds)->func_type : -1 ) 3621 3622 #else /* Ye Olde Waye */ 3623 3624 #define DSET_BRICK_STATCODE(ds,iv) \ 3625 ( ISBUCKET((ds)) ? DBLK_BRICK_STATCODE((ds)->dblk,(iv)) \ 3626 : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \ 3627 ? (ds)->func_type : -1 ) 3628 3629 #endif 3630 3631 #define DBLK_BRICK_STATAUX(db,iv) \ 3632 ( ((db)->brick_stataux != NULL) ? (db)->brick_stataux[iv] : NULL ) 3633 3634 /*! Return float * pointer to statistical parameters for sub-brick iv in dataset ds. 3635 3636 If return is NULL, there aren't any parameters for this sub-brick, 3637 otherwise the number of parameters is given by FUNC_need_stat_aux[code], 3638 where code = DSET_BRICK_STATCODE(ds,iv). 3639 */ 3640 3641 #if 1 3642 3643 #define DSET_BRICK_STATAUX(ds,iv) \ 3644 ( ((ds)->dblk->brick_stataux != NULL) \ 3645 ? (ds)->dblk->brick_stataux[iv] \ 3646 : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \ 3647 ? (ds)->stat_aux : NULL ) 3648 3649 # else /* Ye Olde Waye */ 3650 3651 #define DSET_BRICK_STATAUX(ds,iv) \ 3652 ( ISBUCKET((ds)) ? DBLK_BRICK_STATAUX((ds)->dblk,(iv)) \ 3653 : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \ 3654 ? (ds)->stat_aux : NULL ) 3655 3656 #endif 3657 3658 #define DBLK_BRICK_STATPAR(db,iv,jj) \ 3659 ( ((db)->brick_stataux != NULL) ? (db)->brick_stataux[iv][jj] : 0.0 ) 3660 3661 /*! Return the jj-th statistical parameter for the iv-th volume of dataset ds. */ 3662 3663 #if 1 /* 18 Dec 2017 */ 3664 3665 #define DSET_BRICK_STATPAR(ds,iv,jj) \ 3666 ( ((ds)->dblk->brick_stataux != NULL) \ 3667 ? (ds)->dblk->brick_stataux[iv][jj] \ 3668 : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \ 3669 ? (ds)->stat_aux[jj] : 0.0 ) 3670 3671 #else /* Ye Olde Waye */ 3672 3673 #define DSET_BRICK_STATPAR(ds,iv,jj) \ 3674 ( ISBUCKET((ds)) ? DBLK_BRICK_STATPAR((ds)->dblk,(iv),(jj)) \ 3675 : (ISFUNC(ds) && (iv)==FUNC_ival_thr[(ds)->func_type]) \ 3676 ? (ds)->stat_aux[jj] : 0.0 ) 3677 3678 #endif 3679 3680 #define DBLK_BRICK_KEYWORDS(db,iv) \ 3681 ( ((db)->brick_keywords != NULL) ? ((db)->brick_keywords[iv]) : NULL ) 3682 3683 #define DSET_BRICK_KEYWORDS(ds,iv) DBLK_BRICK_KEYWORDS((ds)->dblk,(iv)) 3684 3685 #define DSET_KEYWORDS(ds) ((ds)->keywords) 3686 3687 #define DSET_BRICK_KEYWORDS_HAS(ds,iv,ss) \ 3688 THD_string_has( DSET_BRICK_KEYWORDS((ds),(iv)) , (ss) ) 3689 3690 #define DSET_KEYWORDS_HAS(ds,ss) \ 3691 THD_string_has( DSET_KEYWORDS((ds)) , (ss) ) 3692 3693 /*---- macros to get the FDR curve for a sub-brick (if any) [23 Jan 2008] ----*/ 3694 3695 #define DBLK_BRICK_FDRCURVE(db,ii) \ 3696 ( ((db)->brick_fdrcurve==NULL) ? NULL : (db)->brick_fdrcurve[ii] ) 3697 3698 #define DSET_BRICK_FDRCURVE(ds,ii) DBLK_BRICK_FDRCURVE((ds)->dblk,(ii)) 3699 3700 /* smallest FDR q in the curve for sub-brick #ii [09 Dec 2015] */ 3701 3702 #define DSET_BRICK_FDRMIN(ds,ii) \ 3703 ( ( (ds)->dblk->brick_fdrcurve==NULL || (ds)->dblk->brick_fdrcurve[ii]==NULL ) \ 3704 ? 0.0 \ 3705 : 2.0*qg((ds)->dblk->brick_fdrcurve[ii]->ar[(ds)->dblk->brick_fdrcurve[ii]->nar-1]) ) 3706 3707 #define DBLK_BRICK_FDRCURVE_KILL(db,ii) \ 3708 do{ if( (db)->brick_fdrcurve != NULL ){ \ 3709 floatvec *fv = (db)->brick_fdrcurve[ii] ; \ 3710 if( fv != NULL ){ KILL_floatvec(fv); (db)->brick_fdrcurve[ii]=NULL; } \ 3711 }} while(0) 3712 3713 #define DSET_BRICK_FDRCURVE_KILL(ds,ii) DBLK_BRICK_FDRCURVE_KILL((ds)->dblk,(ii)) 3714 3715 #define DBLK_BRICK_FDRCURVE_ALLKILL(db) \ 3716 do{ if( (db)->brick_fdrcurve != NULL ){ \ 3717 int qq; \ 3718 for( qq=0; qq < (db)->nvals; qq++ ) DBLK_BRICK_FDRCURVE_KILL(db,qq); \ 3719 free((db)->brick_fdrcurve) ; (db)->brick_fdrcurve = NULL ; \ 3720 }} while(0) 3721 3722 #define DSET_BRICK_FDRCURVE_ALLKILL(ds) DBLK_BRICK_FDRCURVE_ALLKILL((ds)->dblk) 3723 3724 /*---- same for MDF curves [22 Oct 2008] -----*/ 3725 3726 #define DBLK_BRICK_MDFCURVE(db,ii) \ 3727 ( ((db)->brick_mdfcurve==NULL) ? NULL : (db)->brick_mdfcurve[ii] ) 3728 3729 #define DSET_BRICK_MDFCURVE(ds,ii) DBLK_BRICK_MDFCURVE((ds)->dblk,(ii)) 3730 3731 #define DBLK_BRICK_MDFCURVE_KILL(db,ii) \ 3732 do{ if( (db)->brick_mdfcurve != NULL ){ \ 3733 floatvec *fv = (db)->brick_mdfcurve[ii] ; \ 3734 if( fv != NULL ){ KILL_floatvec(fv); (db)->brick_mdfcurve[ii]=NULL; } \ 3735 }} while(0) 3736 3737 #define DSET_BRICK_MDFCURVE_KILL(ds,ii) DBLK_BRICK_MDFCURVE_KILL((ds)->dblk,(ii)) 3738 3739 #define DBLK_BRICK_MDFCURVE_ALLKILL(db) \ 3740 do{ if( (db)->brick_mdfcurve != NULL ){ \ 3741 int qq; \ 3742 for( qq=0; qq < (db)->nvals; qq++ ) DBLK_BRICK_MDFCURVE_KILL(db,qq); \ 3743 free((db)->brick_mdfcurve) ; (db)->brick_mdfcurve = NULL ; \ 3744 }} while(0) 3745 3746 #define DSET_BRICK_MDFCURVE_ALLKILL(ds) DBLK_BRICK_MDFCURVE_ALLKILL((ds)->dblk) 3747 3748 extern int THD_create_one_fdrcurve( THD_3dim_dataset *, int ) ; 3749 extern int THD_create_all_fdrcurves( THD_3dim_dataset * ) ; 3750 extern float THD_fdrcurve_zval( THD_3dim_dataset *, int, float ) ; 3751 extern float THD_mdfcurve_mval( THD_3dim_dataset *, int, float ) ; 3752 extern int THD_count_fdrwork( THD_3dim_dataset *dset ) ; /* 12 Nov 2008 */ 3753 extern float THD_fdrcurve_zqtot( THD_3dim_dataset *dset , int iv , float zval ) ; 3754 3755 /*! Macro to load the self_name and labels of a dataset 3756 with values computed from the filenames; 3757 replaces user control/input of these values in to3d 3758 */ 3759 3760 #define DSET_FIX_NAMES(ds) \ 3761 ( strcpy((ds)->self_name,(ds)->dblk->diskptr->directory_name), \ 3762 strcat((ds)->self_name,(ds)->dblk->diskptr->filecode) , \ 3763 strncpy((ds)->label1 ,(ds)->dblk->diskptr->filecode, THD_MAX_LABEL-1) , \ 3764 strcpy((ds)->label2 ,THD_DEFAULT_LABEL) ) 3765 3766 /*! Macro to load brick statistics of a dataset if it 3767 - doesn't have statistics already, OR 3768 - has bad statistics from the (very very very) old to3d bug 3769 */ 3770 3771 #define RELOAD_STATS(dset) \ 3772 if( ISVALID_3DIM_DATASET((dset)) && \ 3773 ( !ISVALID_STATISTIC((dset)->stats) || \ 3774 ( (dset)->dblk->nvals > 1 && \ 3775 (dset)->stats->bstat[1].min > (dset)->stats->bstat[1].max ) ) ){ \ 3776 THD_load_statistics((dset)) ; } 3777 3778 /*! Determine if the ii-th volume of dataset dset has a valid brick statistic. 3779 Brick statistics are just the min and max values in the volume. 3780 */ 3781 3782 #define DSET_VALID_BSTAT(dset,ii) \ 3783 ( ISVALID_3DIM_DATASET((dset)) && \ 3784 ISVALID_STATISTIC((dset)->stats) && \ 3785 (ii) < (dset)->stats->nbstat && \ 3786 ISVALID_BSTAT( (dset)->stats->bstat[(ii)] ) ) 3787 3788 /*! Mark the ii-th volume's brick statistics to be invalid in dataset dset. */ 3789 3790 #define DSET_CRUSH_BSTAT(dset,ii) \ 3791 do{ if( DSET_VALID_BSTAT(dset,ii) ) \ 3792 INVALIDATE_BSTAT((dset)->stats->bstat[(ii)]) ; } while(0) 3793 3794 /*! Return the ii-th volume's min value from bstat, if present */ 3795 3796 #define DSET_BSTAT_MIN(dset,ii) \ 3797 ( DSET_VALID_BSTAT(dset,ii) ? (dset)->stats->bstat[(ii)].min : 0.0f ) 3798 3799 /*! Return the ii-th volume's max value from bstat, if present */ 3800 3801 #define DSET_BSTAT_MAX(dset,ii) \ 3802 ( DSET_VALID_BSTAT(dset,ii) ? (dset)->stats->bstat[(ii)].max : 0.0f ) 3803 3804 /*! Return the ii-th volume's max abs value from bstat, if present */ 3805 3806 #define DSET_BSTAT_MAXABS(dset,ii) \ 3807 ( DSET_VALID_BSTAT(dset,ii) ? \ 3808 MAX(fabsf((dset)->stats->bstat[(ii)].max),fabsf((dset)->stats->bstat[(ii)].min)) : 0.0f ) 3809 3810 /*! Delete all the sub-brick statistics for dataset ds. */ 3811 3812 #define DSET_KILL_STATS(ds) \ 3813 do{ if( (ds)->stats != NULL ){ \ 3814 REMOVEFROM_KILL( (ds)->kl, (ds)->stats->bstat ) ; \ 3815 REMOVEFROM_KILL( (ds)->kl, (ds)->stats ) ; \ 3816 KILL_STATISTIC( (ds)->stats ) ; \ 3817 (ds)->stats = NULL ; } } while(0) 3818 3819 /*! Macro to initialize the global stat_aux data in a dataset. 3820 3821 Note that each sub-brick now has its own stat_aux data, and this 3822 global data is only used for the older (non-bucket) functional 3823 dataset types such as "fico". 3824 */ 3825 3826 #define INIT_STAT_AUX(ds,nf,ff) \ 3827 do{ int is ; \ 3828 for( is=0 ; is < MAX_STAT_AUX ; is++ ) \ 3829 (ds)->stat_aux[is] = (is < (nf)) ? (ff)[is] : 0.0 ; } while(0) 3830 3831 /*! Clear the global stat_aux data in a dataset. */ 3832 3833 #define ZERO_STAT_AUX(ds) \ 3834 do{ int is ; for( is=0 ; is < MAX_STAT_AUX ; is++ ) \ 3835 (ds)->stat_aux[is] = 0.0 ; } while(0) 3836 3837 /** macros to load and unload a dataset from memory **/ 3838 3839 /*! Load dataset ds's sub-bricks into memory. 3840 3841 If it is already loaded, does nothing (so you can call this without much penalty). 3842 */ 3843 #define DSET_load(ds) THD_load_datablock( (ds)->dblk ) 3844 3845 /*! Unload dataset ds's sub-bricks from memory. 3846 3847 Won't do anything if the dataset is locked into memory 3848 */ 3849 #define DSET_unload(ds) THD_purge_datablock( (ds)?(ds)->dblk:NULL , DATABLOCK_MEM_ANY ) 3850 3851 /*! Unload sub-brick iv in dataset ds from memory. 3852 3853 Only does something if the dataset is malloc()-ed, 3854 not mmap()-ed, and not locked in memory 3855 */ 3856 #define DSET_unload_one(ds,iv) THD_purge_one_brick( (ds)->dblk , (iv) ) 3857 3858 /*! Delete dataset ds's volumes and struct from memory. 3859 Does not delete from disk 3860 */ 3861 #define DSET_delete(ds) THD_delete_3dim_dataset((ds),False) 3862 3863 #define DSET_deletepp(ds) \ 3864 do{ THD_delete_3dim_dataset((ds),False); myRwcFree((ds)); } while(0) 3865 3866 /*! Write dataset ds to disk. 3867 Also loads the sub-brick statistics 3868 */ 3869 #define DSET_write(ds) ( THD_load_statistics( (ds) ) , \ 3870 THD_write_3dim_dataset( NULL,NULL , (ds),True ) ) 3871 3872 /*! Write dataset to disk, fer shur this time, Cletus. [07 Jan 2008] */ 3873 3874 #define DSET_overwrite(ds) \ 3875 do{ THD_force_ok_overwrite(1); \ 3876 DSET_write(ds); THD_force_ok_overwrite(0); } while(0) 3877 3878 #define DSET_quiet_overwrite(ds) \ 3879 do{ int m_q = THD_get_quiet_overwrite(); \ 3880 THD_force_ok_overwrite(1); THD_set_quiet_overwrite(1);\ 3881 DSET_write(ds); THD_force_ok_overwrite(0); \ 3882 THD_set_quiet_overwrite(m_q);} while(0) 3883 3884 extern int THD_deathcon(void) ; /* 06 Jun 2007 */ 3885 extern int THD_ok_overwrite(void) ; /* Jan 2008 */ 3886 extern void THD_force_ok_overwrite( int ) ; /* 07 Jan 2008 */ 3887 extern void THD_set_image_globalrange(int ii); /* 27 Jan 2014 */ 3888 extern int THD_get_image_globalrange(void); 3889 extern char *THD_get_image_globalrange_str(void); 3890 extern void THD_cycle_image_globalrange(void); 3891 extern void THD_set_image_globalrange_env(int ig); 3892 3893 /*! Write only the dataset header to disk, for dataset ds */ 3894 3895 #define DSET_write_header(ds) THD_write_3dim_dataset( NULL,NULL , (ds),False ) 3896 3897 #define DSET_overwrite_header(ds) \ 3898 do{ THD_force_ok_overwrite(1); \ 3899 DSET_write_header(ds); THD_force_ok_overwrite(0); } while(0) 3900 3901 /*! Check if dataset ds if fully loaded into memory. 3902 3903 If return is 0 (false), you could try DSET_load(ds) 3904 */ 3905 #define DSET_LOADED(ds) ( THD_count_databricks((ds)->dblk) == DSET_NVALS(ds) ) 3906 3907 /*! Check if a given brick is loaded [14 Sep 2007] */ 3908 3909 #define DSET_BRICK_LOADED(ds,iq) \ 3910 ( DSET_BRICK(ds,iq) != NULL && DSET_ARRAY(ds,iq) != NULL ) 3911 3912 /*! Lock dataset ds into memory */ 3913 3914 #define DSET_lock(ds) DBLK_lock((ds)->dblk) /* Feb 1998 */ 3915 3916 /*! Unlock dataset ds (so it can be purged) */ 3917 3918 #define DSET_unlock(ds) DBLK_unlock((ds)->dblk) 3919 3920 /*! Check if dataset ds is locked into memory */ 3921 3922 #define DSET_LOCKED(ds) DBLK_LOCKED((ds)->dblk) 3923 3924 /*! Force this dataset to be loaded into memory using malloc(). 3925 3926 If you are altering the dataset contents, this is required, 3927 since a mmap()-ed dataset is readonly. 3928 */ 3929 #define DSET_mallocize(ds) DBLK_mallocize((ds)->dblk) 3930 3931 /*! Force this dataset to be loaded into memory using mmap() 3932 You cannot alter any sub-brick data, since mmap() is done in 3933 readonly mode. 3934 */ 3935 #define DSET_mmapize(ds) DBLK_mmapize((ds)->dblk) 3936 3937 /*! Force this dataset to be loaded into shared memory. 3938 You cannot alter any sub-brick data, since is done in 3939 readonly mode. 3940 */ 3941 #define DSET_shareize(ds) DBLK_shareize((ds)->dblk) 3942 3943 /*! Let AFNI decide how to load a dataset into memory. 3944 3945 May choose mmap() or malloc() 3946 */ 3947 #define DSET_anyize(ds) DBLK_anyize((ds)->dblk) 3948 3949 /*! Super-lock dataset ds into memory. 3950 3951 Super-locked datasets will not be unlocked by DSET_unlock 3952 */ 3953 #define DSET_superlock(ds) DBLK_superlock((ds)->dblk) /* 22 Mar 2001 */ 3954 3955 /*! Check if dataset ds is loaded into memory using malloc() */ 3956 3957 #define DSET_IS_MALLOC(ds) DBLK_IS_MALLOC((ds)->dblk) 3958 3959 /*! Check if dataset ds is loaded into memory using mmap() */ 3960 3961 #define DSET_IS_MMAP(ds) DBLK_IS_MMAP((ds)->dblk) 3962 3963 /*! Check if dataset ds is loaded into shared memory */ 3964 3965 #define DSET_IS_SHARED(ds) DBLK_IS_SHARED((ds)->dblk) 3966 3967 /*! Check if dataset ds is "mastered": gets its data from someone else. 3968 3969 Mastered datasets are specified on the command line with the [a..b] syntax, etc. 3970 */ 3971 #define DSET_IS_MASTERED(ds) DBLK_IS_MASTERED((ds)->dblk) 3972 /*! Swap dset for a fully copy of itself if it is mastered 3973 This is useful when you want to modify a loaded dset that 3974 has been mastered */ 3975 #define DSET_NEW_IF_MASTERED(dset) {\ 3976 if ((dset) && DSET_IS_MASTERED((dset))) {\ 3977 THD_3dim_dataset *dsetc=EDIT_full_copy((dset), "THE_MASTER"); \ 3978 if (dsetc) { DSET_delete((dset)); (dset)=dsetc; } \ 3979 else { ERROR_message("Failed to copy mastered dset. Nothing done."); } \ 3980 } \ 3981 } 3982 /*! Prepare a dset that has been loaded from disk to be modified 3983 and rewritten */ 3984 #define PREP_LOADED_DSET_4_REWRITE(dset, prefix) {\ 3985 DSET_NEW_IF_MASTERED((dset)); \ 3986 ZERO_IDCODE((dset)->idcode); \ 3987 (dset)->idcode = MCW_new_idcode() ; \ 3988 EDIT_dset_items( (dset) , ADN_prefix , \ 3989 (prefix) ? (prefix) : "HUMBUG", ADN_none ) ; \ 3990 } 3991 3992 /*-------------------------------------------------------------------*/ 3993 #undef TWOGIG 3994 #define TWOGIG 2100000000 /* 2 gigabytes, aboot */ 3995 3996 /* Modified 31 May 2011 to allow mmap() for big files on a 64-bit system */ 3997 3998 #define DBLK_mmapfix(db) \ 3999 do{ if( (db)->malloc_type == DATABLOCK_MEM_MMAP && \ 4000 (db)->total_bytes > TWOGIG && \ 4001 sizeof(size_t) < 8 ) \ 4002 (db)->malloc_type = DATABLOCK_MEM_MALLOC ; } while(0) 4003 4004 /*---------------------------------------------------------------------------*/ 4005 4006 extern void THD_patch_dxyz_all( THD_3dim_dataset * ) ; /* 05 Jun 2007 */ 4007 extern void THD_patch_dxyz_one( THD_3dim_dataset * , int ) ; 4008 4009 /*------------- a dynamic array type for 3D datasets ---------------*/ 4010 4011 /*! A dynamic array type for AFNI datasets. 4012 4013 This is used when collecting all the datasets in a directory into a THD_session. 4014 */ 4015 4016 typedef struct THD_3dim_dataset_array { 4017 int num ; /*!< Number of datasets stored */ 4018 int nall ; /*!< Number of datasets slots allocated */ 4019 THD_3dim_dataset**ar ; /*!< Array of datasets: [0..num-1] are in use */ 4020 } THD_3dim_dataset_array ; 4021 4022 #define INC_3DARR 8 4023 4024 /*! Initialize a new AFNI dataset array into variable "name". 4025 4026 You should declare "THD_3dim_dataset_array *name;". 4027 */ 4028 #define INIT_3DARR(name) \ 4029 ( (name) = RwcNew(THD_3dim_dataset_array) ,\ 4030 (name)->num = (name)->nall = 0 , \ 4031 (name)->ar = NULL ) 4032 4033 /*! Add dataset ddset to AFNI dataset array "name" */ 4034 4035 #define ADDTO_3DARR(name,ddset) \ 4036 { if( (name)->num == (name)->nall ){ \ 4037 (name)->nall += INC_3DARR + (name)->nall/8 ; \ 4038 (name)->ar = (THD_3dim_dataset **) \ 4039 RwcRealloc( (char *) (name)->ar , \ 4040 sizeof(THD_3dim_dataset *) * (name)->nall ) ; \ 4041 } \ 4042 if( (ddset) != NULL ){ \ 4043 (name)->ar[(name)->num] = (ddset) ; \ 4044 ((name)->num)++ ; \ 4045 } } 4046 4047 /*! Free the AFNI dataset array (but don't kill the datasets). 4048 4049 This would be used after the dataset pointers have been moved 4050 someplace else (e.g., into the THD_session structure). 4051 */ 4052 4053 #define FREE_3DARR(name) \ 4054 if( (name) != NULL ){ \ 4055 myRwcFree( (name)->ar ) ; \ 4056 myRwcFree( (name) ) ; } 4057 4058 /*! Macro to access the nn-th dataset in AFNI dataset array name */ 4059 4060 #define DSET_IN_3DARR(name,nn) ((name)->ar[(nn)]) 4061 4062 /*! Determine if two datasets are properly ordered */ 4063 4064 #define DSET_ORDERED(d1,d2) \ 4065 ( ( (d1)->view_type < (d2)->view_type ) || \ 4066 ( (d1)->view_type==(d2)->view_type && (d1)->func_type<(d2)->func_type ) ) 4067 4068 /*! Swap 2 dataset pointers (thru pointer dt) */ 4069 4070 #define DSET_SWAP(d1,d2) (dt=(d1),(d1)=(d2),(d2)=dt) 4071 4072 /*! Sort an AFNI dataset array */ 4073 4074 #define SORT_3DARR(name) \ 4075 if( (name) != NULL && (name)->num > 1 ){ \ 4076 int iid , jjd ; THD_3dim_dataset * dt ; \ 4077 for( iid=0 ; iid < (name)->num ; iid++ ){ \ 4078 for( jjd=1 ; jjd < (name)->num ; jjd++ ){ \ 4079 if( !DSET_ORDERED( (name)->ar[jjd-1] , (name)->ar[jjd] ) ) \ 4080 DSET_SWAP( (name)->ar[jjd-1] , (name)->ar[jjd] ) ; \ 4081 }}} 4082 4083 /*-------------------------------------------------------------------*/ 4084 /*-------- holds all data from a session! -----------*/ 4085 4086 #define SESSION_TYPE 97 4087 4088 /*! Holds all the datasets from a directory (session). 4089 [28 Jul 2003: modified to put elide distinction between anat and func] 4090 [20 Jan 2004: modified to put surfaces into here as well] 4091 */ 4092 4093 4094 /* each session can contain a list of dataset in different views */ 4095 /* each row can be represented by this structure showing different 4096 spaces or views for each dataset - orig, acpc, tlrc, mni,...*/ 4097 /* the dataset may be on the disk or an on-the-fly transformed 4098 version of another dataset */ 4099 typedef struct { 4100 int nds; /* the number of dataset spaces for this row */ 4101 THD_3dim_dataset **ds; /* the datasets for that "row" of spaces */ 4102 } THD_dsarr; 4103 4104 typedef struct { 4105 int type ; /*!< code indicating this is a THD_session */ 4106 int num_dsset ; /*!< Number of datasets. */ 4107 char sessname[THD_MAX_NAME] ; /*!< Name of directory datasets were read from */ 4108 char lastname[THD_MAX_NAME] ; /*!< Just/the/last/name of the directory */ 4109 #ifdef oldsessions 4110 THD_3dim_dataset *xdsset[THD_MAX_SESSION_SIZE][LAST_VIEW_TYPE+1] ; 4111 /*!< array of datasets */ 4112 #endif 4113 THD_dsarr **dsrow; /* list of pointers for dataset 4114 in different spaces */ 4115 int ndsets; /* number of datasets */ 4116 Htable *warptable ; /*!< Table of inter-dataset warps [27 Aug 2002] */ 4117 4118 /* 20 Jan 2004: put surfaces here, rather than in the datasets */ 4119 4120 int su_num ; /*!< Number of surfaces */ 4121 SUMA_surface **su_surf ; /*!< Surface array */ 4122 4123 int su_numgroup ; /*!< Number of surface groups */ 4124 SUMA_surfacegroup **su_surfgroup ; /*!< Surface group array */ 4125 4126 int su_nummask ; /*!< Number of SUMA masks (moveable surfaces) */ 4127 SUMA_mask **su_mask ; /*!< array of pointers to SUMA masks */ 4128 4129 int is_collection ; /*!< If a collection rather than a directory */ 4130 4131 RwcPointer parent ; /*!< generic pointer to "owner" of session */ 4132 } THD_session ; 4133 4134 extern char * THD_get_space(THD_3dim_dataset *dset); 4135 extern int THD_space_code(char *space); 4136 extern int space_to_NIFTI_code(THD_3dim_dataset *dset); 4137 4138 4139 extern int is_surface_storage_mode( int smode ) ; 4140 4141 extern THD_3dim_dataset * 4142 get_session_dset_id(THD_session *sess, MCW_idcode idcode, int space_index); 4143 extern THD_3dim_dataset * 4144 get_session_dset(THD_session *sess, int index, int space_index); 4145 extern int 4146 set_session_dset(THD_3dim_dataset *dset, THD_session *sess, 4147 int index, int space_index); 4148 extern void set_nspaces(int n); 4149 extern void set_atlas_nspaces(void); 4150 extern int get_nspaces(void); 4151 4152 #ifdef oldsessions 4153 #define GET_SESSION_DSET(session, index, space) \ 4154 session->xdsset[index][space] 4155 #define SET_SESSION_DSET(sdset, session, index, space) \ 4156 session->xdsset[index][space] = sdset 4157 #else 4158 #define GET_SESSION_DSET(session, index, space) \ 4159 (THD_3dim_dataset *) get_session_dset(session, index, space) 4160 #define SET_SESSION_DSET(sdset, session, index, space) \ 4161 set_session_dset(sdset, session, index, space) 4162 #endif 4163 4164 /*! Determine if ss points to a valid THD_session. */ 4165 4166 #define ISVALID_SESSION(ss) ( (ss) != NULL && (ss)->type == SESSION_TYPE ) 4167 4168 #define IS_COLLECTION(ss) ( ISVALID_SESSION(ss) && (ss)->is_collection != 0 ) 4169 4170 /*! Initialize THD_session ss to hold nothing at all. */ 4171 4172 #define BLANK_SESSION(ss) \ 4173 if( ISVALID_SESSION((ss)) ){ \ 4174 int id , vv ; \ 4175 (ss)->num_dsset = 0 ; \ 4176 (ss)->su_num = 0 ; (ss)->su_surf = NULL ; \ 4177 (ss)->su_nummask= 0 ; (ss)->su_mask = NULL ; \ 4178 (ss)->su_numgroup = 0 ; (ss)->su_surfgroup = NULL ; \ 4179 (ss)->is_collection = 0 ; \ 4180 (ss)->warptable = NULL ; (ss)->dsrow = NULL; \ 4181 for( id=0 ; id < THD_MAX_SESSION_SIZE ; id++ ) \ 4182 for( vv=0 ; vv < get_nspaces() ; vv++ ) \ 4183 SET_SESSION_DSET(NULL, ss, id, vv); \ 4184 } 4185 4186 /*! Determine if session has SUMA surface data attached. */ 4187 4188 #define SESSION_HAS_SUMA(ss) ( (ss) != NULL && \ 4189 ( ( (ss)->su_surf != NULL && (ss)->su_num > 0 ) || \ 4190 ( (ss)->su_mask != NULL && (ss)->su_nummask > 0 ) ) \ 4191 ) 4192 4193 #define SESSIONLIST_TYPE 107 4194 4195 /*! Array of THD_sessions. 4196 4197 Holds all the datasets read into AFNI from all directories. 4198 */ 4199 4200 typedef struct { 4201 int type , num_sess ; 4202 THD_session *ssar[THD_MAX_NUM_SESSION] ; 4203 RwcPointer parent ; 4204 } THD_sessionlist ; 4205 4206 /*! Determine if sl is a valid THD_sessionlist */ 4207 4208 #define ISVALID_SESSIONLIST(sl) ( (sl)!=NULL && (sl)->type==SESSIONLIST_TYPE ) 4209 4210 /*! Initialize a THD_sessionlist to contain nothing. */ 4211 4212 #define BLANK_SESSIONLIST(sl) \ 4213 if( ISVALID_SESSIONLIST((sl)) ){ \ 4214 int is ; \ 4215 for( is=0 ; is < THD_MAX_NUM_SESSION ; is++ ) (sl)->ssar[is] = NULL ; \ 4216 (sl)->num_sess = 0 ; } 4217 4218 /*! Return type for THD_sessionlist searching (see THD_dset_in_*). 4219 4220 There are different ways to search for a dataset in THD_sessionlist 4221 - FIND_NAME to find by the name field (is now obsolete) 4222 - FIND_IDCODE to find by the dataset ID code (the best way) 4223 - FIND_PREFIX to find by the dataset prefix (an OK way) 4224 */ 4225 4226 typedef struct { 4227 int sess_index ; /*!< Session it was found in */ 4228 int dset_index ; /*!< Index it was found at (if >= 0) */ 4229 int view_index ; /*!< View index it was found at (if >= 0) */ 4230 THD_3dim_dataset * dset ; /*!< Pointer to found dataset itself */ 4231 } THD_slist_find ; 4232 4233 /*! Set the find codes to indicate a bad result */ 4234 4235 #define BADFIND(ff) \ 4236 ( (ff).sess_index=(ff).dset_index=(ff).view_index=-1 , \ 4237 (ff).dset = NULL ) 4238 4239 #define FIND_NAME 1 4240 #define FIND_IDCODE 2 4241 #define FIND_PREFIX 3 4242 4243 /*******************************************************************/ 4244 /********************** attribute names ****************************/ 4245 4246 #define ATRNAME_DATANAME "DATASET_NAME" 4247 #define ATRNAME_LABEL1 "LABEL_1" 4248 #define ATRNAME_LABEL2 "LABEL_2" 4249 4250 #define ATRNAME_ANATOMY_PARENT "ANATOMY_PARENTNAME" 4251 4252 #define ATRNAME_ORIENT_SPECIFIC "ORIENT_SPECIFIC" 4253 #define ATRTYPE_ORIENT_SPECIFIC ATR_INT_TYPE 4254 #define ATRSIZE_ORIENT_SPECIFIC 3 4255 4256 #define ATRNAME_ORIENT_GENERAL "ORIENT_GENERAL" /*** not used yet ***/ 4257 #define ATRTYPE_ORIENT_GENERAL ATR_FLOAT_TYPE /* (will someday be */ 4258 #define ATRSIZE_ORIENT_GENERAL 9 /* rotation matrix) */ 4259 4260 #define ATRNAME_ORIGIN "ORIGIN" 4261 #define ATRTYPE_ORIGIN ATR_FLOAT_TYPE 4262 #define ATRSIZE_ORIGIN 3 4263 4264 #define ATRNAME_DELTA "DELTA" 4265 #define ATRTYPE_DELTA ATR_FLOAT_TYPE 4266 #define ATRSIZE_DELTA 3 4267 4268 #define ATRNAME_SKIP "SKIP" 4269 #define ATRTYPE_SKIP ATR_FLOAT_TYPE 4270 #define ATRSIZE_SKIP 3 4271 4272 #define ATRNAME_MARKSXYZ "MARKS_XYZ" 4273 #define ATRTYPE_MARKSXYZ ATR_FLOAT_TYPE 4274 #define ATRSIZE_MARKSXYZ MARKS_FSIZE 4275 4276 #define ATRNAME_MARKSLAB "MARKS_LAB" 4277 #define ATRTYPE_MARKSLAB ATR_STRING_TYPE 4278 #define ATRSIZE_MARKSLAB MARKS_LSIZE 4279 4280 #define ATRNAME_MARKSHELP "MARKS_HELP" 4281 #define ATRTYPE_MARKSHELP ATR_STRING_TYPE 4282 #define ATRSIZE_MARKSHELP MARKS_HSIZE 4283 4284 #define ATRNAME_MARKSFLAG "MARKS_FLAGS" 4285 #define ATRTYPE_MARKSFLAG ATR_INT_TYPE 4286 #define ATRSIZE_MARKSFLAG MARKS_MAXFLAG 4287 4288 #define ATRNAME_TYPESTRING "TYPESTRING" 4289 #define ATRTYPE_TYPESTRING ATR_STRING_TYPE 4290 #define ATRSIZE_TYPESTRING 0 /* 0 size means variable */ 4291 4292 #define ATRNAME_WARP_TYPE "WARP_TYPE" 4293 #define ATRTYPE_WARP_TYPE ATR_INT_TYPE 4294 #define ATRSIZE_WARP_TYPE 8 /* warp, resample (6 expansions) */ 4295 4296 #define ATRNAME_WARP_DATA "WARP_DATA" 4297 #define ATRTYPE_WARP_DATA ATR_FLOAT_TYPE 4298 #define ATRSIZE_WARP_DATA 0 4299 4300 #define ATRNAME_WARP_DATA_3DWD_AF "WARPDRIVE_MATVEC_INV_000000" /* Talairach warp via 3dWarpDrive */ 4301 #define ATRTYPE_WARP_DATA_3DWD_AF ATR_FLOAT_TYPE 4302 #define ATRSIZE_WARP_DATA_3DWD_AF 0 /* not using this one. Calv. Cool. June 24 */ 4303 4304 #define ATRNAME_WARP_PARENT "WARP_PARENTNAME" 4305 #define ATRTYPE_WARP_PARENT ATR_STRING_TYPE 4306 #define ATRSIZE_WARP_PARENT 0 4307 4308 #define ATRNAME_SCENE_TYPE "SCENE_DATA" 4309 #define ATRTYPE_SCENE_TYPE ATR_INT_TYPE 4310 #define ATRSIZE_SCENE_TYPE 8 /* view, func, type (+5) */ 4311 4312 #define ATRNAME_DATASET_RANK "DATASET_RANK" 4313 #define ATRTYPE_DATASET_RANK ATR_INT_TYPE 4314 #define ATRSIZE_DATASET_RANK 8 /* # dims, # vals (+6) */ 4315 4316 #define ATRNAME_DATASET_DIMENSIONS "DATASET_DIMENSIONS" 4317 #define ATRTYPE_DATASET_DIMENSIONS ATR_INT_TYPE 4318 #define ATRSIZE_DATASET_DIMENSIONS THD_MAX_RANK_EVER 4319 4320 #define ATRNAME_MINMAX "MINMAX" 4321 #define ATRTYPE_MINMAX ATR_INT_TYPE 4322 4323 #if 0 4324 # define ATRNAME_DATASET_PREFIX "DATASET_PREFIX" 4325 # define ATRTYPE_DATASET_PREFIX ATR_STRING_TYPE 4326 # define ATRSIZE_DATASET_PREFIX THD_MAX_PREFIX 4327 4328 # define ATRNAME_DATASET_VIEWCODE "DATASET_VIEWCODE" 4329 # define ATRTYPE_DATASET_VIEWCODE ATR_STRING_TYPE 4330 # define ATRSIZE_DATASET_VIEWCODE THD_MAX_VIEWCODE 4331 #endif 4332 4333 /** additions 1995 Nov 15, for variable brick data types **/ 4334 4335 #define ATRNAME_BRICK_TYPES "BRICK_TYPES" 4336 #define ATRTYPE_BRICK_TYPES ATR_INT_TYPE 4337 #define ATRSIZE_BRICK_TYPES 0 4338 4339 #define ATRNAME_BRICK_STATS "BRICK_STATS" 4340 #define ATRTYPE_BRICK_STATS ATR_FLOAT_TYPE 4341 #define ATRSIZE_BRICK_STATS 0 4342 4343 #define ATRNAME_BRICK_FLTFAC "BRICK_FLOAT_FACS" 4344 #define ATRTYPE_BRICK_FLTFAC ATR_FLOAT_TYPE 4345 #define ATRSIZE_BRICK_FLTFAC 0 4346 4347 /** 1996 Mar 26 **/ 4348 4349 #define ATRNAME_STAT_AUX "STAT_AUX" 4350 #define ATRTYPE_STAT_AUX ATR_FLOAT_TYPE 4351 #define ATRSIZE_STAT_AUX 0 4352 4353 /** 1996 May 14 **/ 4354 4355 #define ATRNAME_TAXIS_NUMS "TAXIS_NUMS" 4356 #define ATRSIZE_TAXIS_NUMS 8 4357 4358 #define ATRNAME_TAXIS_FLOATS "TAXIS_FLOATS" 4359 #define ATRSIZE_TAXIS_FLOATS 8 4360 4361 #define ATRNAME_TAXIS_OFFSETS "TAXIS_OFFSETS" 4362 #define ATRSIZE_TAXIS_OFFSETS 0 4363 4364 /** 30 Nov 1997 **/ 4365 4366 #define ATRNAME_BRICK_LABS "BRICK_LABS" 4367 #define ATRNAME_BRICK_STATAUX "BRICK_STATAUX" 4368 #define ATRNAME_BRICK_KEYWORDS "BRICK_KEYWORDS" 4369 4370 #define ATRNAME_KEYWORDS "DATASET_KEYWORDS" 4371 4372 #ifdef __cplusplus 4373 } 4374 #endif 4375 4376 /************************************************************************/ 4377 /******************* rest of prototypes *********************************/ 4378 4379 /** #include <stdarg.h> **/ 4380 #ifdef __cplusplus 4381 extern "C" { 4382 #endif 4383 4384 #ifndef DONT_USE_SCANDIR 4385 #ifdef SCANDIR_WANTS_CONST 4386 extern int THD_select_dirent( const struct dirent * dp ) ; 4387 #else 4388 extern int THD_select_dirent( struct dirent * dp ) ; 4389 #endif 4390 #endif 4391 4392 char * ig_strstr( char *, char *, char * ) ; /* 08 Aug 2002 */ 4393 void freeup_strings( int n , char **sar ) ; 4394 int breakup_string( char *sin , char ***stok ) ; 4395 4396 extern THD_string_array * THD_get_all_filenames( char * ) ; 4397 extern THD_string_array * THD_extract_regular_files( THD_string_array * ) ; 4398 extern THD_string_array * THD_extract_directories( THD_string_array * ) ; 4399 extern int THD_is_file ( char * ) ; 4400 extern int THD_is_fifo ( char * ) ; /* 27 Aug 2019 */ 4401 extern int THD_is_symlink ( char * ) ; /* 03 Mar 1999 */ 4402 extern int THD_is_directory( char * ) ; 4403 extern int THD_forbidden_directory( char *) ; /* 18 Sep 2020 */ 4404 4405 #define THD_is_good_directory(ddd) \ 4406 ( THD_is_directory(ddd) && !THD_forbidden_directory(ddd) ) 4407 4408 extern int THD_is_ondisk ( char * ) ; /* 19 Dec 2002 */ 4409 extern int THD_is_prefix_ondisk( char *pathname, int stripsels ) ; /* Dec 2011 */ 4410 extern int THD_mkdir ( char * ) ; /* 19 Dec 2002 */ 4411 extern int THD_cwd ( char * ) ; /* 19 Dec 2002 */ 4412 extern int THD_equiv_files ( char * , char * ) ; 4413 extern long long THD_filesize( char * pathname ) ; 4414 extern int THD_filetime_diff( char *pathname, 4415 int year, int month, int day); 4416 extern char *THD_filetime( char *pathname ); 4417 extern char *THD_homedir(byte withslash); 4418 extern char *THD_custom_atlas_dir(byte withslash); 4419 extern char *THD_get_custom_atlas_dir(byte withslash); 4420 extern char *THD_afnirc(void); 4421 extern char *THD_custom_atlas_file(char *name); 4422 extern char *THD_helpdir(byte withslash); 4423 extern char *THD_get_helpdir(byte withslash); 4424 extern char *THD_datadir(byte withslash); 4425 extern char *THD_get_datadir(byte withslash); 4426 extern char *THD_abindir(byte withslash); 4427 extern char * THD_facedir(byte withslash); 4428 extern char *find_afni_file(char * nimlname, int niname, char *altpath); 4429 char *THD_helpsearchlog(int createpath); 4430 4431 extern THD_string_array * THD_get_all_subdirs( int , char * ) ; 4432 extern THD_string_array * THD_normalize_flist( THD_string_array * ) ; 4433 extern THD_string_array * THD_get_wildcard_filenames( char * ) ; 4434 4435 extern int THD_check_for_duplicates( int, char **, int ) ; /* 31 May 2007 */ 4436 4437 extern time_t THD_file_mtime( char * ) ; /* 05 Dec 2001 */ 4438 extern char *af_strnstr(char *s1, char *s2, size_t n); 4439 extern char *TrimString(char *lbl, int mxlen); 4440 extern THD_string_array * THD_get_all_files( char *, char ) ; /* 08 Jun 2011 */ 4441 extern THD_string_array * THD_getpathprogs( THD_string_array *, char ); 4442 extern THD_string_array * THD_get_all_afni_executables(void ); 4443 extern THD_string_array * THD_get_all_afni_readmes(void); 4444 extern int list_afni_programs(int withpath, int withnum); 4445 extern int list_afni_readmes(int withpath, int withnum); 4446 extern int list_afni_dsets(int withpath, int withnum); 4447 extern int THD_is_executable( char * pathname ) ; 4448 int progopt_C_array(FILE *fout, int verb, char *thisprog, int appendmode); 4449 char *form_C_progopt_string(char *prog, char **ws, int N_ws); 4450 char *phelp(char *prog, TFORM targ, int verb); 4451 char *sphelp(char *prog, char **str, TFORM targ, int verb); 4452 int phelp_cmd(char *prog, TFORM targ, char cmd[512], char fout[128], int verb ); 4453 int program_supports(char *prog, char *opt, char *oval, int verb); 4454 char *find_popt(char *sh, char *opt, int *nb); 4455 int prog_complete_command (char *prog, char *ofile, int shtp); 4456 void view_prog_help(char *prog); 4457 void web_prog_help(char *prog, int style); 4458 char *web_prog_help_link(char *prog, int style); 4459 void web_class_docs(char *prog); 4460 int view_web_link(char *link, char *browser); 4461 int view_text_file(char *progname) ; 4462 extern char * THD_find_executable( char * ) ; 4463 extern char * THD_find_regular_file( char * , char *) ; 4464 extern THD_string_array *get_elist(void); 4465 char *find_readme_file(char *str); 4466 4467 extern int THD_is_dataset( char * , char * , int ) ; /* 17 Mar 2000 */ 4468 extern char * THD_dataset_headname( char * , char * , int ) ; 4469 4470 /*--------------------- functions for reading tables -------------------------*/ 4471 4472 extern NI_element * THD_simple_table_read( char *fname ) ; /* 19 May 2010 */ 4473 extern NI_element * THD_mixed_table_read ( char *fname ) ; /* 26 Jul 2010 */ 4474 extern NI_element * THD_string_table_read( char *fname , int flags ) ; 4475 4476 /*--------------------- functions for TSV (.tsv) files -----------------------*/ 4477 4478 extern NI_element * THD_read_tsv(char *fname) ; /* 12 Sep 2018 */ 4479 extern void THD_write_tsv( char *fname , NI_element *nel ) ; 4480 extern void THD_set_tsv_column_labels( NI_element *fnel , char **clab ) ; 4481 extern NI_element * THD_mri_to_tsv_element( MRI_IMAGE *imin , char **clab ) ; 4482 extern MRI_IMAGE * THD_niml_to_mri( NI_element *nel ) ; 4483 4484 extern NI_element * THD_read_csv(char *fname) ; /* 15 Apr 2019 */ 4485 extern void THD_write_csv( char *fname , NI_element *nel ) ; 4486 extern void THD_set_csv_column_labels( NI_element *fnel , char **clab ) ; 4487 extern NI_element * THD_mri_to_csv_element( MRI_IMAGE *imin , char **clab ) ; 4488 4489 extern NI_ELARR * THD_get_many_tcsv( THD_string_array * dlist ) ; /* 16 Jun 2020 */ 4490 extern NI_ELARR * THD_get_all_tcsv( char * dname ) ; 4491 4492 /*---------------------------------------------------------------------------*/ 4493 4494 extern MRI_IMARR * THD_get_all_timeseries( char * ) ; 4495 extern MRI_IMARR * THD_get_many_timeseries( THD_string_array * ) ; 4496 extern char * THD_trailname( char * fname , int lev ) ; 4497 extern char * THD_filepath( char *fname ); 4498 extern int THD_filehaspath ( char *fname); 4499 extern int THD_linecount( char * ) ; 4500 4501 extern void THD_read_all_atr ( char * , THD_datablock * ) ; 4502 extern void THD_erase_all_atr( THD_datablock * ) ; 4503 extern void THD_erase_one_atr( THD_datablock * , char * ) ; 4504 extern void THD_read_niml_atr( char * , THD_datablock * ) ; /* 01 Jun 2005 */ 4505 4506 extern void THD_anonymize_dset ( THD_3dim_dataset * ) ; /* 08 Jul 2005 */ 4507 extern void THD_anonymize_write( int ) ; 4508 4509 extern ATR_any * THD_find_atr ( THD_datablock * , char * ) ; 4510 extern ATR_float * THD_find_float_atr ( THD_datablock * , char * ) ; 4511 extern ATR_int * THD_find_int_atr ( THD_datablock * , char * ) ; 4512 extern ATR_string * THD_find_string_atr( THD_datablock * , char * ) ; 4513 4514 extern void THD_set_atr( THD_datablock * , char * , int,int, void * ) ; 4515 4516 extern ATR_any * THD_copy_atr( ATR_any *atr ) ; /* 03 Aug 2005 */ 4517 extern void THD_insert_atr( THD_datablock *blk , ATR_any *atr ) ; 4518 extern int THD_copy_labeltable_atr( THD_datablock *d1, THD_datablock *d2); 4519 4520 extern void THD_store_dataset_keywords ( THD_3dim_dataset * , char * ) ; 4521 extern void THD_append_dataset_keywords( THD_3dim_dataset * , char * ) ; 4522 extern char * THD_dataset_info( THD_3dim_dataset * , int ) ; 4523 extern char * THD_dset_subbrick_info( THD_3dim_dataset * , int ); 4524 4525 extern int THD_subbrick_minmax( THD_3dim_dataset *dset, int isb, int scl, 4526 float *min, float *max); 4527 extern float THD_subbrick_max(THD_3dim_dataset *dset, int isb, int scl); 4528 extern float THD_subbrick_min(THD_3dim_dataset *dset, int isb, int scl); 4529 extern int THD_dset_minmax( THD_3dim_dataset *dset, int scl, 4530 float *min, float *max); 4531 extern int THD_slow_minmax_dset(THD_3dim_dataset *dset, 4532 float *dmin, float *dmax, int iv_bot, int iv_top); 4533 extern float THD_dset_max(THD_3dim_dataset *dset, int scl); 4534 extern float THD_dset_min(THD_3dim_dataset *dset, int scl); 4535 extern float THD_dset_extent(THD_3dim_dataset *dset, char ret,float *RL_AP_IS); 4536 extern float THD_dset_extent_rlpais(THD_3dim_dataset *dset, char ret, 4537 float *RL_PA_IS); 4538 4539 extern void THD_show_dataset_names( THD_3dim_dataset *dset, 4540 char *head, FILE *out); 4541 extern const char * storage_mode_str(int); 4542 extern int dset_obliquity(THD_3dim_dataset *dset , float *anglep); 4543 double dset_obliquity_angle_diff(THD_3dim_dataset *dset1, 4544 THD_3dim_dataset *dset2, 4545 double tol); 4546 double daxes_obliquity_angle_diff(THD_dataxes *ax1, THD_dataxes *ax2, 4547 double tol); 4548 extern void THD_set_float_atr( THD_datablock * , char * , int , float * ) ; 4549 extern void THD_set_int_atr ( THD_datablock * , char * , int , int * ) ; 4550 extern void THD_set_char_atr ( THD_datablock * , char * , int , char * ) ; 4551 4552 /*! Macro to set a string attribute from a C string (vs. a char array). */ 4553 4554 #define THD_set_string_atr(blk,name,str) \ 4555 THD_set_char_atr( (blk) , (name) , strlen(str)+1 , (str) ) 4556 4557 extern void THD_init_diskptr_names( THD_diskptr *, char *,char *,char * , 4558 int, RwcBoolean ) ; 4559 4560 extern THD_datablock * THD_init_one_datablock( char *,char * ) ; 4561 extern THD_datablock_array * THD_init_prefix_datablocks( char *, THD_string_array * ) ; 4562 4563 extern RwcPointer_array * THD_init_alldir_datablocks( char * ) ; 4564 4565 extern THD_session * THD_init_session( char * ) ; 4566 extern void THD_order_session( THD_session * ) ; /* 29 Jul 2003 */ 4567 extern void THD_append_sessions( THD_session *, THD_session *); /* 20 Dec 2001 */ 4568 4569 extern char * THD_suck_pipe( char *cmd ) ; /* 01 Feb 2018 */ 4570 extern NI_str_array * THD_get_subdirs_bysub( char *dirname , char *subid ) ; 4571 extern THD_session * THD_init_session_bysub( char *dirname , char *subid ) ; 4572 extern THD_session * THD_init_session_recursive( char *dirname ) ; 4573 4574 extern char * Add_plausible_path(char *fname); /* ZSS:Aug. 08 */ 4575 extern THD_3dim_dataset * THD_open_one_dataset( char * ) ; 4576 extern THD_3dim_dataset * THD_open_dataset( char * ) ; /* 11 Jan 1999 */ 4577 extern THD_3dim_dataset * THD_open_analyze( char * ) ; /* 27 Aug 2002 */ 4578 extern THD_3dim_dataset * THD_open_ctfmri( char * ) ; /* 04 Dec 2002 */ 4579 extern THD_3dim_dataset * THD_open_ctfsam( char * ) ; /* 04 Dec 2002 */ 4580 extern THD_3dim_dataset * THD_open_1D( char * ) ; /* 04 Mar 2003 */ 4581 extern THD_3dim_dataset * THD_open_3D( char * ) ; /* 21 Mar 2003 */ 4582 extern THD_3dim_dataset * THD_open_nifti( char * ) ; /* 28 Aug 2003 */ 4583 extern THD_3dim_dataset * THD_open_mpeg( char * ) ; /* 03 Dec 2003 */ 4584 extern THD_3dim_dataset * THD_open_tcat( char * ) ; /* 04 Aug 2004 */ 4585 extern THD_3dim_dataset * THD_open_niml( char * ) ; /* 01 Jun 2006 */ 4586 extern THD_3dim_dataset * THD_open_gifti( char * ) ; /* 13 Feb 2008 */ 4587 4588 extern THD_3dim_dataset * THD_open_image( char *fname ) ; /* 06 Jul 2016 */ 4589 extern THD_3dim_dataset * THD_image_to_dset( MRI_IMAGE *im , char *prefix ) ; 4590 4591 extern THD_string_array * THD_multiplex_dataset( char * ) ; /* 19 Jul 2007 */ 4592 4593 extern THD_3dim_dataset * THD_niml_3D_to_dataset( NI_element *, char * ) ; 4594 extern THD_3dim_dataset * THD_ni_surf_dset_to_afni( NI_group *, int ) ; 4595 extern void * read_niml_file( char *, int ) ; 4596 extern int storage_mode_from_niml( void * ) ; 4597 extern int niml_get_major_label_order( char * ) ; /* 28 Jul 2009 */ 4598 4599 4600 extern int NI_write_gifti( NI_group *, char * , int); 4601 extern NI_group * NI_read_gifti( char * , int ) ; 4602 4603 extern int storage_mode_from_filename( char * fname ); /* 20 Apr 2006 */ 4604 int storage_mode_from_prefix( char * fname ); 4605 extern char *storage_mode_name(int mode); 4606 extern int has_known_non_afni_extension( char * fname ) ; /* [rickr] */ 4607 extern int is_writable_storage_mode( int smode ) ; /* 05 Mar 2012 */ 4608 extern char * find_filename_extension( char * fname ); 4609 extern char * modify_afni_prefix( char * fname , char *pref, char *suf); 4610 extern char * without_afni_filename_extension( char *fname); 4611 char * without_afni_filename_view_and_extension( char * fname ); 4612 4613 extern void THD_datablock_apply_atr( THD_3dim_dataset * ) ; /* 09 May 2005 */ 4614 4615 extern THD_3dim_dataset * THD_fetch_dataset (char *) ; /* 23 Mar 2001 */ 4616 extern RwcPointer_array * THD_fetch_many_datasets(char *) ; 4617 extern MRI_IMAGE * THD_fetch_1D (char *) ; /* 26 Mar 2001 */ 4618 4619 extern void THD_set_storage_mode( THD_3dim_dataset *,int ); /* 21 Mar 2003 */ 4620 4621 extern int * get_count_intlist (char *str, int *nret, int maxval ); 4622 extern int * get_count_intlist_eng(char *str, int *nret, int maxval, int ok_neg); 4623 /* get_1dcat_intlist: May 15 2012 ZSS ; added maxval 4 Jan 2016 [rickr] */ 4624 int * get_1dcat_intlist ( char *str , int *nret, int maxval); 4625 int * get_1dcat_intlist_eng( char *str , int *nret, int maxval, int ok_neg); 4626 4627 extern int * MCW_get_intlist( int , char * ) ; 4628 extern int * MCW_get_labels_intlist( char ** , int, char * ); /* ZSS Dec 09 */ 4629 extern int * MCW_get_thd_intlist( THD_3dim_dataset * , char * ); /* ZSS Dec 09 */ 4630 extern void MCW_intlist_allow_negative( int ) ; /* 22 Nov 1999 */ 4631 extern int MCW_get_angle_range(THD_3dim_dataset *, char *, float *, float *); 4632 extern int thd_check_angle_selector(THD_3dim_dataset *, char *); /* 21 Nov 2016 */ 4633 4634 4635 /* copy a dataset, given a list of sub-bricks [rickr] 26 Jul 2004 */ 4636 extern THD_3dim_dataset * THD_copy_dset_subs( THD_3dim_dataset * , int * ) ; 4637 extern THD_3dim_dataset * THD_copy_one_sub ( THD_3dim_dataset * , int ) ; 4638 4639 /*! Help string to explain dataset "mastering" briefly. */ 4640 4641 #define MASTER_SHORTHELP_STRING \ 4642 "INPUT DATASET NAMES\n" \ 4643 "-------------------\n" \ 4644 "This program accepts datasets that are modified on input according to the\n" \ 4645 "following schemes:\n" \ 4646 " 'r1+orig[3..5]' {sub-brick selector}\n" \ 4647 " 'r1+orig<100..200>' {sub-range selector}\n" \ 4648 " 'r1+orig[3..5]<100..200>' {both selectors}\n" \ 4649 " '3dcalc( -a r1+orig -b r2+orig -expr 0.5*(a+b) )' {calculation}\n" \ 4650 "For the gruesome details, see the output of 'afni -help'.\n" 4651 4652 /*! Help string to explain dataset "mastering" at length. */ 4653 4654 #define MASTER_HELP_STRING \ 4655 "INPUT DATASET NAMES\n" \ 4656 "-------------------\n" \ 4657 " An input dataset is specified using one of these forms:\n" \ 4658 " 'prefix+view', 'prefix+view.HEAD', or 'prefix+view.BRIK'.\n" \ 4659 " You can also add a sub-brick selection list after the end of the\n" \ 4660 " dataset name. This allows only a subset of the sub-bricks to be\n" \ 4661 " read in (by default, all of a dataset's sub-bricks are input).\n" \ 4662 " A sub-brick selection list looks like one of the following forms:\n" \ 4663 " fred+orig[5] ==> use only sub-brick #5\n" \ 4664 " fred+orig[5,9,17] ==> use #5, #9, and #17\n" \ 4665 " fred+orig[5..8] or [5-8] ==> use #5, #6, #7, and #8\n" \ 4666 " fred+orig[5..13(2)] or [5-13(2)] ==> use #5, #7, #9, #11, and #13\n" \ 4667 " Sub-brick indexes start at 0. You can use the character '$'\n" \ 4668 " to indicate the last sub-brick in a dataset; for example, you\n" \ 4669 " can select every third sub-brick by using the selection list\n" \ 4670 " fred+orig[0..$(3)]\n" \ 4671 "\n" \ 4672 " N.B.: The sub-bricks are read in the order specified, which may\n" \ 4673 " not be the order in the original dataset. For example, using\n" \ 4674 " fred+orig[0..$(2),1..$(2)]\n" \ 4675 " will cause the sub-bricks in fred+orig to be input into memory\n" \ 4676 " in an interleaved fashion. Using\n" \ 4677 " fred+orig[$..0]\n" \ 4678 " will reverse the order of the sub-bricks.\n" \ 4679 "\n" \ 4680 " N.B.: You may also use the syntax <a..b> after the name of an input \n" \ 4681 " dataset to restrict the range of values read in to the numerical\n" \ 4682 " values in a..b, inclusive. For example,\n" \ 4683 " fred+orig[5..7]<100..200>\n" \ 4684 " creates a 3 sub-brick dataset with values less than 100 or\n" \ 4685 " greater than 200 from the original set to zero.\n" \ 4686 " If you use the <> sub-range selection without the [] sub-brick\n" \ 4687 " selection, it is the same as if you had put [0..$] in front of\n" \ 4688 " the sub-range selection.\n" \ 4689 "\n" \ 4690 " N.B.: Datasets using sub-brick/sub-range selectors are treated as:\n" \ 4691 " - 3D+time if the dataset is 3D+time and more than 1 brick is chosen\n" \ 4692 " - otherwise, as bucket datasets (-abuc or -fbuc)\n" \ 4693 " (in particular, fico, fitt, etc datasets are converted to fbuc!)\n" \ 4694 "\n" \ 4695 " N.B.: The characters '$ ( ) [ ] < >' are special to the shell,\n" \ 4696 " so you will have to escape them. This is most easily done by\n" \ 4697 " putting the entire dataset plus selection list inside forward\n" \ 4698 " single quotes, as in 'fred+orig[5..7,9]', or double quotes \"x\".\n" 4699 4700 4701 /*! Help string to explain catenated datasets. */ 4702 4703 #define CATENATE_HELP_STRING \ 4704 "CATENATED AND WILDCARD DATASET NAMES\n" \ 4705 "------------------------------------\n" \ 4706 " Datasets may also be catenated or combined in memory, as if one first\n"\ 4707 " ran 3dTcat or 3dbucket.\n" \ 4708 " \n" \ 4709 " An input with space-separated elements will be read as a concatenated\n"\ 4710 " dataset, as with 'dset1+tlrc dset2+tlrc dset3+tlrc', or with paths,\n" \ 4711 " 'dir/dset1+tlrc dir/dset2+tlrc dir/dset3+tlrc'.\n" \ 4712 " The datasets will be combined (as if by 3dTcat) and then treated as a\n"\ 4713 " single input dataset. Note that the quotes are required to specify\n"\ 4714 " them as a single argument.\n" \ 4715 " \n" \ 4716 " Sub-brick selection using '[]' works with space separated dataset\n" \ 4717 " names. If the selector is at the end, it is considered global and\n" \ 4718 " applies to all inputs. Otherwise, it applies to the adjacent input.\n" \ 4719 " For example:\n" \ 4720 " local: 'dset1+tlrc[2,3] dset2+tlrc[7,0,1] dset3+tlrc[5,0,$]'\n" \ 4721 " global: 'dset1+tlrc dset2+tlrc dset3+tlrc[5,6]'\n" \ 4722 " \n" \ 4723 " N.B. If AFNI_PATH_SPACES_OK is set to Yes, will be considered as part\n"\ 4724 " of the dataset name, and not as a separator between them.\n" \ 4725 " \n" \ 4726 " Similar treatment applies when specifying datasets using a wildcard\n" \ 4727 " pattern, using '*' or '?', as in: 'dset*+tlrc.HEAD'. Any sub-brick\n" \ 4728 " selectors would apply to all matching datasets, as with:\n" \ 4729 " 'dset*+tlrc.HEAD[2,5,3]'\n" \ 4730 " \n" \ 4731 " N.B.: complete filenames are required when using wildcard matching,\n"\ 4732 " or no files will exist to match, e.g. 'dset*+tlrc' would not work.\n" \ 4733 " \n" \ 4734 " N.B.: '[]' are processed as sub-brick or time point selectors. They\n" \ 4735 " are therefore not allowed as wildcard characters in this context.\n" \ 4736 " \n" \ 4737 " Space and wildcard catenation can be put together. In such a case,\n" \ 4738 " spaces divide the input into wildcard pieces, which are processed\n" \ 4739 " individually.\n" \ 4740 " \n" \ 4741 " Examples (each is processed as a single, combined dataset):\n" \ 4742 " \n" \ 4743 " 'dset1+tlrc dset2+tlrc dset3+tlrc'\n" \ 4744 " 'dset1+tlrc dset2+tlrc dset3+tlrc[2,5,3]'\n" \ 4745 " 'dset1+tlrc[3] dset2+tlrc[0,1] dset3+tlrc[3,0,1]'\n" \ 4746 " \n" \ 4747 " 'dset*+tlrc.HEAD'\n" \ 4748 " 'dset*+tlrc.HEAD[2,5,3]'\n" \ 4749 " 'dset1*+tlrc.HEAD[0,1] dset2*+tlrc.HEAD[7,8]'\n" \ 4750 " \n" \ 4751 " 'group.*/subj.*/stats*+tlrc.HEAD[7]'\n" 4752 4753 /*! Help string to explain calculated datasets. */ 4754 4755 #define CALC_HELP_STRING \ 4756 "CALCULATED DATASETS\n" \ 4757 "-------------------\n" \ 4758 " Datasets may also be specified as runtime-generated results from\n" \ 4759 " program 3dcalc. This type of dataset specifier is enclosed in\n" \ 4760 " quotes, and starts with the string '3dcalc(':\n" \ 4761 " '3dcalc( opt opt ... opt )'\n" \ 4762 " where each 'opt' is an option to program 3dcalc; this program\n" \ 4763 " is run to generate a dataset in the directory given by environment\n" \ 4764 " variable TMPDIR (default=/tmp). This dataset is then read into\n" \ 4765 " memory, locked in place, and deleted from disk. For example\n" \ 4766 " afni -dset '3dcalc( -a r1+orig -b r2+orig -expr 0.5*(a+b) )'\n" \ 4767 " will let you look at the average of datasets r1+orig and r2+orig.\n" \ 4768 " N.B.: using this dataset input method will use lots of memory!\n" 4769 4770 /*! Help string to explain 1D column and row selection. [01 May 2003] */ 4771 4772 #define TS_HELP_STRING \ 4773 "TIMESERIES (1D) INPUT\n" \ 4774 "---------------------\n" \ 4775 "A timeseries file is in the form of a 1D or 2D table of ASCII numbers;\n" \ 4776 "for example: 3 5 7\n" \ 4777 " 2 4 6\n" \ 4778 " 0 3 3\n" \ 4779 " 7 2 9\n" \ 4780 "This example has 4 rows and 3 columns. Each column is considered as\n" \ 4781 "a timeseries in AFNI. The convention is to store this type of data\n" \ 4782 "in a filename ending in '.1D'.\n" \ 4783 "\n" \ 4784 "** COLUMN SELECTION WITH [] **\n" \ 4785 "When specifying a timeseries file to an command-line AFNI program, you\n" \ 4786 "can select a subset of columns using the '[...]' notation:\n" \ 4787 " 'fred.1D[5]' ==> use only column #5\n" \ 4788 " 'fred.1D[5,9,17]' ==> use columns #5, #9, and #17\n" \ 4789 " 'fred.1D[5..8]' ==> use columns #5, #6, #7, and #8\n" \ 4790 " 'fred.1D[5..13(2)]' ==> use columns #5, #7, #9, #11, and #13\n" \ 4791 "Column indices start at 0. You can use the character '$'\n" \ 4792 "to indicate the last column in a 1D file; for example, you\n" \ 4793 "can select every third column in a 1D file by using the selection list\n" \ 4794 " 'fred.1D[0..$(3)]' ==> use columns #0, #3, #6, #9, ....\n" \ 4795 "\n" \ 4796 "** ROW SELECTION WITH {} **\n" \ 4797 "Similarly, you select a subset of the rows using the '{...}' notation:\n" \ 4798 " 'fred.1D{0..$(2)}' ==> use rows #0, #2, #4, ....\n" \ 4799 "You can also use both notations together, as in\n" \ 4800 " 'fred.1D[1,3]{1..$(2)}' ==> columns #1 and #3; rows #1, #3, #5, ....\n" \ 4801 "\n" \ 4802 "** DIRECT INPUT OF DATA ON THE COMMAND LINE WITH 1D: **\n" \ 4803 "You can also input a 1D time series 'dataset' directly on the command\n" \ 4804 "line, without an external file. The 'filename' for such input has the\n" \ 4805 "general format\n" \ 4806 " '1D:n_1@val_1,n_2@val_2,n_3@val_3,...'\n" \ 4807 "where each 'n_i' is an integer and each 'val_i' is a float. For\n" \ 4808 "example\n" \ 4809 " -a '1D:5@0,10@1,5@0,10@1,5@0'\n" \ 4810 "specifies that variable 'a' be assigned to a 1D time series of 35,\n" \ 4811 "alternating in blocks between values 0 and value 1.\n" \ 4812 " * Spaces or commas can be used to separate values.\n" \ 4813 " * A '|' character can be used to start a new input \"line\":\n" \ 4814 " Try 1dplot '1D: 3 4 3 5 | 3 5 4 3'\n" \ 4815 "\n" \ 4816 "** TRANSPOSITION WITH \\' **\n" \ 4817 "Finally, you can force most AFNI programs to transpose a 1D file on\n" \ 4818 "input by appending a single ' character at the end of the filename.\n" \ 4819 "N.B.: Since the ' character is also special to the shell, you'll\n" \ 4820 " probably have to put a \\ character before it. Examples:\n" \ 4821 " 1dplot '1D: 3 2 3 4 | 2 3 4 3' and\n" \ 4822 " 1dplot '1D: 3 2 3 4 | 2 3 4 3'\\'\n" \ 4823 "When you have reached this level of understanding, you are ready to\n" \ 4824 "take the AFNI Jedi Master test. I won't insult you by telling you\n" \ 4825 "where to find this examination.\n" 4826 4827 /*---------------------------- TSV (.tsv) file help -------------------------*/ 4828 4829 #undef TSV_HELP_STRING 4830 #define TSV_HELP_STRING \ 4831 "TAB SEPARATED VALUE (.tsv) FILES [Sep 2018]\n" \ 4832 "-------------------------------------------\n" \ 4833 "These files are used in BIDS http://bids.neuroimaging.io and AFNI\n" \ 4834 "programs can read these in a few places.\n" \ 4835 "\n" \ 4836 "The format of a .tsv file is a set of columns, where the values in\n" \ 4837 "each row are separated by tab characters -- spaces are NOT separators.\n" \ 4838 "Each element is string, some of which are numeric (e.g. 3.1416).\n" \ 4839 "The first row of a .tsv file is a set of strings which are column\n" \ 4840 "desciptors (separated by tabs, of course). For the most part, the\n" \ 4841 "following data in each column are exclusively numeric or exclusively\n" \ 4842 "strings. Strings can contain blanks/spaces since only tabs are used\n" \ 4843 "to separate values.\n" \ 4844 "\n" \ 4845 "A .tsv file can be read in most places where a .1D file is read.\n" \ 4846 "However, columns (after the header row) that are not purely numeric\n" \ 4847 "will be ignored, since the internal usage of .1D data in AFNI is numeric.\n" \ 4848 "Thus, you can do something like\n" \ 4849 " 1dplot -nopush -sepscl sub-10506_task-pamenc_events.tsv\n" \ 4850 "and you will get a plot of all the numeric columns in this BIDS file.\n" \ 4851 "Column selection '[]' can be done, using numbers to specify columns\n" \ 4852 "or using the column labels in the .tsv file.\n" \ 4853 "\n" \ 4854 "N.B.: The string 'N/A' or 'n/a' in a column that is otherwise numeric\n" \ 4855 " will be considered to be a number, and will be replaced on input\n" \ 4856 " with the mean of the \"true\" numbers in the column -- there is\n" \ 4857 " no concept of missing data in an AFNI .1D file.\n" \ 4858 " ++ If you don't like this, well ... too bad for you.\n" \ 4859 "\n" \ 4860 "Program 1dcat has special knowledge of .tsv files, and will cat\n" \ 4861 "(sideways - along rows) .tsv and .1D files together. It also has an\n" \ 4862 "option to write the output in .tsv format.\n" \ 4863 "\n" \ 4864 "For example, to get the 'onset', 'duration', and 'trial_type' columns\n" \ 4865 "out of a BIDS task .tsv file, a command like this could be used:\n" \ 4866 " 1dcat sub-10506_task-pamenc_events.tsv'[onset,duration,trial_type]'\n" \ 4867 "Note that the column headers are lost in this output, but could be kept\n" \ 4868 "if the 1dcat '-tsvout' option were used. In reverse, a numeric .1D file\n" \ 4869 "can be converted to .tsv format by a command like:\n" \ 4870 " 1dcat -tsvout Fred.1D\n" \ 4871 "In this case, since a the data for .1D file doesn't have headers for its\n" \ 4872 "columns, 1dcat will invent some column names.\n" \ 4873 "\n" \ 4874 "At this time, other programs don't 'know' much about .tsv files, and will\n" \ 4875 "ignore the header row and non-numeric columns when reading a .tsv file.\n" \ 4876 "in place of a .1D file.\n" 4877 4878 /*----------------------------------------------------------------------------*/ 4879 4880 extern void THD_delete_3dim_dataset( THD_3dim_dataset * , RwcBoolean ) ; 4881 extern void *DSET_Label_Dtable(THD_3dim_dataset *dset); 4882 extern THD_3dim_dataset * THD_3dim_from_block( THD_datablock * ) ; 4883 extern void THD_allow_empty_dataset( int ) ; /* 23 Mar 2001 */ 4884 extern THD_3dim_dataset_array * 4885 THD_array_3dim_from_block( THD_datablock_array * blk_arr ) ; 4886 4887 extern RwcBoolean THD_write_3dim_dataset( char *,char * , 4888 THD_3dim_dataset * , RwcBoolean ); 4889 4890 extern int THD_get_write_error_count(void) ; /* 23 Sep 2013 */ 4891 extern void THD_reset_write_error_count(void) ; 4892 4893 extern void THD_use_3D_format ( int ) ; /* 21 Mar 2003 */ 4894 extern void THD_use_NIFTI_format( int ) ; /* 06 Apr 2005 */ 4895 extern void THD_set_quiet_overwrite ( int ) ; /* 31 Jan 2011 */ 4896 extern int THD_get_quiet_overwrite (void );/* 31 Jan 2011 */ 4897 extern RwcBoolean THD_write_datablock( THD_datablock * , RwcBoolean ) ; 4898 extern RwcBoolean THD_write_atr( THD_datablock * ) ; 4899 extern RwcBoolean THD_write_nimlatr( THD_datablock * ) ; /* 01 Jun 2005 */ 4900 extern void THD_set_write_compression( int mm ) ; 4901 extern int THD_enviro_write_compression(void) ; 4902 extern int THD_get_write_compression(void) ; 4903 4904 extern void THD_set_write_order( int ) ; 4905 extern void THD_enviro_write_order(void) ; 4906 extern int THD_get_write_order(void) ; 4907 4908 extern int TRUST_host(char *) ; 4909 #define OKHOST(hh) TRUST_host(hh) ; 4910 extern void TRUST_addhost(char *) ; /* 21 Feb 2001 */ 4911 4912 extern RwcBoolean THD_load_datablock( THD_datablock * ) ; 4913 extern void THD_load_no_mmap(void) ; /* Apr 2013 */ 4914 extern void THD_load_datablock_verbose(int) ; /* 21 Aug 2002 */ 4915 extern void THD_set_freeup( generic_func * ) ; /* 18 Oct 2001 */ 4916 extern RwcBoolean THD_purge_datablock( THD_datablock * , int ) ; 4917 extern RwcBoolean THD_purge_one_brick( THD_datablock * , int ) ; 4918 extern void THD_force_malloc_type( THD_datablock * , int ) ; 4919 extern int THD_count_databricks( THD_datablock * ) ; 4920 extern int THD_subset_loaded( THD_3dim_dataset *, int, int * ) ; 4921 extern void THD_load_analyze( THD_datablock * ) ; /* 27 Aug 2002 */ 4922 extern void THD_load_ctfmri ( THD_datablock * ) ; /* 04 Dec 2002 */ 4923 extern void THD_load_ctfsam ( THD_datablock * ) ; /* 04 Dec 2002 */ 4924 extern void THD_load_1D ( THD_datablock * ) ; /* 04 Mar 2003 */ 4925 extern void THD_load_3D ( THD_datablock * ) ; /* 21 Mar 2003 */ 4926 extern void THD_load_nifti ( THD_datablock * ) ; /* 28 Aug 2003 */ 4927 extern void THD_load_mpeg ( THD_datablock * ) ; /* 03 Dec 2003 */ 4928 extern void THD_load_tcat ( THD_datablock * ) ; /* 04 Aug 2004 */ 4929 extern int THD_load_niml ( THD_datablock * ) ; /* 12 Jun 2006 */ 4930 extern int THD_load_gifti ( THD_datablock * ) ; /* 13 Feb 2008 */ 4931 4932 extern int THD_count_potential_databricks( THD_datablock *dblk ); 4933 4934 extern THD_3dim_dataset * THD_mean_dataset( int nds, THD_3dim_dataset **dsin, int ivbot, int ivtop, int verb ) ; 4935 4936 extern void THD_zerofill_dataset( THD_3dim_dataset * ) ; /* 18 Mar 2005 */ 4937 extern int THD_apply_master_subrange( THD_datablock * ); /* 14 Apr 2006 */ 4938 extern int THD_apply_master_subrange_list(THD_datablock *);/* 30 Nov 2016 */ 4939 extern void THD_patch_brickim( THD_3dim_dataset * ) ; /* 20 Oct 2006 */ 4940 4941 extern int THD_datum_constant( THD_datablock * ) ; /* 30 Aug 2002 */ 4942 #define DSET_datum_constant(ds) THD_datum_constant((ds)->dblk) 4943 4944 #define ALLOW_FSL_FEAT /* 27 Aug 2002 */ 4945 4946 #define MINC_FLOATIZE_MASK 1 4947 #define MINC_SWAPIZE_MASK 1<<1 4948 4949 extern void THD_write_1D( char *, char *, THD_3dim_dataset *); /* 04 Mar 2003 */ 4950 extern void THD_write_3D( char *, char *, THD_3dim_dataset *); /* 21 Mar 2003 */ 4951 extern RwcBoolean THD_write_niml( THD_3dim_dataset *, int); 4952 extern RwcBoolean THD_write_niml_to_stream( THD_3dim_dataset *, char *, int); 4953 extern RwcBoolean THD_write_gifti( THD_3dim_dataset *, int, int); 4954 4955 extern int write_niml_file( char *, NI_group *); /* 12 Jun 2006 [rickr] */ 4956 extern int write_niml_stream( char *, NI_group *); /* 10 Oct 2019 [rickr] */ 4957 4958 extern void THD_reconcile_parents( THD_sessionlist * ) ; 4959 extern THD_slist_find THD_dset_in_sessionlist( int,void *, THD_sessionlist *, int ) ; 4960 extern THD_slist_find THD_dset_in_session( int,void * , THD_session * ) ; 4961 extern int AFNI_append_dset_to_session( char *fname, int sss ) ; 4962 4963 extern void THD_check_idcodes( THD_sessionlist * ) ; /* 08 Jun 1999 */ 4964 4965 extern void THD_load_statistics( THD_3dim_dataset * ) ; 4966 extern void THD_update_statistics( THD_3dim_dataset * ) ; 4967 extern THD_brick_stats THD_get_brick_stats( MRI_IMAGE * ) ; 4968 extern void THD_update_one_bstat( THD_3dim_dataset * , int ) ; /* 29 Mar 2005 */ 4969 extern int THD_dset_scale(THD_3dim_dataset *aset, float fac); /* 31 Jan 2015 */ 4970 extern int THD_count_nonzero_bricks( THD_3dim_dataset *dset ) ; /* 17 Jan 2017 */ 4971 4972 extern THD_fvec3 THD_3dind_to_3dmm( THD_3dim_dataset * , THD_ivec3 ) ; 4973 extern THD_fvec3 THD_3dind_to_3dmm_no_wod( THD_3dim_dataset * , THD_ivec3 ) ; 4974 extern THD_ivec3 THD_3dmm_to_3dind( THD_3dim_dataset * , THD_fvec3 ) ; 4975 extern THD_ivec3 THD_3dmm_to_3dind_warn( THD_3dim_dataset * , THD_fvec3, int * ) ; 4976 extern THD_ivec3 THD_3dmm_to_3dind_no_wod( THD_3dim_dataset * , THD_fvec3 ) ; 4977 /* 28 Sep 2004 [rickr] */ 4978 extern THD_fvec3 THD_3dind_to_dicomm_no_wod( THD_3dim_dataset *dset, THD_ivec3 iv ) ; 4979 4980 extern THD_fvec3 THD_3dfind_to_3dmm( THD_3dim_dataset * , THD_fvec3 ) ; 4981 extern THD_fvec3 THD_3dmm_to_3dfind( THD_3dim_dataset * , THD_fvec3 ) ; 4982 4983 extern THD_fvec3 THD_3dmm_to_dicomm( THD_3dim_dataset * , THD_fvec3 ) ; 4984 extern THD_fvec3 THD_dicomm_to_3dmm( THD_3dim_dataset * , THD_fvec3 ) ; 4985 #define AFNI_3D_to_1D_index(i, j, k, ni, nij) \ 4986 ( (int)(i) + (int)(j) * (ni) + (int)(k) * (nij) ) 4987 4988 #define AFNI_1D_to_3D_index(ijk, i, j, k, ni, nij){ \ 4989 k = ((ijk) / (nij)); \ 4990 j = ((ijk) % (nij)); \ 4991 i = ((j) % (ni)); \ 4992 j = ((j) / (ni)); \ 4993 } 4994 4995 4996 extern THD_fvec3 THD_tta_to_mni( THD_fvec3 ) ; /* 29 Apr 2002 */ 4997 extern THD_fvec3 THD_mni_to_tta( THD_fvec3 ) ; 4998 extern void THD_3mni_to_3tta( float *, float *, float *) ; 4999 extern void THD_3tta_to_3mni( float *, float *, float *) ; 5000 5001 extern float THD_timeof ( int , float , THD_timeaxis * ) ; 5002 extern float THD_timeof_vox ( int , int , THD_3dim_dataset * ) ; 5003 extern float THD_timeof_slice( int , int , THD_3dim_dataset * ) ; /* BDW */ 5004 5005 extern float * TS_parse_tpattern( int, float, char * ) ; /* 11 Dec 2007 */ 5006 5007 extern THD_fvec3 THD_dataset_center( THD_3dim_dataset * ) ; /* 01 Feb 2001 */ 5008 extern THD_fvec3 THD_cmass( THD_3dim_dataset *xset , int iv , byte *mmm, 5009 int cmode); 5010 extern float *THD_roi_cmass(THD_3dim_dataset *xset , int iv , 5011 int *rois, int N_rois, int cmode); 5012 extern THD_fvec3 THD_Icent( THD_3dim_dataset *xset , int iv , byte *mmm, 5013 int cmode, THD_fvec3 cmxyz); 5014 THD_fvec3 THD_Dcent( THD_3dim_dataset *xset , int iv , byte *mmm, 5015 int cmode, THD_fvec3 cmxyz); 5016 double THD_xyz_distance( THD_3dim_dataset *xset , MRI_IMAGE *im , 5017 double xcm, double ycm, double zcm); 5018 5019 extern int THD_dataset_mismatch(THD_3dim_dataset *, THD_3dim_dataset *) ; 5020 extern double THD_diff_vol_vals(THD_3dim_dataset *d1, THD_3dim_dataset *d2, 5021 int scl); 5022 extern int THD_dataset_tshift( THD_3dim_dataset * , int ) ; /* 15 Feb 2001 */ 5023 5024 #define MISMATCH_CENTER (1<<0) /* within 0.2 voxel */ 5025 #define MISMATCH_DELTA (1<<1) /* within 0.001 voxel */ 5026 #define MISMATCH_ORIENT (1<<2) 5027 #define MISMATCH_DIMEN (1<<3) 5028 #define MISMATCH_OBLIQ (1<<4) 5029 5030 /*----------------------------------------------------------------*/ 5031 /*-------- FD_brick type: for rapid extraction of slices --------*/ 5032 5033 /*! This type is to hold information needed for the rapid extraction 5034 of slices from an AFNI dataset (THD_3dim_dataset struct). 5035 5036 It exists primarily as a historical artifact. The earliest version 5037 of AFNI was to be called FD3, as a successor to FD2. The FD_brick 5038 was conceived as part of FD3. However, FD3 morphed into AFNI within 5039 a few weeks, but by then I didn't want to throw away the code that 5040 had already been structured around this (primarily the imseq.c stuff). 5041 */ 5042 5043 typedef struct FD_brick { 5044 5045 THD_ivec3 nxyz ; /*!< actual dimensions as read in */ 5046 THD_ivec3 sxyz ; /*!< starting indices in each dataset dimen */ 5047 THD_ivec3 a123 ; /*!< axis codes as supplied in THD_3dim_dataset_to_brick */ 5048 5049 int n1 ; /*!< ni = length in direction i */ 5050 int d1 ; /*!< di = stride in direction i */ 5051 int e1 ; /*!< ei = last index in direc i */ 5052 int n2 ; /*!< ni = length in direction i */ 5053 int d2 ; /*!< di = stride in direction i */ 5054 int e2 ; /*!< ei = last index in direc i */ 5055 int n3 ; /*!< ni = length in direction i */ 5056 int d3 ; /*!< di = stride in direction i */ 5057 int start ; /*!< start = offset of 1st elem */ 5058 5059 float del1 ; /*!< voxel dimensions */ 5060 float del2 ; /*!< voxel dimensions */ 5061 float del3 ; /*!< voxel dimensions */ 5062 5063 THD_3dim_dataset *dset ; /*!< pointer to parent dataset */ 5064 int resam_code ; /*!< how to resample normal sub-bricks */ 5065 int thr_resam_code ; /*!< how to resample statistical sub-bricks */ 5066 int deltival ; /*!< how much to shift the sub-brick index */ 5067 5068 char namecode[32] ; /*!< June 1997 */ 5069 5070 int ntmask ; /*!< Mar 2013 */ 5071 MRI_IMAGE *tmask ; /*!< Mar 2013 */ 5072 5073 RwcPointer parent ; /*!< struct owner */ 5074 RwcPointer brother; 5075 } FD_brick ; 5076 5077 #define TMASK_INDEX(fdb) ((fdb)->ntmask) 5078 5079 #define CLEAR_TMASK(fdb) \ 5080 do{ if( fdb != NULL && fdb->tmask != NULL ){ \ 5081 mri_free(fdb->tmask); fdb->tmask=NULL; fdb->ntmask=-666; \ 5082 } } while(0) 5083 5084 #define STATUS_TMASK(sss,fdb) \ 5085 do{ if( fdb != NULL ) STATUSp(sss,fdb->tmask) ; } while(0) 5086 5087 #define DESTROY_FD_BRICK(fdb) \ 5088 do{ FD_brick *_jj=(FD_brick *)fdb; \ 5089 if( _jj != NULL ){ mri_free(_jj->tmask); myRwcFree(_jj); fdb=NULL; } } while(0) 5090 5091 /*! rotate the three numbers (a,b,c) to (b,c,a) into (na,nb,nc) */ 5092 5093 #define ROT3(a,b,c,na,nb,nc) ((na)=(b),(nb)=(c),(nc)=(a)) 5094 5095 /*! Determine if this FD_brick can be drawn (in an image or graph) */ 5096 5097 #define BRICK_DRAWABLE(br) ((br)->n1 > 1 && (br)->n2 > 1) 5098 #define BRICK_GRAPHABLE(br) ((br)->n1 >= 1 && (br)->n2 >= 1) 5099 5100 extern FD_brick * THD_3dim_dataset_to_brick( THD_3dim_dataset * , 5101 int,int,int ) ; 5102 5103 extern MRI_IMAGE * FD_brick_to_mri( int,int , FD_brick * br ) ; 5104 extern MRI_IMAGE * FD_brick_to_series( int , FD_brick * br ) ; 5105 5106 extern float THD_get_voxel( THD_3dim_dataset *dset , int ijk , int ival ) ; 5107 extern float THD_get_voxel_dicom( THD_3dim_dataset *dset, float x,float y,float z, int ival ) ; 5108 5109 extern MRI_IMAGE * THD_extract_series( int , THD_3dim_dataset * , int ) ; 5110 extern MRI_IMARR * THD_extract_many_series( int, int *, THD_3dim_dataset * ); 5111 extern MRI_IMAGE * THD_dset_to_1Dmri( THD_3dim_dataset *dset ) ; 5112 5113 extern void THD_extract_many_arrays( int ns , int *ind , 5114 THD_3dim_dataset *dset , float *dsar ) ; 5115 5116 /*---------------------------------------------------------------------------*/ 5117 5118 typedef struct { 5119 int nvec , nvals , ignore ; 5120 int *ivec ; 5121 float *fvec ; 5122 int nx,ny,nz ; 5123 float dx,dy,dz , dt ; 5124 } MRI_vectim ; 5125 5126 #undef MAKE_VECTIM 5127 #define MAKE_VECTIM(nam,nvc,nvl) \ 5128 do{ (nam) = (MRI_vectim *)calloc(sizeof(MRI_vectim),1) ; \ 5129 (nam)->nvec = (nvc) ; \ 5130 (nam)->nvals = (nvl) ; \ 5131 (nam)->ivec = (int *) calloc(sizeof(int) ,(nvc)) ; \ 5132 (nam)->fvec = (float *)calloc(sizeof(float)*(nvc),(nvl)) ; \ 5133 } while(0) 5134 5135 #undef ISVALID_VECTIM 5136 #define ISVALID_VECTIM(mv) \ 5137 ( (mv) != NULL && (mv)->ivec != NULL && (mv)->fvec != NULL ) 5138 5139 #undef VECTIM_PTR 5140 #define VECTIM_PTR(mv,j) ((mv)->fvec + (size_t)(j)*(size_t)(mv)->nvals) 5141 5142 #undef VECTIM_extract 5143 #define VECTIM_extract(mv,j,aa) \ 5144 AAmemcpy( (aa) , VECTIM_PTR((mv),(j)) , sizeof(float)*(mv)->nvals ) 5145 5146 #undef VECTIM_insert 5147 #define VECTIM_insert(mv,j,aa) \ 5148 AAmemcpy( VECTIM_PTR((mv),(j)) , (aa) , sizeof(float)*(mv)->nvals ) 5149 5150 #undef VECTIM_destroy 5151 #define VECTIM_destroy(mv) \ 5152 do{ if( (mv)->fvec != NULL ) free((mv)->fvec); \ 5153 if( (mv)->ivec != NULL ) free((mv)->ivec); \ 5154 free((mv)); (mv) = NULL; \ 5155 } while(0) 5156 5157 extern MRI_vectim * THD_dset_to_vectim( THD_3dim_dataset *dset, byte *mask, int ignore ); 5158 extern MRI_vectim * THD_dset_to_vectim_stend( THD_3dim_dataset *dset, byte *mask , int start, int end ) ; 5159 5160 extern MRI_vectim * THD_dset_censored_to_vectim( THD_3dim_dataset *dset, 5161 byte *mask , int nkeep , int *keep ) ; 5162 5163 extern MRI_vectim * THD_dset_list_censored_to_vectim( int nds, THD_3dim_dataset **ds, 5164 byte *mask, int nkeep, int *keep ) ; 5165 5166 MRI_vectim * THD_2dset_to_vectim( THD_3dim_dataset *dset1, byte *mask1 , 5167 THD_3dim_dataset *dset2, byte *mask2 , 5168 int ignore ); 5169 extern int64_t THD_vectim_size( THD_3dim_dataset *dset , byte *mask ) ; 5170 extern int THD_vectim_ifind( int iv , MRI_vectim *mrv ) ; 5171 extern int bsearch_int( int tt , int nar , int *ar ) ; 5172 extern void THD_vectim_to_dset( MRI_vectim *mrv , THD_3dim_dataset *dset ) ; 5173 extern void THD_vectim_to_dset_indexed( MRI_vectim *mrv , 5174 THD_3dim_dataset *dset , int *tlist ) ; /* 06 Aug 2013 */ 5175 extern void THD_vectim_indexed_to_dset( MRI_vectim *mrv, int nlist, int *ilist, 5176 THD_3dim_dataset *dset ) ; /* 06 Feb 2014 */ 5177 5178 extern int THD_vectim_data_tofile( MRI_vectim *mrv , char *fnam ) ; 5179 extern int THD_vectim_reload_fromfile( MRI_vectim *mrv , char *fname ) ; 5180 extern void THD_vector_fromfile( int nvals , int iv , float *vv , FILE *fp ) ; 5181 5182 void THD_check_vectim( MRI_vectim *mv , char *fname ) ; /* 13 Mar 2017 */ 5183 5184 extern void mri_blur3D_vectim( MRI_vectim *vim , float fwhm ) ; 5185 extern void THD_vectim_normalize( MRI_vectim *mrv ) ; 5186 extern void THD_vectim_dotprod ( MRI_vectim *mrv, float *vec, float *dp, int ata ) ; 5187 extern void THD_vectim_spearman ( MRI_vectim *mrv, float *vec, float *dp ) ; /* 01 Mar 2010 */ 5188 extern void THD_vectim_quantile ( MRI_vectim *mrv, float *vec, float *dp ) ; /* 11 May 2012 */ 5189 extern void THD_vectim_quadrant ( MRI_vectim *mrv, float *vec, float *dp ) ; /* 01 Mar 2010 */ 5190 extern void THD_vectim_ktaub ( MRI_vectim *mrv, float *vec, float *dp ) ; /* 29 Apr 2010 */ 5191 extern void THD_vectim_tictactoe( MRI_vectim *mrv, float *vec, float *dp ) ; /* 30 Mar 2011 */ 5192 5193 extern void THD_vectim_pearson_section( MRI_vectim *mrv, float *vec, 5194 float *dp, int ibot , int itop ) ; /* 07 Oct 0214 */ 5195 5196 extern void THD_vectim_applyfunc( MRI_vectim *mrv , void *vp ) ; /* 10 May 2012 */ 5197 5198 extern void THD_vectim_pearsonBC( MRI_vectim *mrv, float srad, int sijk, int pv, float *par ) ; 5199 5200 extern void THD_vectim_distance( MRI_vectim *mrv , float *vec , 5201 float *dp, int abs, char *xform) ; 5202 5203 extern float kendallNlogN ( float *arr1, float *arr2, int len ) ; /* in ktaub.c */ 5204 extern float kendallSmallN( float *arr1, float *arr2, int len ) ; 5205 5206 extern int THD_vectim_subset_average( MRI_vectim *mrv, int nind, int *ind, float *ar ); 5207 5208 extern void THD_vectim_vectim_dot( MRI_vectim *arv, MRI_vectim *brv, float *dp ) ; 5209 5210 extern MRI_vectim * THD_vectim_copy( MRI_vectim *mrv ) ; /* 08 Apr 2010 */ 5211 extern MRI_vectim * THD_tcat_vectims( int , MRI_vectim ** ) ; /* 26 Jul 2010 */ 5212 extern MRI_vectim * THD_dset_list_to_vectim( int, THD_3dim_dataset **, byte * ); 5213 5214 extern MRI_vectim * THD_xyzcat_vectims( int nvim , MRI_vectim **vim ) ; /* 09 Apr 2018 */ 5215 5216 extern MRI_IMAGE * THD_temp_subim_from_vectim( MRI_vectim *vim , 5217 int istart , int numi ) ; /* 19 Nov 2021 */ 5218 5219 #define VECTIM_TEMP_IMAGE(vvv) THD_temp_subim_from_vectim( (vvv) , 0 , 0 ) 5220 5221 5222 #define ICOR_MAX_FTOP 99999 /* 26 Feb 2010 */ 5223 5224 typedef struct { 5225 THD_3dim_dataset *dset , *mset ; 5226 byte *mmm ; 5227 MRI_IMAGE *gortim ; int gortnpc ; 5228 int start,end , automask , mindex ; 5229 int clen,cnum,cstep ; 5230 float fbot , ftop , blur , sblur ; 5231 int polort , cmeth , despike , change ; 5232 MRI_vectim *mv ; 5233 char *prefix ; int ndet ; 5234 float *tseed ; 5235 int iter_count ; /* 05 Feb 2015 */ 5236 float iter_thresh ; 5237 5238 THD_3dim_dataset *eset ; MRI_vectim *ev ; 5239 } ICOR_setup ; 5240 5241 #undef INIT_ICOR_setup 5242 #define INIT_ICOR_setup(is) (is) = (ICOR_setup *)calloc(1,sizeof(ICOR_setup)) 5243 5244 #undef ISVALID_ICOR_setup 5245 #define ISVALID_ICOR_setup(is) ( (is) != NULL && (is)->mv != NULL ) 5246 5247 #undef DESTROY_ICOR_setup 5248 #define DESTROY_ICOR_setup(is) \ 5249 do{ if( (is) != NULL ){ \ 5250 if( (is)->mmm != NULL ) free((is)->mmm) ; \ 5251 if( (is)->gortim != NULL ) mri_free((is)->gortim) ; \ 5252 if( (is)->mv != NULL ) VECTIM_destroy((is)->mv) ; \ 5253 if( (is)->ev != NULL ) VECTIM_destroy((is)->ev) ; \ 5254 if( (is)->prefix != NULL ) free((is)->prefix) ; \ 5255 if( (is)->tseed != NULL ) free((is)->tseed) ; \ 5256 free((is)) ; (is) = NULL ; \ 5257 }} while(0) 5258 5259 extern int THD_instacorr_prepare( ICOR_setup *iset ) ; 5260 extern MRI_IMAGE * THD_instacorr ( ICOR_setup *iset, int ijk ) ; 5261 extern int THD_instacorr_cmeth_needs_normalize( int cmeth ); 5262 extern MRI_IMARR * THD_instacorr_collection( ICOR_setup *iset, int ijk ) ; 5263 5264 extern int THD_instacorr_cmeth_needs_norm(int cmeth) ; 5265 /*---------------------------------------------------------------------------*/ 5266 5267 extern int THD_extract_array ( int, THD_3dim_dataset *, int, void * ) ; 5268 extern int THD_extract_float_array( int, THD_3dim_dataset *, float * ) ; 5269 extern float THD_get_float_value( int, int, THD_3dim_dataset * ) ; 5270 5271 extern MRI_IMAGE * THD_extract_float_brick( int , THD_3dim_dataset * ) ; 5272 extern MRI_IMAGE * THD_extract_double_brick( int , THD_3dim_dataset * ) ; 5273 extern MRI_IMAGE * THD_extract_int_brick( int , THD_3dim_dataset * ) ; 5274 extern float * THD_extract_to_float( int , THD_3dim_dataset * ) ; 5275 extern double * THD_extract_to_double( int , THD_3dim_dataset * ) ; 5276 extern int * THD_extract_to_int( int , THD_3dim_dataset * ) ; 5277 5278 extern void THD_insert_series( int, THD_3dim_dataset *, int, int, void *, int ); 5279 5280 extern int THD_voxel_is_constant( int ind , THD_3dim_dataset *dset ) ; 5281 5282 extern floatvec * THD_fitter( int npt , float *far , 5283 int nref, float *ref[], int meth, float *ccon ) ; 5284 5285 extern floatvec * THD_deconvolve( int npt , float *far , 5286 int minlag , int maxlag , float *kern, 5287 int nbase , float *base[], 5288 int meth , float *ccon , int dcon , 5289 int pencode, float penpar ) ; 5290 5291 extern floatvec * THD_fitter_fitts( int npt, floatvec *fv, 5292 int nref, float *ref[], float *far ) ; 5293 5294 extern void THD_fitter_do_fitts(int qq) ; 5295 extern floatvec * THD_retrieve_fitts(void) ; 5296 extern void THD_fitter_voxid( int i ) ; /* 10 Sep 2008 */ 5297 extern void THD_fitter_set_vthresh( float ) ; /* 18 May 2010 */ 5298 5299 /* 11 Mar 2011: LASSO regression stuff (thd_lasso.c) */ 5300 5301 extern floatvec * THD_lasso_L2fit( int npt , float *far , 5302 int nref , float *ref[] , 5303 float *lam , float *ccon ) ; 5304 extern void THD_lasso_fixlam( float x ) ; 5305 extern void THD_lasso_setlamvec( int nref , float *lam ) ; 5306 extern void THD_lasso_dopost( int x ) ; 5307 extern void THD_lasso_dosigest( int x ) ; 5308 extern void THD_lasso_setdeps( float x ) ; 5309 extern floatvec * THD_lasso( int meth , 5310 int npt , float *far , 5311 int nref , float *ref[] , 5312 float *lam , float *ccon ) ; 5313 extern floatvec * THD_sqrtlasso_L2fit( int npt , float *far , 5314 int nref , float *ref[] , 5315 float *lam , float *ccon ) ; 5316 5317 extern void THD_lasso_add_centro_block( intvec *mb ) ; /* 06 Aug 2021 */ 5318 5319 /*--------------- routines that are in thd_detrend.c ---------------*/ 5320 5321 extern void get_linear_trend ( int, float *, float *, float * ) ; 5322 extern void THD_linear_detrend ( int, float *, float *, float * ) ; 5323 extern void get_quadratic_trend ( int, float *, float *, float *, float * ) ; 5324 extern void THD_quadratic_detrend( int, float *, float *, float *, float * ) ; 5325 extern float THD_normalize ( int, float * ) ; 5326 extern void THD_normRMS ( int, float * ) ; /* 06 Jun 2008 */ 5327 extern void THD_normmax ( int, float * ) ; /* 26 Mar 2008 */ 5328 extern void THD_normL1 ( int, float * ) ; /* 26 Mar 2008 */ 5329 extern void THD_cubic_detrend ( int, float * ) ; /* 15 Nov 1999 */ 5330 5331 extern void THD_const_detrend ( int, float *, float * ); /* 24 Aug 2001 */ 5332 extern void THD_linear_detrend_complex ( int, complex * ); /* 05 Mar 2007 */ 5333 extern int THD_is_constant ( int , float * ); /* 11 May 2011 */ 5334 extern int THD_is_zero ( int , float * ); /* 20 Feb 2014 */ 5335 5336 extern void THD_generic_detrend_LSQ( int, float *, int, int, float **, float *) ; 5337 extern void THD_generic_detrend_L1 ( int, float *, int, int, float **, float *) ; 5338 extern void THD_generic_retrend ( int, float *, int, int, float **, float *) ; 5339 5340 extern MRI_IMARR * THD_time_fit_dataset( THD_3dim_dataset *, int, float **, int, byte *); 5341 extern void THD_extract_detrended_array( THD_3dim_dataset * , 5342 int, float **, MRI_IMARR *, 5343 int, int, float * ) ; 5344 5345 extern THD_3dim_dataset * THD_detrend_dataset( THD_3dim_dataset *dset , 5346 int nref , float **ref , 5347 int meth , int scl , 5348 byte *mask , MRI_IMARR **imar ) ; 5349 5350 extern int THD_retrend_dataset( THD_3dim_dataset *dset , 5351 int nref , float **ref , 5352 int scl , byte *mask , MRI_IMARR *imar ) ; 5353 5354 extern float ** THD_build_trigref( int corder , int nvals ) ; 5355 extern float ** THD_build_polyref( int nref , int nvals ) ; /* 20 Sep 2007 */ 5356 5357 #define DETREND_linear(n,f) THD_linear_detrend(n,f,NULL,NULL) 5358 #define DETREND_quadratic(n,f) THD_quadratic_detrend(n,f,NULL,NULL,NULL) 5359 #define DETREND_cubic(n,f) THD_cubic_detrend(n,f) 5360 #define DETREND_const(n,f) THD_const_detrend(n,f,NULL) 5361 5362 /*! Macro to detrend a time series array in to various polynomial orders. */ 5363 5364 #define DETREND_polort(p,n,f) \ 5365 do{ switch(p){ default: break; \ 5366 case 0: DETREND_const(n,f) ; break; \ 5367 case 1: DETREND_linear(n,f) ; break; \ 5368 case 2: DETREND_quadratic(n,f); break; \ 5369 case 3: DETREND_cubic(n,f) ; break; } } while(0) 5370 5371 /*------------------------------------------------------------------*/ 5372 5373 extern THD_ivec3 THD_fdind_to_3dind( FD_brick * , THD_ivec3 ) ; 5374 extern THD_ivec3 THD_3dind_to_fdind( FD_brick * , THD_ivec3 ) ; 5375 5376 extern THD_fvec3 THD_fdfind_to_3dfind( FD_brick *, THD_fvec3) ; /* 30 Aug 2001 */ 5377 extern THD_fvec3 THD_3dfind_to_fdfind( FD_brick *, THD_fvec3) ; 5378 5379 extern FD_brick ** THD_setup_bricks( THD_3dim_dataset * ) ; 5380 5381 extern FD_brick * THD_oriented_brick( THD_3dim_dataset *, char *) ; /* 07 Dec 2001 */ 5382 5383 extern size_t thd_floatscan ( size_t , float * ) ; /* 30 Jul 1999 */ 5384 extern size_t thd_complexscan( size_t , complex * ) ; /* 14 Sep 1999 */ 5385 5386 #undef MRI_floatscan 5387 #define MRI_floatscan(imm) \ 5388 do{ if( (imm) != NULL ){ \ 5389 if( (imm)->kind== MRI_float ) thd_floatscan ((imm)->nvox,MRI_FLOAT_PTR ((imm))) ; \ 5390 else if( (imm)->kind== MRI_complex ) thd_complexscan((imm)->nvox,MRI_COMPLEX_PTR((imm))) ; \ 5391 }} while(0) 5392 5393 #undef floatfix 5394 #ifdef isfinite 5395 # define floatfix(x) if( !isfinite(x) ) (x) = 0.0f ; else 5396 #else 5397 # define floatfix(x) if( !finite(x) ) (x) = 0.0f ; else 5398 # define isfinite finite 5399 #endif 5400 5401 extern size_t mri_floatscan ( MRI_IMAGE * ) ; /* 22 Feb 2007 */ 5402 extern size_t imarr_floatscan( MRI_IMARR * ) ; 5403 extern size_t dblk_floatscan ( THD_datablock * ) ; 5404 extern size_t dset_floatscan ( THD_3dim_dataset * ) ; 5405 5406 #undef BAD_FLOAT 5407 #define BAD_FLOAT(xx) thd_floatscan(1,&(xx)) /* 31 Dec 2008 */ 5408 5409 #define BOXLEN 7 /* number of values to define a box */ 5410 #define BOX_XYZ 1 5411 #define BOX_DIC 2 5412 #define BOX_NEU 3 5413 #define BOX_IJK 4 5414 #define BALL_XYZ 11 5415 #define BALL_DIC 12 5416 #define BALL_NEU 13 5417 5418 extern int THD_parse_boxball( int *, float **, char **) ; 5419 extern byte * THD_boxballmask( THD_3dim_dataset *, int, float * ) ; 5420 5421 extern byte * THD_makemask( THD_3dim_dataset *, int,float,float) ; 5422 extern int THD_makedsetmask( THD_3dim_dataset *, int,float,float, byte* ) ; 5423 extern int THD_dset_to_mask(THD_3dim_dataset *, float, float); 5424 extern int THD_applydsetmask( THD_3dim_dataset *dset , byte *cmask ); 5425 extern int *THD_unique_vals( THD_3dim_dataset *mask_dset, int miv, 5426 int *n_unique, byte*cmask ); 5427 extern int *THD_unique_rank( THD_3dim_dataset *mask_dset , 5428 int miv, 5429 byte *cmask, 5430 char *mapname, 5431 int **unqp, int *N_unq); 5432 extern int THD_unique_rank_edit( THD_3dim_dataset *mask_dset , 5433 int miv, 5434 byte *cmask, 5435 char *mapname, int **unqp, int *N_unq) ; 5436 int is_integral_dset ( THD_3dim_dataset *dset, int check_data); 5437 int is_integral_sub_brick ( THD_3dim_dataset *dset, int isb, int check_data); 5438 extern int THD_mask_remove_isolas( int nx, int ny, int nz , byte *mmm ) ; 5439 5440 extern int THD_countmask( int , byte * ) ; 5441 extern byte * THD_automask( THD_3dim_dataset * ) ; /* 13 Aug 2001 */ 5442 extern void THD_automask_verbose( int ) ; /* 28 Oct 2003 */ 5443 extern void THD_automask_extclip( int ) ; 5444 extern void THD_automask_set_onlypos( int ) ; /* 09 Nov 2020 */ 5445 extern byte * mri_automask_image( MRI_IMAGE * ) ; /* 05 Mar 2003 */ 5446 extern byte * mri_automask_imarr( MRI_IMARR * ) ; /* 18 Nov 2004 */ 5447 extern int mask_intersect_count( int, byte *, byte * ); /* 30 Mar 2009 */ 5448 extern int mask_union_count ( int, byte *, byte * ); /* 30 Mar 2009 */ 5449 extern int mask_count ( int, byte * ) ; 5450 extern float_triple mask_rgyrate( int nx, int ny, int nz , byte *mmm ) ; 5451 extern byte * mri_automask_image2D( MRI_IMAGE *im ) ; /* 12 Mar 2010 */ 5452 /* 26 Dec 2021, migrated */ 5453 extern THD_3dim_dataset *thd_apply_mask( THD_3dim_dataset *dset, 5454 byte *mask, 5455 char *prefix ); 5456 5457 extern THD_3dim_dataset * THD_remove_allzero(THD_3dim_dataset *); /* 25 Jul 2017 */ 5458 5459 5460 /* 13 Nov 2006 [rickr] */ 5461 extern int thd_mask_from_brick(THD_3dim_dataset *, int, float, byte **, int); 5462 extern int thd_multi_mask_from_brick(THD_3dim_dataset *, int, byte **); 5463 5464 5465 extern THD_3dim_dataset * THD_autobbox( THD_3dim_dataset * , /* 06 Jun 2002 */ 5466 int *, int * , int *, int * , int *, int *, char *) ; 5467 extern void MRI_autobbox( MRI_IMAGE * , 5468 int *, int * , int *, int * , int *, int * ) ; 5469 extern void MRI_autobbox_clust( int ) ; /* 20 Sep 2006 */ 5470 extern void THD_autobbox_clip( int ) ; /* 06 Aug 2007 */ 5471 extern void THD_autobbox_npad(int) ; 5472 extern void THD_autobbox_noexpand(int) ; /* 08 Jan 2019 */ 5473 5474 void MRI_autobbox_byte( MRI_IMAGE *qim , /* 18 Mar 2021 */ 5475 int *xm, int *xp , int *ym, int *yp , int *zm, int *zp ) ; 5476 5477 extern void THD_automask_set_clipfrac( float f ) ; /* 20 Mar 2006 */ 5478 extern void THD_automask_set_peelcounts( int,int ) ; /* 24 Oct 2006 */ 5479 extern void THD_automask_set_gradualize( int ) ; 5480 extern void THD_automask_set_cheapo( int n ) ; /* 13 Aug 2007 */ 5481 5482 extern int THD_mask_fillin_completely( int,int,int, byte *, int ) ; /* 19 Apr 2002 */ 5483 extern int THD_mask_fillin_once ( int,int,int, byte *, int ) ; 5484 5485 extern int THD_mask_clip_neighbors( int,int,int, byte *, float,float,float *) ; /* 28 Oct 2003 */ 5486 extern int THD_mask_fill_holes( int,int,int, byte *, THD_ivec3 *, int); 5487 5488 5489 extern void THD_mask_clust( int nx, int ny, int nz, byte *mmm ) ; 5490 extern void THD_mask_erode( int nx, int ny, int nz, byte *mmm, int redilate, byte nn ) ; 5491 extern void THD_mask_erode_sym(int nx,int ny,int nz, byte *mmm, int nerode, 5492 int NN); /* NN: 19 May 2020 [rickr] */ 5493 5494 extern void THD_mask_erodemany( int nx, int ny, int nz, byte *mmm, int npeel ) ; /* 24 Oct 2006 */ 5495 5496 extern int THD_peel_mask( int nx, int ny, int nz , byte *mmm, int pdepth ) ; 5497 5498 extern int THD_mask_dilate( int, int, int, byte *, int, byte ) ; /* 30 Aug 2002 */ 5499 extern short *THD_mask_depth (int nx, int ny, int nz, byte *mask, 5500 byte preservemask, 5501 short *usethisdepth, byte nn); /* ZSS March 02 2010 */ 5502 /* DRG Dec 23 2019 */ 5503 5504 extern float THD_cliplevel( MRI_IMAGE * , float ) ; /* 12 Aug 2001 */ 5505 extern float THD_cliplevel_abs( MRI_IMAGE * , float ) ; /* 05 Mar 2007 */ 5506 extern float mri_topclip( MRI_IMAGE * ) ; /* 28 Sep 2006 */ 5507 extern float THD_cliplevel_search( MRI_IMAGE *im ) ; /* 17 May 2017 */ 5508 extern MRI_IMAGE * THD_median_brick( THD_3dim_dataset * ) ; /* 12 Aug 2001 */ 5509 extern MRI_IMAGE * THD_mad_brick ( THD_3dim_dataset * ) ; /* 07 Dec 2006 */ 5510 extern MRI_IMAGE * THD_mean_brick ( THD_3dim_dataset * ) ; /* 15 Apr 2005 */ 5511 extern MRI_IMAGE * THD_rms_brick ( THD_3dim_dataset * ) ; /* 15 Apr 2005 */ 5512 extern MRI_IMAGE * THD_aveabs_brick( THD_3dim_dataset * ) ; /* 11 May 2009 */ 5513 extern MRI_IMAGE * THD_maxabs_brick( THD_3dim_dataset * ) ; /* 08 Jan 2019 */ 5514 extern MRI_IMAGE * THD_avepos_brick( THD_3dim_dataset * ) ; /* 09 Nov 2020 */ 5515 5516 extern MRI_IMARR * THD_medmad_bricks (THD_3dim_dataset *); /* 07 Dec 2006 */ 5517 extern MRI_IMARR * THD_meansigma_bricks(THD_3dim_dataset *); /* 07 Dec 2006 */ 5518 extern MRI_IMARR * IMARR_medmad_bricks ( MRI_IMARR * ) ; /* 11 Dec 2006 */ 5519 5520 extern float THD_cliplevel_partial( MRI_IMAGE *im , float mfrac , 5521 int xa,int xb, int ya,int yb, int za,int zb ) ; 5522 extern MRI_IMAGE * THD_cliplevel_gradual( MRI_IMAGE *im , float mfrac ) ; 5523 5524 /* 08 Mar 2001 - functions for dealing with rows */ 5525 5526 extern int THD_get_dset_rowcount( THD_3dim_dataset *, int ) ; 5527 extern void * THD_get_dset_row( THD_3dim_dataset *, int, int, int,int,int ) ; 5528 extern void THD_put_dset_row( THD_3dim_dataset *, int, 5529 int, int,int,int, void * row ) ; 5530 extern int THD_dataset_rowfillin( THD_3dim_dataset *, int, int, int ) ; 5531 extern int THD_dataset_zfillin( THD_3dim_dataset *, int, int, int ) ; /* 03 Jul 2001 */ 5532 5533 extern MRI_IMAGE * mri_get_dset_row( THD_3dim_dataset *, int , int,int,int,int ) ; 5534 5535 /*------------------------------------------------------------------*/ 5536 /*-- October 1998: routines for 3D volume rotation and alignment. --*/ 5537 5538 #define DELTA_AFTER 1 5539 #define DELTA_BEFORE 2 5540 #define DELTA_FIXED 3 5541 5542 /*-- see thd_rotangles.c --*/ 5543 5544 extern void THD_rotangle_user_to_dset( THD_3dim_dataset * , 5545 float,char, float,char, float,char, 5546 float*,int* , float*,int* , float*,int* ); 5547 5548 extern int THD_axcode( THD_3dim_dataset * , char ) ; /* promoted from static */ 5549 extern int THD_handedness( THD_3dim_dataset * ) ; /* on 06 Feb 2001 - RWCox */ 5550 5551 extern THD_dmat33 DBLE_mat_to_dicomm( THD_3dim_dataset * ) ; /* 14 Feb 2001 */ 5552 extern THD_mat33 SNGL_mat_to_dicomm( THD_3dim_dataset * ) ; /* 28 Aug 2002 */ 5553 5554 extern THD_dvecmat THD_rotcom_to_matvec( THD_3dim_dataset * , char * ) ; 5555 5556 extern THD_dvecmat invert_dvecmat( THD_dvecmat avm ) ; /* 24 Jul 2007 */ 5557 extern THD_dvecmat sqrt_dvecmat( THD_dvecmat avm ) ; /* 30 Jul 2007 */ 5558 5559 /*-- see thd_rot3d.c for these routines --*/ 5560 5561 extern void THD_rota_method( int ) ; 5562 5563 extern void THD_rota_setpad( int,int,int ) ; /* 02 Feb 2001 */ 5564 extern void THD_rota_clearpad(void) ; 5565 5566 extern void THD_rota_vol( int, int, int, float, float, float, float *, 5567 int,float, int,float, int,float, 5568 int,float,float,float ) ; 5569 5570 extern MRI_IMAGE * THD_rota3D( MRI_IMAGE * , 5571 int,float, int,float, int,float, 5572 int,float,float,float ) ; 5573 5574 extern MRI_IMAGE * THD_rota3D_matvec( MRI_IMAGE *, THD_dmat33,THD_dfvec3 ) ; 5575 5576 /* routines below added to thd_rot3d.c on 16 Jul 2000 */ 5577 5578 extern void THD_rota_vol_matvec( int, int, int, float, float, float, float *, 5579 THD_dmat33 , THD_dfvec3 ) ; 5580 5581 extern THD_dvecmat DLSQ_rot_trans( int, THD_dfvec3 *, THD_dfvec3 *, double * ); 5582 extern THD_dvecmat DLSQ_affine ( int, THD_dfvec3 *, THD_dfvec3 * ); 5583 extern THD_dvecmat DLSQ_rotscl ( int, THD_dfvec3 *, THD_dfvec3 *, int ); 5584 5585 extern THD_dvecmat THD_read_dvecmat( char * , int ) ; /* THD_read_vecmat.c */ 5586 5587 /* cf. thd_coords.c for cardinal transformation matrix */ 5588 extern void THD_dicom_card_xform (THD_3dim_dataset * dset , 5589 THD_dmat33 *tmat, THD_dfvec3 *dics ); 5590 extern void THD_dicom_real_xform (THD_3dim_dataset * dset , 5591 THD_dmat33 *tmat, THD_dfvec3 *dics ); 5592 extern int THD_dicom_real_to_card(THD_3dim_dataset *dset, /* 23 Mar 2020 */ 5593 THD_fvec3 * coords, int rnd); 5594 extern float THD_compute_oblique_angle(mat44 ijk_to_dicom44, int verbose); 5595 5596 /* coordinate converters - moved from afni.h 17 Feb 2021 [rickr] */ 5597 extern void AFNI_ijk_to_xyz( THD_3dim_dataset * , 5598 int,int,int, float *,float *,float *) ; 5599 extern void AFNI_xyz_to_ijk( THD_3dim_dataset * , 5600 float,float,float , int *,int *,int *) ; 5601 extern void AFNI_xyz_to_dicomm( THD_3dim_dataset * , 5602 float,float,float , float *,float *,float *) ; 5603 extern void AFNI_dicomm_to_xyz( THD_3dim_dataset * , 5604 float,float,float , float *,float *,float *) ; 5605 5606 /* [PT: Nov 4, 2020] functions for reorienting dset via 5607 ijk_to_dicom_real */ 5608 extern int is_valid_orient_char( char ochar[3] ); 5609 extern int is_valid_orient_int( int oint[3] ); 5610 extern void THD_orient_to_int_rlpais( char ochar[4], int oint[3] ); 5611 extern void THD_int_to_orient_rlpais( int oint[3], char ochar[4] ); 5612 extern mat33 THD_char_reorient_perm_mat33( char *ocharA, char *ocharB ); 5613 extern mat33 THD_int_reorient_perm_mat33( int *ointA, int *ointB ); 5614 extern mat33 THD_dset_reorient_perm_mat33( THD_3dim_dataset *dsetA, 5615 char *ocharB ); 5616 extern mat44 THD_refit_orient_ijk_to_dicom_real( THD_3dim_dataset *dsetA, 5617 char *ocharB ); 5618 extern mat44 nifti_orthogonalize_mat44( mat44 Min); 5619 extern int is_mat44_orthogonal(mat44 A); 5620 5621 5622 extern void THD_report_obliquity(THD_3dim_dataset *dset); 5623 extern void set_obliquity_report(int v); 5624 5625 extern void THD_set_oblique_report(int n1, int n2); 5626 5627 extern int THD_get_oblique_report(void); 5628 5629 extern void THD_reset_oblique_report_index(void); 5630 5631 extern void THD_check_oblique_field(THD_3dim_dataset *dset); 5632 extern void THD_make_cardinal(THD_3dim_dataset *dset); 5633 extern void THD_updating_obliquity(int update); 5634 extern int THD_update_obliquity_status(void); 5635 extern void THD_set_dset_atr_status(int st); 5636 extern int THD_update_dset_atr_status(void); 5637 5638 /* cf. thd_tmask.c */ 5639 5640 #define TM_IXY 2 /* fixdir-1 for each plane */ 5641 #define TM_IYZ 0 5642 #define TM_IZX 1 5643 5644 /*! Struct used in cox_render.c to indicate which lines in a volume are all zero. */ 5645 5646 typedef struct { 5647 int nmask[3] ; 5648 byte * mask[3] ; 5649 } Tmask ; 5650 5651 extern void free_Tmask( Tmask * ) ; 5652 extern Tmask * create_Tmask_byte( int, int, int, byte * ) ; 5653 extern Tmask * create_Tmask_rgba( int, int, int, rgba * ) ; 5654 5655 #define TM_ZLINE(tm,i) (tm==NULL || tm->mask[TM_IXY][i]) 5656 #define TM_YLINE(tm,i) (tm==NULL || tm->mask[TM_IZX][i]) 5657 #define TM_XLINE(tm,i) (tm==NULL || tm->mask[TM_IYZ][i]) 5658 5659 /* routines below created in thd_rot3d_byte.c on 23 Oct 2000 */ 5660 5661 extern void THD_rota_vol_byte( int, int, int, float, float, float, byte *, 5662 int,float, int,float, int,float, 5663 int,float,float,float , Tmask * ) ; 5664 5665 extern void THD_rota_byte_mode( int ) ; /* 07 Nov 2000 */ 5666 5667 extern void THD_rota_vol_matvec_byte( int, int, int, float, float, float, byte *, 5668 THD_mat33 , THD_fvec3 , Tmask * ) ; 5669 5670 /*-- see thd_shift2.c for these routines --*/ 5671 5672 extern void SHIFT_set_method( int ) ; 5673 extern int SHIFT_get_method( void ) ; 5674 extern void SHIFT_two_rows( int , int , float , float *, float , float *) ; 5675 5676 extern void fft_shift2 ( int , int , float , float *, float , float *) ; 5677 extern void hept_shift2 ( int , int , float , float *, float , float *) ; 5678 extern void quint_shift2( int , int , float , float *, float , float *) ; 5679 extern void cub_shift2 ( int , int , float , float *, float , float *) ; 5680 extern void lin_shift2 ( int , int , float , float *, float , float *) ; 5681 extern void nn_shift2 ( int , int , float , float *, float , float *) ; 5682 extern void ts_shift2 ( int , int , float , float *, float , float *) ; 5683 5684 extern void hept_shift ( int , float , float *) ; 5685 extern void nn_shift ( int , float , float *) ; 5686 extern void lin_shift ( int , float , float *) ; 5687 extern void cub_shift ( int , float , float *) ; 5688 extern void quint_shift( int , float , float *) ; 5689 5690 extern void wsinc5_shift( int , float , float *) ; /* Aug 2019 */ 5691 extern void wsinc5_shift2( int , int , float , float *, float , float *) ; 5692 extern void wsinc9_shift( int , float , float *) ; /* Aug 2019 */ 5693 extern void wsinc9_shift2( int , int , float , float *, float , float *) ; 5694 5695 extern void THD_fftshift( THD_3dim_dataset *, float,float,float, int ) ; 5696 5697 extern int THD_bandpass_vectors( int nlen, int nvec, float **vec, /* 30 Apr 2009 */ 5698 float dt, float fbot, float ftop, 5699 int qdet, int nort, float **ort ) ; 5700 extern int THD_bandpass_OK( int nx, float dt, float fbot, float ftop, int verb ) ; 5701 extern int THD_bandpass_remain_dim(int nx, float dt, float fbot, float ftop, int verb) ; /* 18 Mar 2015 [rickr] */ 5702 5703 extern int THD_bandpass_set_nfft( int n ) ; 5704 5705 extern int THD_bandpass_vectim( MRI_vectim *mrv , 5706 float dt , float fbot , float ftop , 5707 int qdet , int nort , float **ort ) ; 5708 5709 extern int THD_despike9 ( int, float *) ; /* 08 Oct 2010 */ 5710 extern int_pair THD_vectim_despike9( MRI_vectim *) ; 5711 5712 extern void THD_vectim_despike_L1( MRI_vectim *mrv , int localedit ) ; /* 02 Aug 2013 */ 5713 5714 extern THD_3dim_dataset * THD_despike9_dataset( THD_3dim_dataset *, byte * ) ; 5715 5716 /*-- see mri_3dalign.c for these routines --*/ 5717 5718 /*! Struct that holds information used during 3D registration. */ 5719 5720 typedef struct { 5721 MRI_IMARR * fitim ; /*!< Regression basis images */ 5722 double * chol_fitim ; /*!< Choleski decomposition of the normal equations */ 5723 int xa,xb , ya,yb , za,zb ; /* trim box */ 5724 } MRI_3dalign_basis ; 5725 5726 extern void mri_3dalign_edging( int , int , int ) ; 5727 extern void mri_3dalign_edging_default( int , int , int ) ; 5728 extern void mri_3dalign_force_edging( int ) ; 5729 extern void mri_3dalign_wtrimming( int ) ; 5730 extern void mri_3dalign_wproccing( int ) ; 5731 extern void mri_3dalign_scaleinit( float ) ; /* 22 Mar 2004 */ 5732 5733 extern void mri_3dalign_params( int , float , float , float , 5734 int , int , int , int ) ; 5735 5736 extern void mri_3dalign_method( int , int , int , int ) ; 5737 5738 extern void mri_3dalign_final_regmode( int ) ; 5739 5740 extern MRI_3dalign_basis * mri_3dalign_setup( MRI_IMAGE * , MRI_IMAGE * ) ; 5741 extern MRI_IMAGE * mri_3dalign_one( MRI_3dalign_basis * , MRI_IMAGE * , 5742 float *, float *, float *, 5743 float *, float *, float * ) ; 5744 extern MRI_IMARR * mri_3dalign_many( MRI_IMAGE *, MRI_IMAGE * , MRI_IMARR *, 5745 float *, float *, float *, 5746 float *, float *, float * ) ; 5747 extern void mri_3dalign_cleanup( MRI_3dalign_basis * ) ; 5748 5749 extern void mri_3dalign_initvals( float,float,float,float,float,float ) ; 5750 5751 extern MRI_IMARR * mri_3dalign_oneplus( MRI_3dalign_basis * , MRI_IMARR * , 5752 float *, float *, float *, 5753 float *, float *, float * ) ; 5754 extern MRI_IMARR * mri_3dalign_apply( MRI_3dalign_basis * , MRI_IMARR * , 5755 float, float, float, 5756 float, float, float, int ) ; 5757 5758 /*---------------------------------------------------------------------*/ 5759 5760 /*-- see mri_warp3D_align.c for these routines --*/ 5761 5762 #undef PARAM_MAXTRIAL 5763 #define PARAM_MAXTRIAL 29 5764 typedef struct { 5765 float min, max, siz, ident, delta, toler ; 5766 float val_init , val_out , val_fixed , val_pinit ; 5767 int fixed ; 5768 float val_trial[PARAM_MAXTRIAL] ; 5769 int idx_trial[PARAM_MAXTRIAL] ; /* 24 Jun 2021 */ 5770 char name[32] ; 5771 } MRI_warp3D_param_def ; 5772 5773 /*! Struct that holds information used during warp3D registration. */ 5774 5775 typedef struct { 5776 5777 /*- this stuff is to be set by the user -*/ 5778 5779 int nparam ; 5780 MRI_warp3D_param_def *param ; 5781 float scale_init , scale_out ; 5782 float delfac , tolfac ; 5783 float twoblur ; 5784 5785 int regmode , verb , max_iter , num_iter , wtproc ; 5786 int xedge , yedge , zedge ; 5787 int regfinal ; 5788 5789 MRI_IMAGE *imbase , *imwt ; 5790 5791 void (*vwfor)(float,float,float,float *,float *,float *) ; 5792 void (*vwinv)(float,float,float,float *,float *,float *) ; 5793 void (*vwset)(int,float *) ; 5794 float (*vwdet)(float,float,float) ; 5795 5796 /*- below here is not to be touched by the user! -*/ 5797 5798 int nfree ; 5799 MRI_IMAGE *imww ; 5800 MRI_IMAGE *imap ; 5801 MRI_IMAGE *imps ; 5802 MRI_IMAGE *imsk ; 5803 MRI_IMAGE *imps_blur ; 5804 5805 } MRI_warp3D_align_basis ; 5806 5807 extern int mri_warp3D_align_setup ( MRI_warp3D_align_basis * ) ; 5808 extern MRI_IMAGE * mri_warp3D_align_one ( MRI_warp3D_align_basis *, MRI_IMAGE * ); 5809 extern void mri_warp3D_align_cleanup( MRI_warp3D_align_basis * ) ; 5810 5811 extern void THD_check_AFNI_version(char *) ; /* 26 Aug 2005 */ 5812 extern void THD_death_setup( int msec ) ; /* 14 Sep 2009 */ 5813 5814 extern float THD_saturation_check( THD_3dim_dataset *, byte * , int,int ) ; /* 08 Feb 2010 */ 5815 extern float THD_saturation_check_multi( THD_3dim_dataset *, byte *, int,int *) ; /* 23 Dec 2011 */ 5816 5817 5818 extern THD_3dim_dataset * THD_dummy_N27 (void) ; /* 12 Feb 2010 */ 5819 extern THD_3dim_dataset * THD_dummy_RWCOX(void) ; /* 12 Feb 2010 */ 5820 5821 /*---------------------------------------------------------------------*/ 5822 5823 #if 0 5824 extern float THD_thresh_to_pval( float thr , THD_3dim_dataset * dset ) ; 5825 #endif 5826 5827 extern float THD_stat_to_pval ( float thr , int statcode , float * stataux ) ; 5828 extern float THD_pval_to_stat ( float pval, int statcode , float * stataux ) ; 5829 extern float THD_stat_to_zscore( float thr , int statcode , float * stataux ) ; 5830 extern int THD_stat_is_2sided( int statcode , int thrsign ) ; /* Jan 2015 */ 5831 5832 extern int THD_filename_ok( char * ) ; /* 24 Apr 1997 */ 5833 extern int THD_filename_pure( char * ) ; /* 28 Feb 2001 */ 5834 extern int THD_freemegabytes( char * ) ; /* 28 Mar 2005 */ 5835 extern int THD_character_ok( char ) ; /* 04 Feb 2010 */ 5836 extern int THD_filename_fix( char * ) ; /* 04 Feb 2010 */ 5837 5838 #undef HAS_WILDCARD /* 19 Jun 2012 */ 5839 #define HAS_WILDCARD(sss) ( strchr((sss),'*') != NULL || strchr((sss),'?') != NULL ) 5840 5841 extern THD_warp * AFNI_make_voxwarp( THD_warp * , THD_3dim_dataset * , 5842 THD_3dim_dataset * ) ; 5843 5844 extern THD_linear_mapping * AFNI_make_voxmap( THD_linear_mapping * , 5845 THD_dataxes * , THD_dataxes * ) ; 5846 5847 extern void AFNI_concatenate_warp( THD_warp * , THD_warp * ) ; 5848 5849 extern THD_linear_mapping * AFNI_concatenate_lmap( THD_linear_mapping * , 5850 THD_linear_mapping * ) ; 5851 5852 extern THD_warp * AFNI_make_affwarp_12(float,float,float,float, 5853 float,float,float,float, 5854 float,float,float,float ); /* 27 Aug 2002 */ 5855 5856 extern THD_warp * AFNI_make_affwarp_mat ( THD_mat33 ) ; /* 28 Aug 2002 */ 5857 extern THD_warp * AFNI_make_affwarp_matvec( THD_mat33 , THD_fvec3 ) ; 5858 5859 extern THD_ivec3 THD_matrix_to_orientation( THD_mat33 R ) ; /* 27 Aug 2003 */ 5860 5861 extern THD_3dim_dataset * WINsorize( THD_3dim_dataset * , 5862 int,int,int, float, char *, int,int,byte * ); 5863 5864 #define ZPAD_EMPTY (1<<0) 5865 #define ZPAD_PURGE (1<<1) 5866 #define ZPAD_MM (1<<2) 5867 #define ZPAD_IJK (1<<3) /* ZSS Dec 23 05 pad values are in voxel coords */ 5868 5869 extern THD_3dim_dataset * THD_zeropad( THD_3dim_dataset * , 5870 int,int,int,int,int,int, char *, int ); 5871 5872 THD_3dim_dataset * THD_volume_to_dataset( THD_3dim_dataset *mset , 5873 MRI_IMAGE *imin , 5874 char *prefix , 5875 int pad_xm , int pad_xp , 5876 int pad_ym , int pad_yp , 5877 int pad_zm , int pad_zp ) ; /* 25 Jan 2021 */ 5878 5879 THD_3dim_dataset * THD_imarr_to_dataset( MRI_IMARR *imar, char *prefix ) ; /* 05 Mar 2021 */ 5880 THD_3dim_dataset * THD_image_to_dataset( MRI_IMAGE *imin, char *prefix ) ; 5881 5882 extern THD_3dim_dataset * THD_warp3D( /* cf. mri_warp3D.c - 18 May 2003 */ 5883 THD_3dim_dataset *, 5884 void w_in2out(float,float,float,float *,float *,float *), 5885 void w_out2in(float,float,float,float *,float *,float *), 5886 void * , char *, int , int ) ; 5887 5888 extern THD_3dim_dataset * THD_warp3D_affine( 5889 THD_3dim_dataset *, THD_vecmat, void *, char *, int, int ); 5890 5891 extern THD_3dim_dataset * THD_warp3D_mni2tta( THD_3dim_dataset *, void *, 5892 char *, int, int ); 5893 extern THD_3dim_dataset * THD_warp3D_tta2mni( THD_3dim_dataset *, void *, 5894 char *, int, int ); 5895 5896 #define WARP3D_NEWGRID 1 5897 #define WARP3D_NEWDSET 2 5898 #define WARP3D_GRIDMASK 7 5899 5900 /*-- 02 Mar 2001: thd_entropy16.c --*/ 5901 5902 extern void ENTROPY_setup (void) ; 5903 extern void ENTROPY_setdown (void) ; 5904 extern void ENTROPY_accumulate(int64_t , void *) ; 5905 extern double ENTROPY_compute (void) ; 5906 extern double ENTROPY_dataset (THD_3dim_dataset *) ; 5907 extern double ENTROPY_datablock (THD_datablock *) ; 5908 5909 extern int AFNI_vedit( THD_3dim_dataset *dset , VEDIT_settings vednew , byte *mask ) ; 5910 extern void AFNI_vedit_clear( THD_3dim_dataset *dset ) ; 5911 5912 /*--------------------------------------------------------------------------*/ 5913 5914 /*--- Stuff for Tom Ross's NOTES ---*/ 5915 5916 #define MAX_DSET_NOTES 999 5917 #define MAX_NOTE_SIZE 4000 5918 5919 extern void tross_Add_Note (THD_3dim_dataset *, char *) ; 5920 extern void tross_Delete_Note(THD_3dim_dataset *, int ) ; 5921 5922 extern char * tross_Expand_String( char * ) ; 5923 extern char * tross_Encode_String( char * ) ; 5924 extern void tross_Dont_Encode_Slash( int ) ; /* 13 Mar 2003 */ 5925 5926 extern void tross_Store_Note ( THD_3dim_dataset * , int , char * ) ; 5927 extern char * tross_Get_Note ( THD_3dim_dataset * , int ) ; 5928 extern char * tross_Get_Notedate ( THD_3dim_dataset * , int ) ; 5929 extern int tross_Get_Notecount( THD_3dim_dataset * ) ; 5930 5931 extern void tross_Addto_History( THD_3dim_dataset *, THD_3dim_dataset *) ; 5932 5933 extern char * tross_datetime(void) ; 5934 extern char * tross_username(void) ; 5935 extern char * tross_hostname(void) ; 5936 extern char * tross_commandline( char * , int , char ** ) ; 5937 5938 extern int AFNI_logger( char * , int , char ** ) ; /* 13 Aug 2001 */ 5939 extern void AFNI_sleep( int ) ; 5940 #define AFNI_log_string(ss) AFNI_logger(ss,0,NULL) 5941 extern long long AFNI_logfilesize(void) ; /* 17 Oct 2007 */ 5942 5943 extern void AFNI_serverlog( char * ) ; /* 24 Mar 2005 */ 5944 5945 void THD_outlier_count( THD_3dim_dataset *, float, int **, int * ) ; /* 15 Aug 2001 */ 5946 5947 extern void tross_Append_History ( THD_3dim_dataset * , char * ) ; 5948 extern char * tross_Get_History ( THD_3dim_dataset * ) ; 5949 extern void tross_Make_History ( char *, int, char **, THD_3dim_dataset * ) ; 5950 extern void tross_Copy_History ( THD_3dim_dataset *, THD_3dim_dataset * ) ; 5951 extern void tross_Replace_History( THD_3dim_dataset * , char * ) ; 5952 5953 #define tross_Erase_History(ds) THD_erase_one_atr((ds)->dblk,"HISTORY_NOTE") 5954 5955 extern char * tross_breakup_string( char *, int , int ) ; 5956 5957 void tross_multi_Append_History( THD_3dim_dataset * , ... ) ; 5958 5959 #define ATLAS_CMAX 64 /* If you change this parameter,edit constant in 5960 CA_EZ_Prep.m (MaxLbl* checks), thd_ttatlas_query.h TTO_FORMAT */ 5961 5962 typedef enum { UNKNOWN_SPC=0, /*!< Dunno */ 5963 AFNI_TLRC_SPC, /*!< The Classic */ 5964 MNI_SPC, /*!< A la Canadienne */ 5965 MNI_ANAT_SPC, /*!< Mit viele liebe */ 5966 5967 NUMBER_OF_SPC /*!< A flag for the number of spaces, 5968 leave for last */ 5969 } AFNI_STD_SPACES; 5970 5971 typedef struct { 5972 /* tdval and tdlev stand for "Talairach Daemon" value and level */ 5973 /* these are kept for historical purposes */ 5974 /* perhaps one day making an unusally boring PBS special */ 5975 short tdval; /* Leave this one to be the very first element */ 5976 char name[ATLAS_CMAX] ; /* Leave this one to be the second element */ 5977 float xx,yy,zz; /* xx,yy,zz - RAI position of region - now in float */ 5978 short tdlev,okey ; /* tdlev = unknown, gyrus or area code */ 5979 /* okey = original value in atlas */ 5980 /* this value was converted for TT daemon */ 5981 /* atlas values because left and right */ 5982 /* ROIs shared the same value */ 5983 char sblabel[ATLAS_CMAX]; /* This is the sub-brick label 5984 of a dataset related to this point. 5985 The only time this is used is for 5986 linking an atlas point to the probability 5987 map volume. */ 5988 char longname[ATLAS_CMAX] ; /* Leave this one to be the second element */ 5989 } ATLAS_POINT ; 5990 5991 5992 extern int atlas_n_points(char *atname); 5993 extern ATLAS_POINT *atlas_points(char *atname); 5994 5995 extern char * TT_whereami( float , float , float, 5996 char *, void *) ; 5997 extern char * TT_whereami_old( float , float , float ) ; 5998 extern int TT_load_atlas_old (void); 5999 extern void TT_purge_atlas(void); 6000 extern THD_3dim_dataset * TT_retrieve_atlas_old(void) ; 6001 extern THD_3dim_dataset * TT_retrieve_atlas_dset(char *aname, int szflag); 6002 extern void TT_setup_popup_func( void (*pf)(char *) ) ; /* 26 May 2006 */ 6003 6004 extern THD_3dim_dataset * TT_retrieve_atlas_big_old(void) ; /* 01 Aug 2001 */ 6005 extern void TT_purge_atlas_big(void); 6006 6007 extern THD_3dim_dataset * TT_retrieve_atlas_either_old(void); /* 22 Aug 2001 */ 6008 extern char **atlas_chooser_formatted_labels(char *atname,int flipxy); 6009 6010 #define TT_ATLAS_NZ_SMALL 141 /* 01 Aug 2001 */ 6011 #define TT_ATLAS_NZ_BIG 151 6012 6013 #define TT_retrieve_atlas_dset_nz(nz) \ 6014 ( ((nz)==TT_ATLAS_NZ_SMALL) \ 6015 ? TT_retrieve_atlas_dset("TT_Daemon",-1) \ 6016 : ((nz)==TT_ATLAS_NZ_BIG) ? TT_retrieve_atlas_dset("TT_Daemon",1) : NULL ) 6017 6018 /*------------------------------------------------------------------------*/ 6019 6020 extern float THD_spearman_corr( int,float *,float *) ; /* 23 Aug 2001 */ 6021 extern float THD_quadrant_corr( int,float *,float *) ; 6022 extern float THD_pearson_corr ( int,float *,float *) ; 6023 extern float THD_pearson_partial_corr( int, float *, float *, float *); 6024 extern double THD_pearson_corrd ( int, double *, double *) ; 6025 extern float THD_covariance( int n, float *x , float *y ); 6026 extern float THD_ktaub_corr ( int,float *,float *) ; /* 29 Apr 2010 */ 6027 extern float THD_eta_squared ( int,float *,float *) ; /* 25 Jun 2010 */ 6028 extern double THD_eta_squared_masked(int,float *,float *,byte *);/* 16 Jun'11 */ 6029 extern float THD_dice_coef_f_masked(int,float *,float *,byte *);/* 28 Jul'15 */ 6030 // orig- Apr. 2014; updated- Jan. 2017, as part of some attempted saBobtage: 6031 extern THD_3dim_dataset * THD_Tcorr1D(THD_3dim_dataset *xset, 6032 byte *mask, int nmask, MRI_IMAGE *ysim, 6033 char *smethod, char *prefix,int do_short,int do_atanh); 6034 6035 extern float THD_quantile_corr( int,float *,float *) ; /* 10 May 2012 */ 6036 extern float quantile_corr( int n , float *x , float rv , float *r ) ; 6037 extern void THD_quantile_corr_setup( int ) ; 6038 extern float quantile_prepare( int n , float *a ) ; 6039 6040 extern float THD_tictactoe_corr( int,float *,float *) ; /* 19 Jul 2011 */ 6041 6042 extern float THD_pearson_corr_wt(int,float *,float *,float *); /* 13 Sep 2006 */ 6043 6044 extern void THD_pearson_corr_boot( int n, float *x, float *y, 6045 float_triple *rrr , 6046 float_triple *aaa , 6047 float_triple *bbb ) ; /* 01 Mar 2011 */ 6048 extern float_triple THD_pearson_indexed( int nix, int *ix, float *x, float *y ); 6049 extern float_triple THD_bootstrap_confinv( float estim , float alpha , 6050 int nboot , float *eboot ) ; 6051 extern float THD_bootstrap_biascorr( float estim , int nboot , float *eboot ) ; 6052 6053 extern void THD_spearman_corr_boot( int n , float *x , float *y , float_triple *rrr ) ; 6054 6055 extern float_pair THD_l1_fit_to_line( int n , float *x , float *y ) ; 6056 6057 extern float THD_bootstrap_vectcorr( int nlen, int nboot, int use_pv, int xtyp, 6058 int xnum, void *xp , int ynum , void *yp ); 6059 6060 extern float THD_spearman_corr_nd( int,float *,float *) ; /* 23 Aug 2006 */ 6061 extern float THD_quadrant_corr_nd( int,float *,float *) ; 6062 extern float THD_distance( int, float *, float *, int ); /* 04 May 2012 */ 6063 #define THD_pearson_corr_nd THD_pearson_corr 6064 6065 double THD_spearman_corr_dble( int n , double *x , double *y ) ; 6066 6067 extern void rank_order_float ( int , float * ); 6068 extern float spearman_rank_prepare( int , float * ); 6069 extern float quadrant_corr_prepare( int , float * ); 6070 extern float spearman_rank_corr ( int , float * , float , float * ); 6071 extern float quadrant_corr ( int , float * , float , float * ); 6072 6073 extern float tictactoe_corr_prepare( int , float * ); 6074 extern float tictactoe_corr ( int , float * , float , float * ); 6075 extern void tictactoe_set_thresh ( float bb , float tt ) ; 6076 6077 extern void rank_order_float_arrays( int , int * , float ** ); /* 10 Nov 2010 */ 6078 extern void rank_order_2floats( int , float * , int , float * ) ; 6079 6080 extern float THD_mutual_info_scl( int, float,float,float *, /* 16 Aug 2006 */ 6081 float,float,float *, float * ) ; 6082 extern float THD_mutual_info( int , float *, float * ) ; 6083 6084 extern void THD_correlate_ignore_zerozero(int) ; 6085 6086 extern float THD_corr_ratio_scl( int, float,float,float *, /* 23 Aug 2006 */ 6087 float,float,float *, float * ) ; 6088 extern float THD_corr_ratio( int , float *, float * ) ; 6089 extern void THD_corr_ratio_mode( int ) ; /* 11 Oct 2006 */ 6090 #define THD_corr_ratio_sym_not THD_corr_ratio_mode(0) /* unsymm */ 6091 #define THD_corr_ratio_sym_mul THD_corr_ratio_mode(1) /* sym by * */ 6092 #define THD_corr_ratio_sym_add THD_corr_ratio_mode(2) /* sym by + */ 6093 6094 extern float THD_norm_mutinf_scl( int, float,float,float *, /* 25 Sep 2006 */ 6095 float,float,float *, float * ) ; 6096 extern float THD_norm_mutinf( int , float *, float * ) ; 6097 6098 extern float THD_jointentrop_scl( int, float,float,float *, /* 25 Sep 2006 */ 6099 float,float,float *, float * ) ; 6100 extern float THD_jointentrop( int , float *, float * ) ; 6101 6102 extern float THD_hellinger_scl( int, float,float,float *, /* 26 Sep 2006 */ 6103 float,float,float *, float * ) ; 6104 extern float THD_hellinger( int , float *, float * ) ; 6105 6106 extern float_quad THD_helmicra_scl( int, float,float,float *, 6107 float,float,float *, float * ) ; 6108 extern float_quad THD_helmicra( int , float *, float * ) ; 6109 6110 extern float_pair THD_binary_mutinfo( int n0, float *y0, int n1, float *y1 ) ; 6111 6112 extern int retrieve_2Dhist ( float **xyhist ) ; /* 28 Sep 2006 */ 6113 extern int retrieve_2Dhist1 ( float **, float ** ) ; /* 07 May 2007 */ 6114 extern void set_2Dhist_hpower( double ) ; /* 03 Oct 2006 */ 6115 extern void set_2Dhist_hbin ( int ) ; 6116 extern int get_2Dhist_hbin ( void ) ; 6117 extern void clear_2Dhist ( void ) ; 6118 extern void build_2Dhist( int n , float xbot,float xtop,float *x , 6119 float ybot,float ytop,float *y , float *w ) ; 6120 extern void addto_2Dhist( int n , float xbot,float xtop,float *x , 6121 float ybot,float ytop,float *y , float *w ) ; 6122 extern void normalize_2Dhist(void) ; 6123 6124 extern void set_2Dhist_xybin( int nb, float *xb, float *yb ) ; /* 07 May 2007 */ 6125 extern int get_2Dhist_xybin( float **xb , float **yb ) ; 6126 extern void set_2Dhist_xybin_eqwide( int,float,float,float,float ) ; 6127 extern void set_2Dhist_xybin_eqhigh( int,int,float *,float * ) ; 6128 extern void set_2Dhist_xyclip ( int, float *, float * ) ; 6129 extern int get_2Dhist_xyclip ( float *, float *, float *, float * ) ; 6130 6131 extern MRI_IMAGE *build_byteized_vectors( int n , /* 02 Mar 2009 */ 6132 float xbot,float xtop,float *x , 6133 float ybot,float ytop,float *y ) ; 6134 6135 extern double ljung_box_uneven( int nval, int hh, double *val, int *tau ) ; /* 21 Jan 2020 */ 6136 extern double ljung_box_zcens ( int nval, int hh, double *val ) ; 6137 extern MRI_IMAGE * mri_vec_to_ljmap( MRI_IMAGE *inim ) ; /* 05 Feb 2020 */ 6138 6139 /*------------------------------------------------------------------------*/ 6140 /* Stuff for compression via zlib - see zfun.c - 02 Mar 2009 == snow day! */ 6141 6142 extern void zz_compress_dosave( int ii ); 6143 extern void zz_compress_dlev( int ii ); 6144 extern int zz_compress_some( int nsrc, void *ptr ); 6145 extern int zz_compress_all( int nsrc , char *src , char **dest ); 6146 extern int zz_uncompress_some( int nsrc, char *src, int ndest, char *dest ); 6147 extern int zz_uncompress_all( int nsrc , byte *src , char **dest ); 6148 extern MRI_IMAGE * zz_ncd_many( int nar , int *nsrc , char **src ); 6149 extern float zz_ncd_pair( int n1 , char *s1 , int n2 , char *s2 ); 6150 extern float THD_ncdfloat( int n , float *x , float *y ); 6151 extern float THD_ncdfloat_scl( int n , float xbot,float xtop,float *x , 6152 float ybot,float ytop,float *y ); 6153 6154 /* stuff below, for masks, created Jul 2010 */ 6155 6156 extern char * array_to_zzb64( int nsrc , char *src , int linelen ) ; 6157 extern int zzb64_to_array( char *zb , char **dest ) ; 6158 6159 extern byte * mask_binarize( int , byte * ) ; 6160 extern byte * mask_unbinarize( int , byte * ) ; 6161 6162 extern char * mask_to_b64string ( int nvox , byte *mful ) ; 6163 extern byte * mask_from_b64string( char *str , int *nvox ) ; 6164 extern int mask_b64string_nvox( char *str ) ; 6165 6166 extern bytevec * THD_create_mask_from_string( char *str ) ; 6167 6168 /*------------------------------------------------------------------------*/ 6169 6170 extern THD_fvec3 THD_autonudge( THD_3dim_dataset *dsepi, int ivepi, 6171 THD_3dim_dataset *dsant, int ivant, 6172 float step, 6173 int xstep, int ystep, int zstep, int code ) ; 6174 6175 extern MRI_IMAGE * mri_brainormalize( MRI_IMAGE *, int,int,int , MRI_IMAGE **, MRI_IMAGE **) ; /* 05 Apr 2004 */ 6176 extern void mri_brainormalize_verbose( int ) ; 6177 extern void brainnormalize_coord( float ispat, float jspat, float kspat , 6178 float *iorig, float *jorig, float *korig , 6179 THD_3dim_dataset *origset, 6180 float *xrai_orig, float *yrai_orig, float *zrai_orig); /* ZSS */ 6181 extern MRI_IMAGE * mri_watershedize( MRI_IMAGE * , float ) ; 6182 extern void mri_speciebusiness( int ) ; 6183 extern void mri_brain_normalize_cuts ( char * ); 6184 extern void mri_brainormalize_initialize(float dx, float dy, float dz); 6185 extern float THD_BN_dxyz(void); 6186 extern int THD_BN_nx(void); 6187 extern int THD_BN_ny(void); 6188 extern int THD_BN_nz(void); 6189 extern float THD_BN_xorg(void); 6190 extern float THD_BN_yorg(void); 6191 extern float THD_BN_zorg(void); 6192 extern float THD_BN_zheight(void); 6193 extern float THD_BN_xcm (void); 6194 extern float THD_BN_ycm (void); 6195 extern float THD_BN_zcm (void); 6196 extern float THD_BN_rat (void); 6197 /*------------------------------------------------------------------------*/ 6198 /* 09 May 2005: stuff for converting a dataset to from a NIML group. */ 6199 6200 extern NI_group * THD_nimlize_dsetatr( THD_3dim_dataset *) ; 6201 extern NI_group * THD_dset_to_ni_surf_dset( THD_3dim_dataset * , int ) ; 6202 extern NI_element * NI_find_element_by_aname(NI_group *,char *,char *,char *); 6203 6204 extern void THD_dblkatr_from_niml( NI_group *, THD_datablock * ) ; 6205 extern void THD_set_dataset_attributes( THD_3dim_dataset * ) ; 6206 6207 extern char * THD_make_statsym_string(THD_3dim_dataset *, int); 6208 extern char * unescape_unix_str(const char *); 6209 6210 extern THD_3dim_dataset * THD_niml_to_dataset( NI_group * , int ) ; 6211 extern int THD_add_bricks( THD_3dim_dataset * , void *, THD_3dim_dataset * ) ; 6212 extern int THD_add_sparse_data( THD_3dim_dataset * , NI_group * ) ; 6213 extern int THD_add_sparse_bricks( THD_3dim_dataset *, NI_element *) ; 6214 6215 extern int NI_get_byte_order(NI_element *) ; /* 29 Aug 2006 [rickr] */ 6216 extern int dtype_nifti_to_niml(int dtype); /* 19 Feb 2008 [rickr] */ 6217 extern int dtype_niml_to_nifti(int dtype); /* 20 Feb 2008 [rickr] */ 6218 extern int nsd_string_atr_to_slist(char ***, int, ATR_string *); 6219 6220 6221 extern int get_gni_debug(void) ; /* 3 Aug 2006 [rickr] */ 6222 extern int get_gni_to_float(void) ; 6223 extern int get_gni_write_mode(void) ; 6224 extern void set_gni_debug(int) ; 6225 extern void set_gni_to_float(int) ; 6226 extern void set_gni_write_mode(int) ; 6227 extern int set_ni_globs_from_env(void) ; 6228 extern int set_sparse_data_attribs(NI_element *, THD_3dim_dataset *, int) ; 6229 6230 /*------------------------------------------------------------------------*/ 6231 /* for converting between NIFTI-1 and NIFTI-2 10 Jul, 2015 [rickr] */ 6232 int64_t * copy_ints_as_i64 (int * ivals, int nvals); 6233 int nifti_mat44_2_dmat44(mat44 * fm, nifti_dmat44 * dm); 6234 int nifti_dmat44_2_mat44(nifti_dmat44 * dm, mat44 * fm); 6235 6236 6237 6238 #define SBFLAG_INDEX (1<<0) 6239 #define SBFLAG_FACTOR (1<<1) 6240 #define SBFLAG_STATCODE (1<<2) 6241 6242 extern NI_element * THD_subbrick_to_niml( THD_3dim_dataset *, int , int ) ; 6243 extern NI_group * THD_dataset_to_niml( THD_3dim_dataset * ) ; 6244 6245 extern MRI_IMAGE * niml_to_mri( NI_element * ) ; 6246 extern NI_element * mri_to_niml( MRI_IMAGE * ) ; 6247 6248 /* a random-ish seed for a random number generator */ 6249 6250 #undef GSEED 6251 #define GSEED (time(NULL) + 701*getpid()) 6252 6253 #ifdef __cplusplus 6254 } 6255 #endif 6256 6257 typedef struct { 6258 int npthr , nathr ; 6259 float *pthr , *athr ; 6260 float **cluthr ; 6261 } CLU_threshtable ; /* from 3dClustSim [Jul 2010] */ 6262 6263 extern char * THD_clustsim_atr_mask_dset_idcode( THD_3dim_dataset *dset ) ; 6264 extern float_triple THD_clustsim_atr_fwhmxyz( THD_3dim_dataset *dset ) ; 6265 6266 /*------ Moved here from afni.h [13 Jan 2020] ------*/ 6267 extern void AFNI_store_dset_index(int,int) ; /* 18 May 2000 */ 6268 extern int AFNI_needs_dset_ijk(void) ; 6269 extern int AFNI_needs_dset_tin(void) ; 6270 6271 #endif /* _MCW_3DDATASET_ */ 6272