1 #ifndef SUMA_DATASETS_INCLUDED 2 #define SUMA_DATASETS_INCLUDED 3 4 #include "replaceXt.h" /* 09 Nov 2018 */ 5 6 #include "suma_objs.h" 7 #include "matrix.h" 8 #include "suma_afni_surface.h" 9 10 #define MAX_ERRLOG_MSG 1000 11 #define MAX_ERRLOG_FUNCNAME 200 12 #define TMP_NAME_SEP "_LDPID_" 13 14 /*! macro to avoid typecasting warnings when going from 15 void * pointers (or XtPointer) to int and vice versa */ 16 /* I use INT_MAX and LONG_MAX 17 to guess whether or not we have 64 bit pointers. 18 I need to guess with #if to do proper type casting and 19 avoid compiler warnings */ 20 #if INT_MAX < LONG_MAX 21 #define INT_CAST int)(long int 22 #define VOID_CAST void *)(long int 23 #define CVOID_CAST const void *)(long int 24 #define XTP_CAST XtPointer)(long int 25 #define NIGRP_CAST NI_group *)(long int 26 #else 27 #define INT_CAST int 28 #define VOID_CAST void * 29 #define CVOID_CAST const void * 30 #define XTP_CAST XtPointer 31 #define NIGRP_CAST NI_group * 32 #endif 33 34 35 #define SUMA_free(a) mcw_free(a,__FILE__,__LINE__) 36 #define SUMA_ifree(p) { if ((p)) {SUMA_free((p));} (p)=NULL; } 37 38 #ifdef USE_TRACING 39 #define SUMA_DUMP_TRACE( ... ) { /* taken from dbtrace.h */\ 40 int m_ii; \ 41 SUMA_S_Note( __VA_ARGS__ );\ 42 if( DBG_num >= 0 ){ \ 43 for( m_ii=DBG_num-1; m_ii >= 0 ; m_ii-- ) \ 44 fprintf(stderr,"%*.*s%s\n",m_ii+1,m_ii+1," ",DBG_rout[m_ii]) ; \ 45 } else { \ 46 fprintf(stderr,"[No debug tracing stack: DBG_num=%d]\n",DBG_num) ; \ 47 } \ 48 } 49 #define SUMA_EDUMP_TRACE( ... ) { /* taken from dbtrace.h */\ 50 int m_ii; \ 51 SUMA_S_Err( __VA_ARGS__ ); \ 52 if( DBG_num >= 0 ){ \ 53 for( m_ii=DBG_num-1; m_ii >= 0 ; m_ii-- ) \ 54 fprintf(stderr,"%*.*s%s\n",m_ii+1,m_ii+1," ",DBG_rout[m_ii]) ; \ 55 } else { \ 56 fprintf(stderr,"[No debug tracing stack: DBG_num=%d]\n",DBG_num) ; \ 57 } \ 58 } 59 #else 60 #define SUMA_DUMP_TRACE(...) /* nada */ 61 #define SUMA_EDUMP_TRACE( ... ) /* nada */ 62 #endif 63 #define SUMA_T_Err SUMA_EDUMP_TRACE 64 65 typedef struct { 66 char macroname[100]; 67 char msg[MAX_ERRLOG_MSG]; 68 char FuncName[MAX_ERRLOG_FUNCNAME]; 69 } SUMA_ERRLOG; 70 71 72 typedef enum { SUMA_SIDE_ERROR=-1, SUMA_NO_SIDE, SUMA_LR, SUMA_LEFT, SUMA_RIGHT } SUMA_SO_SIDE; 73 74 typedef enum { SUMA_NO_NUM_UNITS = 0, 75 SUMA_MM_UNITS, 76 SUMA_P_VALUE_UNITS, 77 SUMA_Q_VALUE_UNITS, 78 SUMA_PERC_VALUE_UNITS, 79 80 SUMA_N_NUMERICAL_UNITS 81 } SUMA_NUMERICAL_UNITS; 82 83 84 /*! simple vectors */ 85 typedef struct { 86 int n; 87 int *v; 88 } SUMA_IVEC; 89 90 typedef struct { 91 int n; 92 float *v; 93 } SUMA_FVEC; 94 95 typedef struct { 96 int n; 97 double *v; 98 } SUMA_DVEC; 99 100 101 102 typedef enum { 103 SUMA_ERROR_DSET_TYPE = -1, 104 SUMA_NO_DSET_TYPE, 105 SUMA_NODE_BUCKET, 106 SUMA_VOXEL_BUCKET, 107 SUMA_AFNI_NODE_BUCKET, 108 SUMA_NODE_ROI, /*!< Col0: Node ID, Col1: ROI label (int) */ 109 SUMA_NODE_RGB, 110 SUMA_NODE_RGBb, 111 SUMA_NODE_RGBA, 112 SUMA_NODE_RGBAb, 113 SUMA_NODE_LABEL, 114 SUMA_NODE_XYZ, 115 SUMA_NEW_NODE_XYZ, 116 SUMA_NODE_CONVEXITY, 117 SUMA_NEW_MESH_IJK, 118 SUMA_MESH_IJK, 119 SUMA_PREP_NEW_SURFACE, 120 SUMA_VIEWER_SETTING, 121 SUMA_SURFACE_VOLUME_PARENT, 122 SUMA_SURFACE_OBJECT, 123 SUMA_ENGINE_INSTRUCTION, 124 SUMA_SEGMENT_OBJECT, 125 SUMA_LABEL_TABLE_OBJECT, 126 SUMA_GRAPH_BUCKET, 127 SUMA_TRACT_BUCKET, 128 SUMA_CIFTI_BUCKET, 129 SUMA_N_DSET_TYPES 130 } SUMA_DSET_TYPE; /*!< Type of data set ( should be called Object, not DSET ) 131 When you add a new element, modify functions 132 SUMA_Dset_Type_Name 133 SUMA_Dset_Type */ 134 135 typedef enum { 136 SUMA_ERROR_DSET_FORMAT = -1, 137 SUMA_NO_DSET_FORMAT, /* 0 */ 138 SUMA_ASCII_NIML, /* 1 */ 139 SUMA_BINARY_NIML, /* 2 */ 140 SUMA_NIML, /* 3 */ 141 SUMA_1D, /* 4 */ 142 SUMA_1D_PURE, /* 5 */ 143 SUMA_ASCII_OPEN_DX_DSET, /* 6 */ 144 SUMA_1D_PURE_TRANSPOSE, /* 7 */ 145 SUMA_1D_STDOUT, /* THIS ONE IS USED AS A MARKER TOO */ /*8 */ 146 SUMA_1D_STDERR, /* 9 */ 147 SUMA_NIML_STDOUT, /* 10 */ 148 SUMA_NIML_STDERR, /* 11 */ 149 SUMA_1D_PURE_STDOUT, /* 12 */ 150 SUMA_1D_PURE_STDERR, /* 13 */ 151 SUMA_1D_PURE_STDOUT_TRANSPOSE, /* 14 */ 152 SUMA_1D_PURE_STDERR_TRANSPOSE,/* THIS ONE IS USED AS A MARKER TOO*/ /* 15 */ 153 SUMA_XML_DSET, /* 16 */ 154 SUMA_XML_ASCII_DSET, /* 17 */ 155 SUMA_XML_B64_DSET, /* 18 */ 156 SUMA_XML_B64GZ_DSET, /* 19 */ 157 158 SUMA_N_DSET_FORMATS /* leave at the end */ 159 } SUMA_DSET_FORMAT; /*!< Format of data set 160 When you add a new element, modify functions 161 SUMA_Dset_Format_Name 162 SUMA_Dset_Format */ 163 #define SUMA_IS_DSET_1D_FORMAT(d) ( (d)==SUMA_1D || (d)==SUMA_1D_PURE || (d)==SUMA_1D_STDOUT || (d)==SUMA_1D_STDERR ) ? 1:0 164 165 #define SUMA_IS_DSET_STDXXX_FORMAT(d) ( (d)>=SUMA_1D_STDOUT && (d)<= SUMA_1D_PURE_STDERR_TRANSPOSE) ? 1:0 166 167 typedef enum { 168 SUMA_ERROR_COL_TYPE = -1, 169 SUMA_NO_COL_TYPE, 170 SUMA_NODE_INT, /*!< Generic integer */ 171 SUMA_NODE_INDEX, /*!< index of a node OR edge to locate it in its domain */ 172 SUMA_NODE_ILABEL, /*!< An integer coding for an integer label */ 173 SUMA_NODE_SLABEL, /*!< An string label */ 174 SUMA_GNODE_IGROUP, /*!< An integer coding for a group integer label of 175 a graph node*/ 176 SUMA_NODE_FLOAT, /*!< Generic float */ 177 SUMA_NODE_CX, /*!< Node convexity */ 178 SUMA_NODE_X, /*!< Node X coordinate */ 179 SUMA_NODE_Y, /*!< Node Y coordinate */ 180 SUMA_NODE_Z, /*!< Node Z coordinate */ 181 SUMA_NODE_3C, /*!< Node XYZ triplets */ 182 SUMA_NODE_R, /*!< Node R color */ 183 SUMA_NODE_G, /*!< Node G color */ 184 SUMA_NODE_B, /*!< Node B color */ 185 SUMA_NODE_A, /*!< Node A value */ 186 SUMA_NODE_BYTE, /*!< Generic byte */ 187 SUMA_NODE_Rb, /*!< Node R color in bytes*/ 188 SUMA_NODE_Gb, /*!< Node G color in bytes*/ 189 SUMA_NODE_Bb, /*!< Node B color in bytes*/ 190 SUMA_NODE_Ab, /*!< Node A value in bytes*/ 191 SUMA_NODE_STRING, /*!< Generic String */ 192 SUMA_NODE_SHORT, /*!< Generic short */ 193 SUMA_NODE_DOUBLE, /*!< Generic double */ 194 SUMA_NODE_COMPLEX, /*!< Generic complex */ 195 SUMA_NODE_XCORR, /*!< Cross Correlation Coefficient */ 196 SUMA_NODE_ZSCORE, /*!< Zscore */ 197 SUMA_NODE_VFR, /* Visual Field Ration */ 198 SUMA_NODE_PHASE, /* Phase of some sort */ 199 SUMA_NODE_AREA, /* Area associated with node*/ 200 SUMA_NODE_VOLUME, /* Volume associated with node */ 201 SUMA_NODE_THICKNESS, /* Thickness (distance between isotopic nodes) */ 202 SUMA_GNODE_INDEX, /*!< index of a graph's node/point, 203 not to be confused with SUMA_NODE_INDEX which 204 really should be named SUMA_DATUM_INDEX if it were 205 not for all the other _NODE_ which would also 206 need changing*/ 207 SUMA_EDGE_P1_INDEX, /* First point (Graph Node) defining an edge */ 208 SUMA_EDGE_P2_INDEX, /* Second point defining an edge */ 209 210 SUMA_MD_NODE_INDEX, /*!< Index col. into a Multiple Domain object a la CIFTI*/ 211 212 SUMA_N_COL_TYPES /* MAX number of col types */ 213 } SUMA_COL_TYPE; /*!< Column types. 214 When you add a new element, you need to modify 215 SUMA_AddColAttr 216 SUMA_Col_Type 217 SUMA_Col_Type_Name 218 SUMA_ColType2TypeCast 219 */ 220 #define SUMA_IS_GNODE_IXYZ_COL(ctp) (((ctp)==SUMA_NODE_X || \ 221 (ctp)==SUMA_NODE_Y || \ 222 (ctp)==SUMA_NODE_Z || \ 223 (ctp)==SUMA_GNODE_INDEX || \ 224 (ctp)==SUMA_GNODE_IGROUP || \ 225 (ctp)==SUMA_NODE_R || \ 226 (ctp)==SUMA_NODE_G || \ 227 (ctp)==SUMA_NODE_B || \ 228 (ctp)==SUMA_NODE_SLABEL) ? 1:0) 229 230 #define SUMA_GNODE_IXYZ_CTP2COL(ctp) ( (ctp)==SUMA_NODE_X ? 1 : \ 231 ( (ctp)==SUMA_NODE_Y ? 2: \ 232 ( (ctp)==SUMA_NODE_Z ? 3: \ 233 ( (ctp)==SUMA_NODE_SLABEL ? 4: \ 234 ( (ctp)==SUMA_GNODE_IGROUP ? 5: \ 235 ( (ctp)==SUMA_NODE_R ? 6: \ 236 ( (ctp)==SUMA_NODE_G ? 7: \ 237 ( (ctp)==SUMA_NODE_B ? 8: \ 238 ( (ctp)==SUMA_GNODE_INDEX ? 0: \ 239 -1 ) ) ) ) ) ) ) ) ) 240 241 #define SUMA_IS_DATUM_INDEX_COL(ctp) (((ctp)==SUMA_NODE_INDEX || \ 242 (ctp)==SUMA_EDGE_P1_INDEX || \ 243 (ctp)==SUMA_EDGE_P2_INDEX ) ? 1:0) 244 #define SUMA_IS_MD_DATUM_INDEX_COL(ctp) (((ctp)==SUMA_NODE_INDEX) ? 1 : 0) 245 #define SUMA_DATUM_INDEX_CTP2COL(ctp) ( ((ctp)==SUMA_NODE_INDEX || \ 246 (ctp)==SUMA_MD_NODE_INDEX) ? 0 : \ 247 ( (ctp)==SUMA_EDGE_P1_INDEX ? 1: \ 248 ( (ctp)==SUMA_EDGE_P2_INDEX ? 2:-1 ) ) ) 249 250 /*!< Displayable Object Types 251 S: surface, A: axis, G: grid, 252 ROId: Region of interest drawn type, 253 LS_type: line segment 254 NBLS_type: Node-based line segment 255 256 OLS_type: oriented line segment 257 NBOLS_type: Node-based oriented line segment 258 NBV_type: Node-Based vector (displayed as a line from node) 259 ONBV_type: NBV with a ball on the bottom (slower to render) 260 SP_type: spherical markers 261 NBSP_type: Node-Based spherical markers 262 PL_type: planes 263 NBT_type: Node-based text 264 SBT_type: Screen-based text 265 DBT_type: Dicom-based text 266 DIR_type: Directions 267 ODIR_type: Oriented Directions (not in use yet) 268 269 PNT_type: Cloud of points 270 271 */ 272 typedef enum { NOT_SET_type = -1, 273 not_DO_type, SO_type, AO_type, ROIdO_type, ROIO_type, 274 GO_type, LS_type, NBLS_type, OLS_type, NBOLS_type, 275 NBV_type, ONBV_type, SP_type, 276 NBSP_type, PL_type, VO_type, 277 NBT_type, SBT_type, DBT_type, /*!< Those three will 278 likely not be used */ 279 NIDO_type, ANY_DSET_type, GDSET_type, MD_DSET_type, TRACT_type, 280 GRAPH_LINK_type, MASK_type, DIR_type, ODIR_type, 281 PNT_type, 282 CDOM_type, /* The domain of a CIFTI beast */ 283 N_DO_TYPES } SUMA_DO_Types; 284 285 #define iDO_isSO(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? 0: \ 286 ( SUMAg_DOv[(i)].ObjectType == SO_type ? 1:0) ) 287 #define iDO_isGLDO(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? 0: \ 288 ( SUMAg_DOv[(i)].ObjectType == GRAPH_LINK_type ? 1:0) ) 289 #define iDO_isTDO(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? 0: \ 290 ( SUMAg_DOv[(i)].ObjectType == TRACT_type ? 1:0) ) 291 #define iDO_isMDO(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? 0: \ 292 ( SUMAg_DOv[(i)].ObjectType == MASK_type ? 1:0) ) 293 #define iDO_isVO(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? 0: \ 294 ( SUMAg_DOv[(i)].ObjectType == VO_type ? 1:0) ) 295 #define iDO_type(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? NOT_SET_type: \ 296 ( SUMAg_DOv[(i)].ObjectType ) ) 297 #define iDO_typename(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? \ 298 "NO OBJECT!": \ 299 ( SUMA_ObjectTypeCode2ObjectTypeName(\ 300 SUMAg_DOv[(i)].ObjectType) ) ) 301 #define iDO_ADO(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? NULL : \ 302 (SUMA_ALL_DO *)SUMAg_DOv[(i)].OP) 303 #define ADO_iDO(ado) ( (ado) ? SUMA_whichDO(SUMA_ADO_idcode((ado)), \ 304 SUMAg_DOv, SUMAg_N_DOv):-1 ) 305 #define iDO_state SUMA_iDO_state 306 #define iDO_group SUMA_iDO_group 307 308 #define ADO_TNAME(ado) (!(ado) ? \ 309 "NULL ADO!": \ 310 ( SUMA_ObjectTypeCode2ObjectTypeName(\ 311 (ado)->do_type) ) ) 312 #define ADO_ID(ado) SUMA_ADO_idcode(ado) 313 #define ADO_LABEL(ado) SUMA_ADO_sLabel(ado) 314 #define ADO_STATE(ado) SUMA_iDO_state(ADO_iDO(ado)) 315 #define ADO_GROUP(ado) SUMA_iDO_group(ADO_iDO(ado)) 316 317 #define iDO_label(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? \ 318 "NO OBJECT!": \ 319 ( (SUMA_ADO_Label((SUMA_ALL_DO *)SUMAg_DOv[(i)].OP) ) ) ) 320 #define iDO_variant(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? \ 321 "NO OBJECT!": \ 322 ( (SUMA_ADO_variant((SUMA_ALL_DO *)SUMAg_DOv[(i)].OP) ) ) ) 323 324 #define iDO_GSaux(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? \ 325 NULL: \ 326 ( (SUMA_ADO_GSaux((SUMA_ALL_DO *)SUMAg_DOv[(i)].OP) ) ) ) 327 #define iDO_idcode(i) ( ((i)<0 || (i)>=SUMAg_N_DOv) ? \ 328 NULL: \ 329 ( (SUMA_ADO_idcode((SUMA_ALL_DO *)SUMAg_DOv[(i)].OP) ) ) ) 330 #define iDO_is_variant(i,var) ( (var) ? !strcmp(iDO_variant(i),(var)):0 ) 331 #define DO_label(DO) ( !(DO) ? "NO OBJECT!": \ 332 ((SUMA_ADO_Label((SUMA_ALL_DO *)(DO)) ) ) ) 333 334 #define SUMA_IS_GOOD_STATE(mm) ( ((mm)&&strncmp(mm,"TheShadow",9))?1:0 ) 335 #define SUMA_IS_REAL_VARIANT(mm) ( ((mm)&&strncmp(mm,"TheShadow",9))?1:0 ) 336 337 /*! 338 I do not think we can have both nodes and triangles in this struct. 339 I guess I can make this be a Node Datum then create a similar struct 340 for triangle Datum and add them to SUMA_NIML_DRAWN_ROI. 341 If you do something like this rename: 342 SUMA_NIML_ROI_DATUM to SUMA_NIML_NODE_ROI_DATUM 343 */ 344 typedef struct { 345 int action; /*!< action taken with this datum, 346 see same field in SUMA_ROI_DATUM */ 347 int Type; /*!< describes the type of the DrawnROI datum 348 (see SUMA_ROI_TYPE) */ 349 int N_n; 350 int *nPath; 351 /* int Type; 352 int N_t; 353 int *tPath; */ 354 } SUMA_NIML_ROI_DATUM; /*!< a version of SUMA_ROI_DATUM struct 355 that can be used by niml. */ 356 357 typedef struct { 358 int Type; /*!< The final type of the DrawnROI, 359 see SUMA_ROI_DRAWING_TYPE*/ 360 char *idcode_str; 361 char *Parent_idcode_str; 362 int Parent_side; 363 char *Label; 364 char *ColPlaneName; 365 float FillColor[4]; /*!< RGB fill color */ 366 float EdgeColor[4]; /*!< RGB edge color */ 367 int EdgeThickness; /*!< thickness of edge */ 368 int iLabel; 369 SUMA_NIML_ROI_DATUM *ROI_datum; /*!< a vector of ROI data 370 (a multitude of ROI datum) */ 371 int N_ROI_datum; 372 } SUMA_NIML_DRAWN_ROI; /*!< a version of SUMA_DRAWN_ROI struct that 373 can be used by niml. Fields are a reflection 374 of those in SUMA_DRAWN_ROI*/ 375 376 typedef struct { /* A structure to contain information about a domain 377 over which a subset of a dataset is defined. 378 This structure was introduced to support CIFTI data */ 379 /* The following variables are named after those in CIFTI's documentation for 380 BrainModel Element */ 381 int IndexOffset; /* The number of the first row in dset corresponding to 382 the first datum over this domain */ 383 int IndexCount; /* How many consecutive rows in dset correspond to this 384 domain*/ 385 int Max_N_Data; /* Maximum number of data points in domain 386 SO->N_Node, DSET_NVOX(dset) */ 387 SUMA_DO_Types ModelType; /* Is this a surface, volume, etc...*/ 388 SUMA_SO_SIDE ModelSide; /* Which hemisphere? ...*/ 389 int Range[4]; /* min , max , imin, imax 390 min, and max are the minimum and maximum node indices 391 present in the full index list for this domain. 392 imin and imax are the rows into the full index list 393 where these min and max indices are found */ 394 char *Source; 395 char *edset_id; /* ID to elementary dataset defining that part of 396 the parent multi domain dataset that is 397 defined over this one domain only. 398 'edset' is an elementary (single domain) dataset. */ 399 } SUMA_DSET_DOMAIN; 400 /* Get the pointer to the beginning of the data indices for domain dom */ 401 402 #define SUMA_DOMAIN_INDICES(dset,dom) ((( (dset) && \ 403 (dset)->inel && \ 404 (dset)->inel->vec[0] && \ 405 IndexOffset >= 0)) ? \ 406 dset->inel->vec[0]+IndexOffset:NULL) 407 408 typedef enum { SUMA_NO_PTR_TYPE, 409 SUMA_LINKED_DSET_TYPE, /*!< For pointers to SUMA_DSET */ 410 SUMA_LINKED_OVERLAY_TYPE, /*!< For pointers to SUMA_OVERLAYS */ 411 SUMA_LINKED_ND_FRST_NEI_TYPE, 412 /*!< For pointers to SUMA_NODE_FIRST_NEIGHB*/ 413 SUMA_LINKED_MEMB_FACE_TYPE, 414 /*!< For pointers to SUMA_MEMBER_FACE_SETS*/ 415 SUMA_LINKED_SURFCONT_TYPE, /*!< For pointers to SUMA_X_SurfCont*/ 416 SUMA_LINKED_COLORLIST_TYPE,/* pointers to SUMA_COLORLIST_STRUCT */ 417 SUMA_LINKED_DRAW_MASKS_TYPE, /*!< Pointers to SUMA_DRAW_MASKS */ 418 SUMA_N_LINKED_PTR_TYPES } SUMA_LINKED_PTR_TYPES; 419 420 typedef enum { MAT_UNKNOWN=-2, MAT_NA = -1, MAT_HEEHAW = 0 /* not set */, 421 MAT_FULL = 1, MAT_TRI, MAT_TRI_DIAG, MAT_SPARSE 422 } SUMA_SQ_MATRIX_SHAPES; 423 424 typedef enum { SURF_DSET, GRAPH_DSET, TRACT_DSET, VOLUME_DSET, 425 CIFTI_DSET, MD_DSET} SUMA_DSET_FLAVORS; 426 typedef enum { SUMA_ELEM_DAT=0, /* Nodes of surface, points of tracts, 427 edges of graph */ 428 SUMA_LEV1_DAT, /* data at the tract level*/ 429 SUMA_LEV2_DAT, /* data at the bundle level */ 430 SUMA_N_LEV_DAT} SUMA_DATUM_LEVEL; 431 432 typedef struct { /* Something to hold auxiliary datasets structs */ 433 /* The Saux kids are not always set, they should be 434 reached by accessor functions and macros, not 435 fished directly from here 436 Where Saux lies depends on the flavor of dset at hand */ 437 void *Saux; /* A pointer to a structure for SUMA's use */ 438 void (*FreeSaux)(void *Saux); /* Function to free Saux */ 439 440 /* Some fields that make queries faster, WARNING, they 441 are duplicates of fields in the NI_group* so you 442 should not set these values explicitly */ 443 SUMA_SQ_MATRIX_SHAPES matrix_shape; 444 long int matrix_max_index; /* max number of edges */ 445 long int matrix_size[2]; 446 long int matrix_2M; 447 long int range_edge_index[2]; /* min, max, edge index */ 448 long int range_node_index[2]; /* min, max, node index 449 (points defining edges)*/ 450 long int N_seg_nodes; /* Number of node indices making up segments*/ 451 long int N_all_nodes; /* Total number of nodes stored in nodelist of the 452 graph dataset */ 453 SUMA_DSET_FLAVORS isGraph; 454 455 SUMA_DSET_DOMAIN **doms; /* domains over which the dataset 456 (only CIFTI for now) is defined */ 457 int N_doms; /* Number of domains */ 458 } SUMA_DSET_AUX; 459 460 /*! 461 Structure to track copies of a certain pointer. 462 DO NOT CHANGE THE ORDER OF THE STRUCTURE's FIELDS 463 */ 464 465 typedef struct { 466 SUMA_DO_Types do_type; /*!< To check if this is a displayable object 467 Leave on top for SUMA_ALL_DO and SUMA_DSET */ 468 int LinkedPtrType; /*!< Indicates the type of linked pointer */ 469 int N_links; /*!< Number of links to this pointer */ 470 char owner_id[SUMA_IDCODE_LENGTH]; /*!< The id of whoever created 471 that pointer. Might never get used.... */ 472 } SUMA_LinkedPtr; 473 474 /*! Structure to contain a dataset defined on the surface */ 475 476 typedef struct { 477 /* *** DO NOT ADD ANYTHING BEFORE THESE FIELDS 478 DO NOT CHANGE THE ORDER OF THESE FIELDS 479 These fields are use for tracking copies 480 (links) to a pointer. 481 ANY CHANGES HERE SHOULD BE REFLECTED IN 482 SUMA_LinkedPtr structure 483 */ 484 SUMA_DO_Types do_type; /*!< To check if this is a displayable object 485 This is to remain on top, to fit with 486 SUMA_ALL_DO */ 487 int LinkedPtrType; /*!< Indicates the type of linked pointer */ 488 int N_links; /*!< Number of links to this pointer */ 489 char owner_id[SUMA_IDCODE_LENGTH]; /*!< The id of whoever created 490 that pointer. Might never get used.... */ 491 492 #ifdef OLD_DSET 493 NI_element *nel; /*!< The whole deal 494 nel is a NIML data element which is briefly 495 defined by a set of attributes, and a collection 496 of data columns. 497 nel contains the following string attributes: 498 filename: The filename 499 label: A short text label identifying the data set. 500 Typically, a short version of the filename 501 idcode_str: Unique identifier for the data set 502 MeshParent_idcode: Unique identifier of the surface containing the mesh 503 over which this set is defined 504 geometry_parent_idcode: Unique identifier of the surface containing the 505 coordinates of the nodes whose attributes 506 (values) are in this set. 507 sorted_node_def: flag indicating that nodes in NodeDef are sorted 508 see NodeDef below. 509 LabelCol_'i': Label of column i 510 RangeCol_'i': Range of values in column i. 511 See function: 512 SUMA_GetColRange. 513 TypeCol_'i': Type of data in column i. 514 See functions: 515 SUMA_Col_Type 516 SUMA_Col_Type_Name 517 SUMA_ColType2TypeCast 518 and typedef: 519 SUMA_COL_TYPE 520 AttrCol_'i': Attributes specific to that column type. 521 At the moment, I don't use it much. But 522 think attributes to store with an f-stat 523 column for example and so on. 524 RangeCol_, TypeCol_ and AttrCol_: are automatically 525 generated, see: 526 SUMA_AddColAttr 527 SUMA_AddGenColAttr 528 529 nel structure contains the following fields: 530 name: A string for the type of dataset. 531 See functions: 532 SUMA_Dset_Type_Name 533 SUMA_Dset_Type 534 and typedef: 535 SUMA_DSET_TYPE 536 vec: A vector of pointers to the data columns. 537 vec_num: Number of columns in vec. So your columns 538 are vec[0] .. vec[vec_num - 1] 539 THINK SUB-BRICKS 540 vec_len: Total number of rows in the dset. Think total 541 number of voxels. 542 vec_filled: Number of rows (node data) filled in the dset. 543 You'd think this should be equal to vec_len, 544 but in instances where you may be receiving data for a 545 varying number of nodes, it's a pain to have to destroy 546 and recreate dsets. The trouble is not one of allocation 547 but of multiple links and associated structures created 548 for each new dset. So, while the juice is only up to 549 vec_filled, the allocation is for vec_len 550 NodeDef: A vector containing an explicit list of the node index 551 associated with each row of data. 552 ACTUALLY this is not a field of nel, but it is a column of 553 data of the type SUMA_NODE_INDEX or "Node_Index". This 554 column may or may not exist. If it exist then NodeDef is 555 (int *)nel->vec[i_node_index] where i_node_index is the 556 index of the column containing node definitions. To 557 find i_node_index, see function: 558 SUMA_GetColIndex 559 560 Functions to read and write dsets: 561 SUMA_LoadDset 562 SUMA_Load1DDset 563 SUMA_LoadNimlDset 564 SUMA_WriteDset 565 SUMA_RemoveDsetExtension 566 Functions to form/access dsets and contents: 567 SUMA_NewNel 568 SUMA_AddNelCol 569 SUMA_FillNelCol 570 SUMA_GetColIndex 571 SUMA_Col2Float 572 SUMA_GetNodeDef 573 SUMA_FreeDset 574 Functions for debugging: 575 SUMA_ShowNel 576 SUMA_NI_nel_Info 577 SUMA_DsetInfo 578 SUMA_ShowMeSome 579 Miscellaneous functions/tools: 580 SUMA_Dset_Format 581 SUMA_Dset_Format_Name 582 SUMA_AddNelHist 583 584 */ 585 #else /* the post april 06 05 way */ 586 /* *** You can go crazy below */ 587 NI_group *ngr; /*!< This is now April 06 05, the container of the dataset, 588 as opposed to the olde days where nel 589 contained everything. The reason that was done is to 590 accomodate large sized attibutes that 591 do not fit nicely in ASCII forms tucked inside the header. 592 What used to be called nel, is now called dnel (for 593 data-part nel) and is nothing but a copy 594 of the pointer under ngr to the nel that contains the 595 tabular dataset. 596 597 ngr contains two types of attributes: 598 STRING attributes: 599 filename: The filename 600 label: A short text label identifying the data set. 601 Typically, a short version of the filename 602 idcode_str: Unique identifier for the data set 603 MeshParent_idcode: Unique identifier of the surface containing 604 the mesh over which this set is defined 605 geometry_parent_idcode: Unique identifier of the surface containing 606 the coordinates of the nodes whose attributes 607 (values) are in this set. 608 sorted_node_def: flag indicating that nodes in NodeDef are sorted 609 see NodeDef below. 610 611 ELEMENT (data) attributes 612 ColumnRange 613 ColumnType 614 ColumnLabel 615 ColumnAttribute 616 History 617 618 Sample Code: SUMA_TestDSETIO.c 619 */ 620 NI_element *dnel; /*!< a copy of the NI_element pointer that contains 621 the tabular data inside ngr. Do not free this 622 element separately, and make sure its value is changed 623 in syncrony with the one in ngr. */ 624 NI_element *inel; /*!< a copy of the NI_element pointer that contains the 625 node (or edge for graph dsets) index column inside ngr. 626 Do not free this 627 element separately, and make sure its value is 628 changed in syncrony with the one in ngr. */ 629 NI_element *pdnel; /*!< a copy of the NI_element pointer that contains the 630 tabular graph point data inside ngr. Do not free this 631 element separately, and make sure its value is changed 632 in syncrony with the one in ngr. */ 633 NI_element *pinel; /*!< a copy of the NI_element pointer that contains the 634 point index column inside ngr. Do not free this 635 element separately, and make sure its value is 636 changed in syncrony with the one in ngr. */ 637 SUMA_DSET_AUX *Aux; 638 #endif 639 } SUMA_DSET; 640 641 /*! 642 Structure containing NIML formatted displayable objects 643 */ 644 typedef struct { 645 /* FIRST VARIABLES MUST RETAIN THEIR ORDER and follow SUMA_ALL_DO */ 646 SUMA_DO_Types do_type; 647 char *idcode_str; /*!< unique idcode for DO */ 648 char *Label; /*!< ascii label for DO */ 649 650 /* Begin specific fields */ 651 NI_group *ngr; 652 } SUMA_NIDO; 653 654 typedef struct { 655 float x; 656 float y; 657 float z; 658 } SUMA_XYZ; 659 660 typedef struct { 661 int N_vals; /* Number of values in each array below. 662 Each array can be NULL, a singleton, 663 or N_vals long. 664 a singleton is marked by setting (ptr+1) 665 to NULL */ 666 SUMA_NIDO **nido; /* Display DOs, perhaps */ 667 char **lab; 668 float *val; 669 SUMA_XYZ *loc; 670 } SUMA_G_DATUM; 671 672 /*! structure for holding graph nodes */ 673 typedef struct { 674 int id; 675 676 SUMA_G_DATUM *gd; 677 } SUMA_G_NODE; 678 679 /*! structure for holding graph edges */ 680 typedef struct { 681 int id; 682 int n0id; /* id of starting node */ 683 int n1id; /* id of ending node */ 684 685 SUMA_G_DATUM *gd; 686 } SUMA_G_EDGE; 687 688 typedef struct { 689 SUMA_G_NODE **gn; /* vector of nodes */ 690 int N_gn; 691 int N_alloc; 692 } SUMA_G_NODES; 693 694 typedef struct { 695 SUMA_G_EDGE **ge; /* vector of edges */ 696 int N_ge; 697 int N_alloc; 698 } SUMA_G_EDGES; 699 700 typedef struct { 701 SUMA_G_NODES *nodes; 702 SUMA_G_EDGES *edges; 703 int O_nodes; /* order of number of nodes, used to increment allocation */ 704 int O_edges; 705 } SUMA_GRAPH; 706 707 #define SUMA_COUNTER_SUFFIX(ic) ( ((ic) == 1) ? "st" : ((ic) == 2) ? "nd" : ((ic) == 3) ? "rd" : "th" ) 708 #define SUMA_COUNTER_PLURAL(ic) ( ((ic) == 1) ? "" : "s" ) 709 710 #define SUMA_ECHO_EDU(brk, kar) { \ 711 if (!brk && (strcmp(argv[kar], "-echo_edu") == 0)) { \ 712 int m_jj; \ 713 fprintf(SUMA_STDOUT,"\n+++ Now running:\n "); \ 714 for (m_jj=0; m_jj<argc; ++m_jj) { \ 715 if (m_jj != kar) { \ 716 fprintf(SUMA_STDOUT,"%s ", argv[m_jj]); \ 717 } \ 718 } \ 719 fprintf(SUMA_STDOUT,"\n+++\n"); \ 720 brk = YUP; \ 721 } \ 722 } 723 724 725 726 #define SUMA_SKIP_COMMON_OPTIONS(m_brk, m_kar) {\ 727 SUMA_ECHO_EDU(m_brk, m_kar); \ 728 if (!m_brk && \ 729 ( (strcmp(argv[m_kar], "-memdbg") == 0) || \ 730 (strcmp(argv[m_kar], "-iodbg") == 0) || \ 731 (strcmp(argv[m_kar], "-nomall") == 0) || \ 732 (strcmp(argv[m_kar], "-yesmall") == 0) || \ 733 (strcmp(argv[m_kar], "-trace") == 0) || \ 734 (strcmp(argv[m_kar], "-novolreg") == 0) || \ 735 (strcmp(argv[m_kar], "-noxform") == 0) || \ 736 (strcmp(argv[m_kar], "-TRACE") == 0)) ) { \ 737 /* valid options, but already taken care of */ \ 738 m_brk = YUP; \ 739 } \ 740 } 741 742 /*! 743 set a to 1 if vector values are sorted in increasing order 744 0 if not 745 */ 746 #define SUMA_IS_SORTED_UP(v, n_v, a) {\ 747 int m_i, m_nv = n_v-1; \ 748 if (v) { \ 749 a = 1; \ 750 for (m_i =0; m_i <m_nv; ++m_i) { \ 751 if (v[m_i] > v[m_i+1]) { a = 0; break; } \ 752 } \ 753 } else {\ 754 SUMA_S_Warn("NULL vector in SUMA_IS_SORTED_UP\nReturning 0 for ans.\n"); \ 755 a = 0; \ 756 }\ 757 }/*! 758 set a to 1 if vector values are sorted in decreasing order 759 0 if not 760 */ 761 #define SUMA_IS_SORTED_DOWN(v, n_v, a) {\ 762 int m_i, m_nv = n_v-1; \ 763 if (v) { \ 764 a = 1; \ 765 for (m_i =0; m_i <m_nv; ++m_i) { \ 766 if (v[m_i] < v[m_i+1]) { a = 0; break; } \ 767 } \ 768 } else {\ 769 SUMA_S_Warn("NULL vector in SUMA_IS_SORTED_DOWN\nReturning 0 for ans.\n"); \ 770 a = 0; \ 771 }\ 772 } 773 774 /*! 775 Convenience function for SUMA_StringAppend cleanup 776 */ 777 #define SUMA_SS2S(SS, stmp) {\ 778 if (SS) { \ 779 SS = SUMA_StringAppend(SS, NULL); \ 780 stmp = SS->s; \ 781 SUMA_free(SS); SS = NULL; } \ 782 } 783 /*! 784 Frees so, if not NULL 785 copies sn into so, takes care of so's allocation 786 Does not free sn 787 */ 788 #define SUMA_STRING_REPLACE(so, sn) { \ 789 if (so) SUMA_free(so); \ 790 so = SUMA_copy_string(sn); \ 791 } 792 793 #define SUMA_TO_LOWER_C(c) ( (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A'): c ) 794 #define SUMA_IS_UPPER_C(c) ( (c >= 'A' && c <= 'Z') ) 795 #define SUMA_IS_LOWER_C(c) ( (c >= 'a' && c <= 'z') ) 796 797 #define SUMA_TO_LOWER(s) { \ 798 int m_i, m_d; \ 799 if (s) { \ 800 m_d = 'a' - 'A'; \ 801 for (m_i=0; m_i < strlen(s); ++m_i) { \ 802 if (s[m_i] >= 'A' && s[m_i] <= 'Z') s[m_i] = s[m_i] + m_d; \ 803 } \ 804 } \ 805 } 806 807 #define SUMA_TO_UPPER_C(c) ( (c >= 'a' && c <= 'z') ? (c - 'a' + 'A'): c ) 808 809 #define SUMA_TO_UPPER(s) { \ 810 int m_i, m_d; \ 811 if (s) { \ 812 m_d = 'a' - 'A'; \ 813 for (m_i=0; m_i < strlen(s); ++m_i) { \ 814 if (s[m_i] >= 'a' && s[m_i] <= 'z') s[m_i] = s[m_i] - m_d; \ 815 } \ 816 } \ 817 } 818 819 820 821 /*! 822 Is this attribute string empty ? 823 */ 824 #define SUMA_IS_EMPTY_STR_ATTR(str) ( (!(str) || !strcmp((str),SUMA_EMPTY_ATTR)) ? 1 : 0 ) 825 826 827 /*! 828 \brief Macros to access dataset elements 829 Almost all of them involve a function call 830 so don't use them in loops where the returned 831 value is not expected to change 832 */ 833 #ifdef OLD_DSET 834 #define SDSET_FILENAME(dset) NI_get_attribute(dset->nel,"filename") 835 #define SDSET_LABEL(dset) NI_get_attribute(dset->nel,"label") 836 #define SDSET_ID(dset) SUMA_sdset_id(dset) 837 #define SDSET_IDGDOM(dset) NI_get_attribute(dset->nel,"geometry_parent_idcode") 838 #define SDSET_IDMDOM(dset) SUMA_sdset_idmdom(dset) 839 #define SDSET_SORTED(dset) NI_get_attribute(dset->nel,"sorted_node_def") 840 #define SDSET_TYPE_NAME(dset) dset->nel->name 841 #define SDSET_TYPE(dset) SUMA_Dset_Type(dset->nel->name) 842 #define SDSET_VECLEN(dset) dset->nel->vec_len 843 #define SDSET_VECNUM(dset) dset->nel->vec_num 844 #define SDSET_VECFILLED(dset) dset->nel->vec_filled 845 #else 846 #define SDSET_FILENAME(dset) NI_get_attribute(dset->ngr,"filename") 847 /* A safer version than SDSET_FILENAME */ 848 #define SDSET_FILENAME_s(dset) SUMA_sdset_filename(dset) 849 850 /* This macro can return NULL, use it wisely, or use the safer macro */ 851 #define SDSET_LABEL(dset) NI_get_attribute(dset->ngr,"label") 852 #define SDSET_LABEL_s(dset) SUMA_sdset_label(dset) 853 854 /* This macro can return NULL, can't change behavior of SUMA_sdset_id() 855 unless I check usage of SDSET_ID everywhere in the code... */ 856 #define SDSET_ID(dset) SUMA_sdset_id(dset) 857 #define SDSET_IDGDOM(dset) \ 858 NI_get_attribute(dset->ngr,"geometry_parent_idcode") 859 #define SDSET_IDMDOM(dset) SUMA_sdset_idmdom(dset) 860 #define SDSET_SORTED(dset) ( (!dset || !dset->inel) ? \ 861 NULL:NI_get_attribute(dset->inel,"sorted_node_def") ) 862 #define SDSET_IS_SORTED(dset) ( (!dset || !dset->inel || \ 863 !NI_get_attribute(dset->inel,"sorted_node_def") || \ 864 strcmp(NI_get_attribute(dset->inel,"sorted_node_def"), "Yes") != 0) \ 865 ? 0 : 1 ) 866 #define SDSET_TYPE_NAME(dset) NI_get_attribute(dset->ngr,"dset_type") 867 #define SDSET_TYPE(dset) \ 868 SUMA_Dset_Type(NI_get_attribute(dset->ngr,"dset_type")) 869 #define SDSET_DAT_LEVEL(dset) \ 870 SUMA_sdset_datum_level(dset); 871 #define SDSET_COLCAST(dset, i) \ 872 SUMA_ColType2TypeCast(SUMA_TypeOfDsetColNumb(dset, i)) 873 #define SDSET_COLTYPE(dset, i) \ 874 SUMA_TypeOfDsetColNumb(dset, i) 875 #define SDSET_VECLEN(dset) ( (!dset || !dset->dnel) ? -1:dset->dnel->vec_len ) 876 #define SDSET_VECALLOC(dset) MAX(SDSET_VECLEN(dset),0) /* 24 Sep 2021 - RWC */ 877 #define SDSET_VEC(dset,iii) dset->dnel->vec[iii] 878 #define SDSET_NVOX SDSET_VECLEN 879 #define SDSET_IS_VOL SUMA_isVolDataset 880 #define SDSET_BRICK_FACTOR SUMA_GetBrickFactor 881 #define SDSET_BRICK_TYPE SUMA_GetBrickType 882 #define SDSET_ARRAY SDSET_VEC 883 #define SDSET_NODEINDLEN(dset) dset->inel->vec_len 884 #define SDSET_VECNUM(dset) dset->dnel->vec_num 885 #define SDSET_NODEINDNUM(dset) dset->inel->vec_num 886 #define SDSET_VECFILLED(dset) dset->dnel->vec_filled 887 #define SDSET_NODEINDFILLED(dset) dset->inel->vec_filled 888 #define SDSET_NODE_INDEX_COL(dset) ( (!dset || !dset->inel || \ 889 !dset->inel->vec) ? \ 890 NULL:(int*)(dset->inel->vec[0]) ) 891 #define SDSET_EDGE_INDEX_COL SDSET_NODE_INDEX_COL 892 #define SDSET_EDGE_P1_INDEX_COL(dset) ( (!dset || !dset->inel || \ 893 !dset->inel->vec || \ 894 dset->inel->vec_num != 3) ? \ 895 NULL:(int*)(dset->inel->vec[1]) ) 896 #define SDSET_EDGE_P2_INDEX_COL(dset) ( (!dset || !dset->inel || \ 897 !dset->inel->vec || \ 898 dset->inel->vec_num != 3) ? \ 899 NULL:(int*)(dset->inel->vec[2]) ) 900 #define SDSET_EDGE_NODE_INDEX_COLS(dset, PE, P1, P2) {\ 901 (PE)=(P1)=(P2)=NULL; \ 902 if ( (dset) && (dset->inel) && (dset->inel->vec) && \ 903 dset->inel->vec_num ==3 ) { \ 904 (PE) = (int*)(dset->inel->vec[0]); \ 905 (P1) = (int*)(dset->inel->vec[1]); \ 906 (P2) = (int*)(dset->inel->vec[2]); \ 907 } \ 908 } 909 910 #define SDSET_COL(dset, icol) ( (!dset || !dset->dnel || !dset->dnel->vec) \ 911 ? NULL:(dset->dnel->vec[icol]) ) 912 #define SDSET_MATRIX_SZ0(dset) ( (!(dset) || !(dset)->Aux) ? \ 913 -1: ((dset)->Aux->matrix_size[0]) ) 914 #define SDSET_MATRIX_SZ1(dset) ( (!(dset) || !(dset)->Aux) ? \ 915 -1: ((dset)->Aux->matrix_size[1]) ) 916 #define GDSET_N_SEG_POINTS(dset) ( (!(dset) || !(dset)->Aux) ? \ 917 -1: ((dset)->Aux->N_seg_nodes) ) 918 #define GDSET_N_ALL_POINTS(dset) ( (!(dset) || !(dset)->Aux) ? \ 919 -1: ((dset)->Aux->N_all_nodes) ) 920 #endif 921 922 #define DSET_MAX_NODE_INDEX(dset, MM) {\ 923 double r[2]; int loc[2]; \ 924 if (!SUMA_GetDsetNodeIndexColRange( dset, r, loc, 1)) { \ 925 MM = -1; \ 926 } else { \ 927 MM = (int)r[1]; \ 928 } \ 929 } 930 931 /* Edges are the 'nodes' of datasets */ 932 #define GDSET_MAX_EDGE_INDEX DSET_MAX_NODE_INDEX 933 934 /*! 935 \brief Macros to access commonly used colorplane parameters 936 DO NOT USE COLP_NODEDEF macro inside a loop where the returned 937 value is not to change because it involves a function call (SLOW) 938 */ 939 /* Post March 29 04. You can't go frugal and use dset's fields 940 NodeDef might be dynamically changed in the overlay plane */ 941 #define COLP_NODEDEF(cop) cop->NodeDef 942 #define COLP_N_NODEDEF(cop) cop->N_NodeDef 943 #ifdef OLD_DSET 944 #define COLP_N_ALLOC(cop) cop->dset_link->nel->vec_len 945 #else 946 #define COLP_N_ALLOC(cop) cop->dset_link->dnel->vec_len 947 #endif 948 /* #define DSET_(dset) NI_get_attribute(dset->nel,"") */ 949 950 static byte NI_GOT; 951 952 #define NI_SET_STR(ngr, name, val) {\ 953 if (val && val[0] != '\0') NI_set_attribute(ngr, name, val); \ 954 else NI_set_attribute(ngr, name, SUMA_EMPTY_ATTR); \ 955 } 956 #define NI_GET_STR(ngr, name, val) {\ 957 char *m_s = NI_get_attribute(ngr, name); \ 958 if (m_s) { \ 959 NI_GOT = 1; \ 960 if (strcmp(m_s,SUMA_EMPTY_ATTR) == 0) val[0] = '\0'; else sprintf(val,"%s", m_s); \ 961 } else { \ 962 NI_GOT = 0; \ 963 val[0] = '\0'; \ 964 } \ 965 } 966 967 #define NI_GET_STR_CP(ngr, name, val) {\ 968 char *m_s = NI_get_attribute(ngr, name); \ 969 if (m_s) { \ 970 NI_GOT = 1; \ 971 if (strcmp(m_s,SUMA_EMPTY_ATTR) == 0) val = NULL; else val = SUMA_copy_string(m_s); \ 972 } else { \ 973 NI_GOT = 0; val = NULL; \ 974 } \ 975 } 976 977 #define NI_SET_INT(ngr, name, val) {\ 978 char m_stmp[100]; sprintf(m_stmp,"%d", val); \ 979 NI_set_attribute(ngr, name, m_stmp); \ 980 } 981 #define NI_GET_INT(ngr, name, val) {\ 982 char *m_s = NI_get_attribute(ngr, name); \ 983 if (m_s) { NI_GOT = 1; val = atoi(m_s); } else { NI_GOT = 0; val = 0; }\ 984 } 985 #define NI_SET_INTv(ngr, name, valv, n) {\ 986 char m_stmp[400]={""}; int m_i=0, m_s=0; m_stmp[0] = '\0';\ 987 for (m_i=0; m_i<n && m_s < 350; ++m_i) { \ 988 sprintf(m_stmp+m_s, " %d", valv[m_i]); \ 989 m_s = strlen(m_stmp); \ 990 if (m_s >= 350) { SUMA_S_Warn("Too long a vector, might get truncated"); }\ 991 }\ 992 NI_set_attribute(ngr, name, m_stmp); \ 993 } 994 995 #define NI_GET_INTv(ngr, name, valv, n, verb) {\ 996 char *m_s = NI_get_attribute(ngr, name); \ 997 int m_nr, m_i; int *m_iv; \ 998 for (m_i=0; m_i<n; ++m_i) valv[m_i] = 0.0; \ 999 if (m_s) { \ 1000 NI_GOT = 1; \ 1001 m_iv = (int *)SUMA_strtol_vec(m_s, n, &m_nr, SUMA_int, NULL); \ 1002 if (m_iv) {\ 1003 if (!verb) { \ 1004 if (m_nr < n) { \ 1005 SUMA_S_Warn("Fewer values in field\nProceeding..."); } \ 1006 else if (m_nr > n) { \ 1007 SUMA_S_Warn("More values in field\nProceeding..."); } \ 1008 } \ 1009 for (m_i=0; m_i<SUMA_MIN_PAIR(n, m_nr);++m_i) valv[m_i] = m_iv[m_i]; \ 1010 SUMA_free(m_iv); \ 1011 } else { \ 1012 NI_GOT = 1; \ 1013 if (verb) SUMA_S_Warn("NULL vec, filling with zeros"); \ 1014 } \ 1015 } else { NI_GOT = 0; } \ 1016 } 1017 1018 #define NI_SET_FLOAT(ngr, name, val) {\ 1019 char m_stmp[100]; sprintf(m_stmp,"%f", val); \ 1020 NI_set_attribute(ngr, name, m_stmp); \ 1021 } 1022 1023 #define NI_GET_FLOAT(ngr, name, val) {\ 1024 char *m_s = NI_get_attribute(ngr, name); \ 1025 if (m_s) { NI_GOT = 1; val = atof(m_s); } else { NI_GOT = 0; val = 0.0; }\ 1026 } 1027 1028 #define NI_SET_FLOATv(ngr, name, valv, n) {\ 1029 char m_stmp[400]; int m_i=0, m_s=0; m_stmp[0] = '\0';\ 1030 for (m_i=0; m_i<n && m_s < 350; ++m_i) { \ 1031 sprintf(m_stmp+m_s, " %f", valv[m_i]); \ 1032 m_s = strlen(m_stmp); \ 1033 if (m_s >= 350) { SUMA_S_Warn("Too long a vector, might get truncated"); }\ 1034 }\ 1035 NI_set_attribute(ngr, name, m_stmp); \ 1036 } 1037 1038 #define NI_GET_FLOATv(ngr, name, valv, n, verb) {\ 1039 char *m_s = NI_get_attribute(ngr, name); \ 1040 int m_nr, m_i; float *m_fv; \ 1041 for (m_i=0; m_i<n; ++m_i) valv[m_i] = 0.0; \ 1042 if (m_s) { \ 1043 NI_GOT = 1; \ 1044 m_fv = (float *)SUMA_strtol_vec(m_s, n, &m_nr, SUMA_float, NULL); \ 1045 if (m_fv) {\ 1046 if (verb) {\ 1047 if (m_nr < n) { \ 1048 SUMA_S_Warn("Fewer values in field\nProceeding..."); } \ 1049 else if (m_nr > n) { \ 1050 SUMA_S_Warn("More values in field\nProceeding..."); } \ 1051 } \ 1052 for (m_i=0; m_i<SUMA_MIN_PAIR(n, m_nr);++m_i) \ 1053 valv[m_i] = m_fv[m_i]; \ 1054 SUMA_free(m_fv); \ 1055 } else { \ 1056 NI_GOT = 1; \ 1057 if (verb) SUMA_S_Warn("NULL vec, filling with zeros"); \ 1058 } \ 1059 } else { NI_GOT = 0; } \ 1060 } 1061 1062 #define NI_SET_DOUBLE(ngr, name, val) {\ 1063 char m_stmp[100]; sprintf(m_stmp,"%f", val); \ 1064 NI_set_attribute(ngr, name, m_stmp); \ 1065 } 1066 1067 #define NI_GET_DOUBLE(ngr, name, val) {\ 1068 char *m_s = NI_get_attribute(ngr, name); \ 1069 if (m_s) { NI_GOT = 1; val = strtod(m_s,NULL); } else { NI_GOT = 0; val = 0.0; }\ 1070 } 1071 1072 #define NI_SET_DOUBLEv(ngr, name, valv, n) {\ 1073 char m_stmp[400]; int m_i=0, m_s=0; m_stmp[0] = '\0';\ 1074 for (m_i=0; m_i<n && m_s < 350; ++m_i) { \ 1075 sprintf(m_stmp+m_s, " %f", valv[m_i]); \ 1076 m_s = strlen(m_stmp); \ 1077 if (m_s >= 350) { SUMA_S_Warn("Too long a vector, might get truncated"); }\ 1078 }\ 1079 NI_set_attribute(ngr, name, m_stmp); \ 1080 } 1081 1082 #define NI_GET_DOUBLEv(ngr, name, valv, n, verb) {\ 1083 char *m_s = NI_get_attribute(ngr, name); \ 1084 int m_nr, m_i; double *m_fv; \ 1085 for (m_i=0; m_i<n; ++m_i) valv[m_i] = 0.0; \ 1086 if (m_s) { \ 1087 NI_GOT = 1; \ 1088 m_fv = (double *)SUMA_strtol_vec(m_s, n, &m_nr, SUMA_double, NULL); \ 1089 if (m_fv) {\ 1090 if (verb) {\ 1091 if (m_nr < n) { \ 1092 SUMA_S_Warn("Fewer values in field\nProceeding..."); } \ 1093 else if (m_nr > n) { \ 1094 SUMA_S_Warn("More values in field\nProceeding..."); } \ 1095 } \ 1096 for (m_i=0; m_i<SUMA_MIN_PAIR(n, m_nr);++m_i) \ 1097 valv[m_i] = m_fv[m_i]; \ 1098 SUMA_free(m_fv); \ 1099 } else { \ 1100 NI_GOT = 1; \ 1101 if (verb) SUMA_S_Warn("NULL vec, filling with zeros"); \ 1102 } \ 1103 } else { NI_GOT = 0; } \ 1104 } 1105 1106 #define NI_SET_PTR(ngr, name, val) { \ 1107 char m_stmp[100]; sprintf(m_stmp,"%p",val); \ 1108 NI_set_attribute(ngr, name, m_stmp); \ 1109 } 1110 1111 #define NI_GET_PTR(ngr, name, val) { \ 1112 char *m_s = NI_get_attribute(ngr, name); \ 1113 if (m_s) { NI_GOT = 1; sscanf(m_s,"%p", &val); }\ 1114 } 1115 1116 #define NI_IS_STR_ATTR_EQUAL(ngr, name, stmp) ( (!name || !NI_get_attribute(ngr,name) || !stmp || strcmp(NI_get_attribute(ngr,name), stmp) ) ? 0:1 ) 1117 #define NI_IS_STR_ATTR_EMPTY(ngr, name) ( (!name || !NI_get_attribute(ngr,name) || !strlen(NI_get_attribute(ngr,name)) ) ? 0:1 ) 1118 1119 #define NI_YES_ATTR(ngr, name) ( \ 1120 ( !name || \ 1121 !NI_get_attribute(ngr,name) || \ 1122 strncmp(SUMA_to_lower(NI_get_attribute(ngr,name)), "y",1) ) \ 1123 ? 0:1 ) 1124 #define NI_NO_ATTR(ngr, name) ( (!name || !NI_get_attribute(ngr,name) || strncmp(SUMA_to_lower(NI_get_attribute(ngr,name)), "n",1) ) ? 0:1 ) 1125 1126 /*! 1127 NEL_READ macro for reading a NI element from strm 1128 nel (NI_element *) to contain the deed (if null then read failed) 1129 frm the source such as: "file:Test_niml_file" 1130 */ 1131 #define NEL_READ(nel, frm) { \ 1132 NI_stream m_ns = NULL; \ 1133 { \ 1134 nel = NULL; \ 1135 m_ns = NI_stream_open( frm , "r" ) ; \ 1136 if( m_ns == NULL ) { \ 1137 SUMA_SL_Err ("Failed to open stream"); \ 1138 } else { \ 1139 /* read the element */ \ 1140 if (!(nel = NI_read_element( m_ns , 1 ))) { \ 1141 SUMA_SL_Err ("Failed to read element"); \ 1142 } \ 1143 } \ 1144 /* close the stream */ \ 1145 NI_stream_close( m_ns ) ; \ 1146 } \ 1147 } 1148 1149 #define DSET_READ(dset, frm) { \ 1150 NI_stream m_ns = NULL; \ 1151 if (dset->ngr || dset->dnel) { SUMA_SL_Err("dset elements not empty!\nNeed a clean dset"); } \ 1152 else { \ 1153 m_ns = NI_stream_open( frm , "r" ) ; \ 1154 if( m_ns == NULL ) { \ 1155 SUMA_SL_Err ("Failed to open stream"); \ 1156 } else { \ 1157 /* read the element */ \ 1158 if (!(dset->ngr = NI_read_element( m_ns , 1 ))) { \ 1159 SUMA_SL_Err ("Failed to read element"); \ 1160 } else { \ 1161 /* Look for the _data element */ \ 1162 if (!(dset->dnel = SUMA_FindDsetDataElement(dset))) { \ 1163 SUMA_SL_Err("Cannot find data element!\nCleaning up.\n"); \ 1164 NI_free_element (dset->ngr); dset->ngr = NULL; \ 1165 } \ 1166 dset->inel = SUMA_FindDsetDatumIndexElement(dset); \ 1167 }\ 1168 } \ 1169 /* close the stream */ \ 1170 NI_stream_close( m_ns ) ; \ 1171 } \ 1172 } 1173 1174 #define DSET_FIND(id) (SUMA_FindDset_s(id, SUMAg_CF->DsetList)) 1175 1176 /*! Write an array to a text file, mcol consecutive values per line. 1177 v is the array 1178 Nel is the total number of values 1179 m is the number of consecutive values to write per line 1180 If you want to have some index before the entries, use SUMA_WRITE_IND_ARRAY_1D*/ 1181 #define SUMA_WRITE_ARRAY_1D(v,Nel,m,iname){ \ 1182 int m_kkk; \ 1183 char *name=(char*)iname; \ 1184 FILE * m_fp=NULL;\ 1185 m_fp = (name) ? fopen((name),"w"): fopen("yougavemenoname","w"); \ 1186 if (m_fp) { \ 1187 fprintf(m_fp,"# Output from %s, %d values (%d per line).", FuncName, Nel, m); \ 1188 for (m_kkk=0; m_kkk<Nel; ++m_kkk) { if (!(m_kkk % m)) fprintf(m_fp,"\n"); fprintf(m_fp,"%f ", (double)v[m_kkk]); }\ 1189 fclose(m_fp); \ 1190 } \ 1191 } 1192 #define SUMA_WRITE_INT_ARRAY_1D(v,Nel,m,name){ \ 1193 int m_kkk; \ 1194 FILE * m_fp=NULL;\ 1195 m_fp = (name) ? fopen((name),"w"): fopen("yougavemenoname","w"); \ 1196 if (m_fp) { \ 1197 fprintf(m_fp,"# Output from %s, %d values (%d per line).", \ 1198 FuncName, Nel, m); \ 1199 for (m_kkk=0; m_kkk<Nel; ++m_kkk) { \ 1200 if (!(m_kkk % m)) fprintf(m_fp,"\n"); \ 1201 fprintf(m_fp,"%d ", (int)v[m_kkk]); }\ 1202 fclose(m_fp); \ 1203 } \ 1204 } 1205 #define SUMA_WRITE_INT_ARRAY_AND_FLAG_1D(v,Nel,m,name,flg){ \ 1206 int m_kkk; \ 1207 FILE * m_fp=NULL;\ 1208 m_fp = (name) ? fopen((name),"w"): fopen("yougavemenoname","w"); \ 1209 if (m_fp) { \ 1210 fprintf(m_fp,"# Output from %s, %d values (%d per line).", \ 1211 FuncName, Nel, m); \ 1212 for (m_kkk=0; m_kkk<Nel; ++m_kkk) { \ 1213 if (!(m_kkk % m)) { \ 1214 if (m_kkk) fprintf(m_fp,"%d ", flg); \ 1215 fprintf(m_fp,"\n"); \ 1216 } \ 1217 fprintf(m_fp,"%d ", (int)v[m_kkk]); }\ 1218 fprintf(m_fp,"%d ", flg); \ 1219 fclose(m_fp); \ 1220 } \ 1221 } 1222 1223 /* Just like SUMA_WRITE_ARRAY_1D but ind contains indices 1224 to add at the beginning of each line. 1225 If ind is NULL, then the index will be the line number. 1226 */ 1227 #define SUMA_WRITE_IND_ARRAY_1D(v,m_ind,Nel,m,name){ \ 1228 int m_kkk, *ind = (int *)m_ind; \ 1229 FILE * m_fp = (name) ? fopen((name),"w"): fopen("yougavemenoidly","w"); \ 1230 if (m_fp) { \ 1231 fprintf(m_fp, "# Output from %s, index followed by %d values "\ 1232 "(%d per line).\n", FuncName, Nel, 1); \ 1233 if (!ind) { \ 1234 for (m_kkk=0; m_kkk<Nel; ++m_kkk) { \ 1235 if (!(m_kkk % m)) fprintf(m_fp,"\n%d ", m_kkk/m); \ 1236 fprintf(m_fp,"%f ", (double)v[m_kkk]); }\ 1237 } else {\ 1238 for (m_kkk=0; m_kkk<Nel; ++m_kkk) { \ 1239 if (!(m_kkk % m)) fprintf(m_fp,"\n%d ", ind[m_kkk/m]); \ 1240 fprintf(m_fp,"%f ", (double)v[m_kkk]); }\ 1241 } \ 1242 fclose(m_fp); \ 1243 } \ 1244 } 1245 1246 /*! 1247 NEL_WRITE_TX(nel, strm, suc) 1248 NEL_WRITE_BI(nel, strm, suc) 1249 NEL_WRITE_1D(nel, strm, suc) 1250 NEL_WRITE_1D_PURE(nel, strm, suc) 1251 macros for writing a NI element in NI_TEXT_MODE, NI_BINARY_MODE or 1252 NI_TEXT_MODE | NI_HEADERSHARP_FLAG which is a la 1D 1253 nel is the NI element 1254 frm is someting like: "file:Test_write_asc_1D" (for a file output) 1255 "fd:1" (for stdout) 1256 or "stderr:" or "stdout:" 1257 suc is a flag for success (1), failure (0) 1258 */ 1259 #define NEL_WRITE_TX(nel, frm, suc) NEL_WRITE_TX_ENG(nel, frm, suc, NI_TEXT_MODE) 1260 #define NEL_WRITE_TXH(nel, frm, suc) NEL_WRITE_TX_ENG(nel, frm, suc, (NI_TEXT_MODE | NI_HEADERSHARP_FLAG)) 1261 1262 #define NEL_WRITE_TX_ENG(nel, frm, suc, form) { \ 1263 NI_stream m_ns = NULL; \ 1264 suc = 1; \ 1265 m_ns = NI_stream_open( frm , "w" ) ; \ 1266 if( m_ns == NULL ) { \ 1267 SUMA_S_Err ("Failed to open stream"); \ 1268 suc = 0; \ 1269 } else { \ 1270 /* write out the element */ \ 1271 if (NI_write_element( m_ns , nel , form ) < 0) { \ 1272 SUMA_S_Err ("Failed to write element"); \ 1273 suc = 0; \ 1274 } \ 1275 } \ 1276 /* close the stream */ \ 1277 NI_stream_close( m_ns ) ; \ 1278 } 1279 1280 1281 1282 #define DSET_WRITE_1D(dset, frm, suc, addindex) { \ 1283 NI_stream m_ns = NULL; \ 1284 int m_allnum; \ 1285 suc = 1; \ 1286 m_allnum = SUMA_is_AllNumeric_dset(dset); \ 1287 if (!m_allnum) { \ 1288 SUMA_SL_Err ("Element cannont be written to 1D format"); \ 1289 suc = 0; \ 1290 } else { \ 1291 m_ns = NI_stream_open( frm , "w" ) ; \ 1292 if( m_ns == NULL ) { \ 1293 SUMA_SL_Err ("Failed to open stream"); \ 1294 suc = 0; \ 1295 } else { \ 1296 /* write out the element */ \ 1297 if (addindex) { \ 1298 if (!dset->inel) { SUMA_SL_Err ("No inel in dset! No node indices written!\n"); addindex = 0;} \ 1299 else { NI_insert_column(dset->dnel, dset->inel->vec_typ[0], dset->inel->vec[0], 0); } \ 1300 } \ 1301 if (NI_write_element( m_ns , dset->dnel , NI_TEXT_MODE | NI_HEADERSHARP_FLAG) < 0) { \ 1302 SUMA_SL_Err ("Failed to write element"); \ 1303 suc = 0; \ 1304 } \ 1305 if (addindex) { NI_remove_column(dset->dnel, 0); } \ 1306 } \ 1307 /* close the stream */ \ 1308 NI_stream_close( m_ns ) ; \ 1309 } \ 1310 } 1311 #define DSET_WRITE_1D_PURE(dset, frm, suc, addindex) { \ 1312 FILE *m_fid = NULL; \ 1313 int m_ind, m_ival; \ 1314 int m_allnum; \ 1315 suc = 1; \ 1316 m_allnum = SUMA_is_AllNumeric_dset(dset); \ 1317 if (!m_allnum) { \ 1318 SUMA_SL_Err ("Element cannont be written to 1D format"); \ 1319 suc = 0; \ 1320 } else { \ 1321 if (!strcmp(frm,"stdout")) m_fid = stdout; \ 1322 else if (!strcmp(frm,"stderr")) m_fid = stderr; \ 1323 else m_fid = fopen(frm,"w"); \ 1324 if( m_fid == NULL ) { \ 1325 SUMA_SL_Err ("Failed to open file for output"); \ 1326 suc = 0; \ 1327 } else { \ 1328 if (addindex) { \ 1329 if (!dset->inel) { SUMA_SL_Err ("No inel in dset! No node indices written!\n"); addindex = 0;} \ 1330 } \ 1331 if (!addindex) { \ 1332 for (m_ival=0; m_ival<dset->dnel->vec_len; ++m_ival) { \ 1333 for (m_ind=0; m_ind<dset->dnel->vec_num; ++m_ind) { \ 1334 fprintf(m_fid,"%f ", SUMA_GetDsetValInCol2(dset, m_ind, m_ival)); \ 1335 } \ 1336 fprintf(m_fid,"\n"); \ 1337 } \ 1338 } else { \ 1339 int *m_n=(int *)dset->inel->vec[0]; \ 1340 for (m_ival=0; m_ival<dset->dnel->vec_len; ++m_ival) { \ 1341 fprintf(m_fid,"%d ", m_n[m_ival]); \ 1342 for (m_ind=0; m_ind<dset->dnel->vec_num; ++m_ind) { \ 1343 fprintf(m_fid,"%f ", SUMA_GetDsetValInCol2(dset, m_ind, m_ival)); \ 1344 } \ 1345 fprintf(m_fid,"\n"); \ 1346 } \ 1347 } \ 1348 fclose(m_fid); m_fid = NULL; \ 1349 } \ 1350 }\ 1351 } 1352 1353 #define DSET_WRITE_1D_PURE_TRANSPOSE(dset, frm, suc, addindex) { \ 1354 FILE *m_fid = NULL; \ 1355 int m_ind, m_ival; \ 1356 int m_allnum; \ 1357 suc = 1; \ 1358 m_allnum = SUMA_is_AllNumeric_dset(dset); \ 1359 if (!m_allnum) { \ 1360 SUMA_SL_Err ("Element cannont be written to 1D format"); \ 1361 suc = 0; \ 1362 } else { \ 1363 if (!strcmp(frm,"stdout")) m_fid = stdout; \ 1364 else if (!strcmp(frm,"stderr")) m_fid = stderr; \ 1365 else m_fid = fopen(frm,"w"); \ 1366 if( m_fid == NULL ) { \ 1367 SUMA_SL_Err ("Failed to open file for output"); \ 1368 suc = 0; \ 1369 } else { \ 1370 if (addindex) { \ 1371 if (!dset->inel) { SUMA_SL_Err ("No inel in dset! No node indices written!\n"); addindex = 0;} \ 1372 } \ 1373 if (!addindex) { \ 1374 for (m_ind=0; m_ind<dset->dnel->vec_num; ++m_ind) { \ 1375 for (m_ival=0; m_ival<dset->dnel->vec_len; ++m_ival) { \ 1376 fprintf(m_fid,"%f ", SUMA_GetDsetValInCol2(dset, m_ind, m_ival)); \ 1377 } \ 1378 fprintf(m_fid,"\n"); \ 1379 } \ 1380 } else { \ 1381 int *m_n=(int *)dset->inel->vec[0]; \ 1382 for (m_ind=0; m_ind<dset->dnel->vec_num; ++m_ind) { \ 1383 for (m_ival=0; m_ival<dset->dnel->vec_len; ++m_ival) { \ 1384 fprintf(m_fid,"%d ", m_n[m_ival]); \ 1385 fprintf(m_fid,"%f ", \ 1386 SUMA_GetDsetValInCol2(dset, m_ind, m_ival)); \ 1387 } \ 1388 fprintf(m_fid,"\n"); \ 1389 } \ 1390 } \ 1391 fclose(m_fid); m_fid = NULL; \ 1392 } \ 1393 }\ 1394 } 1395 1396 #define NEL_WRITE_1D(nel, frm, suc) { \ 1397 NI_stream m_ns = NULL; \ 1398 int m_tt = NI_element_type((void*)nel) ; \ 1399 int m_allnum; \ 1400 suc = 1; \ 1401 if (m_tt == NI_GROUP_TYPE) { \ 1402 m_allnum = 0; \ 1403 SUMA_SL_Err ("Group, use DSET_WRITE_1D_PURE"); }/* USE DSET_WRITE_1D */ \ 1404 else m_allnum = SUMA_is_AllNumeric_nel(nel); \ 1405 if (!m_allnum) { \ 1406 SUMA_SL_Err ("Element cannont be written to 1D format"); \ 1407 suc = 0; \ 1408 } else { \ 1409 m_ns = NI_stream_open( frm , "w" ) ; \ 1410 if( m_ns == NULL ) { \ 1411 SUMA_SL_Err ("Failed to open stream"); \ 1412 suc = 0; \ 1413 } else { \ 1414 /* write out the element */ \ 1415 if (NI_write_element( m_ns , nel , \ 1416 NI_TEXT_MODE | NI_HEADERSHARP_FLAG) < 0) { \ 1417 SUMA_SL_Err ("Failed to write element"); \ 1418 suc = 0; \ 1419 } \ 1420 } \ 1421 /* close the stream */ \ 1422 NI_stream_close( m_ns ) ; \ 1423 } \ 1424 } 1425 1426 /*! 1427 NEL_WRITE* macros are left for the record, they should not be used 1428 */ 1429 #define NEL_WRITE_1D_PURE(nel, frm, suc) { \ 1430 FILE *m_fid = NULL; \ 1431 int m_ind, m_ival; \ 1432 int m_tt = NI_element_type((void*)nel) ; \ 1433 int m_allnum; \ 1434 suc = 1; \ 1435 if (m_tt == NI_GROUP_TYPE) { \ 1436 m_allnum = 0; \ 1437 SUMA_SL_Err ("Group, use DSET_WRITE_1D_PURE"); } /* USE DSET_WRITE_1D */ \ 1438 else m_allnum = SUMA_is_AllNumeric_nel(nel); \ 1439 if (!m_allnum) { \ 1440 SUMA_SL_Err ("Element cannont be written to 1D format"); \ 1441 suc = 0; \ 1442 } else { \ 1443 m_fid = fopen(frm,"w"); \ 1444 if( m_fid == NULL ) { \ 1445 SUMA_SL_Err ("Failed to open file for output"); \ 1446 suc = 0; \ 1447 } else { \ 1448 for (m_ival=0; m_ival<nel->vec_len; ++m_ival) { \ 1449 for (m_ind=0; m_ind<nel->vec_num; ++m_ind) { \ 1450 fprintf(m_fid,"%f ", SUMA_GetValInCol2(nel, m_ind, m_ival)); \ 1451 } \ 1452 fprintf(m_fid,"\n"); \ 1453 } \ 1454 fclose(m_fid); m_fid = NULL; \ 1455 } \ 1456 }\ 1457 } 1458 1459 #define NEL_WRITE_BI(nel, frm, suc) { \ 1460 NI_stream m_ns = NULL; \ 1461 suc = 1; \ 1462 m_ns = NI_stream_open( frm , "w" ) ; \ 1463 if( m_ns == NULL ) { \ 1464 SUMA_SL_Err ("Failed to open stream"); \ 1465 suc = 0; \ 1466 } else { \ 1467 /* write out the element */ \ 1468 if (NI_write_element( m_ns , nel , NI_BINARY_MODE) < 0) { \ 1469 SUMA_SL_Err ("Failed to write element"); \ 1470 suc = 0; \ 1471 } \ 1472 } \ 1473 /* close the stream */ \ 1474 NI_stream_close( m_ns ) ; \ 1475 } 1476 1477 /*! 1478 get a string positioned in column col, row row in NI_element * nel. 1479 str is a copy of the pointer to that string and must not be freed 1480 */ 1481 #define SUMA_NEL_GET_STRING(nel, row, col, str) {\ 1482 char **m_rc; \ 1483 m_rc = (char **)(nel)->vec[(col)]; \ 1484 str = m_rc[(row)];\ 1485 } 1486 /*! 1487 replace a string positioned in column col, row row in NI_element * nel. 1488 */ 1489 #define SUMA_NEL_REPLACE_STRING(nel, row, col, str) {\ 1490 char **m_rc; \ 1491 m_rc = (char **)(nel)->vec[(col)]; \ 1492 if (m_rc[(row)]) NI_free(m_rc[(row)]); \ 1493 m_rc[(row)] = NULL;\ 1494 if (str) { \ 1495 m_rc[(row)] = (char*)NI_malloc(char, (strlen((str))+1)*sizeof(char));\ 1496 strcpy( m_rc[(row)], str ); \ 1497 } \ 1498 } 1499 1500 /*! 1501 \brief A macro to be run from main() before writing a dset. 1502 Changes a dset's ID, label (using prefix) and history 1503 */ 1504 #define SUMA_NEWDSET_ID_LABEL(dset, prefix) {\ 1505 if (dset) { \ 1506 if (!SUMA_NewDsetID (dset)) { \ 1507 SUMA_SL_Err("Failed in SUMA_NewDsetID, proceeding..."); } \ 1508 if (!SUMA_LabelDset(dset, prefix)) { \ 1509 SUMA_SL_Err("Failed in SUMA_LabelDset, proceeding..."); } \ 1510 } else {\ 1511 SUMA_SL_Err("NULL dset"); \ 1512 } \ 1513 } 1514 1515 #define SUMA_NEWDSET_ID_LABEL_HIST(dset, prefix) {\ 1516 if (dset) { \ 1517 SUMA_NEWDSET_ID_LABEL(dset, prefix); \ 1518 if (!SUMA_AddNgrHist (dset->ngr, FuncName, argc, argv)) { \ 1519 SUMA_SL_Err("Failed in SUMA_AddNgrHist, proceeding..."); } \ 1520 } else {\ 1521 SUMA_SL_Err("NULL dset"); \ 1522 } \ 1523 } 1524 1525 /*! A macro to transport common attributes when 1526 copying columns from one dset to another. 1527 Do not include in ATR_LIST here, any of 1528 HISTORY_NOTE (this should be done by appending old history separately) 1529 COLMS_LABELS 1530 COLMS_TYPES 1531 COLMS_RANGE as these are handled at the moment of column creation 1532 */ 1533 #define SUMA_COPY_DSET_COL_ATTRIBUTES(odset, ndset, io, in) { \ 1534 static char *m_ATR_LIST[64] = { \ 1535 "COLMS_STATSYM", "FDRCURVE", \ 1536 NULL }; \ 1537 if (!SUMA_CopyDsetAttributes (odset, ndset, m_ATR_LIST, io, in)) { \ 1538 SUMA_S_Err("Failed to copy dset attributes"); \ 1539 } \ 1540 } 1541 #define SUMA_COPY_DSET_ALL_COL_ATTRIBUTES(odset, ndset) { \ 1542 int m_i=-1;\ 1543 if (SDSET_VECNUM(odset) != SDSET_VECNUM(ndset)) {\ 1544 SUMA_S_Err("Mismatch in number of columns"); \ 1545 } \ 1546 for (m_i=0; m_i<SDSET_VECNUM(dset); ++m_i) { \ 1547 SUMA_COPY_DSET_COL_ATTRIBUTES(odset, ndset, m_i, m_i); \ 1548 } \ 1549 } 1550 1551 #define SUMA_COPY_DSETWIDE_ATTRIBUTES(odset, ndset) { \ 1552 static char *m_ATR_LIST[64] = { \ 1553 "TR", \ 1554 "AFNI_labeltable", \ 1555 NULL }; \ 1556 if (!SUMA_CopyDsetAttributes (odset, ndset, m_ATR_LIST, -1, -1)) { \ 1557 SUMA_S_Err("Failed to copy dset attributes"); \ 1558 } \ 1559 } 1560 1561 /*! 1562 A typical check on the output status of a selected prefix for 1563 surface datasets 1564 */ 1565 #define SUMA_CHECK_OUTPUT_SDSET_STATUS(Opref, InName, oform, pre, app, exists) {\ 1566 char *ooo = SUMA_OutputDsetFileStatus(Opref, InName, \ 1567 &(oform), pre, app, &(exists)); \ 1568 if (exists && !THD_ok_overwrite()) { \ 1569 SUMA_S_Errv("Output file %s already exists.\n" \ 1570 "Pick another prefix or add -overwrite\n", ooo); \ 1571 exit(1); \ 1572 } \ 1573 if (ooo) SUMA_free(ooo); ooo=NULL;\ 1574 } 1575 1576 1577 #define SUMA_MAX_OPEN_DX_FIELD_COMPONENTS 500 1578 #define SUMA_MAX_OPEN_DX_FIELD_ATTRIBUTES 500 1579 #define SUMA_MAX_OPEN_DX_OBJECTS 500 1580 1581 typedef struct { 1582 int rank; 1583 int shape; 1584 int items; 1585 int bad_data; 1586 char *type; 1587 char *object; 1588 char *class; 1589 char *data; 1590 char *data_off; 1591 int data_format; 1592 void *datap; 1593 int n_comp; 1594 char *comp_name[SUMA_MAX_OPEN_DX_FIELD_COMPONENTS]; 1595 char *comp_value[SUMA_MAX_OPEN_DX_FIELD_COMPONENTS]; 1596 int n_attr; 1597 char *attr_name[SUMA_MAX_OPEN_DX_FIELD_ATTRIBUTES]; 1598 char *attr_string[SUMA_MAX_OPEN_DX_FIELD_ATTRIBUTES]; 1599 int *counts; 1600 int n_counts; 1601 float *delta; 1602 int n_delta; 1603 float *origin; 1604 int n_origin; 1605 } SUMA_OPEN_DX_STRUCT; 1606 1607 #define SUMA_OK_OPENDX_DATA_TYPE(tp) ( ( tp == SUMA_int || \ 1608 tp == SUMA_float || \ 1609 tp == SUMA_double || \ 1610 tp == SUMA_byte ) \ 1611 ? 1 : 0 ) 1612 1613 #define SUMA_NCOL_OPENDX(dx) ( ( ( (dx)->shape == 0 ) ? 1 : ((dx)->shape) ) ) 1614 char *SUMA_getcwd(void); 1615 void SUMA_FreeErrLog ( void *data); 1616 void SUMA_PushErrLog(char *macroname, char *msg, char *fname); 1617 DListElmt* SUMA_PopErrLog(DListElmt *eldone); 1618 void WorkErrLog_ns(void); 1619 1620 NI_element *SUMA_FindDsetDataElement(SUMA_DSET *dset); 1621 NI_element *SUMA_FindGDsetNodeListElement(SUMA_DSET *dset); 1622 NI_element *SUMA_AddGDsetNodeListElement(SUMA_DSET *dset, 1623 int *I, float *X, float *Y, float *Z, 1624 char **names, int *cln, float *cols, 1625 int N_Node); 1626 NI_element *SUMA_FindDsetDatumIndexElement(SUMA_DSET *dset); 1627 NI_element *SUMA_FindSDsetNodeIndexElement(SUMA_DSET *dset); 1628 NI_element *SUMA_FindGDsetEdgeIndexElement(SUMA_DSET *dset); 1629 NI_element *SUMA_FindDsetAttributeElement(SUMA_DSET *dset, char *attname); 1630 NI_element *SUMA_FindNgrAttributeElement(NI_group *ngr, char *attname); 1631 NI_element *SUMA_FindNgrDataElement(NI_group *ngr, char *nelname, 1632 char *typename); 1633 float SUMA_LatestVersionNumber(void); 1634 int SUMA_IcoNums(int depth, byte bin, char what); 1635 char * SUMA_Dset_Type_Name (SUMA_DSET_TYPE tp); 1636 SUMA_DSET_TYPE SUMA_Dset_Type (char *Name); 1637 char * SUMA_Col_Type_Name (SUMA_COL_TYPE tp); 1638 SUMA_COL_TYPE SUMA_Col_Type (char *Name); 1639 char * SUMA_AttrOfDsetColNumb(SUMA_DSET *dset, int ind); 1640 SUMA_COL_TYPE SUMA_TypeOfDsetColNumb(SUMA_DSET *dset, int ind); 1641 SUMA_COL_TYPE SUMA_TypeOfColNumb(NI_element *nel, int ind) ; 1642 SUMA_VARTYPE SUMA_ColType2TypeCast (SUMA_COL_TYPE ctp); 1643 SUMA_Boolean SUMA_isSameDsetColTypes(SUMA_DSET *dset1, SUMA_DSET *dset2); 1644 int SUMA_ShowNel (void *nel); 1645 char *SUMA_NI_nel_Info (NI_element *nel, int detail); 1646 1647 void SUMA_allow_nel_use(int al); 1648 int SUMA_AddDsetIndexCol(SUMA_DSET *dset, int *icolu, int *icolp1, int *icolp2); 1649 int SUMA_AddGDsetNelXYZCol ( SUMA_DSET *dset, char *col_label, 1650 SUMA_COL_TYPE ctp, void *col, 1651 void *col_attr, int stride); 1652 int SUMA_AddDsetNelIndexCol ( SUMA_DSET *dset, char *col_label, 1653 SUMA_COL_TYPE ctp, void *col, 1654 void *col_attr, int stride); 1655 int SUMA_AddDsetNelCol ( SUMA_DSET *dset, char *col_label, 1656 SUMA_COL_TYPE ctp, void *col, 1657 void *col_attr, int stride); 1658 int SUMA_InsertDsetNelCol ( SUMA_DSET *dset, char *col_label, 1659 SUMA_COL_TYPE ctp, void *col, 1660 void *col_attr, int stride, int icol); 1661 int SUMA_AddNelCol ( NI_element *nel, char *col_label, 1662 SUMA_COL_TYPE ctp, void *col, 1663 void *col_attr, int stride); 1664 int SUMA_AddDsetColAttr (SUMA_DSET *dset, char *col_label, 1665 SUMA_COL_TYPE ctp, void *col_attr, 1666 int col_index, int insert_mode); 1667 int SUMA_AddDsetNodeIndexColAttr (SUMA_DSET *dset, char *col_label, 1668 SUMA_COL_TYPE ctp, void *col_attr ); 1669 int SUMA_AddGDsetNodeXYZColAttr (SUMA_DSET *dset, char *col_label, 1670 SUMA_COL_TYPE ctp, void *col_attr); 1671 int SUMA_AddColAttr (NI_element *nel, char *col_label, 1672 SUMA_COL_TYPE ctp, void *col_attr, int col_index); 1673 SUMA_Boolean SUMA_isMultiColumnAttr(NI_element *nel); 1674 SUMA_Boolean SUMA_isSingleColumnAttr(NI_element *nel, int *icolb, char *rtname); 1675 SUMA_Boolean SUMA_isDsetwideColumnAttr(NI_element *nel); 1676 SUMA_Boolean SUMA_isDsetNelAttr(NI_element *nel); 1677 char * SUMA_CreateDsetColRangeCompString( SUMA_DSET *dset, int col_index, 1678 SUMA_COL_TYPE ctp); 1679 int SUMA_UpdateDsetColRange(SUMA_DSET *dset, int icol); 1680 int SUMA_UpdateDsetColLabel(SUMA_DSET *dset, int icol, char *label); 1681 char * SUMA_GetDsetColStringAttr( SUMA_DSET *dset, int col_index, 1682 char *attrname); 1683 char * SUMA_GetNgrColStringAttr( NI_group *ngr, int col_index, 1684 char *attrname); 1685 SUMA_Boolean SUMA_ParseAttrName(NI_element *nel, int *tp, 1686 int *icol, char *rtname); 1687 SUMA_Boolean SUMA_CopyDsetAttributes ( SUMA_DSET *src, SUMA_DSET *dest, 1688 char **attrlist, 1689 int isrc, int idest ); 1690 1691 /* A quick way to check graphinity. Use SUMA_isGraphDset for safety */ 1692 #define SUMA_isGraphDset_fast(dset) ( ((dset)->Aux->isGraph==GRAPH_DSET) ) 1693 #define SUMA_isTractDset_fast(dset) ( ((dset)->Aux->isGraph==TRACT_DSET) ) 1694 #define SUMA_isCIFTIDset_fast(dset) ( ((dset)->Aux->isGraph==CIFTI_DSET) ) 1695 #define SUMA_isMD_Dset_fast(dset) ( ((dset)->Aux->isGraph==MD_DSET) ) 1696 byte SUMA_isGraphDset(SUMA_DSET *dset); 1697 byte SUMA_isGraphDsetNgr(NI_group *ngr); 1698 byte SUMA_isTractDset(SUMA_DSET *dset); 1699 byte SUMA_isTractDsetNgr(NI_group *ngr); 1700 byte SUMA_isMD_Dset(SUMA_DSET *dset); 1701 byte SUMA_isCIFTIDset(SUMA_DSET *dset); 1702 byte SUMA_isCIFTIDsetNgr(NI_group *ngr); 1703 SUMA_Boolean SUMA_Add_Dset_Aux(SUMA_DSET *dset); 1704 SUMA_Boolean SUMA_NewDsetGrp (SUMA_DSET *dset, SUMA_DSET_TYPE dtp, 1705 char* MeshParent_idcode, 1706 char * geometry_parent_idcode, 1707 int N_el, int N_eel, 1708 char *filename, char *thisidcode); 1709 NI_element * SUMA_NewNel (SUMA_DSET_TYPE dtp, char* MeshParent_idcode, 1710 char * geometry_parent_idcode, int N_el, 1711 char *name, char *thisidcode); 1712 SUMA_DSET_FORMAT SUMA_Dset_Format (char *Name); 1713 long SUMA_sdset_dnel_size(SUMA_DSET *dset); 1714 char * SUMA_Dset_Format_Name (SUMA_DSET_FORMAT fr); 1715 char *SUMA_HistString (char *CallingFunc, int N_arg, char **arg, char *sold); 1716 char * SUMA_GetNgrHist(NI_group *ngr); 1717 int SUMA_AddNgrHist(NI_group *ngr, char *CallingFunc, int N_arg, char **arg); 1718 int SUMA_RemoveNgrHist(NI_group *ngr); 1719 int SUMA_RemoveDsetHist(SUMA_DSET *dset); 1720 int SUMA_AddNelHist(NI_element *nel, char *CallingFunc, int N_arg, char **arg); 1721 void SUMA_FreeDset(void *dset); 1722 SUMA_Boolean SUMA_FreeDsetContent (SUMA_DSET *dset); 1723 SUMA_DSET * SUMA_FindDset_ns (char *idcode_str, DList *DsetList); 1724 SUMA_DSET * SUMA_FindDset2_ns (char *idcode_str, DList *DsetList, char *itype); 1725 DListElmt * SUMA_FindDsetEl_ns (char *idcode, DList *DsetList); 1726 SUMA_DSET * SUMA_FindDset_eng (char *idcode_str, DList *DsetList, 1727 DListElmt **elp, char *itype); 1728 char *SUMA_DsetInfo (SUMA_DSET *dset, int detail); 1729 void SUMA_ShowDset (SUMA_DSET *dset, int detail, FILE *out); 1730 char *SUMA_ShowMeSome (void *dt, SUMA_VARTYPE tp, int N_dt, 1731 int mxshow, char *title); 1732 SUMA_DSET * SUMA_NewDsetPointer(void); 1733 SUMA_DSET * SUMA_CreateDsetPointer ( 1734 char *name, 1735 SUMA_DSET_TYPE tp, 1736 char *idcode_str, 1737 char *domain_idcode_str, 1738 int N_Alloc); 1739 SUMA_DSET * SUMA_CreateFullDsetPointer ( 1740 char *filename, SUMA_DSET_TYPE tp, 1741 char *idcode, 1742 char *domain_idcode, 1743 int N_Alloc); 1744 int SUMA_InsertDsetPointer (SUMA_DSET **dset, DList *DsetList, int replace); 1745 int SUMA_DeleteDsetPointer (SUMA_DSET **dsetp, DList *DsetList); 1746 void * SUMA_GetCx(char *idcode_str, DList *DsetList, int ReturnDsetPointer) ; 1747 #if 0 1748 SUMA_DSET *SUMA_LinkToDset(SUMA_DSET *dset); 1749 SUMA_DSET *SUMA_UnlinkFromDset(SUMA_DSET *dset); 1750 #endif 1751 void *SUMA_LinkToPointer(void *ptr); 1752 void *SUMA_UnlinkFromPointer(void *ptr); 1753 int * SUMA_GetNodeDef(SUMA_DSET *dset); 1754 int SUMA_GetNodeDefColIndex(SUMA_DSET *dset); 1755 int SUMA_FillDsetNelCol (SUMA_DSET *dset, char *col_label, 1756 SUMA_COL_TYPE ctp, void *col, 1757 void *col_attr, int stride); 1758 int SUMA_FillDsetNelNodeIndexCol (SUMA_DSET *dset, char *col_label, 1759 SUMA_COL_TYPE ctp, void *col, 1760 void *col_attr, int stride); 1761 SUMA_Boolean SUMA_PopulateDsetNodeIndexNel(SUMA_DSET *dset, int verb); 1762 int SUMA_FillNelCol (NI_element *nel, char *col_label, 1763 SUMA_COL_TYPE ctp, void *col, 1764 void *col_attr, int stride); 1765 int *SUMA_GetDsetColIndex (SUMA_DSET *dset, SUMA_COL_TYPE tp, int *N_i); 1766 int *SUMA_GetColIndex (NI_element *nel, SUMA_COL_TYPE tp, int *N_i); 1767 int SUMA_Float2DsetCol (SUMA_DSET *dset, int ind, float *V, int FilledOnly, 1768 byte *replacemask); 1769 int SUMA_Vec2DsetCol (SUMA_DSET *dset, int ind, 1770 void *V, SUMA_VARTYPE Vtp, 1771 int FilledOnly, 1772 byte *replacemask); 1773 int * SUMA_DsetCol2Int (SUMA_DSET *dset, int ind, int FilledOnly); 1774 float * SUMA_DsetCol2Float (SUMA_DSET *dset, int ind, int FilledOnly); 1775 double * SUMA_DsetCol2Double (SUMA_DSET *dset, int ind, int FilledOnly); 1776 float * SUMA_Col2Float (NI_element *nel, int ind, int FilledOnly); 1777 SUMA_Boolean SUMA_SetUniqueValsAttr(SUMA_DSET *dset, int icol, byte replace); 1778 NI_element * SUMA_GetUniqueValsAttr(SUMA_DSET *dset, int icol); 1779 NI_element * SUMA_GetUniqueIndicesAttr(SUMA_DSET *dset, int iindex); 1780 int * SUMA_GetUniqueIndicesVec(SUMA_DSET *dset, int iindex); 1781 int * SUMA_GetDatasetDimensions(SUMA_DSET *dset); 1782 float * SUMA_GetDatasetFactors(SUMA_DSET *dset); 1783 MRI_TYPE SUMA_GetBrickType(SUMA_DSET *dset, int ii); 1784 float SUMA_GetBrickFactor(SUMA_DSET *dset, int ii); 1785 float * SUMA_GetDatasetI2X(SUMA_DSET *dset, float M[4][4]); 1786 int SUMA_isVolDataset(SUMA_DSET *dset); 1787 NI_element * SUMA_GetAtlasLabelTable(SUMA_DSET *dset); 1788 NI_element * SUMA_GetValueLabelTable(SUMA_DSET *dset); 1789 SUMA_Boolean SUMA_SetUniqueIndicesAttr(SUMA_DSET *dset, byte replace); 1790 int SUMA_GetDsetColRange(SUMA_DSET *dset, int col_index, 1791 double range[2], int loc[2]); 1792 int SUMA_GetDsetNodeIndexColRange(SUMA_DSET *dset, 1793 double range[2], int loc[2], int addifmissing); 1794 int SUMA_GetColRange(NI_element *nel, int col_index, 1795 double range[2], int loc[2]); 1796 int SUMA_AddGenDsetColAttr (SUMA_DSET *dset, SUMA_COL_TYPE ctp, void *col, 1797 int stride, int col_index, int insert_mode); 1798 int SUMA_AddGenDsetNodeIndexColAttr (SUMA_DSET *dset, SUMA_COL_TYPE ctp, 1799 void *col, int stride) ; 1800 int SUMA_AddGenGDsetNodeXYZColAttr (SUMA_DSET *dset, SUMA_COL_TYPE ctp, 1801 void *col, int stride) ; 1802 int SUMA_AddGenColAttr (NI_element *nel, SUMA_COL_TYPE ctp, void *col, 1803 int stride, int col_index); 1804 SUMA_DSET *SUMA_LoadNimlDset (char *Name, int verb); 1805 SUMA_DSET *SUMA_LoadGIFTIDset (char *Name, int verb); 1806 SUMA_DSET *SUMA_LoadDset_eng (char *Name, SUMA_DSET_FORMAT *form, int verb); 1807 SUMA_DSET *SUMA_LoadDset_ns (char *Name, SUMA_DSET_FORMAT *form, int verb); 1808 SUMA_DSET *SUMA_Load1DDset_eng (char *Name, int verb); 1809 SUMA_DSET *SUMA_Load1DDset_ns (char *Name, int verb); 1810 SUMA_DSET *SUMA_LoadDXDset_eng (char *Name, int verb); 1811 SUMA_DSET *SUMA_LoadDXDset_ns (char *Name, int verb); 1812 char *SUMA_RemoveDsetExtension_ns (char*Name, SUMA_DSET_FORMAT form); 1813 char *SUMA_RemoveDsetExtension_eng (char*Name, SUMA_DSET_FORMAT *form); 1814 char * SUMA_WriteDset_ns (char *Name, SUMA_DSET *dset, SUMA_DSET_FORMAT form, 1815 int overwrite, int verb); 1816 int SUMA_WriteDset_NameCheck_ns (char *Name, SUMA_DSET *dset, 1817 SUMA_DSET_FORMAT form, int verb, 1818 char **NameOutp); 1819 int SUMA_WriteDset_NameCheck_eng (char *Name, SUMA_DSET *dset, 1820 SUMA_DSET_FORMAT form, int verb, 1821 char **NameOutp); 1822 char * SUMA_WriteDset_eng (char *Name, SUMA_DSET *dset, SUMA_DSET_FORMAT form, 1823 int overwrite, int verb, int rename_autoid); 1824 SUMA_DSET * SUMA_far2dset_eng( char *FullName, char *dset_id, char *dom_id, 1825 float **farp, int vec_len, int vec_num, 1826 int ptr_cpy); 1827 SUMA_DSET * SUMA_far2dset_ns( char *FullName, char *dset_id, char *dom_id, 1828 float **farp, int vec_len, int vec_num, 1829 int ptr_cpy); 1830 SUMA_DSET * SUMA_iar2dset_eng( char *FullName, char *dset_id, char *dom_id, 1831 int **farp, int vec_len, int vec_num, 1832 int ptr_cpy); 1833 SUMA_DSET * SUMA_iar2dset_ns( char *FullName, char *dset_id, char *dom_id, 1834 int **farp, int vec_len, int vec_num, 1835 int ptr_cpy); 1836 int SUMA_is_AllNumeric_dset(SUMA_DSET *dset); 1837 int SUMA_dset_to_Label_dset(SUMA_DSET *dset); 1838 int SUMA_is_Label_dset(SUMA_DSET *dset, NI_group **NIcmap); 1839 int SUMA_is_Label_dset_col(SUMA_DSET *dset, int icol); 1840 int SUMA_is_Phase_dset(SUMA_DSET *dset); 1841 int SUMA_is_RetinoAngle_dset(SUMA_DSET *dset); 1842 int SUMA_is_VFR_dset(SUMA_DSET *dset); 1843 NI_group *SUMA_NICmapToNICmap(NI_group *NIcmap); 1844 int * SUMA_UniqueValuesInLabelDset(SUMA_DSET *dset, int *N_unq); 1845 int SUMA_is_AllConsistentNumeric_dset(SUMA_DSET *dset, SUMA_VARTYPE *vtpp); 1846 int SUMA_GetConsistentColType_dset(SUMA_DSET *dset); 1847 int SUMA_is_AllConsistentColType_dset(SUMA_DSET *dset, SUMA_COL_TYPE ctpi); 1848 int SUMA_is_AllConsistentCastType_dset(SUMA_DSET *dset, int typecast); 1849 int SUMA_is_AllNumeric_ngr(NI_group *ngr) ; 1850 int SUMA_is_AllNumeric_nel(NI_element *nel); 1851 int SUMA_is_TimeSeries_dset(SUMA_DSET *dset, double *TRp); 1852 SUMA_Boolean SUMA_SetDsetTR(SUMA_DSET *dset, double TR); 1853 SUMA_Boolean SUMA_NewDsetID (SUMA_DSET *dset); 1854 SUMA_Boolean SUMA_NewDsetID2 (SUMA_DSET *dset, char *str); 1855 char *SUMA_DsetColStringAttrCopy(SUMA_DSET *dset, int i, 1856 int addcolnum, char *attrname); 1857 char *SUMA_DsetColLabel(SUMA_DSET *dset, int i); 1858 char *SUMA_DsetColLabelCopy(SUMA_DSET *dset, int i, int addcolnum); 1859 int SUMA_FindDsetColLabeled(SUMA_DSET *dset, char *label); 1860 int SUMA_FindNelColLabeled(NI_element *nelb, char *label); 1861 char **SUMA_AllDsetColLabels(SUMA_DSET *dset); 1862 char **SUMA_FreeAllDsetColLabels(char **); 1863 char *SUMA_ColLabelCopy(NI_element *nel, int i, int addcolnum); 1864 int SUMA_FloatScanDset ( SUMA_DSET *odset, int doNan, int doInf, 1865 int zeroout, int fixrange); 1866 SUMA_Boolean SUMA_Reset_NodeIndex_Element(SUMA_DSET *dset, NI_element **inel); 1867 SUMA_DSET * SUMA_PaddedCopyofDset ( SUMA_DSET *odset, int MaxNodeIndex ); 1868 SUMA_DSET * SUMA_MaskedCopyofDset(SUMA_DSET *odset, 1869 byte *rowmask, byte *colmask, 1870 int masked_only, int keep_node_index); 1871 SUMA_DSET *SUMA_CoercedCopyofDset( SUMA_DSET *odset, SUMA_VARTYPE vtp, 1872 byte *colmask); 1873 SUMA_DSET * SUMA_MaskedByOrderedNodeIndexCopyofDset( 1874 SUMA_DSET *odset, int *indexlist, 1875 int N_indexlist, byte *colmask, 1876 int masked_only, int keep_node_index); 1877 SUMA_DSET * SUMA_MaskedByNodeIndexCopyofDset(SUMA_DSET *odset, int *indexlist, 1878 int N_indexlist, byte *colmask, 1879 int masked_only, int keep_node_index); 1880 SUMA_DSET * SUMA_VcatDset(SUMA_DSET *odset, 1881 byte *rowmask, byte *colmask, 1882 int masked_only, int keep_node_index); 1883 SUMA_Boolean SUMA_Append_Copy_Part_Column(void *col, NI_rowtype *rt, int N_col, 1884 byte *rowmask, int masked_only, 1885 void **appendhere, int *append_rowtype_code, 1886 int *n_inappendhere); 1887 void *SUMA_Copy_Part_Column(void *col, NI_rowtype *rt, int N_col, 1888 byte *rowmask, int masked_only, int *n_incopy); 1889 char* SUMA_sdset_id(SUMA_DSET *dset); 1890 char *SUMA_sdset_label(SUMA_DSET *dset); 1891 char *SUMA_sdset_filename(SUMA_DSET *dset); 1892 char* SUMA_sdset_idmdom(SUMA_DSET *dset); 1893 char *SUMA_Dset_orcode(SUMA_DSET *dset); 1894 SUMA_DATUM_LEVEL SUMA_sdset_datum_level(SUMA_DSET *dset); 1895 SUMA_Boolean SUMA_sdset_set_datum_level(SUMA_DSET *dset, SUMA_DATUM_LEVEL lvl); 1896 NI_group *SUMA_oDsetNel2nDsetNgr(NI_element *nel); 1897 void SUMA_SetParent_DsetToLoad(char *parent); 1898 float *SUMA_Load1D_eng (char *oName, int *ncol, int *nrow, int RowMajor, int verb); 1899 double *SUMA_LoadDouble1D_eng (char *oName, int *ncol, int *nrow, int RowMajor, int verb); 1900 complex *SUMA_LoadComplex1D_eng (char *oName, int *ncol, int *nrow, int RowMajor, int verb); 1901 float *SUMA_Load1D_ns (char *oName, int *ncol, int *nrow, int RowMajor, int verb); 1902 SUMA_OPEN_DX_STRUCT **SUMA_OpenDX_Read(char *fname, int *nobj); 1903 void SUMA_Show_OpenDX_Struct(SUMA_OPEN_DX_STRUCT **dxv, int N_dxv, FILE *out); 1904 SUMA_OPEN_DX_STRUCT *SUMA_Free_OpenDX_Struct(SUMA_OPEN_DX_STRUCT *dx); 1905 SUMA_OPEN_DX_STRUCT *SUMA_Alloc_OpenDX_Struct(void); 1906 void * SUMA_OpenDx_Object_Header_Field(char *op, int nchar, const char *attr, 1907 char **op_end); 1908 SUMA_Boolean SUMA_OpenDx_Object_Data(char *op, int nchar, 1909 SUMA_OPEN_DX_STRUCT *dx); 1910 int * SUMA_FindNumericDataDsetCols(SUMA_DSET *dset, int *N_icols); 1911 float * SUMA_DsetCol2FloatFullSortedColumn( 1912 SUMA_DSET *dset, int ico, byte **nmaskp, float fillval, 1913 int N_Node, int *N_inmask, SUMA_Boolean MergeMask); 1914 double * SUMA_DsetCol2DoubleFullSortedColumn( 1915 SUMA_DSET *dset, int ico, byte **nmaskp, double fillval, 1916 int N_Node, int *N_inmask, SUMA_Boolean MergeMask); 1917 SUMA_Boolean SUMA_MakeSparseColumnFullSorted(float **vp, int N_v, float mask_val, byte **bmp, SUMA_DSET *dset, int N_Node); 1918 SUMA_Boolean SUMA_MakeSparseDoubleColumnFullSorted ( 1919 double **vp, int N_v, 1920 double mask_val, byte **bmp, 1921 SUMA_DSET *dset, int N_Node); 1922 SUMA_Boolean SUMA_AddNodeIndexColumn(SUMA_DSET *dset, int N_Node); 1923 int *SUMA_CreateNodeIndexToRowIndexMap(SUMA_DSET *dset, int maxind, 1924 double *range); 1925 SUMA_DSET * SUMA_ngr_2_dset(NI_group *nini, int warn); 1926 SUMA_Boolean SUMA_LabelDset(SUMA_DSET *dset, char *lbl); 1927 SUMA_Boolean SUMA_RenameDset(SUMA_DSET *dset, char *filename, int autoid); 1928 byte *SUMA_load_1D_n_mask(char *name, int N_Node, byte *omask, 1929 const char *oper, int *N_inmask); 1930 byte * SUMA_indexlist_2_bytemask(int *ind_list, int N_ind_list, 1931 int N_mask, int *N_inmask); 1932 byte * SUMA_Meshbmask_2_IndexListbmask(byte *Mbmask, int N_Mbmask, 1933 int *ind_list, int N_ind_list, int *N_ILbmask); 1934 byte *SUMA_load_1D_b_mask(char *name, int N_Node, byte *omask, 1935 const char *oper, int *N_inmask); 1936 byte *SUMA_get_c_mask(char *mask, int N_Node, byte *omask, 1937 const char *oper, int *N_inmask); 1938 byte * SUMA_load_all_command_masks(char *bmaskname, char *nmaskname, 1939 char *cmask, int N_Node, int *N_inmask); 1940 void SUMA_SetAddIndex_1D(int); 1941 int SUMA_GetAddIndex_1D(void); 1942 THD_3dim_dataset *SUMA_sumadset2afnidset(SUMA_DSET **dsetp, int copy_data, 1943 int cleardset); 1944 SUMA_DSET *SUMA_afnidset2sumadset(THD_3dim_dataset **dsetp, int copy_data, 1945 int cleardset, int floatize); 1946 int SUMA_GetDsetColStatAttr( SUMA_DSET *dset, int col_index, 1947 int *statcode, 1948 float *p1, float *p2, float *p3); 1949 float SUMA_fdrcurve_zval( SUMA_DSET *dset , int iv , float thresh ); 1950 NI_group *SUMA_NI_Cmap_of_Dset(SUMA_DSET *dset); 1951 1952 1953 /*********************** BEGIN Miscellaneous support functions **************************** */ 1954 #define SUMA_STANDALONE_INIT { \ 1955 /* install signal handler, shamelessly copied from AFNI) */ \ 1956 signal(SIGINT ,SUMA_sigfunc) ; \ 1957 signal(SIGBUS ,SUMA_sigfunc) ; \ 1958 signal(SIGSEGV,SUMA_sigfunc) ; \ 1959 signal(SIGTERM,SUMA_sigfunc) ; \ 1960 SUMA_process_environ(); \ 1961 SUMA_ParseInput_basics_ns (argv, argc); \ 1962 } 1963 1964 #define SUMA_DSET_NAME_CHECK(prefix) { \ 1965 char *NameOut=NULL; SUMA_DSET_FORMAT form=SUMA_NO_DSET_FORMAT; \ 1966 if (!THD_ok_overwrite()) { \ 1967 form = SUMA_GuessFormatFromExtension(prefix, "jeveux.niml.dset" ); \ 1968 if (SUMA_WriteDset_NameCheck_s (prefix, NULL, form, \ 1969 0, &NameOut)) { \ 1970 SUMA_S_Errv("Dset %s already exists\n", NameOut); \ 1971 SUMA_free(NameOut); \ 1972 exit(1); \ 1973 } \ 1974 } if (NameOut) SUMA_free(NameOut); \ 1975 } 1976 1977 SUMA_DSET_FORMAT SUMA_FormatFromFormString(char *arg); 1978 SUMA_DSET_FORMAT SUMA_GuessFormatFromExtension(char *Name, char *fallbackname); 1979 const char *SUMA_ExtensionOfDsetFormat (SUMA_DSET_FORMAT form); 1980 char *SUMA_OutputDsetFileStatus(char *prefix, char *inname, 1981 SUMA_DSET_FORMAT *oform, 1982 char *pre, char *app, int *exists); 1983 char * SUMA_GetDsetValInCol(SUMA_DSET *dset, int ind, int ival, double *dval) ; 1984 char * SUMA_GetValInCol(NI_element *nel, int ind, int ival, double *dval); 1985 void **SUMA_Dset2VecArray(SUMA_DSET *dset, 1986 int *ind, int nind, 1987 int *node, int N_Node, 1988 int iNodeMax, 1989 int *N_ret, 1990 SUMA_VARTYPE tp); 1991 SUMA_DSET *SUMA_VecArray2Dset(void **resv, 1992 SUMA_DSET *usethisdset, 1993 int *ind, int nind, 1994 int *node, int N_Node, 1995 int iNodeMax, 1996 SUMA_VARTYPE tp); 1997 void * SUMA_GetDsetAllNodeValsInCols2(SUMA_DSET *dset, 1998 int *ind, int nind, 1999 int node, int N_Node, 2000 int *N_ret, 2001 SUMA_VARTYPE tp); 2002 double SUMA_GetDsetValInCol2(SUMA_DSET *dset, int ind, int ival) ; 2003 double SUMA_GetValInCol2(NI_element *nel, int ind, int ival); 2004 int SUMA_GetNodeRow_FromNodeIndex_ns(SUMA_DSET *dset, int node, int N_Node); 2005 int SUMA_GetNodeRow_FromNodeIndex_eng(SUMA_DSET *dset, int node, int N_Node); 2006 int SUMA_GetNodeIndex_FromNodeRow_ns(SUMA_DSET *dset, int row, int N_Node); 2007 int SUMA_GetNodeIndex_FromNodeRow_eng(SUMA_DSET *dset, int row, int N_Node); 2008 double SUMA_GetDsetNodeValInCol2(SUMA_DSET *dset, int ind, 2009 int node, int N_Node); 2010 SUMA_VARTYPE SUMA_CTypeName2VarType (char *vt); 2011 const char *SUMA_VarType2CTypeName (SUMA_VARTYPE vt); 2012 SUMA_COL_TYPE SUMA_VarType2ColType (char *vt); 2013 int SUMA_SizeOf(SUMA_VARTYPE vt); 2014 void *SUMA_BinarySuck(char *fname, SUMA_VARTYPE data_type, int endian, int start, int end, int *nvals_read); 2015 void SUMA_swap_2(void *ppp); 2016 void SUMA_swap_4(void *ppp); 2017 void SUMA_swap_8(void *ppp); 2018 int SUMA_suck_file( char *fname , char **fbuf ); 2019 char * SUMA_file_suck( char *fname , int *nread ); 2020 2021 2022 /******** BEGIN functions for surface structure ******************** */ 2023 SUMA_SO_SIDE SUMA_giiStringToNumSide(char *cc); 2024 void SUMA_ShowAfniSurfaceObject(NI_group *aSO, FILE *out, 2025 int detail, char *title); 2026 char *SUMA_AfniSurfaceObject_Info(NI_group *aSO, 2027 int detail, char *title); 2028 NI_group * afni_open_gifti_surf(char * fname, int read_data); 2029 int afni_write_gifti_surf( NI_group *aSO, char * fname, 2030 int write_data, int encoding); 2031 2032 2033 /******** END functions for surface structure ******************** */ 2034 int SUMA_init_GISET_setup(NI_stream nsg , NI_element *nel, GICOR_setup *giset, 2035 int bmode); /* 17 Aug 2012 [rickr] */ 2036 int SUMA_PopulateDsetsFromGICORnel(NI_element *nel, GICOR_setup *giset, 2037 SUMA_DSET **sdsetv); 2038 const char *SUMA_ObjectTypeCode2ObjectTypeName(SUMA_DO_Types dd); 2039 SUMA_DO_Types SUMA_ObjectTypeName2ObjectTypeCode(char *cc); 2040 #define SUMA_otn2otc SUMA_ObjectTypeName2ObjectTypeCode 2041 #define SUMA_otc2otn SUMA_ObjectTypeCode2ObjectTypeName 2042 2043 /************************ GRAPH Dset functions ******************** */ 2044 2045 /*! Return the 1D (p) index corresponding to the compact 2046 columnwise storage of a triangular matrix 2047 Use the R test function ij2p in CompactIndexing.R 2048 for details and tests. 2049 Note, we pass two_n instead of n, the dimension of the matrix 2050 for speed. 2051 i and j, must be integers or floor operation will fail 2052 */ 2053 #define SUMA_CItri_ij2p_diag(i, j, two_n) ((i+(two_n-(j)-1)*(j))/2) 2054 #define SUMA_CItri_ij2p(i, j, two_n) ((i-1+(two_n-(j)-3)*(j))/2) 2055 #define SUMA_CItri_pmax_diag(n) (((n)*((n)+1))/2-1) 2056 #define SUMA_CItri_pmax(n) (((n)*((n)-1))/2-1) 2057 2058 SUMA_DSET *SUMA_FloatVec_to_GDSET(float **vec, int vec_num, int vec_len, 2059 char *mtype, 2060 char **vec_labs, int *ie, int *i0, int *i1); 2061 SUMA_Boolean SUMA_Dset_to_GDSET(SUMA_DSET **dset, char *mtype, 2062 int ok_verticalize, int *ie, int *i0, int *i1); 2063 byte SUMA_CItri_p2ij(int p, int n, int two_n, byte withdiag, int *i, int *j); 2064 SUMA_Boolean SUMA_GDSET_Set_Aux_matrix_shape(SUMA_DSET *dset); 2065 byte SUMA_GDSET_SegIndexToPoints(SUMA_DSET *dset, int si, 2066 int *i1, int *i2, int *row); 2067 byte SUMA_GDSET_PointsToSegIndex(SUMA_DSET *dset, int i1, int i2, int *si); 2068 byte SUMA_GDSET_SegRowToPoints(SUMA_DSET *dset, int ri, 2069 int *i1, int *i2, int *index); 2070 byte SUMA_GDSET_PointsToSegRow(SUMA_DSET *dset, int i1, int i2, int *ri); 2071 byte SUMA_GDSET_PointToDiagSegRowIndex(SUMA_DSET *dset,int i1, int *ri, int *si); 2072 byte SUMA_GDSET_PointToDiagSegIndex(SUMA_DSET *dset, int i1, int *si); 2073 byte SUMA_GDSET_PointToDiagSegRow(SUMA_DSET *dset, int i1, int *ri); 2074 SUMA_SQ_MATRIX_SHAPES SUMA_matrix_shape_name_to_matrix_shape(char *name); 2075 char * SUMA_matrix_shape_to_matrix_shape_name(SUMA_SQ_MATRIX_SHAPES sq); 2076 int *SUMA_GDSET_GetPointIndexColumn(SUMA_DSET *dset, int *N_vals, NI_element **); 2077 char **SUMA_GDSET_GetPointNamesColumn(SUMA_DSET *dset, int *N_vals, 2078 NI_element **nelxyzr); 2079 float *SUMA_GDSET_GetPointColumn_f(SUMA_DSET *dset, int *N_vals, 2080 NI_element **nelxyzr, char *label); 2081 int *SUMA_GDSET_GetPointGroupColumn(SUMA_DSET *dset, int *N_vals, 2082 NI_element **nelxyzr); 2083 int SUMA_GDSET_Index_To_NodeIndex(SUMA_DSET *dset, int cinode); 2084 int SUMA_GDSET_NodeIndex_To_Index(SUMA_DSET *dset, int node); 2085 int SUMA_GDSET_EdgeIndex_To_Row(SUMA_DSET *dset, int ei); 2086 int SUMA_GDSET_EdgeRow_To_Index(SUMA_DSET *dset, int ri); 2087 int SUMA_GDSET_Max_Edge_Index(SUMA_DSET *dset); 2088 char *SUMA_GDSET_Node_Label(SUMA_DSET *dset, int psel); 2089 char *SUMA_GDSET_Edge_Label(SUMA_DSET *dset, int isel, char *pref, char *sep); 2090 2091 /************************ CIFTI Dset functions ******************** */ 2092 SUMA_Boolean SUMA_CIFTI_Set_Domains(SUMA_DSET *dset, int N_doms, 2093 int *dind, int *dindoff, int *dn, 2094 SUMA_DO_Types *dtp, char **dsrcs); 2095 SUMA_DSET *SUMA_CIFTI_2_edset(SUMA_DSET *dset, int i, byte *colmask, 2096 DList *DsetList, int allowreplace); 2097 SUMA_Boolean SUMA_CIFTI_NgrFromDomains(SUMA_DSET *dset); 2098 SUMA_Boolean SUMA_CIFTI_DomainsFromNgr(SUMA_DSET *dset, DList *DsetList, 2099 int allowreplace, SUMA_DSET **ret_edset); 2100 SUMA_Boolean SUMA_CIFTI_free_MD_data(SUMA_DSET *dset); 2101 SUMA_Boolean SUMA_CIFTI_Free_Doms(SUMA_DSET *dset); 2102 #endif 2103