00001
00002 #include "SUMA_suma.h"
00003 #include "PLY/ply.h"
00004
00005 #undef STAND_ALONE
00006
00007 #if defined SUMA_SureFit_STAND_ALONE
00008 #define STAND_ALONE
00009 #elif defined SUMA_FreeSurfer_STAND_ALONE
00010 #define STAND_ALONE
00011 #elif defined SUMA_Ply_Read_STAND_ALONE
00012 #define STAND_ALONE
00013 #elif defined SUMA_ConvertSurface_STAND_ALONE
00014 #define STAND_ALONE
00015 #elif defined SUMA_ROI2dataset_STAND_ALONE
00016 #define STAND_ALONE
00017 #elif defined SUMA_FScurv_to_1D_STAND_ALONE
00018 #define STAND_ALONE
00019 #elif defined SUMA_FSread_annot_STAND_ALONE
00020 #define STAND_ALONE
00021 #endif
00022
00023 #ifdef STAND_ALONE
00024
00025 SUMA_SurfaceViewer *SUMAg_cSV = NULL;
00026 SUMA_SurfaceViewer *SUMAg_SVv = NULL;
00027
00028 int SUMAg_N_SVv = 0;
00029 SUMA_DO *SUMAg_DOv = NULL;
00030 int SUMAg_N_DOv = 0;
00031 SUMA_CommonFields *SUMAg_CF = NULL;
00032 #else
00033 extern SUMA_CommonFields *SUMAg_CF;
00034 extern SUMA_DO *SUMAg_DOv;
00035 extern SUMA_SurfaceViewer *SUMAg_SVv;
00036 extern int SUMAg_N_SVv;
00037 extern int SUMAg_N_DOv;
00038 #endif
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 SUMA_SurfaceObject *SUMA_Load_Surface_Object_Wrapper ( char *if_name, char *if_name2, char *vp_name,
00051 SUMA_SO_File_Type SO_FT, SUMA_SO_File_Format SO_FF, char *sv_name, int debug)
00052 {
00053 static char FuncName[]={"SUMA_Load_Surface_Object_Wrapper"};
00054 SUMA_SurfaceObject *SO=NULL;
00055 void *SO_name=NULL;
00056 SUMA_SFname *SF_name = NULL;
00057 SUMA_Boolean LocalHead = NOPE;
00058
00059 SUMA_ENTRY;
00060
00061 switch (SO_FT) {
00062 case SUMA_SUREFIT:
00063 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
00064 sprintf(SF_name->name_coord,"%s", if_name);
00065 sprintf(SF_name->name_topo,"%s", if_name2);
00066 if (!vp_name) {
00067 SF_name->name_param[0] = '\0';
00068 }
00069 else {
00070 sprintf(SF_name->name_param,"%s", vp_name);
00071 }
00072 SO_name = (void *)SF_name;
00073 if (debug > 0) fprintf (SUMA_STDOUT,"Reading %s and %s...\n", SF_name->name_coord, SF_name->name_topo);
00074 SO = SUMA_Load_Surface_Object (SO_name, SUMA_SUREFIT, SUMA_ASCII, sv_name);
00075 break;
00076 case SUMA_VEC:
00077 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
00078 sprintf(SF_name->name_coord,"%s", if_name);
00079 sprintf(SF_name->name_topo,"%s", if_name2);
00080 SO_name = (void *)SF_name;
00081 fprintf (SUMA_STDOUT,"Reading %s and %s...\n", SF_name->name_coord, SF_name->name_topo);
00082 SO = SUMA_Load_Surface_Object (SO_name, SUMA_VEC, SUMA_ASCII, sv_name);
00083 break;
00084 case SUMA_FREE_SURFER:
00085 case SUMA_FREE_SURFER_PATCH:
00086 SO_name = (void *)if_name;
00087 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
00088 if (SUMA_isExtension(SO_name, ".asc"))
00089 SO = SUMA_Load_Surface_Object (SO_name, SUMA_FREE_SURFER, SUMA_ASCII, sv_name);
00090 else
00091 SO = SUMA_Load_Surface_Object_eng (SO_name, SUMA_FREE_SURFER, SUMA_BINARY_BE, sv_name, 0);
00092 break;
00093 case SUMA_OPENDX_MESH:
00094 SO_name = (void *)if_name;
00095 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
00096 SO = SUMA_Load_Surface_Object (SO_name, SUMA_OPENDX_MESH, SUMA_ASCII, sv_name);
00097 break;
00098 case SUMA_PLY:
00099 SO_name = (void *)if_name;
00100 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
00101 SO = SUMA_Load_Surface_Object (SO_name, SUMA_PLY, SUMA_FF_NOT_SPECIFIED, sv_name);
00102 break;
00103 case SUMA_BRAIN_VOYAGER:
00104 SO_name = (void *)if_name;
00105 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
00106 SO = SUMA_Load_Surface_Object (SO_name, SUMA_BRAIN_VOYAGER, SUMA_BINARY, sv_name);
00107 break;
00108 default:
00109 fprintf (SUMA_STDERR,"Error %s: Bad format.\n", FuncName);
00110 exit(1);
00111 }
00112
00113 if (SF_name) SUMA_free(SF_name); SF_name = NULL;
00114 SUMA_RETURN(SO);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 char *SUMA_RemoveSurfNameExtension (char*Name, SUMA_SO_File_Type oType)
00125 {
00126 static char FuncName[]={"SUMA_RemoveSurfNameExtension"};
00127 char *noex = NULL, *tmp = NULL;
00128
00129 SUMA_ENTRY;
00130
00131 if (!Name) { SUMA_SL_Err("NULL Name"); SUMA_RETURN(NULL); }
00132
00133 switch (oType) {
00134 case SUMA_SUREFIT:
00135 tmp = SUMA_Extension(Name, ".coord", YUP);
00136 noex = SUMA_Extension(tmp, ".topo", YUP); SUMA_free(tmp); tmp = NULL;
00137 break;
00138 case SUMA_VEC:
00139 tmp = SUMA_Extension(Name, ".1D.coord", YUP);
00140 noex = SUMA_Extension(tmp, ".1D.topo", YUP); SUMA_free(tmp); tmp = NULL;
00141 break;
00142 case SUMA_FREE_SURFER:
00143 case SUMA_FREE_SURFER_PATCH:
00144 noex = SUMA_Extension(Name, ".asc", YUP);
00145 break;
00146 case SUMA_PLY:
00147 noex = SUMA_Extension(Name,".ply" , YUP);
00148 break;
00149 case SUMA_OPENDX_MESH:
00150 noex = SUMA_Extension(Name,".dx" , YUP);
00151 break;
00152 case SUMA_INVENTOR_GENERIC:
00153 noex = SUMA_Extension(Name,".iv" , YUP);
00154 break;
00155 case SUMA_BRAIN_VOYAGER:
00156 noex = SUMA_Extension(Name,".srf" , YUP);
00157 break;
00158 default:
00159
00160 noex = SUMA_copy_string(Name);
00161 break;
00162 }
00163
00164 SUMA_RETURN(noex);
00165 }
00166
00167
00168
00169
00170
00171 void * SUMA_2Prefix2SurfaceName (char *namecoord, char *nametopo, char *path, char *vp_name, SUMA_SO_File_Type oType, SUMA_Boolean *exists)
00172 {
00173 static char FuncName[]={"SUMA_2Prefix2SurfaceName"};
00174 SUMA_Boolean exist1, exist2;
00175 SUMA_SFname *SF_name1 = NULL, *SF_name2 = NULL;
00176
00177 SUMA_ENTRY;
00178
00179 if (!nametopo && !namecoord) { SUMA_RETURN(NULL); }
00180
00181 if (!nametopo) SUMA_RETURN(SUMA_Prefix2SurfaceName (namecoord, path, vp_name, oType, exists));
00182 if (!namecoord) SUMA_RETURN(SUMA_Prefix2SurfaceName (nametopo, path, vp_name, oType, exists));
00183
00184 if (strcmp(namecoord, nametopo) == 0) SUMA_RETURN(SUMA_Prefix2SurfaceName (nametopo, path, vp_name, oType, exists));
00185 if (oType != SUMA_SUREFIT && oType != SUMA_VEC) {
00186 SUMA_SL_Err("Wrong usage of function, namecoord and nametopo are different but surface type is neither SUMA_SUREFIT nor SUMA_VEC");
00187 SUMA_RETURN(NULL);
00188 }
00189
00190
00191 SF_name1 = SUMA_Prefix2SurfaceName (namecoord, path, vp_name, oType, &exist1);
00192 if (!SF_name1) {
00193 SUMA_SL_Err("Failed to create name");
00194 SUMA_RETURN(NULL);
00195 }
00196 SF_name2 = SUMA_Prefix2SurfaceName (nametopo, path, vp_name, oType, &exist2);
00197 if (!SF_name2) {
00198 SUMA_free(SF_name1); SF_name1= NULL;
00199 SUMA_SL_Err("Failed to create name");
00200 SUMA_RETURN(NULL);
00201 }
00202
00203 if (exist1 || exist2) *exists = YUP;
00204
00205 sprintf(SF_name1->name_topo, "%s", SF_name2->name_topo);
00206 SUMA_free(SF_name2); SF_name2= NULL;
00207
00208 SUMA_RETURN(SF_name1);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 void * SUMA_Prefix2SurfaceName (char *prefix_in, char *path, char *vp_name, SUMA_SO_File_Type oType, SUMA_Boolean *exists)
00221 {
00222 static char FuncName[]={"SUMA_Prefix2SurfaceName"};
00223 SUMA_SFname *SF_name = NULL;
00224 char *ppref = NULL, *prefix=NULL;
00225 void *SO_name = NULL;
00226
00227 SUMA_ENTRY;
00228
00229 if (!prefix_in) {
00230 fprintf (SUMA_STDERR,"Error %s: NULL name input\n", FuncName);
00231 SUMA_RETURN(NULL);
00232 }
00233
00234 if (!(prefix = SUMA_RemoveSurfNameExtension (prefix_in, oType))) {
00235 fprintf (SUMA_STDERR,"Error %s: Failed to remove extension\n", FuncName);
00236 SUMA_RETURN(NULL);
00237 }
00238
00239 if (path) {
00240 if (path[strlen(path)-1] == '/') {
00241 ppref = SUMA_append_replace_string(path, prefix, "", 0);
00242 } else {
00243 ppref = SUMA_append_replace_string(path, prefix, "/", 0);
00244 }
00245 } else {
00246 ppref = SUMA_copy_string(prefix);
00247 }
00248
00249 switch (oType) {
00250 case SUMA_SUREFIT:
00251 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
00252 snprintf(SF_name->name_coord, (SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH+1)*sizeof(char),
00253 "%s.coord", ppref);
00254 snprintf(SF_name->name_topo, (SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH+1)*sizeof(char),
00255 "%s.topo", ppref);
00256 if (SUMA_filexists(SF_name->name_topo) || SUMA_filexists(SF_name->name_coord)) *exists = YUP;
00257 else *exists = NOPE;
00258 if (!vp_name) {
00259 SF_name->name_param[0] = '\0';
00260 }
00261 else {
00262 snprintf(SF_name->name_param, (SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH+1)*sizeof(char),
00263 "%s", vp_name);
00264 }
00265 SO_name = (void *)SF_name;
00266 break;
00267 case SUMA_VEC:
00268 if (SF_name) SUMA_free(SF_name);
00269 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
00270 snprintf(SF_name->name_coord, (SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH+1)*sizeof(char),
00271 "%s.1D.coord", ppref);
00272 snprintf(SF_name->name_topo, (SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH+1)*sizeof(char),
00273 "%s.1D.topo", ppref);
00274 if (SUMA_filexists(SF_name->name_topo) || SUMA_filexists(SF_name->name_coord)) *exists = YUP;
00275 else *exists = NOPE;
00276 SO_name = (void *)SF_name;
00277 break;
00278 case SUMA_FREE_SURFER:
00279 case SUMA_FREE_SURFER_PATCH:
00280 SO_name = (void *)SUMA_append_string(ppref,".asc");
00281 if (SUMA_filexists((char*)SO_name)) *exists = YUP;
00282 else *exists = NOPE;
00283 break;
00284 case SUMA_OPENDX_MESH:
00285 SO_name = (void *)SUMA_append_string(ppref,".dx");
00286 if (SUMA_filexists((char*)SO_name)) *exists = YUP;
00287 else *exists = NOPE;
00288 break;
00289 case SUMA_PLY:
00290 SO_name = (void *)SUMA_append_string(ppref,".ply");
00291 if (SUMA_filexists((char*)SO_name)) *exists = YUP;
00292 else *exists = NOPE;
00293 break;
00294 case SUMA_BRAIN_VOYAGER:
00295 SO_name = (void *)SUMA_append_string(ppref,".srf");
00296 if (SUMA_filexists((char*)SO_name)) *exists = YUP;
00297 else *exists = NOPE;
00298 break;
00299 case SUMA_INVENTOR_GENERIC:
00300 SO_name = (void *)SUMA_append_string(ppref,".iv");
00301 if (SUMA_filexists((char*)SO_name)) *exists = YUP;
00302 else *exists = NOPE;
00303 break;
00304 default:
00305 fprintf (SUMA_STDERR,"Error %s: Unknown format.\n", FuncName);
00306 SO_name = (void *)SUMA_copy_string(ppref);
00307 if (SUMA_filexists((char*)SO_name)) *exists = YUP;
00308 else *exists = NOPE;
00309 break;
00310 }
00311
00312 if (ppref) SUMA_free(ppref);
00313 if (prefix) SUMA_free(prefix);
00314
00315 SUMA_RETURN(SO_name);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 SUMA_Boolean SUMA_SureFit_Read_Coord (char * f_name, SUMA_SureFit_struct *SF)
00341 {
00342 static char FuncName[]={"SUMA_SureFit_Read_Coord"};
00343 FILE *sf_file;
00344 int ex, EndHead, FoundHead, evl, cnt, skp, ND, id;
00345 char stmp[100], head_strt[100], head_end[100], s[1000], delimstr[] = {' ', '\0'}, *st;
00346
00347 SUMA_ENTRY;
00348
00349 ND = 3;
00350
00351
00352 if (!SUMA_filexists(f_name)) {
00353 fprintf(SUMA_STDERR,"File %s does not exist or cannot be read.\n", f_name);
00354 SUMA_RETURN (NOPE);
00355 }
00356
00357 sprintf(SF->name_coord, "%s", f_name);
00358
00359
00360 sf_file = fopen (f_name,"r");
00361 if (sf_file == NULL)
00362 {
00363 SUMA_error_message (FuncName,"Could not open input file ",0);
00364 SUMA_RETURN (NOPE);
00365 }
00366
00367
00368 ex = 1;
00369 FoundHead = 0;
00370 sprintf(head_strt,"BeginHeader");
00371 while (ex != EOF && !FoundHead)
00372 {
00373 ex = fscanf (sf_file,"%s",s);
00374 if (strlen (s) >= strlen(head_strt))
00375 {
00376 evl = SUMA_iswordin (s,head_strt);
00377 if (evl == 1) FoundHead = 1;
00378 }
00379 }
00380
00381 if (!FoundHead) {
00382 fprintf(SUMA_STDERR,"Error %s: BeginHeader not found in %s.\nPerhaps you are using old versions of Caret/SureFit files.\n", FuncName, f_name);
00383 SUMA_RETURN (NOPE);
00384 }
00385 EndHead = 0;
00386 sprintf(head_end,"EndHeader");
00387 sprintf(delimstr," ");
00388
00389 while (ex != EOF && !EndHead) {
00390 ex = fscanf (sf_file,"%s",s);
00391
00392 if (strlen (s) >= strlen(head_end))
00393 {
00394 evl = SUMA_iswordin (s,head_end);
00395 if (evl == 1) EndHead = 1;
00396 }
00397
00398 skp = 0;
00399 if (!EndHead) {
00400 st = strtok(s, delimstr);
00401 sprintf(stmp,"encoding");
00402 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00403
00404 ex = fscanf (sf_file,"%s",(SF->encoding_coord));
00405 skp = 1;
00406 }
00407
00408 sprintf(stmp,"configuration_id");
00409 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00410
00411 ex = fscanf (sf_file,"%s",(SF->configuration_id));
00412 skp = 1;
00413 }
00414
00415 sprintf(stmp,"coordframe_id");
00416 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00417
00418 ex = fscanf (sf_file,"%s",(SF->coordframe_id));
00419 skp = 1;
00420 }
00421
00422 }
00423 }
00424
00425 fscanf(sf_file, "%d", &SF->N_Node);
00426
00427
00428
00429 SF->NodeList = (float *)SUMA_calloc(SF->N_Node * ND, sizeof(float));
00430 SF->NodeId = (int *)SUMA_calloc (SF->N_Node, sizeof(int));
00431
00432 if (SF->NodeList == NULL || SF->NodeId == NULL) {
00433 fprintf(SUMA_STDERR, "Error %s: Could not allocate space for NodeList &/| NodeId.\n", FuncName);
00434 SUMA_RETURN (NOPE);
00435 }
00436
00437
00438 cnt = 0;
00439 while (ex != EOF && cnt < SF->N_Node) {
00440 id = cnt * ND;
00441 ex = fscanf (sf_file,"%d %f %f %f",&(SF->NodeId[cnt]), \
00442 &(SF->NodeList[id]), &(SF->NodeList[id+1]), &(SF->NodeList[id+2]));
00443 ++cnt;
00444 }
00445 if (cnt != SF->N_Node) {
00446 fprintf(SUMA_STDERR, "Error %s: Expecting %d Nodes, read %d.\n", FuncName, SF->N_Node, cnt);
00447 SUMA_RETURN (NOPE);
00448 }
00449 fclose (sf_file);
00450 SUMA_RETURN (YUP);
00451 }
00452
00453 SUMA_Boolean SUMA_SureFit_Read_Topo (char * f_name, SUMA_SureFit_struct *SF)
00454 {
00455 static char FuncName[]={"SUMA_SureFit_Read_Topo"};
00456 FILE *sf_file;
00457 int ex, EndHead, FoundHead, evl, cnt, skp, jnk, i, ip, NP;
00458 char stmp[100], head_strt[100], head_end[100], s[1000], delimstr[] = {' ', '\0'}, *st;
00459
00460 SUMA_ENTRY;
00461
00462
00463 if (!SUMA_filexists(f_name)) {
00464 fprintf(SUMA_STDERR,"File %s does not exist or cannot be read.\n", f_name);
00465 SUMA_RETURN (NOPE);
00466 }
00467
00468 sprintf(SF->name_topo, "%s", f_name);
00469
00470
00471 sf_file = fopen (f_name,"r");
00472 if (sf_file == NULL)
00473 {
00474 SUMA_error_message (FuncName,"Could not open input file ",0);
00475 SUMA_RETURN (NOPE);
00476 }
00477
00478
00479 ex = 1;
00480 FoundHead = 0;
00481 sprintf(head_strt,"BeginHeader");
00482 while (ex != EOF && !FoundHead)
00483 {
00484 ex = fscanf (sf_file,"%s",s);
00485 if (strlen (s) >= strlen(head_strt))
00486 {
00487 evl = SUMA_iswordin (s,head_strt);
00488 if (evl == 1) FoundHead = 1;
00489 }
00490 }
00491 if (!FoundHead) {
00492 fprintf(SUMA_STDERR,"Error %s: BeginHeader not found in %s.\nPerhaps you are using old versions of Caret/SureFit files.\n", FuncName, f_name);
00493 SUMA_RETURN (NOPE);
00494 }
00495 EndHead = 0;
00496 sprintf(head_end,"EndHeader");
00497 sprintf(delimstr," ");
00498
00499 while (ex != EOF && !EndHead) {
00500 ex = fscanf (sf_file,"%s",s);
00501
00502 if (strlen (s) >= strlen(head_end))
00503 {
00504 evl = SUMA_iswordin (s,head_end);
00505 if (evl == 1) EndHead = 1;
00506 }
00507
00508 skp = 0;
00509 if (!EndHead) {
00510 st = strtok(s, delimstr);
00511 sprintf(stmp,"encoding");
00512 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00513
00514 ex = fscanf (sf_file,"%s",(SF->encoding_topo));
00515 skp = 1;
00516 }
00517
00518 sprintf(stmp,"perimeter_id");
00519 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00520
00521 ex = fscanf (sf_file,"%s",(SF->perimeter_id));
00522 skp = 1;
00523 }
00524
00525 sprintf(stmp,"date");
00526 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00527
00528 ex = fscanf (sf_file,"%s\n",(SF->date));
00529 skp = 1;
00530 }
00531
00532 }
00533 }
00534
00535 fscanf(sf_file, "%d", &SF->N_Node_Specs);
00536
00537
00538 SF->FN.N_Node = SF->N_Node_Specs;
00539 SF->FN.N_Neighb_max = 0;
00540
00541
00542 SF->Specs_mat = (int **) SUMA_allocate2D(SF->N_Node_Specs, 6, sizeof(int));
00543
00544 SF->FN.FirstNeighb = (int **) SUMA_allocate2D(SF->FN.N_Node, SUMA_MAX_NUMBER_NODE_NEIGHB, sizeof (int));
00545 SF->FN.N_Neighb = (int *) SUMA_calloc (SF->FN.N_Node, sizeof(int));
00546 SF->FN.NodeId = (int *) SUMA_calloc (SF->FN.N_Node, sizeof(int));
00547
00548 if (SF->Specs_mat == NULL || SF->FN.FirstNeighb == NULL || SF->FN.N_Neighb == NULL || SF->FN.NodeId == NULL ){
00549 fprintf(SUMA_STDERR, "Error %s: Could not allocate space for SF->Specs_mat &/| SF->FN.FirstNeighb &/| SF->FN.N_Neighb &/| SF->FN.NodeId.\n", FuncName);
00550 SUMA_RETURN (NOPE);
00551 }
00552
00553
00554
00555 cnt = 0;
00556 while (ex != EOF && cnt < SF->N_Node_Specs) {
00557 ex = fscanf (sf_file,"%d %d %d %d %d %d",&(SF->Specs_mat[cnt][0]), &(SF->Specs_mat[cnt][1]), \
00558 &(SF->Specs_mat[cnt][2]), &(SF->Specs_mat[cnt][3]), &(SF->Specs_mat[cnt][4]), &(SF->Specs_mat[cnt][5]));
00559 SF->FN.NodeId[cnt] = SF->Specs_mat[cnt][0];
00560 SF->FN.N_Neighb[cnt] = SF->Specs_mat[cnt][1];
00561 if (SF->FN.N_Neighb[cnt] > SUMA_MAX_NUMBER_NODE_NEIGHB-1) {
00562 fprintf (SUMA_STDERR,"Error %s: Node %d has more neighbors (%d) than the maximum allowed (%d)\n", \
00563 FuncName, SF->FN.NodeId[cnt], SF->FN.N_Neighb[cnt], SUMA_MAX_NUMBER_NODE_NEIGHB-1);
00564 SUMA_RETURN (NOPE);
00565 }
00566 if (SF->FN.N_Neighb[cnt] > SF->FN.N_Neighb_max) SF->FN.N_Neighb_max = SF->FN.N_Neighb[cnt];
00567
00568
00569 for (i=0; i < SF->FN.N_Neighb[cnt]; ++ i) {
00570 ex = fscanf (sf_file,"%d %d", &jnk, &(SF->FN.FirstNeighb[cnt][i]));
00571 }
00572
00573 SF->FN.FirstNeighb[cnt][SF->FN.N_Neighb[cnt]] = -1;
00574
00575 ++cnt;
00576 }
00577 if (cnt != SF->N_Node_Specs) {
00578 fprintf(SUMA_STDERR, "Error %s: Expecting %d NodeSpecs, read %d.\n", FuncName, SF->N_Node_Specs, cnt);
00579 SUMA_RETURN (NOPE);
00580 }
00581
00582 ex = fscanf (sf_file,"%d", &(SF->N_FaceSet));
00583
00584
00585 NP = 3;
00586 SF->FaceSetList = (int *) SUMA_calloc(SF->N_FaceSet * 3, sizeof(int));
00587 if (SF->FaceSetList == NULL){
00588 fprintf(SUMA_STDERR, "Error %s: Could not allocate space for SF->FaceSetList.\n", FuncName);
00589 SUMA_RETURN (NOPE);
00590 }
00591
00592
00593 cnt = 0;
00594 while (ex != EOF && cnt < SF->N_FaceSet) {
00595 ip = NP * cnt;
00596 ex = fscanf (sf_file,"%d %d %d ",&(SF->FaceSetList[ip]), &(SF->FaceSetList[ip+1]), \
00597 &(SF->FaceSetList[ip+2]));
00598 ++cnt;
00599 }
00600 if (cnt != SF->N_FaceSet) {
00601 fprintf(SUMA_STDERR, "Error %s: Expecting %d FaceSets, read %d.\n", FuncName, SF->N_FaceSet, cnt);
00602 SUMA_RETURN (NOPE);
00603 }
00604 fclose (sf_file);
00605
00606 SUMA_RETURN (YUP);
00607 }
00608
00609
00610
00611
00612 void SUMA_Show_SureFit (SUMA_SureFit_struct *SF, FILE *Out)
00613 { int cnt, id, ND, NP;
00614 static char FuncName[]={"SUMA_Show_SureFit"};
00615
00616 SUMA_ENTRY;
00617
00618 ND = 3;
00619 NP = 3;
00620 if (Out == NULL) Out = SUMA_STDOUT;
00621 fprintf (Out, "\n%s: Coord Info\n", SF->name_coord);
00622 fprintf (Out, "N_Node %d\n", SF->N_Node);
00623 fprintf (Out, "encoding_coord: %s\nconfiguration id: %s, coordframe_id: %s\n", SF->encoding_coord,SF->configuration_id, SF->coordframe_id);
00624 fprintf (Out, "First 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
00625 SF->NodeId[0], SF->NodeList[0], SF->NodeList[1], SF->NodeList[2],
00626 SF->NodeId[1], SF->NodeList[3], SF->NodeList[4], SF->NodeList[5]);
00627 if (SF->N_Node > 2) {
00628 fprintf (Out, "Last 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
00629 SF->NodeId[SF->N_Node-2], SF->NodeList[ND*(SF->N_Node-2)], SF->NodeList[ND*(SF->N_Node-2)+1], SF->NodeList[ND*(SF->N_Node-2)+2],
00630 SF->NodeId[SF->N_Node-1], SF->NodeList[ND*(SF->N_Node-1)], SF->NodeList[ND*(SF->N_Node-1)+1], SF->NodeList[ND*(SF->N_Node-1)+2]);
00631 }
00632 fprintf (Out, "\n%s: Topo Info\n", SF->name_topo);
00633 fprintf (Out, "N_Node_Specs %d\n", SF->N_Node_Specs);
00634 fprintf (Out, "ecnoding_topo: %s, date %s\n", SF->encoding_topo, SF->date);
00635 fprintf (Out, "N_FaceSet %d\n", SF->N_FaceSet);
00636 if (SF->N_FaceSet > 2) {
00637 fprintf (Out, "First 2 polygons:\n\t%d %d %d\n\t%d %d %d\n", \
00638 SF->FaceSetList[0], SF->FaceSetList[1], SF->FaceSetList[2],
00639 SF->FaceSetList[3], SF->FaceSetList[4], SF->FaceSetList[5]);
00640 fprintf (Out, "Last 2 polygons:\n\t%d %d %d\n\t%d %d %d\n", \
00641 SF->FaceSetList[NP*(SF->N_FaceSet-2)], SF->FaceSetList[NP*(SF->N_FaceSet-2) + 1], SF->FaceSetList[NP*(SF->N_FaceSet-2) + 2],
00642 SF->FaceSetList[NP*(SF->N_FaceSet-1)], SF->FaceSetList[NP*(SF->N_FaceSet-1) + 1], SF->FaceSetList[NP*(SF->N_FaceSet-1) + 2]);
00643 } else {
00644 fprintf (Out, "First polygon:\n\t%d %d %d\n", \
00645 SF->FaceSetList[0], SF->FaceSetList[1], SF->FaceSetList[2] );
00646 }
00647 fprintf (Out, "\nNode Specs (%d):\n", SF->N_Node_Specs);
00648 fprintf (Out, "First Entry: \t%d %d %d %d %d %d\n", \
00649 SF->Specs_mat[0][0], SF->Specs_mat[0][1],SF->Specs_mat[0][2], SF->Specs_mat[0][3],SF->Specs_mat[0][4], SF->Specs_mat[0][5]);
00650 cnt = 0;
00651 while (cnt < SF->FN.N_Neighb[0]) {
00652 fprintf (Out, "\t%d %d\n", cnt, SF->FN.FirstNeighb[0][cnt]);
00653 ++cnt;
00654 }
00655 fprintf (Out, "Last Entry: \t%d %d %d %d %d %d\n", \
00656 SF->Specs_mat[SF->N_Node_Specs-1][0], SF->Specs_mat[SF->N_Node_Specs-1][1],SF->Specs_mat[SF->N_Node_Specs-1][2],\
00657 SF->Specs_mat[SF->N_Node_Specs-1][3],SF->Specs_mat[SF->N_Node_Specs-1][4], SF->Specs_mat[SF->N_Node_Specs-1][5]);
00658 cnt = 0;
00659 while (cnt < SF->FN.N_Neighb[SF->N_Node_Specs-1]) {
00660 fprintf (Out, "\t%d %d\n", cnt, SF->FN.FirstNeighb[SF->N_Node_Specs-1][cnt]);
00661 ++cnt;
00662 }
00663
00664 SUMA_RETURNe;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 SUMA_Boolean SUMA_SureFit_Write (SUMA_SFname *Fname, SUMA_SurfaceObject *SO)
00707 {
00708
00709 static char FuncName[]={"SUMA_SureFit_Write"};
00710 int i, j;
00711 FILE *outFile = NULL;
00712
00713 SUMA_ENTRY;
00714
00715 if (strlen(Fname->name_coord)) {
00716 if (SUMA_filexists(Fname->name_coord)) {
00717 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_coord);
00718 SUMA_RETURN (NOPE);
00719 }
00720 }
00721
00722 if (strlen(Fname->name_topo)) {
00723 if (SUMA_filexists(Fname->name_topo)) {
00724 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_topo);
00725 SUMA_RETURN (NOPE);
00726 }
00727 }
00728
00729 if (SO->NodeDim != 3 || SO->FaceSetDim != 3) {
00730 fprintf (SUMA_STDERR, "Error %s: Must have NodeDim and FaceSetDim = 3.\n",FuncName);
00731 SUMA_RETURN (NOPE);
00732 }
00733
00734 if (strlen(Fname->name_coord)) {
00735 outFile = fopen(Fname->name_coord, "w");
00736 if (!outFile) {
00737 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_coord);
00738 SUMA_RETURN (NOPE);
00739 }
00740
00741
00742 fprintf (outFile,"BeginHeader\nconfiguration_id NA\ncoordframe_id NA\nencoding ASCII\nEndHeader\n");
00743 fprintf (outFile,"%d\n", SO->N_Node);
00744
00745 j=0;
00746 for (i=0; i<SO->N_Node; ++i) {
00747 j=SO->NodeDim * i;
00748 fprintf (outFile, "%d %f %f %f\n", i, SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
00749 }
00750
00751 fclose (outFile);
00752 }
00753
00754 if (strlen(Fname->name_topo)) {
00755 outFile = fopen(Fname->name_topo, "w");
00756 if (!outFile) {
00757 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_topo);
00758 SUMA_RETURN (NOPE);
00759 }
00760
00761
00762 if (!SO->FN) {
00763 fprintf (SUMA_STDERR, "%s: Must compute Node Neighborhood list.\n", FuncName);
00764 if (!SUMA_SurfaceMetrics(SO, "EdgeList", NULL)){
00765 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
00766 SUMA_RETURN (NOPE);
00767 }
00768 #if 0
00769 if (!SO->EL) {
00770 fprintf (SUMA_STDERR, "%s: Computing Edge List...\n", FuncName);
00771 SO->EL = SUMA_Make_Edge_List (SO->FaceSetList, SO->N_FaceSet, SO->N_Node, SO->NodeList);
00772 }
00773 if (!SO->EL) {
00774 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Make_Edge_List.\n", FuncName);
00775 SUMA_RETURN (NOPE);
00776 }
00777 fprintf (SUMA_STDERR, "%s: Computing FirstNeighb list.\n", FuncName);
00778 SO->FN = SUMA_Build_FirstNeighb (SO->EL, SO->N_Node);
00779 if (!SO->FN) {
00780 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Build_FirstNeighb.\n", FuncName);
00781 SUMA_RETURN (NOPE);
00782 }
00783 #endif
00784
00785 }
00786
00787 fprintf (outFile,"BeginHeader\ndate NA\nencoding ASCII\nperimeter_id NA\nEndHeader\n");
00788 fprintf (outFile,"%d\n", SO->N_Node);
00789 j = 0;
00790 while (j < SO->FN->N_Node) {
00791
00792 fprintf (outFile,"%d %d 0 0 0 0\n", SO->FN->NodeId[j], SO->FN->N_Neighb[j]);
00793
00794
00795 for (i=0; i < SO->FN->N_Neighb[j]; ++ i) {
00796 fprintf (outFile,"%d %d\n", i, SO->FN->FirstNeighb[j][i]);
00797 }
00798 ++j;
00799 }
00800
00801 fprintf (outFile,"%d\n", SO->N_FaceSet);
00802
00803 j=0;
00804 for (i=0; i<SO->N_FaceSet; ++i) {
00805 j = SO->FaceSetDim * i;
00806 fprintf (outFile, "%d %d %d\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
00807 }
00808
00809 fclose (outFile);
00810 }
00811 SUMA_RETURN (YUP);
00812
00813 }
00814
00815
00816
00817
00818 SUMA_Boolean SUMA_Free_SureFit (SUMA_SureFit_struct *SF)
00819 {
00820 static char FuncName[]={"SUMA_Free_SureFit"};
00821
00822 SUMA_ENTRY;
00823
00824 if (SF->NodeList != NULL) SUMA_free(SF->NodeList);
00825 if (SF->NodeId != NULL) SUMA_free(SF->NodeId);
00826 if (SF->Specs_mat != NULL) SUMA_free2D ((char **)SF->Specs_mat, SF->N_Node_Specs);
00827 if (SF->FN.FirstNeighb != NULL) SUMA_free2D((char **)SF->FN.FirstNeighb, SF->FN.N_Node);
00828 if (SF->FN.N_Neighb != NULL) SUMA_free(SF->FN.N_Neighb);
00829 if (SF->FN.NodeId != NULL) SUMA_free(SF->FN.NodeId);
00830 if (SF->FaceSetList != NULL) SUMA_free(SF->FaceSetList);
00831 if (SF!= NULL) SUMA_free(SF);
00832
00833 SUMA_RETURN (YUP);
00834 }
00835
00836
00837
00838
00839 SUMA_Boolean SUMA_Read_SureFit_Param (char *f_name, SUMA_SureFit_struct *SF)
00840 {
00841 static char FuncName[]={"SUMA_Read_SureFit_Param"};
00842 int ex, evl;
00843 FILE *sf_file;
00844 SUMA_Boolean Done;
00845 char delimstr[] = {' ', '\0'}, stmp[100], s[1000], *st;
00846
00847 SUMA_ENTRY;
00848
00849
00850 if (!SUMA_filexists(f_name)) {
00851 fprintf(SUMA_STDERR,"File %s does not exist or cannot be read.\n", f_name);
00852 SUMA_RETURN (NOPE);
00853 }
00854
00855 sprintf(SF->name_param, "%s", f_name);
00856
00857
00858 sf_file = fopen (f_name,"r");
00859 if (sf_file == NULL)
00860 {
00861 fprintf (SUMA_STDERR,"Error %s: Could not open input file ",FuncName);
00862 SUMA_RETURN (NOPE);
00863 }
00864
00865
00866 ex = 1;
00867 Done = NOPE;
00868 sprintf(delimstr,"=");
00869 while (ex != EOF && !Done)
00870 {
00871 ex = fscanf (sf_file,"%s",s);
00872
00873 sprintf(stmp,"ACx_WholeVolume");
00874 evl = SUMA_iswordin (s,stmp);
00875 if (evl == 1) {
00876
00877
00878
00879 st = strtok(s, delimstr);
00880 st = strtok(NULL, delimstr);
00881 SF->AC_WholeVolume[0] = atof(st);
00882
00883 continue;
00884 }
00885 sprintf(stmp,"ACy_WholeVolume");
00886 evl = SUMA_iswordin (s,stmp);
00887 if (evl == 1) {
00888
00889
00890
00891 st = strtok(s, delimstr);
00892 st = strtok(NULL, delimstr);
00893 SF->AC_WholeVolume[1] = atof(st);
00894
00895 continue;
00896 }
00897 sprintf(stmp,"ACz_WholeVolume");
00898 evl = SUMA_iswordin (s,stmp);
00899 if (evl == 1) {
00900
00901
00902
00903 st = strtok(s, delimstr);
00904 st = strtok(NULL, delimstr);
00905 SF->AC_WholeVolume[2] = atof(st);
00906
00907 continue;
00908 }
00909
00910 sprintf(stmp,"ACx");
00911 evl = SUMA_iswordin (s,stmp);
00912 if (evl == 1) {
00913
00914
00915
00916 st = strtok(s, delimstr);
00917 st = strtok(NULL, delimstr);
00918 SF->AC[0] = atof(st);
00919
00920 continue;
00921 }
00922 sprintf(stmp,"ACy");
00923 evl = SUMA_iswordin (s,stmp);
00924 if (evl == 1) {
00925
00926
00927
00928 st = strtok(s, delimstr);
00929 st = strtok(NULL, delimstr);
00930 SF->AC[1] = atof(st);
00931
00932 continue;
00933 }
00934 sprintf(stmp,"ACz");
00935 evl = SUMA_iswordin (s,stmp);
00936 if (evl == 1) {
00937
00938
00939
00940 st = strtok(s, delimstr);
00941 st = strtok(NULL, delimstr);
00942 SF->AC[2] = atof(st);
00943
00944 continue;
00945 }
00946
00947 }
00948
00949 fclose(sf_file);
00950
00951
00952 if (SF->AC[0] == 0.0 && SF->AC[1] == 0.0 && SF->AC[2] == 0.0) {
00953 fprintf (SUMA_STDERR,"Error %s: All values for AC are 0.0. Check your params file.\n", FuncName);
00954 SUMA_RETURN (NOPE);
00955 }
00956
00957 if (SF->AC_WholeVolume[0] == 0.0 && SF->AC_WholeVolume[1] == 0.0 && SF->AC_WholeVolume[2] == 0.0) {
00958 fprintf (SUMA_STDERR,"Error %s: All values for AC_WholeVolume are 0.0. Check your params file.\n", FuncName);
00959 SUMA_RETURN (NOPE);
00960 }
00961
00962 if (SF->AC[0] == SF->AC_WholeVolume[0] && SF->AC[1] == SF->AC_WholeVolume[1] && SF->AC[2] == SF->AC_WholeVolume[2])
00963 {
00964 SUMA_SL_Warn("Idetincal values for AC and AC_WholeVolume.\nCheck your params file if not using Talairach-ed surfaces.\n");
00965
00966
00967
00968
00969
00970 }
00971 if (SF->AC[0] < 0 || SF->AC[1] < 0 || SF->AC[2] < 0 || SF->AC_WholeVolume[0] < 0 || SF->AC_WholeVolume[1] < 0 || SF->AC_WholeVolume[2] < 0)
00972 {
00973 fprintf (SUMA_STDERR,"Error %s: Negative values in AC or AC_WholeVolume. Check you params file.\n", FuncName);
00974 SUMA_RETURN (NOPE);
00975 }
00976
00977 SUMA_RETURN (YUP);
00978 }
00979 #ifdef SUMA_SureFit_STAND_ALONE
00980
00981
00982
00983 void usage_SUMA_SureFit_Main ()
00984
00985 {
00986 printf ("\nUsage: SUMA_SureFit CoordRoot TopoRoot \n");
00987 printf ("\t ..... \n\n");
00988 printf ("\t To Compile:\ngcc -DSUMA_SureFit_STAND_ALONE -Wall -o $1 $1.c -I./ -I//usr/X11R6/include SUMA_lib.a\n");
00989 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tFri Feb 8 16:29:06 EST 2002 \n");
00990 exit (0);
00991 }
00992
00993 int main (int argc,char *argv[])
00994 {
00995 static char FuncName[]={"SUMA_SureFit_Main"};
00996 char SF_name[200];
00997 SUMA_SureFit_struct *SF;
00998
00999
01000 SUMAg_CF = SUMA_Create_CommonFields ();
01001 if (SUMAg_CF == NULL) {
01002 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01003 exit(1);
01004 }
01005
01006
01007 SF = (SUMA_SureFit_struct *) SUMA_malloc(sizeof(SUMA_SureFit_struct));
01008 if (SF == NULL) {
01009 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SF\n", FuncName);
01010 exit(1);
01011 }
01012
01013 if (argc < 3)
01014 {
01015 usage_SUMA_SureFit_Main ();
01016 exit (1);
01017 }
01018
01019 sprintf(SF_name, "%s.coord", argv[1]);
01020 if (!SUMA_SureFit_Read_Coord (SF_name, SF)) {
01021 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Coord.\n", FuncName);
01022 exit(1);
01023 }
01024
01025 sprintf(SF_name, "%s.topo", argv[2]);
01026 if (!SUMA_SureFit_Read_Topo (SF_name, SF)) {
01027 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Topo.\n", FuncName);
01028 exit(1);
01029 }
01030
01031 SUMA_Show_SureFit (SF, NULL);
01032 fprintf(stdout, "freeing ..\n");
01033 if (!SUMA_Free_SureFit (SF)) {
01034 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_SureFit.\n", FuncName);
01035 exit(1);
01036 }
01037
01038 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
01039
01040 SUMA_RETURN (0);
01041 }
01042 #endif
01043
01044
01045
01046
01047 #define SUMA_FS_ANNOT_TAG_COLORTABLE 1
01048 #define SUMA_FS_STRLEN 50
01049 typedef struct {
01050 int r;
01051 int g;
01052 int b;
01053 int flag;
01054 char name[SUMA_FS_STRLEN];
01055 } SUMA_FS_COLORTABLE_ENTRY;
01056
01057 typedef struct {
01058 char *fname;
01059 int nbins;
01060 SUMA_FS_COLORTABLE_ENTRY *bins;
01061 } SUMA_FS_COLORTABLE;
01062
01063 SUMA_FS_COLORTABLE *SUMA_CreateFS_ColorTable(int nbins, int len)
01064 {
01065 static char FuncName[]={"SUMA_CreateFS_ColorTable"};
01066 SUMA_FS_COLORTABLE *ct = NULL;
01067
01068 SUMA_ENTRY;
01069
01070 ct = (SUMA_FS_COLORTABLE*) SUMA_malloc(sizeof(SUMA_FS_COLORTABLE));
01071 if (!ct) {
01072 SUMA_SL_Crit("Failed to allocate for ct");
01073 SUMA_RETURN(NULL);
01074 }
01075 ct->nbins = nbins;
01076 ct->bins = (SUMA_FS_COLORTABLE_ENTRY *) SUMA_malloc(nbins *
01077 sizeof(SUMA_FS_COLORTABLE_ENTRY));
01078
01079 ct->fname = (char *)SUMA_malloc((len + 1)*sizeof(char));
01080 if (!ct->bins || !ct->fname) {
01081 SUMA_SL_Crit("Failed to allocate for ct fields");
01082 if (ct->bins) SUMA_free(ct->bins);
01083 if (ct->fname) SUMA_free(ct->fname);
01084 SUMA_free(ct);
01085 SUMA_RETURN(NULL);
01086 }
01087 ct->fname[0] = '\0';
01088 SUMA_RETURN(ct);
01089 }
01090
01091 SUMA_FS_COLORTABLE *SUMA_FreeFS_ColorTable (SUMA_FS_COLORTABLE *ct)
01092 {
01093 static char FuncName[]={"SUMA_FreeFS_ColorTable"};
01094
01095 SUMA_ENTRY;
01096
01097 if (!ct) SUMA_RETURN(NULL);
01098
01099 if (ct->bins) SUMA_free(ct->bins);
01100 if (ct->fname) SUMA_free(ct->fname);
01101
01102 SUMA_free(ct);
01103
01104 SUMA_RETURN(NULL);
01105 }
01106
01107 char *SUMA_FS_ColorTable_Info(SUMA_FS_COLORTABLE *ct)
01108 {
01109 static char FuncName[]={"SUMA_FS_ColorTable_Info"};
01110 char *s=NULL;
01111 int i;
01112 SUMA_STRING *SS = NULL;
01113
01114 SUMA_ENTRY;
01115
01116 SS = SUMA_StringAppend (NULL, NULL);
01117
01118 if (!ct) SS = SUMA_StringAppend(SS,"NULL ct");
01119 else {
01120 if (ct->fname) SS = SUMA_StringAppend_va(SS, "fname: %s\nnbins: %d\n", ct->fname, ct->nbins);
01121 else SS = SUMA_StringAppend_va(SS, "fname: NULL\nnbins: %d\n", ct->nbins);
01122 if (!ct->bins) SS = SUMA_StringAppend_va(SS, "NULL bins\n");
01123 else {
01124 for (i=0; i<ct->nbins; ++i) {
01125 SS = SUMA_StringAppend_va(SS, "bin[%d]: %d %d %d %d : %s\n",
01126 i, ct->bins[i].r, ct->bins[i].g,
01127 ct->bins[i].b, ct->bins[i].flag,
01128 ct->bins[i].name);
01129 }
01130 }
01131 }
01132
01133 SS = SUMA_StringAppend(SS,NULL);
01134 s = SS->s;
01135 SUMA_free(SS);
01136
01137 SUMA_RETURN(s);
01138
01139 }
01140
01141 SUMA_Boolean SUMA_Show_FS_ColorTable(SUMA_FS_COLORTABLE *ct, FILE *fout)
01142 {
01143 static char FuncName[]={"SUMA_Show_FS_ColorTable"};
01144 char *s=NULL;
01145
01146 SUMA_ENTRY;
01147
01148 if (!fout) fout = stdout;
01149
01150 s = SUMA_FS_ColorTable_Info(ct);
01151 if (s) {
01152 fprintf(fout, "%s\n", s);
01153 SUMA_free(s);
01154 } else {
01155 SUMA_SL_Err("Failed in SUMA_FS_ColorTable_Info");
01156 SUMA_RETURN(NOPE);
01157 }
01158
01159 SUMA_RETURN(YUP);
01160 }
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 SUMA_Boolean SUMA_readFSannot (char *f_name, char *f_ROI, char *f_cmap, char *f_col, int Showct)
01174 {
01175 static char FuncName[]={"SUMA_readFSannot"};
01176 int n_labels = -1, ex, ni, chnk, j, annot, r, g, b, imap;
01177 int tg, len, nbins, i;
01178 FILE *fl=NULL;
01179 FILE *fr=NULL;
01180 FILE *fc=NULL;
01181 FILE *fo=NULL;
01182 SUMA_FS_COLORTABLE *ct=NULL;
01183 SUMA_FS_COLORTABLE_ENTRY *cte;
01184 SUMA_Boolean bs = NOPE;
01185 int *rv=NULL, *gv=NULL, *bv=NULL, *anv=NULL, *niv=NULL;
01186 SUMA_Boolean LocalHead = NOPE;
01187
01188 SUMA_ENTRY;
01189
01190
01191 if (!SUMA_filexists(f_name)) {
01192 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
01193 SUMA_RETURN (NOPE);
01194 }else if (LocalHead) {
01195 fprintf(SUMA_STDERR,"%s: File %s exists and will be read.\n", FuncName, f_name);
01196 }
01197 if (f_ROI) {
01198 if (SUMA_filexists(f_ROI)) {
01199 fprintf(SUMA_STDERR,"Error %s: File %s exists, will not overwrite.\n", FuncName, f_ROI);
01200 SUMA_RETURN (NOPE);
01201 }else {
01202 fr = fopen(f_ROI, "w");
01203 if (!fr) {
01204 SUMA_SL_Err("Failed to open file for writing.\n");
01205 SUMA_RETURN(NOPE);
01206 }
01207 }
01208 }
01209
01210 if (f_cmap) {
01211 if (SUMA_filexists(f_cmap)) {
01212 fprintf(SUMA_STDERR,"Error %s: File %s exists, will not overwrite.\n", FuncName, f_cmap);
01213 SUMA_RETURN (NOPE);
01214 }else {
01215 fc = fopen(f_cmap, "w");
01216 if (!fc) {
01217 SUMA_SL_Err("Failed to open file for writing.\n");
01218 SUMA_RETURN(NOPE);
01219 }
01220 }
01221 }
01222
01223 if (f_col) {
01224 if (SUMA_filexists(f_col)) {
01225 fprintf(SUMA_STDERR,"Error %s: File %s exists, will not overwrite.\n", FuncName, f_col);
01226 SUMA_RETURN (NOPE);
01227 }else {
01228 fo = fopen(f_col, "w");
01229 if (!fo) {
01230 SUMA_SL_Err("Failed to open file for writing.\n");
01231 SUMA_RETURN(NOPE);
01232 }
01233 }
01234 }
01235
01236 bs = NOPE;
01237 fl = fopen(f_name, "r");
01238 if (!fl) {
01239 SUMA_SL_Err("Failed to open file for reading.\n");
01240 SUMA_RETURN(NOPE);
01241 }
01242 chnk = sizeof(int);
01243 ex = fread (&n_labels, chnk, 1, fl);
01244 if (n_labels < 0 || n_labels > 500000) {
01245 if (LocalHead) {
01246 SUMA_SL_Warn("Byte swapping binary data.");
01247 }
01248 SUMA_swap_4( &n_labels ) ;
01249 bs = YUP;
01250 }
01251
01252
01253 niv = (int *) SUMA_malloc(sizeof(int)*n_labels);
01254 rv = (int *) SUMA_malloc(sizeof(int)*n_labels);
01255 gv = (int *) SUMA_malloc(sizeof(int)*n_labels);
01256 bv = (int *) SUMA_malloc(sizeof(int)*n_labels);
01257 anv = (int *) SUMA_malloc(sizeof(int)*n_labels);
01258 if (!rv || !gv || !bv || !anv || !niv) {
01259 SUMA_SL_Crit("Failed to allocate.");
01260 SUMA_RETURN(NOPE);
01261 }
01262
01263 if (ex != EOF) {
01264 if (LocalHead) fprintf(SUMA_STDERR,"%s:\n Expecting to read %d labels\n", FuncName, n_labels);
01265 }
01266 SUMA_LH("Reading annotations...");
01267 for (j=0; j<n_labels; ++j) {
01268 SUMA_READ_INT (&ni, bs, fl, ex);
01269 if (ni < 0 || ni >= n_labels) {
01270 fprintf(SUMA_STDERR,"Error %s:\n Read a node index of %d. Bad because < 0 or > %d\n", FuncName, ni, n_labels);
01271 SUMA_RETURN(NOPE);
01272 }
01273 SUMA_READ_INT (&annot, bs, fl, ex);
01274 niv[j] = ni;
01275 anv[j] = annot;
01276 rv[j] = annot & 0x0000ff;
01277 gv[j] = (annot >> 8) & 0x0000ff;
01278 bv[j] = (annot >> 16) & 0x0000ff;
01279 if (LocalHead && ( j < 5 || j > n_labels - 5)) {
01280 fprintf (SUMA_STDERR, "annot[%d]: %d = %d %d %d\n",
01281 ni, anv[j], rv[j], gv[j], bv[j]);
01282 }
01283 }
01284
01285 SUMA_LH("Searching for colortables");
01286 while (!feof(fl)) {
01287 SUMA_READ_INT (&tg, bs, fl, ex);
01288 if (tg == SUMA_FS_ANNOT_TAG_COLORTABLE) {
01289 SUMA_LH("Found color table");
01290 SUMA_READ_INT (&nbins, bs, fl, ex);
01291 SUMA_READ_INT (&len, bs, fl, ex);
01292 ct = SUMA_CreateFS_ColorTable(nbins, len);
01293 fread(ct->fname, sizeof(char), len, fl) ;
01294 for (i = 0 ; i < nbins ; i++)
01295 {
01296 cte = &ct->bins[i] ;
01297 SUMA_READ_INT (&len, bs, fl, ex);
01298 if (len < 0 || len > SUMA_FS_STRLEN ) {
01299 SUMA_SL_Err("Too long a name");
01300 SUMA_RETURN(NOPE);
01301 }
01302 fread(cte->name, sizeof(char), len, fl) ;
01303 SUMA_READ_INT (&(cte->r), bs, fl, ex);
01304 SUMA_READ_INT (&(cte->g), bs, fl, ex);
01305 SUMA_READ_INT (&(cte->b), bs, fl, ex);
01306 SUMA_READ_INT (&(cte->flag), bs, fl, ex);
01307 }
01308
01309 }
01310 }
01311
01312 if (fc) {
01313 fprintf(fc, "#name\n#bin r g b flag \n");
01314 for (i=0; i<ct->nbins; ++i) {
01315 fprintf(fc, "#%s\n", ct->bins[i].name);
01316 fprintf(fc, "%d %f %f %f %d\n",
01317 i, (float)ct->bins[i].r/255.0, (float)ct->bins[i].g/255.0,
01318 (float)ct->bins[i].b/255.0, ct->bins[i].flag );
01319 }
01320 }
01321
01322 if (fr) {
01323 if (ct) {
01324 fprintf(fr, "#NodeID ROI(indexed into labels cmap) r g b \n");
01325 for (i=0; i < n_labels; ++i) {
01326 j = 0;
01327 imap = -1;
01328 while (j < ct->nbins && imap < 0) {
01329 if ( ct->bins[j].r == rv[i] &&
01330 ct->bins[j].b == bv[i] &&
01331 ct->bins[j].g == gv[i] ) {
01332 imap = j;
01333 }
01334 ++j;
01335 }
01336 if (imap < 0) {
01337 static int iwarn;
01338 if (!iwarn) {
01339 SUMA_SL_Warn("Node Color (label) not found in cmap.\nMarking with annotation value.\nFurther occurences will not be reported.");
01340 ++iwarn;
01341 }
01342 imap = anv[i];
01343 }
01344 fprintf(fr, "%d %d %f %f %f \n",
01345 niv[i], imap, (float)rv[i]/255.0, (float)gv[i]/255.0, (float)bv[i]/255.0);
01346 }
01347 } else {
01348 fprintf(fr, "#NodeID Annotation\n");
01349 for (i=0; i < n_labels; ++i) {
01350 fprintf(fr, "%d %d \n", niv[i], anv[i]);
01351 }
01352 }
01353 }
01354
01355 if (fo) {
01356 if (ct) {
01357 fprintf(fo, "#NodeID r g b \n");
01358 for (i=0; i < n_labels; ++i) {
01359 fprintf(fo, "%d %f %f %f \n",
01360 niv[i], (float)rv[i]/255.0, (float)gv[i]/255.0, (float)bv[i]/255.0);
01361 }
01362 } else {
01363 fprintf(fo, "#NodeID Annotation\n");
01364 for (i=0; i < n_labels; ++i) {
01365 fprintf(fo, "%d %d \n", niv[i], anv[i]);
01366 }
01367 }
01368 }
01369
01370 if (Showct) {
01371 if (ct) {
01372 SUMA_Show_FS_ColorTable(ct, NULL);
01373 ct = SUMA_FreeFS_ColorTable(ct);
01374 }else {
01375 fprintf(SUMA_STDOUT,"No color table found.\n");
01376 }
01377 }
01378
01379
01380
01381
01382
01383
01384
01385
01386 if (fl) fclose (fl); fl = NULL;
01387 if (fr) fclose (fr); fr = NULL;
01388 if (fc) fclose (fc); fc = NULL;
01389 if (fo) fclose (fo); fo = NULL;
01390
01391 if (niv) SUMA_free(niv); niv = NULL;
01392 if (rv) SUMA_free(rv); rv = NULL;
01393 if (gv) SUMA_free(gv); gv = NULL;
01394 if (bv) SUMA_free(bv); bv = NULL;
01395 if (anv) SUMA_free(anv); anv = NULL;
01396
01397 SUMA_RETURN(YUP);
01398 }
01399
01400 #ifdef SUMA_FSread_annot_STAND_ALONE
01401
01402 void usage_SUMA_FSread_annot_Main ()
01403
01404 {
01405 static char FuncName[]={"usage_SUMA_FSread_annot_Main"};
01406 char * s = NULL;
01407 printf ("\n"
01408 "Usage: \n"
01409 " FSread_annot <-input ANNOTFILE> \n"
01410 " [-col_1D annot.1D.col] \n"
01411 " [-roi_1D annot.1D.roi] \n"
01412 " [-cmap_1D annot.1D.cmap]\n"
01413 " [show_FScmap]\n"
01414 " [-help] \n"
01415 " Reads a FreeSurfer annotaion file and outputs\n"
01416 " an equivalent ROI file and/or a colormap file \n"
01417 " for use with SUMA.\n"
01418 "\n"
01419 " Required options:\n"
01420 " -input ANNOTFILE: Binary formatted FreeSurfer\n"
01421 " annotation file.\n"
01422 " AND one of the optional options.\n"
01423 " Optional options:\n"
01424 " -col_1D annot.1D.col: Write a 4-column 1D color file. \n"
01425 " The first column is the node\n"
01426 " index followed by r g b values.\n"
01427 " This color file can be imported \n"
01428 " using the 'c' option in SUMA.\n"
01429 " If no colormap was found in the\n"
01430 " ANNOTFILE then the file has 2 columns\n"
01431 " with the second being the annotation\n"
01432 " value.\n"
01433 " -roi_1D annot.1D.roi: Write a 5-column 1D roi file.\n"
01434 " The first column is the node\n"
01435 " index, followed by its index in the\n"
01436 " colormap, followed by r g b values.\n"
01437 " This roi file can be imported \n"
01438 " using the 'Load' button in SUMA's\n"
01439 " 'Draw ROI' controller.\n"
01440 " If no colormap was found in the\n"
01441 " ANNOTFILE then the file has 2 columns\n"
01442 " with the second being the annotation\n"
01443 " value. \n"
01444 " -cmap_1D annot.1D.cmap: Write a 4-column 1D color map file.\n"
01445 " The first column is the color index,\n"
01446 " followed by r g b and flag values.\n"
01447 " The name of each color is inserted\n"
01448 " as a comment because 1D files do not\n"
01449 " support text data.\n"
01450 " -show_FScmap: Show the info of the colormap in the ANNOT file.\n"
01451 "\n"
01452 "\n");
01453 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
01454 printf(" Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
01455 exit (0);
01456 }
01457
01458 int main (int argc,char *argv[])
01459 {
01460 static char FuncName[]={"FSread_annot"};
01461 int kar, Showct;
01462 char *fname = NULL, *fcmap = NULL, *froi = NULL, *fcol = NULL;
01463 SUMA_Boolean SkipCoords = NOPE, brk;
01464 SUMA_Boolean LocalHead = NOPE;
01465
01466
01467 SUMAg_CF = SUMA_Create_CommonFields ();
01468 if (SUMAg_CF == NULL) {
01469 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01470 exit(1);
01471 }
01472
01473
01474 kar = 1;
01475 fname = NULL;
01476 froi = NULL;
01477 fcmap = NULL;
01478 fcol = NULL;
01479 brk = NOPE;
01480 Showct = 0;
01481 while (kar < argc) {
01482
01483 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
01484 usage_SUMA_FSread_annot_Main();
01485 exit (0);
01486 }
01487
01488 if (!brk && (strcmp(argv[kar], "-show_FScmap") == 0)) {
01489 Showct = 1;
01490 brk = YUP;
01491 }
01492
01493 if (!brk && (strcmp(argv[kar], "-input") == 0)) {
01494 kar ++;
01495 if (kar >= argc) {
01496 fprintf (SUMA_STDERR, "need argument after -input\n");
01497 exit (1);
01498 }
01499 fname = argv[kar];
01500 brk = YUP;
01501 }
01502
01503 if (!brk && (strcmp(argv[kar], "-roi_1D") == 0)) {
01504 kar ++;
01505 if (kar >= argc) {
01506 fprintf (SUMA_STDERR, "need argument after -ROI_1D\n");
01507 exit (1);
01508 }
01509 froi = argv[kar];
01510 brk = YUP;
01511 }
01512
01513 if (!brk && (strcmp(argv[kar], "-cmap_1D") == 0)) {
01514 kar ++;
01515 if (kar >= argc) {
01516 fprintf (SUMA_STDERR, "need argument after -cmap_1D\n");
01517 exit (1);
01518 }
01519 fcmap = argv[kar];
01520 brk = YUP;
01521 }
01522
01523 if (!brk && (strcmp(argv[kar], "-col_1D") == 0)) {
01524 kar ++;
01525 if (kar >= argc) {
01526 fprintf (SUMA_STDERR, "need argument after -col_1D\n");
01527 exit (1);
01528 }
01529 fcol = argv[kar];
01530 brk = YUP;
01531 }
01532
01533 if (!brk) {
01534 fprintf (SUMA_STDERR,"Error %s:\nOption %s not understood. Try -help for usage\n", FuncName, argv[kar]);
01535 exit (1);
01536 } else {
01537 brk = NOPE;
01538 kar ++;
01539 }
01540 }
01541
01542 if (!fcmap && !froi && !fcol && !Showct) {
01543 SUMA_SL_Err("Nothing to do.\nUse either -cmap_1D or \n -roi_1D or -col_1D or \n -show_FScmap options.");
01544 exit(1);
01545 }
01546 if (!fname) {
01547 SUMA_SL_Err("No input file specified.");
01548 exit(1);
01549 }
01550
01551 SUMA_readFSannot (fname, froi, fcmap, fcol, Showct);
01552
01553 exit(0);
01554 }
01555 #endif
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576 float * SUMA_readFScurv (char *f_name, int *nrows, int *ncols, SUMA_Boolean rowmajor, SUMA_Boolean SkipCoords)
01577 {
01578 static char FuncName[]={"SUMA_readFScurv"};
01579 MRI_IMAGE *im = NULL;
01580 float *v = NULL, jnk, *far;
01581 int cnt, ex, id, i, ncol, nvec;
01582 char c, comment[SUMA_MAX_STRING_LENGTH];
01583 FILE *fs_file = NULL;
01584 SUMA_Boolean LocalHead = NOPE;
01585
01586 SUMA_ENTRY;
01587
01588
01589 if (!SUMA_filexists(f_name)) {
01590 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
01591 SUMA_RETURN (NULL);
01592 }else if (LocalHead) {
01593 fprintf(SUMA_STDERR,"%s: File %s exists and will be read.\n", FuncName, f_name);
01594 }
01595
01596 if (SkipCoords) *ncols = 2;
01597 else *ncols = 5;
01598
01599 if (*ncols !=2 && *ncols != 5) {
01600 SUMA_SL_Crit("ncols must be either 2 or 5");
01601 SUMA_RETURN(NULL);
01602 }
01603
01604
01605 #if 0
01606
01607
01608 fs_file = fopen (f_name,"r");
01609 if (fs_file == NULL) {
01610 SUMA_SL_Err ("Could not open input file");
01611 SUMA_RETURN (v);
01612 }
01613
01614
01615 ex = fscanf (fs_file,"%c",&c);
01616 if (c == '#') {
01617 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Found comment\n", FuncName);
01618
01619
01620 cnt = 0;
01621 while (ex != EOF && c != '\n') {
01622 ex = fscanf (fs_file,"%c",&c);
01623 if (cnt < SUMA_MAX_STRING_LENGTH-2) {
01624 sprintf(comment, "%s%c", comment, c);
01625 ++cnt;
01626 } else {
01627 fprintf(SUMA_STDERR,"Error %s: Too long a comment in curvature file, increase SUMA_MAX_STRING_LENGTH\n", FuncName);
01628 SUMA_RETURN (NOPE);
01629 }
01630 }
01631 }
01632
01633
01634
01635 ex = fscanf(fs_file, "%d", nrows);
01636
01637 if (*nrows <= 0) {
01638 SUMA_SL_Crit("Trouble parsing curvature file.\nNull or negative number of nodes\n");
01639 SUMA_RETURN(NULL);
01640 }
01641
01642 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Allocating for data (%dx%d) \n", FuncName, *nrows, *ncols);
01643
01644 v = (float *) SUMA_calloc(*nrows * *ncols, sizeof(float));
01645 if (!v) {
01646 SUMA_SL_Crit("Failed to allocate for v");
01647 SUMA_RETURN(v);
01648 }
01649
01650 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Parsing file...\n", FuncName);
01651
01652 if (rowmajor) {
01653 cnt = 0;
01654 if (*ncols == 5) {
01655 while (ex != EOF && cnt < *nrows) {
01656 id = *ncols * cnt;
01657 ex = fscanf(fs_file, "%f %f %f %f %f", &(v[id]), &(v[id+1]),&(v[id+2]), &(v[id+3]), &(v[id+4]) );
01658 ++cnt;
01659 }
01660 } else {
01661 while (ex != EOF && cnt < *nrows) {
01662 id = *ncols * cnt;
01663 ex = fscanf(fs_file, "%f %f %f %f %f", &(v[id]), &jnk, &jnk, &jnk, &(v[id+1]) );
01664 ++cnt;
01665 }
01666 }
01667
01668 } else {
01669 cnt = 0;
01670 if (*ncols == 5) {
01671 while (ex != EOF && cnt < *nrows) {
01672 ex = fscanf(fs_file, "%f %f %f %f %f", &(v[cnt]), &(v[cnt+ *nrows]),&(v[cnt+ 2 * *nrows]), &(v[cnt+ 3 * *nrows]), &(v[cnt+ 4 * *nrows]));
01673 ++cnt;
01674 }
01675 } else if (*nrows == 2) {
01676 while (ex != EOF && cnt < *nrows) {
01677 ex = fscanf(fs_file, "%f %f %f %f %f", &(v[cnt]), &jnk, &jnk, &jnk, &(v[cnt+ *nrows]));
01678 ++cnt;
01679 }
01680 } else {
01681
01682 }
01683 }
01684
01685 if (cnt != *nrows) {
01686 fprintf(SUMA_STDERR,"Error %s: Expected %d rows, %d read.\n", FuncName, *nrows, cnt);
01687 SUMA_free(v); v = NULL;
01688 SUMA_RETURN (NULL);
01689 }
01690 #else
01691
01692 SUMA_LH("Reading file...");
01693 im = mri_read_1D (f_name);
01694
01695 if (!im) {
01696 SUMA_SL_Err("Failed to read 1D file");
01697 SUMA_RETURN(NULL);
01698 }
01699
01700 far = MRI_FLOAT_PTR(im);
01701 nvec = im->nx;
01702 ncol = im->ny;
01703
01704
01705 if (!nvec) {
01706 SUMA_SL_Err("Empty file");
01707 SUMA_RETURN(NULL);
01708 }
01709
01710 if (ncol != 5) {
01711 SUMA_SL_Err("Must have 5 columns in data file.");
01712 mri_free(im); im = NULL;
01713 SUMA_RETURN(NULL);
01714 }
01715
01716 *nrows = nvec;
01717
01718 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Allocating for data (%dx%d) \n", FuncName, *nrows, *ncols);
01719
01720 v = (float *) SUMA_calloc(*nrows * *ncols, sizeof(float));
01721
01722 if (!v) {
01723 SUMA_SL_Crit("Failed to allocate for v");
01724 SUMA_RETURN(v);
01725 }
01726
01727 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Parsing file...\n", FuncName);
01728
01729 if (rowmajor) {
01730 if (*ncols == 5) {
01731 SUMA_LH("RowMajor, All Coords");
01732 for (i=0; i< *nrows; ++i) {
01733 id = *ncols*i;
01734 v[id] = far[i];
01735 v[id+1] = far[i+*nrows];
01736 v[id+2] = far[i+2 * *nrows];
01737 v[id+3] = far[i+3 * *nrows];
01738 v[id+4] = far[i+4 * *nrows];
01739 }
01740 } else {
01741 SUMA_LH("RowMajor, Skipping Coords");
01742 for (i=0; i< *nrows; ++i) {
01743 id = *ncols*i;
01744 v[id] = far[i];
01745 v[id+1] = far[i+4 * *nrows];
01746 }
01747 }
01748 } else {
01749 if (*ncols == 5) {
01750 SUMA_LH("ColMajor, All Coords");
01751 for (i=0; i<*ncols * *nrows; ++i) v[i] = far[i];
01752 } else if (*ncols == 2) {
01753 SUMA_LH("ColMajor, Skipping Coords");
01754 for (i=0; i<*nrows; ++i) v[i] = far[i];
01755 for (i=*nrows; i< 2 * *nrows; ++i) v[i] = far[i+3 * *nrows];
01756 }
01757 }
01758 mri_free(im); im = NULL; far = NULL;
01759 #endif
01760 SUMA_RETURN(v);
01761 }
01762
01763
01764 #ifdef SUMA_FScurv_to_1D_STAND_ALONE
01765
01766 void usage_SUMA_FScurv_to_1D_Main ()
01767
01768 {
01769 static char FuncName[]={"usage_FScurv_to_1D"};
01770 char * s = NULL;
01771 printf ("\n"
01772 "Usage: FScurv_to_1D [-skip_coords] [-output outfile] -input curv_name.asc \n"
01773 " Reads in a FreeSurfer curvature file and writes it out in 1D format. \n"
01774 " But the format is 1D to begin with, so 'what is that program for?' you ask. \n"
01775 " Not much, I say. It is used to test a SUMA function and also allows you\n"
01776 " to select the node index and data values from the 5 columns of the curv files.\n"
01777 "\n"
01778 " -input curv_name.asc: name of ASCII curvature file. To change a curvature file \n"
01779 " to ASCII, use mris_convert -c curv_name surf curvfile.asc \n"
01780 " surf is the surface over which the curvfile is defined, like\n"
01781 " lh.inflated.\n"
01782 " -skip_coords: If specified, the node coordinates are not included in the output.\n"
01783 " -output outfile: If specified, the output goes to a file instead of stdout, \n"
01784 " which is the screen\n"
01785 "\n");
01786 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
01787 printf(" Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
01788 exit (0);
01789 }
01790
01791 int main (int argc,char *argv[])
01792 {
01793 static char FuncName[]={"FScurv_to_1D"};
01794 int i, j, id, nrows=0, ncols=0, kar;
01795 float *v = NULL;
01796 char *outname = NULL;
01797 char *fname = NULL;
01798 FILE *outfile=NULL;
01799 SUMA_Boolean SkipCoords = NOPE, brk, rowmajor;
01800 SUMA_Boolean LocalHead = NOPE;
01801
01802
01803 SUMAg_CF = SUMA_Create_CommonFields ();
01804 if (SUMAg_CF == NULL) {
01805 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01806 exit(1);
01807 }
01808
01809
01810 kar = 1;
01811 outname = NULL;
01812 fname = NULL;
01813 SkipCoords = NOPE;
01814 rowmajor = YUP;
01815 brk = NOPE;
01816 while (kar < argc) {
01817
01818 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
01819 usage_SUMA_FScurv_to_1D_Main();
01820 exit (0);
01821 }
01822 if (!brk && ( (strcmp(argv[kar], "-skip_coords") == 0) ) ) {
01823 SkipCoords = YUP;
01824 brk = YUP;
01825 }
01826 if (!brk && (strcmp(argv[kar], "-output") == 0)) {
01827 kar ++;
01828 if (kar >= argc) {
01829 fprintf (SUMA_STDERR, "need argument after -output\n");
01830 exit (1);
01831 }
01832 outname = argv[kar];
01833 brk = YUP;
01834 }
01835 if (!brk && (strcmp(argv[kar], "-input") == 0)) {
01836 kar ++;
01837 if (kar >= argc) {
01838 fprintf (SUMA_STDERR, "need argument after -input\n");
01839 exit (1);
01840 }
01841 fname = argv[kar];
01842 brk = YUP;
01843 }
01844 if (!brk) {
01845 fprintf (SUMA_STDERR,"Error %s:\nOption %s not understood. Try -help for usage\n", FuncName, argv[kar]);
01846 exit (1);
01847 } else {
01848 brk = NOPE;
01849 kar ++;
01850 }
01851 }
01852
01853 if (!fname) {
01854 SUMA_SL_Err("No input file specified.");
01855 exit(1);
01856 }
01857
01858 if (!outname) {
01859 outfile = SUMA_STDOUT;
01860 } else {
01861 outname = SUMA_Extension(outname, ".1D", NOPE);
01862 if (SUMA_filexists(outname)) {
01863 fprintf(SUMA_STDERR,"Error %s: Output file %s exists, will not overwrite.\n", FuncName, outname);
01864 exit(1);
01865 }
01866 outfile = fopen(outname, "w");
01867 if (!outfile) {
01868 SUMA_SL_Crit("Failed to open file for writing.\n"
01869 "Check file permissions.");
01870 exit(1);
01871 }
01872 }
01873
01874
01875 v = SUMA_readFScurv (fname, &nrows, &ncols, rowmajor, SkipCoords);
01876 if (!v) {
01877 SUMA_SL_Err("Failed in SUMA_readFScurv");
01878 exit(1);
01879 }
01880
01881 if (rowmajor) {
01882 for (i=0; i<nrows; ++i) {
01883 id = ncols * i;
01884 fprintf(outfile,"%d\t", (int) v[id]);
01885 for (j=1; j<ncols; ++j) fprintf(outfile,"%f\t", v[id+j]);
01886 fprintf(outfile,"\n");
01887 }
01888
01889 } else {
01890 for (i=0; i<nrows; ++i) {
01891 fprintf(outfile,"%d\t", (int) v[i]);
01892 for (j=1; j<ncols; ++j) fprintf(outfile,"%f\t", v[i+j*nrows]);
01893 fprintf(outfile,"\n");
01894 }
01895 }
01896
01897 if (outname) {
01898 fclose (outfile); outfile = NULL;
01899 SUMA_free(outname); outname = NULL;
01900 }
01901 SUMA_free(v); v = NULL;
01902
01903 exit(0);
01904 }
01905 #endif
01906
01907
01908 SUMA_Boolean SUMA_FreeSurfer_Read (char * f_name, SUMA_FreeSurfer_struct *FS)
01909 {
01910 static char FuncName[]={"SUMA_FreeSurfer_Read"};
01911
01912 SUMA_ENTRY;
01913
01914 SUMA_RETURN(SUMA_FreeSurfer_Read_eng(f_name, FS, 1));
01915 }
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954 SUMA_Boolean SUMA_FreeSurfer_Read_eng (char * f_name, SUMA_FreeSurfer_struct *FS, int debug)
01955 {
01956 static char FuncName[]={"SUMA_FreeSurfer_Read_eng"};
01957 char stmp[50];
01958 FILE *fs_file;
01959 int ex, cnt, jnki, amax[3], maxamax, maxamax2, id, ND, id2, NP, ip, *NodeId;
01960 float jnkf, *NodeList;
01961 char c;
01962 SUMA_Boolean LocalHead = NOPE;
01963
01964 SUMA_ENTRY;
01965
01966
01967 if (!SUMA_filexists(f_name)) {
01968 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
01969 SUMA_RETURN (NOPE);
01970 }else if ( debug > 1) {
01971 fprintf(SUMA_STDERR,"%s: File %s exists and will be read.\n", FuncName, f_name);
01972 }
01973
01974
01975
01976 fs_file = fopen (f_name,"r");
01977 if (fs_file == NULL)
01978 {
01979 SUMA_error_message (FuncName,"Could not open input file ",0);
01980 SUMA_RETURN (NOPE);
01981 }
01982
01983 sprintf(FS->name, "%s", f_name);
01984
01985
01986 ex = fscanf (fs_file,"%c",&c);
01987 if (c == '#') {
01988 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Found comment\n", FuncName);
01989
01990
01991 sprintf(FS->comment,"#");
01992 cnt = 0;
01993 while (ex != EOF && c != '\n') {
01994 ex = fscanf (fs_file,"%c",&c);
01995 if (cnt < SUMA_MAX_STRING_LENGTH-2) {
01996 sprintf(FS->comment, "%s%c", FS->comment, c);
01997 ++cnt;
01998 } else {
01999 fprintf(SUMA_STDERR,"Error %s: Too long a comment in FS file, increase SUMA_FS_MAX_COMMENT_LENGTH\n", FuncName);
02000 SUMA_RETURN (NOPE);
02001 }
02002 }
02003 }
02004
02005
02006 sprintf(stmp,"patch");
02007 if (SUMA_iswordin (FS->comment, stmp) == 1) {
02008 FS->isPatch = YUP;
02009 }
02010 else {
02011 FS->isPatch = NOPE;
02012 }
02013
02014
02015 ex = fscanf(fs_file, "%d %d", &(FS->N_Node), &(FS->N_FaceSet));
02016
02017 if (FS->N_Node <= 0 || FS->N_FaceSet <= 0) {
02018 SUMA_SL_Crit("Trouble parsing FreeSurfer file.\nNull or negative number of nodes &/| facesets.\n");
02019 SUMA_RETURN(NOPE);
02020 }
02021
02022 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Allocating for NodeList (%dx3) and FaceSetList(%dx3)\n", FuncName, FS->N_Node, FS->N_FaceSet);
02023
02024
02025 FS->NodeList = (float *)SUMA_calloc(FS->N_Node * 3, sizeof(float));
02026 FS->FaceSetList = (int *)SUMA_calloc(FS->N_FaceSet * 3, sizeof(int));
02027 FS->NodeId = (int *)SUMA_calloc(FS->N_Node, sizeof(int));
02028 if (FS->NodeList == NULL || FS->FaceSetList == NULL || FS->NodeId == NULL) {
02029 fprintf(SUMA_STDERR,"Error %s: Could not allocate for FS->NodeList &/| FS->FaceSetList &/| FS->NodeId\n", FuncName);
02030 SUMA_RETURN (NOPE);
02031 }
02032 if (FS->isPatch) {
02033 FS->FaceSetIndexInParent = (int *)SUMA_calloc(FS->N_FaceSet, sizeof(int));
02034 if (FS->FaceSetIndexInParent == NULL) {
02035 fprintf(SUMA_STDERR,"Error %s: Could not allocate for FS->FaceSetIndexInParent\n", FuncName);
02036 SUMA_RETURN (NOPE);
02037 }
02038 } else {
02039 FS->FaceSetIndexInParent = NULL;
02040 }
02041
02042 if (!FS->isPatch) {
02043 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading full surface...\n", FuncName);
02044
02045 cnt = 0;
02046 while (ex != EOF && cnt < FS->N_Node) {
02047 FS->NodeId[cnt] = cnt;
02048 id = 3 * cnt;
02049 ex = fscanf(fs_file, "%f %f %f %f", &(FS->NodeList[id]), &(FS->NodeList[id+1]),&(FS->NodeList[id+2]), &jnkf);
02050 ++cnt;
02051 }
02052 if (cnt != FS->N_Node) {
02053 fprintf(SUMA_STDERR,"Error %s: Expected %d nodes, %d read.\n", FuncName, FS->N_Node, cnt);
02054 SUMA_RETURN (NOPE);
02055 }
02056
02057
02058 cnt = 0;
02059 while (ex != EOF && cnt < FS->N_FaceSet) {
02060 ip = 3 * cnt;
02061 ex = fscanf(fs_file, "%d %d %d %d", &(FS->FaceSetList[ip]), &(FS->FaceSetList[ip+1]),&(FS->FaceSetList[ip+2]), &jnki);
02062 ++cnt;
02063 }
02064 if (cnt != FS->N_FaceSet) {
02065 fprintf(SUMA_STDERR,"Error %s: Expected %d FaceSets, %d read.\n", FuncName, FS->N_FaceSet, cnt);
02066 SUMA_RETURN (NOPE);
02067 }
02068 }
02069 else {
02070 #if 0
02071 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading patch olde way...\n", FuncName);
02072
02073 cnt = 0;
02074 while (ex != EOF && cnt < FS->N_Node) {
02075 ex = fscanf(fs_file, "%d", &(FS->NodeId[cnt]));
02076 id = 3 * cnt;
02077
02078 ex = fscanf(fs_file, "%f %f %f", &(FS->NodeList[id]),&(FS->NodeList[id+1]),&(FS->NodeList[id+2]));
02079 ++cnt;
02080 }
02081 if (cnt != FS->N_Node) {
02082 fprintf(SUMA_STDERR,"Error %s: Expected %d nodes, %d read.\n", FuncName, FS->N_Node, cnt);
02083 SUMA_RETURN (NOPE);
02084 }
02085
02086 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading FaceSets...\n", FuncName);
02087
02088 cnt = 0;
02089 while (ex != EOF && cnt < FS->N_FaceSet) {
02090 ex = fscanf(fs_file, "%d", &(FS->FaceSetIndexInParent[cnt]));
02091 ip = 3 * cnt;
02092 ex = fscanf(fs_file, "%d %d %d", &(FS->FaceSetList[ip]), &(FS->FaceSetList[ip+1]),&(FS->FaceSetList[ip+2]));
02093 ++cnt;
02094 }
02095 if (cnt != FS->N_FaceSet) {
02096 fprintf(SUMA_STDERR,"Error %s: Expected %d FaceSets, %d read.\n", FuncName, FS->N_FaceSet, cnt);
02097 SUMA_RETURN (NOPE);
02098 }
02099 #else
02100 {
02101 char *fl=NULL, *eop=NULL, *florig=NULL;
02102 int ans, pnodes, ptri, Found, nchar;
02103 double dbuf;
02104
02105 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading patch new way...\n", FuncName);
02106
02107 fl = florig = SUMA_file_suck(f_name, &nchar);
02108 if (!nchar || !fl) {
02109 SUMA_SL_Err("Failed to read patch file.");
02110 SUMA_RETURN(NOPE);
02111 }
02112
02113 SUMA_IS_COMMENT_LINE(fl, NULL, '#', ans);
02114 if (ans) {
02115 SUMA_LH("Skipping comment...");
02116 SUMA_SKIP_LINE(fl, NULL);
02117 }else {
02118 SUMA_SL_Err("Expected comment line....");
02119 }
02120
02121 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); pnodes = (int)dbuf;
02122 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); ptri = (int)dbuf;
02123
02124
02125 Found = 1;
02126 cnt = 0;
02127 while (Found && cnt < FS->N_Node) {
02128 eop = fl+50;
02129
02130 SUMA_ADVANCE_PAST(fl, eop,"vno=",Found,0);
02131 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->NodeId[cnt] = (int)dbuf;
02132 id = 3 * cnt;
02133
02134 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->NodeList[id] = (float)dbuf;
02135 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->NodeList[id+1] = (float)dbuf;
02136 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->NodeList[id+2] = (float)dbuf;
02137 ++cnt;
02138 }
02139 if (cnt != FS->N_Node) {
02140 fprintf(SUMA_STDERR,"Error %s: Expected %d nodes, %d read.\n", FuncName, FS->N_Node, cnt);
02141 SUMA_RETURN (NOPE);
02142 }
02143 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading FaceSets...\n", FuncName);
02144
02145 Found = 1;
02146 cnt = 0;
02147 while (Found && cnt < FS->N_FaceSet) {
02148 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->FaceSetIndexInParent[cnt] = (int)dbuf;
02149 ip = 3 * cnt;
02150 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->FaceSetList[ip ] = (int)dbuf;
02151 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->FaceSetList[ip+1] = (int)dbuf;
02152 SUMA_ADVANCE_PAST_NUM(fl, dbuf, Found); FS->FaceSetList[ip+2] = (int)dbuf;
02153 ++cnt;
02154 }
02155 if (cnt != FS->N_FaceSet) {
02156 fprintf(SUMA_STDERR,"Error %s: Expected %d FaceSets, %d read.\n", FuncName, FS->N_FaceSet, cnt);
02157 SUMA_RETURN (NOPE);
02158 }
02159 SUMA_free(florig); fl = florig = NULL;
02160 }
02161 #endif
02162
02163
02164
02165
02166
02167
02168
02169 SUMA_MAX_VEC(FS->FaceSetList, FS->N_FaceSet * 3, maxamax); ++maxamax;
02170
02171 SUMA_MAX_VEC(FS->NodeId, FS->N_Node, maxamax2); ++maxamax2;
02172 if (maxamax2 > maxamax) {
02173 fprintf(SUMA_STDERR,"Error %s: Found NodeId in the NodeList larger than Ids found in FaceSetList.\n", FuncName);
02174 SUMA_RETURN (NOPE);
02175 }
02176 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Copying NodeList, allocating for new nodelist %dx3 elements...\n", \
02177 FuncName, maxamax);
02178
02179 NodeList = (float *)SUMA_calloc(maxamax * 3, sizeof(float));
02180 NodeId = (int *)SUMA_calloc (maxamax, sizeof(int));
02181
02182 if (NodeList == NULL || NodeId == NULL)
02183 {
02184 fprintf(SUMA_STDERR,"Error %s: Could not allocate for NodeList or NodeId\n", FuncName);
02185 SUMA_RETURN (NOPE);
02186 }
02187
02188
02189 for (cnt=0; cnt< FS->N_Node; ++cnt) {
02190 id = 3*cnt;
02191 id2 = 3*FS->NodeId[cnt];
02192
02193 NodeList[id2] = FS->NodeList[id];
02194 NodeList[id2+1] = FS->NodeList[id+1];
02195 NodeList[id2+2] = FS->NodeList[id+2];
02196 }
02197
02198
02199 for (cnt=0; cnt< maxamax; ++cnt) {
02200 NodeId[cnt] = cnt;
02201 }
02202
02203
02204 SUMA_free(FS->NodeList);
02205 SUMA_free(FS->NodeId);
02206
02207
02208 FS->NodeList = NodeList;
02209 FS->NodeId = NodeId;
02210 FS->N_Node = maxamax;
02211 }
02212
02213 fclose (fs_file);
02214 SUMA_RETURN (YUP);
02215
02216 }
02217
02218 SUMA_Boolean SUMA_FreeSurfer_WritePatch (char *fileNm, SUMA_SurfaceObject *SO, char *firstLine, SUMA_SurfaceObject *SO_parent)
02219 {
02220 static char FuncName[]={"SUMA_FreeSurfer_WritePatch"};
02221 int cnt, i, iface;
02222 int *FaceSetIndexInParent=NULL;
02223 SUMA_Boolean *isInPatch=NULL;
02224 FILE *fout=NULL;
02225
02226 SUMA_ENTRY;
02227
02228 if (!fileNm || !SO || !SO_parent || !SO_parent->EL) {
02229 SUMA_SL_Err("NULL input params");
02230 SUMA_RETURN(NOPE);
02231 }
02232
02233 if (SUMA_filexists(fileNm)) {
02234 SUMA_SL_Err("Output file exists, will not overwrite");
02235 SUMA_RETURN(NOPE);
02236 }
02237
02238 fout = fopen(fileNm,"w");
02239 if (!fout) {
02240 SUMA_SL_Err("Failed to open file for writing.\nCheck permissions.");
02241 SUMA_RETURN(NOPE);
02242 }
02243
02244 if (firstLine) {
02245 fprintf(fout, "%s\n", firstLine);
02246 } else {
02247 if (!SO->Label) SO->Label = SUMA_SurfaceFileName (SO, NOPE);
02248 fprintf(fout, "#!ascii version of patch %s\n", SO->Label);
02249 }
02250
02251
02252 isInPatch = SUMA_MaskOfNodesInPatch(SO, &cnt);
02253 if (!isInPatch) {
02254 SUMA_SL_Crit("Failed in SUMA_MaskOfNodesInPatch");
02255 SUMA_RETURN(NOPE);
02256 }
02257
02258
02259 fprintf(fout, "%d %d\n", cnt, SO->N_FaceSet);
02260
02261 for (i=0; i < SO->N_Node; ++i) {
02262 if (isInPatch[i]) {
02263 fprintf(fout, "%d\n%f\t%f\t%f\n", i, SO->NodeList[3*i], SO->NodeList[3*i+1], SO->NodeList[3*i+2]);
02264 }
02265 }
02266 for (i=0; i < SO->N_FaceSet; ++i) {
02267 iface = SUMA_whichTri (SO_parent->EL, SO->FaceSetList[3*i], SO->FaceSetList[3*i+1], SO->FaceSetList[3*i+2], 0);
02268 if (iface < 0) {
02269 SUMA_SL_Warn("Parent surface does not contain triangle in patch!\nTriangle skipped.");
02270 } else {
02271 fprintf(fout, "%d\n%d\t%d\t%d\n", iface, SO->FaceSetList[3*i], SO->FaceSetList[3*i+1], SO->FaceSetList[3*i+2]);
02272 }
02273 }
02274
02275
02276 SUMA_free(FaceSetIndexInParent); FaceSetIndexInParent = NULL;
02277 SUMA_free(isInPatch); isInPatch = NULL;
02278
02279 fclose(fout);
02280 SUMA_RETURN(YUP);
02281 }
02282
02283
02284
02285
02286 SUMA_Boolean SUMA_FreeSurfer_ReadBin_eng (char * f_name, SUMA_FreeSurfer_struct *FS, int debug)
02287 {
02288 static char FuncName[]={"SUMA_FreeSurfer_ReadBin_eng"};
02289 char stmp[50];
02290 FILE *fs_file;
02291 int ex, End, rmax, chnk, cnt, i, amax[3], maxamax, maxamax2, id, ND, id2, NP, ip, *NodeId, magic;
02292 float jnkf, *NodeList;
02293 char c;
02294 byte m1, m2, m3;
02295 SUMA_Boolean bs;
02296 SUMA_Boolean LocalHead = NOPE;
02297
02298 SUMA_ENTRY;
02299
02300 if (debug) LocalHead = YUP;
02301
02302
02303 if (!SUMA_filexists(f_name)) {
02304 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
02305 SUMA_RETURN (NOPE);
02306 }else if ( debug > 1) {
02307 fprintf(SUMA_STDERR,"%s: File %s exists and will be read.\n", FuncName, f_name);
02308 }
02309
02310
02311 fs_file = fopen (f_name,"r");
02312 if (fs_file == NULL)
02313 {
02314 SUMA_SL_Err ("Could not open input file ");
02315 SUMA_RETURN (NOPE);
02316 }
02317
02318 SUMA_WHAT_ENDIAN(End);
02319 if (End == MSB_FIRST) {
02320 SUMA_LH("No swapping needed");
02321 bs = NOPE;
02322 } else {
02323 bs = YUP;
02324 SUMA_LH("Swapping needed");
02325 }
02326
02327 ex = fread (&m1, 1, 1, fs_file);
02328 ex = fread (&m2, 1, 1, fs_file);
02329 ex = fread (&m3, 1, 1, fs_file);
02330 magic = (m1 << 16) + (m2 << 8) + m3 ;
02331 if (magic == (-2 & 0x00ffffff)) {
02332 SUMA_LH("OK tri");
02333 } else {
02334 SUMA_SL_Err("Failed to identify magic number for a triangulated surface.\n");
02335 SUMA_RETURN(NOPE);
02336 }
02337 chnk = sizeof(char);
02338 ex = fread (&c, chnk, 1, fs_file);
02339 rmax = 0;
02340 while (c != '\n' &&rmax < 5000) {
02341 if (LocalHead) fprintf(SUMA_STDERR,"%c",c);
02342 ex = fread (&c, chnk, 1, fs_file);
02343 ++rmax;
02344 }
02345 if (rmax >= 5000) {
02346 SUMA_SL_Err("Unexpected tres tres long comment.");
02347 SUMA_RETURN(NOPE);
02348 }
02349 SUMA_LH("End of comment");
02350
02351 ex = fread (&c, chnk, 1, fs_file);
02352 if (c != '\n') {
02353 SUMA_SL_Err("Failed to find second newline.");
02354 SUMA_RETURN(NOPE);
02355 }else {
02356 SUMA_LH("Found end of comment");
02357 }
02358
02359
02360 SUMA_READ_INT (&FS->N_Node, bs, fs_file, ex);
02361 if (FS->N_Node < 0 || FS->N_Node > 2000000) {
02362 SUMA_SL_Err("Failed to get number of nodes");
02363 SUMA_RETURN(NOPE);
02364 }else {
02365 if (LocalHead) fprintf(SUMA_STDERR,"%s: Expecting to read %d nodes.\n", FuncName, FS->N_Node);
02366 }
02367
02368 SUMA_READ_INT (&FS->N_FaceSet, bs, fs_file, ex);
02369 if (FS->N_FaceSet < 0 || FS->N_FaceSet > 2000000) {
02370 SUMA_SL_Err("Failed to get number of triangles");
02371 SUMA_RETURN(NOPE);
02372 }else {
02373 if (LocalHead) fprintf(SUMA_STDERR,"%s: Expecting to read %d triangles.\n", FuncName, FS->N_FaceSet);
02374 }
02375
02376
02377 FS->NodeList = (float *)SUMA_calloc(FS->N_Node * 3, sizeof(float));
02378 FS->FaceSetList = (int *)SUMA_calloc(FS->N_FaceSet * 3, sizeof(int));
02379 if (!FS->NodeList || !FS->FaceSetList) {
02380 SUMA_SL_Err("Failed to allocate");
02381 SUMA_RETURN(NOPE);
02382 }
02383
02384
02385 for (i=0; i<FS->N_Node * 3; ++i) {
02386 SUMA_READ_FLOAT (&(FS->NodeList[i]), bs, fs_file, ex);
02387 if (ex == EOF) {
02388 SUMA_SL_Err("Premature end of file!");
02389 SUMA_free(FS->NodeList); SUMA_free(FS->FaceSetList); FS->NodeList = NULL ; FS->FaceSetList = NULL;
02390 SUMA_RETURN(NOPE);
02391 }
02392 }
02393 for (i=0; i<FS->N_FaceSet * 3; ++i) {
02394 SUMA_READ_INT (&(FS->FaceSetList[i]), bs, fs_file, ex);
02395 if (ex == EOF) {
02396 SUMA_SL_Err("Premature end of file!");
02397 SUMA_free(FS->NodeList); SUMA_free(FS->FaceSetList); FS->NodeList = NULL ; FS->FaceSetList = NULL;
02398 SUMA_RETURN(NOPE);
02399 }
02400 }
02401
02402 fclose(fs_file);
02403 SUMA_LH("Returning");
02404 SUMA_RETURN(YUP);
02405 }
02406
02407
02408
02409 SUMA_Boolean SUMA_Free_FreeSurfer (SUMA_FreeSurfer_struct *FS)
02410 {
02411 static char FuncName[]={"SUMA_Free_FreeSurfer"};
02412
02413 SUMA_ENTRY;
02414
02415 if (FS->FaceSetList != NULL) SUMA_free(FS->FaceSetList);
02416 if (FS->NodeList != NULL) SUMA_free(FS->NodeList);
02417 if (FS->NodeId != NULL) SUMA_free(FS->NodeId);
02418 if (FS->FaceSetIndexInParent != NULL) SUMA_free(FS->FaceSetIndexInParent);
02419 if (FS != NULL) SUMA_free(FS);
02420 SUMA_RETURN (YUP);
02421 }
02422
02423
02424
02425
02426 void SUMA_Show_FreeSurfer (SUMA_FreeSurfer_struct *FS, FILE *Out)
02427 {
02428 static char FuncName[]={"SUMA_Show_FreeSurfer"};
02429 int ND = 3, id, ip;
02430
02431 SUMA_ENTRY;
02432
02433 if (Out == NULL) Out = SUMA_STDOUT;
02434 if (FS->comment) fprintf (Out, "Comment: %s\n", FS->comment);
02435 else fprintf (Out, "Comment: NULL\n");
02436 fprintf (Out, "N_Node %d\n", FS->N_Node);
02437 if (FS->NodeId) {
02438 fprintf (Out, "First 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
02439 FS->NodeId[0], FS->NodeList[0], FS->NodeList[1], FS->NodeList[2],
02440 FS->NodeId[1], FS->NodeList[3], FS->NodeList[4], FS->NodeList[5]);
02441 if (FS->N_Node > 2) {
02442 fprintf (Out, "Last 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
02443 FS->NodeId[FS->N_Node-2], FS->NodeList[3*(FS->N_Node-2)], FS->NodeList[3*(FS->N_Node-2)+1], FS->NodeList[3*(FS->N_Node-2)+2],
02444 FS->NodeId[FS->N_Node-1], FS->NodeList[3*(FS->N_Node-1)], FS->NodeList[3*(FS->N_Node-1)+1], FS->NodeList[3*(FS->N_Node-1)+2]);
02445 }
02446 } else {
02447 fprintf (Out, "NULL NodeId\n");
02448 fprintf (Out, "First 2 points X Y Z:\n\t %f %f %f\n\t %f %f %f\n", \
02449 FS->NodeList[0], FS->NodeList[1], FS->NodeList[2],
02450 FS->NodeList[3], FS->NodeList[4], FS->NodeList[5]);
02451 if (FS->N_Node > 2) {
02452 fprintf (Out, "Last 2 points X Y Z:\n\t %f %f %f\n\t %f %f %f\n", \
02453 FS->NodeList[3*(FS->N_Node-2)], FS->NodeList[3*(FS->N_Node-2)+1], FS->NodeList[3*(FS->N_Node-2)+2],
02454 FS->NodeList[3*(FS->N_Node-1)], FS->NodeList[3*(FS->N_Node-1)+1], FS->NodeList[3*(FS->N_Node-1)+2]);
02455 }
02456 }
02457 fprintf (Out, "N_FaceSet %d\n", FS->N_FaceSet);
02458 if (!FS->isPatch) {
02459 if (FS->N_FaceSet > 2) {
02460 fprintf (Out, "First 2 polygons:\n\t%d %d %d\n\t%d %d %d\n", \
02461 FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2],
02462 FS->FaceSetList[3], FS->FaceSetList[4], FS->FaceSetList[5]);
02463 fprintf (Out, "Last 2 polygons:\n%d %d %d\n%d %d %d\n", \
02464 FS->FaceSetList[3 * (FS->N_FaceSet-2)], FS->FaceSetList[3 * (FS->N_FaceSet-2) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-2) + 2],
02465 FS->FaceSetList[3 * (FS->N_FaceSet-1)], FS->FaceSetList[3 * (FS->N_FaceSet-1) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-1) + 2]);
02466 }else {
02467 fprintf (Out, "First polygon:\n\t%d %d %d\n", \
02468 FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2]);
02469 }
02470 } else {
02471 if (FS->N_FaceSet > 2) {
02472 fprintf (Out, "First 2 polygons:\n\t[parent ID:%d] %d %d %d\n\t[parent ID:%d] %d %d %d\n", \
02473 FS->FaceSetIndexInParent[0], FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2],
02474 FS->FaceSetIndexInParent[1], FS->FaceSetList[3], FS->FaceSetList[4], FS->FaceSetList[5]);
02475 fprintf (Out, "Last 2 polygons:\n\t[parent ID:%d]%d %d %d\n\t[parent ID:%d]%d %d %d\n", \
02476 FS->FaceSetIndexInParent[FS->N_FaceSet-2], FS->FaceSetList[3 * (FS->N_FaceSet-2)], \
02477 FS->FaceSetList[3 * (FS->N_FaceSet-2) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-2) + 2], \
02478 FS->FaceSetIndexInParent[FS->N_FaceSet-1], FS->FaceSetList[3 * (FS->N_FaceSet-1)], \
02479 FS->FaceSetList[3 * (FS->N_FaceSet-1) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-1) + 2]);
02480 } else {
02481 fprintf (Out, "First polygon:\n\t[parent ID:%d] %d %d %d\n", \
02482 FS->FaceSetIndexInParent[0], FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2]);
02483 }
02484 }
02485 SUMA_RETURNe;
02486
02487 }
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506 SUMA_Boolean SUMA_BrainVoyager_Read(char *f_name, SUMA_SurfaceObject *SO, int debug)
02507 {
02508 static char FuncName[]={"SUMA_BrainVoyager_Read"};
02509 float FileVersion, cx, cy, cz, *fbuf = NULL;
02510 int i, ii, chnk, ex, surf_type, n_neighbors, bs;
02511 char buffer[256];
02512 float fbuffer[256];
02513 FILE *fl=NULL;
02514 SUMA_Boolean LocalHead = NOPE;
02515
02516 SUMA_ENTRY;
02517
02518
02519 if (!SUMA_filexists(f_name)) {
02520 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
02521 SUMA_RETURN (NOPE);
02522 }else {
02523 if ( debug > 1) {
02524 fprintf(SUMA_STDERR,"%s: File %s exists and will be read.\n", FuncName, f_name);
02525 }
02526 }
02527
02528 fl = fopen(f_name, "r");
02529 if (!fl) {
02530 SUMA_SL_Err("Failed to open file for reading.\n");
02531 SUMA_RETURN(NOPE);
02532 }
02533
02534 SO->N_Node=0;
02535 SO->N_FaceSet=0;
02536
02537
02538 bs = 0;
02539 chnk = sizeof(float);
02540 ex = fread (&FileVersion, chnk, 1, fl);
02541 chnk = sizeof(int);
02542 ex = fread (&surf_type, chnk, 1, fl);
02543 ex = fread (&(SO->N_Node), chnk, 1, fl);
02544 ex = fread (&(SO->N_FaceSet), chnk, 1, fl);
02545 if (FileVersion < 0 || FileVersion > 500000 || SO->N_Node < 0 || SO->N_FaceSet < 0) {
02546 SUMA_LH("Byte swapping needed...");
02547 bs = 1;
02548 }
02549 if (bs) {
02550 SUMA_SWAP_THIS(&FileVersion, sizeof(float));
02551 SUMA_SWAP_THIS(&surf_type, sizeof(int));
02552 SUMA_SWAP_THIS(&(SO->N_Node), sizeof(int));
02553 SUMA_SWAP_THIS(&(SO->N_FaceSet), sizeof(int));
02554 }
02555
02556 if (LocalHead) {
02557 fprintf (SUMA_STDERR,"%s:\nSurfType is %d\nN_Node = %d, N_FaceSet = %d\n",
02558 FuncName, surf_type, SO->N_Node, SO->N_FaceSet);
02559 }
02560
02561 if (FileVersion < 0 || FileVersion > 500000) {
02562 SUMA_SL_Err("Version number < 0 || > 500000 \nSeems like bad news to me, quitting...");
02563 fclose(fl);
02564 SUMA_RETURN(NOPE);
02565 }
02566
02567
02568 if (SO->N_Node < 0 || SO->N_FaceSet < 0) {
02569 SUMA_SL_Err("Negative values for N_Node and N_FaceSet.");
02570 fclose(fl);
02571 SUMA_RETURN(NOPE);
02572 }
02573
02574 SUMA_READ_FLOAT(&cx, bs, fl, ex);
02575 SUMA_READ_FLOAT(&cy, bs, fl, ex);
02576 SUMA_READ_FLOAT(&cz, bs, fl, ex);
02577 if (LocalHead) {
02578 fprintf (SUMA_STDERR,"%s:\ncenter = [%f, %f, %f]\n(Niko adds 30 to cy ...)\n", FuncName, cx, cy, cz);
02579 }
02580 SO->NodeDim = 3;
02581 SO->FaceSetDim = 3;
02582 fbuf = (float *)SUMA_malloc(SO->N_Node*sizeof(float));
02583 SO->NodeList = (float *)SUMA_malloc(SO->NodeDim*SO->N_Node*sizeof(float));
02584 SO->FaceSetList = (int *)SUMA_malloc(SO->FaceSetDim*SO->N_FaceSet*sizeof(int));
02585 if (!fbuf || !SO->NodeList || !SO->FaceSetList) {
02586 SUMA_SL_Crit("Failed to allocate.");
02587 SUMA_RETURN(NOPE);
02588 }
02589
02590
02591 SUMA_LH("Reading coords...");
02592 ex = fread(fbuf, sizeof(float), SO->N_Node, fl);
02593 if (ex != SO->N_Node) { SUMA_SL_Warn("Failed to read all node X info"); }
02594 if (bs) SUMA_SWAP_VEC(fbuf,SO->N_Node,sizeof(float));
02595 for (i=0; i<SO->N_Node; ++i) SO->NodeList[3*i] = fbuf[i];
02596 ex = fread(fbuf, sizeof(float), SO->N_Node, fl);
02597 if (ex != SO->N_Node) { SUMA_SL_Warn("Failed to read all node Y info"); }
02598 if (bs) SUMA_SWAP_VEC(fbuf,SO->N_Node,sizeof(float));
02599 for (i=0; i<SO->N_Node; ++i) SO->NodeList[3*i+1] = fbuf[i];
02600 ex = fread(fbuf, sizeof(float), SO->N_Node, fl);
02601 if (ex != SO->N_Node) { SUMA_SL_Warn("Failed to read all node Z info"); }
02602 if (bs) SUMA_SWAP_VEC(fbuf,SO->N_Node,sizeof(float));
02603 for (i=0; i<SO->N_Node; ++i) SO->NodeList[3*i+2] = fbuf[i];
02604 SUMA_free(fbuf); fbuf = NULL;
02605 if (LocalHead) {
02606 char *sdbg = SUMA_ShowMeSome((void *)SO->NodeList, SUMA_float, SUMA_MIN_PAIR(20, SO->N_Node), 20);
02607 fprintf(SUMA_STDERR,"%s NodeList:\n%s\n", FuncName, sdbg);
02608 SUMA_free(sdbg);sdbg = NULL;
02609 }
02610
02611 fseek(fl, SO->N_Node*3*sizeof(float), SEEK_CUR);
02612
02613
02614 ex = fread(fbuffer, sizeof(float), 8, fl);
02615 if (bs) SUMA_SWAP_VEC(fbuffer,8, sizeof(float));
02616 if (LocalHead) {
02617 char *sdbg = SUMA_ShowMeSome((void *)fbuffer, SUMA_float, 8,8);
02618 fprintf(SUMA_STDERR,"%s colorstuff:\n%s\n", FuncName, sdbg);
02619 SUMA_free(sdbg);sdbg = NULL;
02620 }
02621 fseek(fl, SO->N_Node*sizeof(float), SEEK_CUR);
02622
02623
02624 for (i=0; i<SO->N_Node; ++i) {
02625 ex = fread(&n_neighbors, sizeof(int), 1, fl);
02626 if (bs) SUMA_SWAP_THIS(&n_neighbors, sizeof(int));
02627 fseek(fl, n_neighbors*sizeof(int), SEEK_CUR);
02628 }
02629
02630
02631 SUMA_LH("Reading FaceSets...");
02632 ex = fread(SO->FaceSetList, sizeof(int), SO->N_FaceSet * SO->FaceSetDim , fl);
02633 if (ex != SO->N_FaceSet * SO->FaceSetDim) {
02634 fprintf(SUMA_STDERR,"Error %s: Failed to read all faceset info.\nRead %d values, expected %d\n", FuncName, ex, SO->N_FaceSet * SO->FaceSetDim );
02635 SUMA_RETURN(NOPE);
02636 }
02637
02638 if (bs) SUMA_SWAP_VEC(SO->FaceSetList,(SO->N_FaceSet * SO->FaceSetDim),sizeof(int));
02639 if (LocalHead) {
02640 char *sdbg = SUMA_ShowMeSome((void *)SO->FaceSetList, SUMA_int, SUMA_MIN_PAIR(20, SO->N_FaceSet * SO->FaceSetDim), 20);
02641 fprintf(SUMA_STDERR,"%s FaceSetList:\n%s\n", FuncName, sdbg);
02642 SUMA_free(sdbg);sdbg = NULL;
02643 }
02644 fclose(fl); fl = NULL;
02645
02646 SO->FileType = SUMA_BRAIN_VOYAGER;
02647 SO->Name = SUMA_StripPath(f_name);
02648 SO->FileFormat = SUMA_BINARY;
02649
02650 SUMA_LH("Done.");
02651
02652 SUMA_RETURN(YUP);
02653 }
02654
02655 #ifdef SUMA_FreeSurfer_STAND_ALONE
02656
02657
02658 void usage_SUMA_FreeSurfer_Main ()
02659
02660 {
02661 printf ("\nUsage: SUMA_FreeSurfer f_name \n");
02662 printf ("\t ..... \n\n");
02663 printf ("\t To Compile:\ngcc -DSUMA_FreeSurfer_STAND_ALONE -Wall -o $1 $1.c -I./ -I//usr/X11R6/include SUMA_lib.a\n");
02664 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tFri Feb 8 16:29:06 EST 2002 \n");
02665 exit (0);
02666 }
02667
02668 int main (int argc,char *argv[])
02669 {
02670 char FuncName[100];
02671 char FS_name[200];
02672 SUMA_FreeSurfer_struct *FS;
02673
02674
02675 sprintf (FuncName,"SUMA_FreeSurfer-Main-");
02676
02677
02678 SUMAg_CF = SUMA_Create_CommonFields ();
02679 if (SUMAg_CF == NULL) {
02680 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02681 exit(1);
02682 }
02683
02684
02685 FS = (SUMA_FreeSurfer_struct *) SUMA_malloc(sizeof(SUMA_FreeSurfer_struct));
02686 if (FS == NULL) {
02687 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for FS\n", FuncName);
02688 exit(1);
02689 }
02690
02691 if (argc < 2)
02692 {
02693 usage_SUMA_FreeSurfer_Main ();
02694 exit (1);
02695 }
02696
02697 sprintf(FS_name, "%s", argv[1]);
02698
02699 if (!SUMA_isExtension(FS_name, ".asc")) {
02700 if (!SUMA_FreeSurfer_ReadBin_eng (FS_name, FS, 0)) {
02701 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_FreeSurferBin_Read\n", FuncName);
02702 exit(1);
02703 }
02704 }else {
02705 if (!SUMA_FreeSurfer_Read_eng (FS_name, FS, 0)) {
02706 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_FreeSurfer_Read\n", FuncName);
02707 exit(1);
02708 }
02709 }
02710
02711
02712 SUMA_Show_FreeSurfer (FS, NULL);
02713 fprintf(stdout, "freeing ..\n");
02714 if (!SUMA_Free_FreeSurfer (FS)) {
02715 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_FreeSurfer.\n", FuncName);
02716 exit(1);
02717 }
02718
02719 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02720
02721 return (0);
02722 }
02723 #endif
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746 typedef struct Vertex {
02747 float x,y,z;
02748 } Vertex;
02749
02750 typedef struct Face {
02751 unsigned char intensity;
02752 unsigned char nverts;
02753 int *verts;
02754 } Face;
02755
02756
02757
02758 PlyProperty vert_props[] = {
02759 {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0},
02760 {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0},
02761 {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0},
02762 };
02763
02764 PlyProperty face_props[] = {
02765 {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(Face,intensity), 0, 0, 0, 0},
02766 {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
02767 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)},
02768 };
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795 SUMA_Boolean SUMA_Ply_Read (char * f_name, SUMA_SurfaceObject *SO)
02796 {
02797 static char FuncName[]={"SUMA_Ply_Read"};
02798 int i,j,k, j3, ji;
02799 PlyFile *ply = NULL;
02800 int nelems;
02801 char **elist = NULL;
02802 int file_type;
02803 float version;
02804 int nprops;
02805 int num_elems;
02806 PlyProperty **plist = NULL;
02807 Vertex **vlist = NULL;
02808 Face **flist = NULL;
02809 char *elem_name;
02810 int num_comments;
02811 char **comments = NULL;
02812 int num_obj_info;
02813 char **obj_info = NULL;
02814 SUMA_Boolean LocalHead = NOPE;
02815
02816 SUMA_ENTRY;
02817
02818
02819 ply = ply_open_for_reading(f_name, &nelems, &elist, &file_type, &version);
02820 if (!ply) {
02821 fprintf (SUMA_STDERR, "Error %s: Failed to find/read %s.\n", FuncName, f_name);
02822 SUMA_RETURN (NOPE);
02823 }
02824
02825
02826 if (LocalHead) fprintf (SUMA_STDERR, "%s: version %f\n", FuncName, version);
02827 if (LocalHead) fprintf (SUMA_STDERR, "%s: type %d\n", FuncName, file_type);
02828
02829
02830
02831
02832 for (i = 0; i < nelems; i++) {
02833
02834
02835 elem_name = elist[i];
02836 plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);
02837
02838
02839 if (LocalHead) fprintf (SUMA_STDERR, "%s: element %s %d\n", FuncName, elem_name, num_elems);
02840
02841
02842 if (equal_strings ("vertex", elem_name)) {
02843
02844
02845 #ifdef USE_PLY_VERTEX
02846 vlist = (Vertex **) SUMA_malloc (sizeof (Vertex *) * num_elems);
02847 #endif
02848
02849 SO->NodeList = (float *) SUMA_calloc (3*num_elems, sizeof(float));
02850 if (!SO->NodeList) {
02851 fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SO->NodeList.\n", FuncName);
02852 SUMA_RETURN(NOPE);
02853 }
02854
02855
02856
02857 ply_get_property (ply, elem_name, &vert_props[0]);
02858 ply_get_property (ply, elem_name, &vert_props[1]);
02859 ply_get_property (ply, elem_name, &vert_props[2]);
02860
02861 SO->NodeDim = 3;
02862 SO->N_Node = num_elems;
02863
02864 for (j = 0; j < num_elems; j++) {
02865
02866
02867 #ifdef USE_PLY_VERTEX
02868
02869
02870
02871 if (LocalHead) fprintf (SUMA_STDERR, "%s vertex: %g %g %g\n", FuncName, vlist[j]->x, vlist[j]->y, vlist[j]->z);
02872
02873 j3 = SO->NodeDim*j;
02874 SO->NodeList[j3] = vlist[j]->x;
02875 SO->NodeList[j3+1] = vlist[j]->y;
02876 SO->NodeList[j3+2] = vlist[j]->z;
02877
02878 #else
02879 j3 = SO->NodeDim*j;
02880 ply_get_element (ply, (void *) &(SO->NodeList[j3]));
02881
02882 if (LocalHead) fprintf (SUMA_STDERR, "%s vertex: %g %g %g\n", FuncName,
02883 SO->NodeList[j3], SO->NodeList[j3+1], SO->NodeList[j3+2]);
02884 #endif
02885
02886 }
02887 }
02888
02889
02890 if (equal_strings ("face", elem_name)) {
02891
02892
02893 flist = (Face **) SUMA_malloc (sizeof (Face *) * num_elems);
02894
02895
02896
02897 ply_get_property (ply, elem_name, &face_props[0]);
02898 ply_get_property (ply, elem_name, &face_props[1]);
02899
02900
02901 for (j = 0; j < num_elems; j++) {
02902
02903
02904 flist[j] = (Face *) SUMA_malloc (sizeof (Face));
02905 ply_get_element (ply, (void *) flist[j]);
02906
02907
02908 if (LocalHead) {
02909 fprintf (SUMA_STDERR,"%s face: %d, list = ", FuncName, flist[j]->intensity);
02910 for (k = 0; k < flist[j]->nverts; k++)
02911 fprintf (SUMA_STDERR,"%d ", flist[j]->verts[k]);
02912 fprintf (SUMA_STDERR,"\n");
02913 }
02914
02915 }
02916
02917 SO->FaceSetDim = flist[0]->nverts;
02918 SO->N_FaceSet = num_elems;
02919 SO->FaceSetList = (int *) SUMA_calloc (SO->FaceSetDim * num_elems, sizeof(int));
02920 if (!SO->FaceSetList) {
02921 fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SO->NodeList.\n", FuncName);
02922 if (SO->NodeList) SUMA_free(SO->NodeList);
02923 SUMA_RETURN(NOPE);
02924 }
02925
02926 for (j = 0; j < num_elems; j++) {
02927 if (flist[j]->nverts != SO->FaceSetDim) {
02928 fprintf (SUMA_STDERR, "Error %s: All FaceSets must have the same dimension for SUMA.\n", FuncName);
02929 if (SO->NodeList) SUMA_free(SO->NodeList);
02930 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
02931 SO->NodeList = NULL;
02932 SO->FaceSetList = NULL;
02933 SUMA_RETURN(NOPE);
02934 }
02935 ji = SO->FaceSetDim * j;
02936 for (k = 0; k < flist[j]->nverts; k++)
02937 SO->FaceSetList[ji+k] = flist[j]->verts[k];
02938 }
02939 }
02940
02941
02942 SO->FileType = SUMA_PLY;
02943 if (file_type == PLY_ASCII) SO->FileFormat = SUMA_ASCII;
02944 else if (file_type == PLY_BINARY_BE) SO->FileFormat = SUMA_BINARY_BE;
02945 else if (file_type == PLY_BINARY_LE) SO->FileFormat = SUMA_BINARY_LE;
02946 else {
02947 fprintf (SUMA_STDERR, "Error %s: PLY_TYPE %d not recognized.\n", FuncName, file_type);
02948 }
02949
02950 SO->Name = SUMA_StripPath(f_name);
02951
02952
02953 if (LocalHead) {
02954 for (j = 0; j < nprops; j++)
02955 fprintf (SUMA_STDERR, "%s property %s\n", FuncName, plist[j]->name);
02956 }
02957 }
02958
02959
02960 comments = ply_get_comments (ply, &num_comments);
02961 if (LocalHead) {
02962 for (i = 0; i < num_comments; i++)
02963 fprintf (SUMA_STDERR, "%s comment = '%s'\n", FuncName, comments[i]);
02964 }
02965
02966
02967 obj_info = ply_get_obj_info (ply, &num_obj_info);
02968 if (LocalHead) {
02969 for (i = 0; i < num_obj_info; i++)
02970 fprintf (SUMA_STDERR, "%s obj_info = '%s'\n", FuncName, obj_info[i]);
02971 }
02972
02973
02974 for (j = 0; j < SO->N_FaceSet; j++) {
02975 SUMA_free(flist[j]);
02976 }
02977 SUMA_free(flist); flist = NULL;
02978
02979 #ifdef USE_PLY_VERTEX
02980 for (j = 0; j < SO->N_Node; j++) {
02981 SUMA_free(vlist[j]);
02982 }
02983 SUMA_free(vlist); vlist = NULL;
02984 #endif
02985
02986 ply_close (ply);
02987
02988
02989 for (j = 0; j < nprops; j++) if (plist[j]) SUMA_free (plist[j]);
02990 if (plist) SUMA_free(plist);
02991
02992
02993 for (i = 0; i < num_comments; i++) if (comments[i]) SUMA_free (comments[i]);
02994 if (comments) SUMA_free (comments);
02995
02996
02997 for (i = 0; i < nelems; i++) if (elist[i]) SUMA_free (elist[i]);
02998 if (elist) SUMA_free (elist);
02999
03000
03001 for (i = 0; i < num_obj_info; i++) if (obj_info[i]) SUMA_free (obj_info[i]);
03002 if (obj_info) SUMA_free (obj_info);
03003
03004 SUMA_RETURN(YUP);
03005 }
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019 SUMA_Boolean SUMA_Ply_Write (char * f_name_in, SUMA_SurfaceObject *SO)
03020 {
03021 static char FuncName[]={"SUMA_Ply_Write"};
03022 int i,j;
03023 PlyFile *ply = NULL;
03024 int nelems;
03025 int file_type;
03026 float version;
03027 int nverts ;
03028 int nfaces ;
03029 char *f_name, *f_name2, *elem_names[] = { "vertex", "face" };
03030 int n_elem_names = 2;
03031 Vertex **verts = NULL;
03032 Face *faces = NULL;
03033 SUMA_Boolean LocalHead = NOPE;
03034
03035 SUMA_ENTRY;
03036
03037 if (!f_name_in) {
03038 fprintf (SUMA_STDERR, "Error %s: NULL filename\n", FuncName);
03039 SUMA_RETURN (NOPE);
03040 }
03041
03042 f_name = SUMA_Extension(f_name_in,".ply" , YUP);
03043 f_name2 = SUMA_append_string(f_name,".ply");
03044 if (SUMA_filexists (f_name2)) {
03045 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n", FuncName, f_name2);
03046 SUMA_free(f_name2);f_name2 = NULL;
03047 SUMA_free(f_name);f_name = NULL;
03048 SUMA_RETURN (NOPE);
03049 }
03050 SUMA_free(f_name2); f_name2 = NULL;
03051
03052 nverts = SO->N_Node;
03053 nfaces = SO->N_FaceSet;
03054
03055
03056 if (SO->NodeDim != 3) {
03057 fprintf (SUMA_STDERR, "Error %s: SO->NodeDim != 3.\n", FuncName);
03058 SUMA_RETURN (NOPE);
03059 }
03060
03061
03062 verts = (Vertex **) SUMA_malloc (nverts*sizeof(Vertex *));
03063 faces = (Face *) SUMA_malloc (nfaces*sizeof(Face));
03064 if (!verts || !faces) {
03065 fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
03066 if (verts) SUMA_free(verts);
03067 if (faces) SUMA_free(faces);
03068 SUMA_RETURN (NOPE);
03069 }
03070
03071 for (i = 0; i < nfaces; i++) {
03072 faces[i].intensity = '\001';
03073 faces[i].nverts = SO->FaceSetDim;
03074 faces[i].verts = &(SO->FaceSetList[SO->FaceSetDim*i]);
03075 }
03076
03077
03078
03079
03080
03081 switch (SO->FileFormat) {
03082 case SUMA_BINARY_BE:
03083 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_BINARY_BE, &version);
03084 break;
03085
03086 case SUMA_BINARY_LE:
03087 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_BINARY_LE, &version);
03088 break;
03089
03090 case SUMA_ASCII:
03091 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_ASCII, &version);
03092 break;
03093
03094 case SUMA_BINARY:
03095 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_BINARY_BE, &version);
03096 break;
03097
03098 case SUMA_FF_NOT_SPECIFIED:
03099 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_ASCII, &version);
03100 break;
03101
03102 default:
03103 fprintf (SUMA_STDERR, "Error %s: %d Unrecognized file format.\n", FuncName, SO->FileFormat);
03104 SUMA_RETURN (NOPE);
03105 break;
03106 }
03107
03108 if (!ply) {
03109 fprintf (SUMA_STDERR,"Error %s: Failed to create %s.ply\n", FuncName, f_name);
03110 if (verts) SUMA_free(verts);
03111 if (faces) SUMA_free(faces);
03112 SUMA_RETURN (NOPE);
03113 }
03114
03115
03116 ply_element_count (ply, "vertex", nverts);
03117 ply_describe_property (ply, "vertex", &vert_props[0]);
03118 ply_describe_property (ply, "vertex", &vert_props[1]);
03119 ply_describe_property (ply, "vertex", &vert_props[2]);
03120
03121 ply_element_count (ply, "face", nfaces);
03122 ply_describe_property (ply, "face", &face_props[0]);
03123 ply_describe_property (ply, "face", &face_props[1]);
03124
03125
03126 ply_put_comment (ply, "author: Greg Turk");
03127 ply_put_obj_info (ply, "random information");
03128
03129
03130
03131 ply_header_complete (ply);
03132
03133
03134 ply_put_element_setup (ply, "vertex");
03135 for (i = 0; i < nverts; i++)
03136 ply_put_element (ply, (void *) &(SO->NodeList[SO->NodeDim*i]));
03137
03138
03139 ply_put_element_setup (ply, "face");
03140 for (i = 0; i < nfaces; i++)
03141 ply_put_element (ply, (void *) &faces[i]);
03142
03143
03144 ply_close (ply);
03145
03146
03147 if (verts) SUMA_free(verts);
03148 if (faces) SUMA_free(faces);
03149 if (f_name) SUMA_free(f_name);
03150 SUMA_RETURN (YUP);
03151 }
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166 SUMA_Boolean SUMA_FS_Write (char *fileNm, SUMA_SurfaceObject *SO, char *firstLine)
03167 {
03168 static char FuncName[]={"SUMA_FS_Write"};
03169 int i, j;
03170 FILE *outFile = NULL;
03171
03172 SUMA_ENTRY;
03173
03174 if (SUMA_filexists(fileNm)) {
03175 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, fileNm);
03176 SUMA_RETURN (NOPE);
03177 }
03178
03179 if (SO->NodeDim != 3 || SO->FaceSetDim != 3) {
03180 fprintf (SUMA_STDERR, "Error %s: Must have NodeDim and FaceSetDim = 3.\n",FuncName);
03181 SUMA_RETURN (NOPE);
03182 }
03183
03184 outFile = fopen(fileNm, "w");
03185 if (!outFile) {
03186 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, fileNm);
03187 SUMA_RETURN (NOPE);
03188 }
03189
03190 fprintf (outFile,"#%s\n", firstLine);
03191 fprintf (outFile, "%d %d\n", SO->N_Node, SO->N_FaceSet);
03192
03193 j=0;
03194 for (i=0; i<SO->N_Node; ++i) {
03195 j=SO->NodeDim * i;
03196 fprintf (outFile, "%f %f %f 0\n", SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
03197 }
03198
03199 j=0;
03200 for (i=0; i<SO->N_FaceSet; ++i) {
03201 j = SO->FaceSetDim * i;
03202 fprintf (outFile, "%d %d %d 0\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
03203 }
03204
03205
03206 fclose(outFile);
03207
03208 SUMA_RETURN (YUP);
03209
03210 }
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227 SUMA_Boolean SUMA_VEC_Write (SUMA_SFname *Fname, SUMA_SurfaceObject *SO)
03228 {
03229
03230 static char FuncName[]={"SUMA_VEC_Write"};
03231 int i, j;
03232 FILE *outFile = NULL;
03233
03234 SUMA_ENTRY;
03235
03236 if (strlen(Fname->name_coord)) {
03237 if (SUMA_filexists(Fname->name_coord)) {
03238 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_coord);
03239 SUMA_RETURN (NOPE);
03240 }
03241 }
03242 if (strlen(Fname->name_topo)) {
03243 if (SUMA_filexists(Fname->name_topo)) {
03244 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_topo);
03245 SUMA_RETURN (NOPE);
03246 }
03247 }
03248 if (SO->NodeDim != 3 || SO->FaceSetDim != 3) {
03249 fprintf (SUMA_STDERR, "Error %s: Must have NodeDim and FaceSetDim = 3.\n",FuncName);
03250 SUMA_RETURN (NOPE);
03251 }
03252
03253 if (strlen(Fname->name_coord)) {
03254 outFile = fopen(Fname->name_coord, "w");
03255 if (!outFile) {
03256 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_coord);
03257 SUMA_RETURN (NOPE);
03258 }
03259
03260 j=0;
03261 for (i=0; i<SO->N_Node; ++i) {
03262 j=SO->NodeDim * i;
03263 fprintf (outFile, "%f %f %f \n", SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
03264 }
03265
03266 fclose (outFile);
03267 }
03268
03269 if (strlen(Fname->name_topo)) {
03270 outFile = fopen(Fname->name_topo, "w");
03271 if (!outFile) {
03272 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_topo);
03273 SUMA_RETURN (NOPE);
03274 }
03275 j=0;
03276 for (i=0; i<SO->N_FaceSet; ++i) {
03277 j = SO->FaceSetDim * i;
03278 fprintf (outFile, "%d %d %d\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
03279 }
03280
03281 fclose (outFile);
03282 }
03283
03284 SUMA_RETURN (YUP);
03285
03286 }
03287
03288
03289
03290
03291
03292 SUMA_Boolean SUMA_VEC_Read(SUMA_SFname *Fname, SUMA_SurfaceObject *SO)
03293 {
03294 static char FuncName[]={"SUMA_VEC_Read"};
03295 MRI_IMAGE *im = NULL;
03296 float *far=NULL;
03297 int icnt;
03298 SUMA_Boolean LocalHead = NOPE;
03299
03300 SUMA_ENTRY;
03301
03302 if (!SO || !Fname) {
03303 SUMA_SL_Err("NULL input");
03304 SUMA_RETURN(NOPE);
03305 }
03306 if (SO->NodeList || SO->FaceSetList) {
03307 SUMA_SL_Err("Non NULL SO->NodeList || SO->FaceSetList");
03308 SUMA_RETURN(NOPE);
03309 }
03310
03311 im = mri_read_1D (Fname->name_coord);
03312 if (!im) {
03313 SUMA_SLP_Err("Failed to read 1D file");
03314 SUMA_RETURN(NOPE);
03315 }
03316 far = MRI_FLOAT_PTR(im);
03317 SO->N_Node = im->nx;
03318 SO->NodeDim = im->ny;
03319 if (!SO->N_Node) {
03320 SUMA_SL_Err("Empty file");
03321 SUMA_RETURN(NOPE);
03322 }
03323 if (SO->NodeDim != 3 ) {
03324 SUMA_SL_Err("File must have\n"
03325 "3 columns.");
03326 mri_free(im); im = NULL;
03327 SUMA_RETURN(NOPE);
03328 }
03329
03330 SO->NodeList = (float *)SUMA_calloc (SO->N_Node*SO->NodeDim, sizeof(float));
03331 if (!SO->NodeList) {
03332 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for NodeList.\n", FuncName);
03333 if (SO->NodeList) SUMA_free(SO->NodeList);
03334 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
03335 SUMA_RETURN (NOPE);
03336 }
03337
03338 for (icnt=0; icnt < SO->N_Node; ++icnt) {
03339 SO->NodeList[3*icnt] = far[icnt];
03340 SO->NodeList[3*icnt+1] = far[icnt+SO->N_Node];
03341 SO->NodeList[3*icnt+2] = far[icnt+2*SO->N_Node];
03342 }
03343 if (LocalHead) {
03344 fprintf (SUMA_STDERR,"%s: SO->NodeList\n Node 0: %f, %f, %f \n Node %d: %f, %f, %f \n",
03345 FuncName,
03346 SO->NodeList[0], SO->NodeList[1], SO->NodeList[2], SO->N_Node -1,
03347 SO->NodeList[3*(SO->N_Node-1)], SO->NodeList[3*(SO->N_Node-1)+1], SO->NodeList[3*(SO->N_Node-1)+2]);
03348 }
03349 mri_free(im); im = NULL;
03350
03351 im = mri_read_1D (Fname->name_topo);
03352 if (!im) {
03353 SUMA_SL_Err("Failed to read 1D file");
03354 SUMA_RETURN(NOPE);
03355 }
03356 far = MRI_FLOAT_PTR(im);
03357 SO->N_FaceSet = im->nx;
03358 SO->FaceSetDim = im->ny;
03359 if (!SO->N_FaceSet) {
03360 SUMA_SL_Err("Empty file");
03361 SUMA_RETURN(NOPE);
03362 }
03363 if (SO->FaceSetDim != 3 ) {
03364 SUMA_SL_Err("File must have\n"
03365 "3 columns.");
03366 mri_free(im); im = NULL;
03367 SUMA_RETURN(NOPE);
03368 }
03369
03370 SO->FaceSetList = (int *)SUMA_calloc (SO->N_FaceSet*SO->FaceSetDim, sizeof(int));
03371 if (!SO->FaceSetList) {
03372 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for FaceSetList.\n", FuncName);
03373 if (SO->NodeList) SUMA_free(SO->NodeList);
03374 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
03375 SUMA_RETURN (NOPE);
03376 }
03377
03378 for (icnt=0; icnt < SO->N_FaceSet; ++icnt) {
03379 SO->FaceSetList[3*icnt] = (int)far[icnt];
03380 SO->FaceSetList[3*icnt+1] = (int)far[icnt+SO->N_FaceSet];
03381 SO->FaceSetList[3*icnt+2] = (int)far[icnt+2*SO->N_FaceSet];
03382 }
03383
03384 if (LocalHead) {
03385 fprintf (SUMA_STDERR,"%s: SO->FaceSetList\n Node 0: %d, %d, %d \n Node %d: %d, %d, %d \n",
03386 FuncName,
03387 SO->FaceSetList[0], SO->FaceSetList[1], SO->FaceSetList[2], SO->N_FaceSet -1,
03388 SO->FaceSetList[3*(SO->N_FaceSet-1)], SO->FaceSetList[3*(SO->N_FaceSet-1)+1], SO->FaceSetList[3*(SO->N_FaceSet-1)+2]);
03389 }
03390 mri_free(im); im = NULL;
03391
03392 SUMA_RETURN(YUP);
03393 }
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406 #ifdef SUMA_Ply_Read_STAND_ALONE
03407 void usage_SUMA_Ply_Read_Main ()
03408
03409 {
03410 printf ("\nUsage: SUMA_Ply_Read -s f_name \n");
03411 printf ("\t reads in a .ply file and writes it out to copy_f_name.ply\n");
03412 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \t Wed Jan 8 13:44:29 EST 2003 \n");
03413 exit (0);
03414 }
03415
03416 int main (int argc,char *argv[])
03417 {
03418 static char FuncName[]={"SUMA_Ply_Read_Main"};
03419 int kar;
03420 char *f_name=NULL, out_f_name[200];
03421 SUMA_SurfaceObject *SO = NULL;
03422 SUMA_Boolean brk;
03423
03424
03425 SUMAg_CF = SUMA_Create_CommonFields ();
03426 if (SUMAg_CF == NULL) {
03427 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
03428 exit(1);
03429 }
03430
03431 if (argc < 3)
03432 {
03433 usage_SUMA_Ply_Read_Main ();
03434 exit (1);
03435 }
03436
03437 kar = 1;
03438 brk = NOPE;
03439 while (kar < argc) {
03440
03441 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
03442 usage_SUMA_Ply_Read_Main();
03443 exit (1);
03444 }
03445
03446 if (!brk && (strcmp(argv[kar], "-s") == 0)) {
03447 kar ++;
03448 if (kar >= argc) {
03449 fprintf (SUMA_STDERR, "need argument after -s ");
03450 exit (1);
03451 }
03452 f_name = argv[kar];
03453
03454
03455 brk = YUP;
03456 }
03457
03458 if (!brk) {
03459 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
03460 exit (1);
03461 } else {
03462 brk = NOPE;
03463 kar ++;
03464 }
03465 }
03466
03467 if (!f_name) {
03468 fprintf (SUMA_STDERR,"Error %s: Missing filename.\n", FuncName);
03469 exit(1);
03470 }
03471
03472 SO = SUMA_Alloc_SurfObject_Struct(1);
03473 if (!SUMA_Ply_Read (f_name, SO)) {
03474 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Read.\n", FuncName);
03475 exit (1);
03476 }
03477
03478 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
03479 sprintf (out_f_name , "copy_%s", SO->Label);
03480 fprintf (SUMA_STDERR,"%s: Success apparent. Now writing SO to %s\n", FuncName, out_f_name);
03481 if (!SUMA_Ply_Write (out_f_name, SO)) {
03482 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Write.\n", FuncName);
03483 exit (1);
03484 }
03485
03486 SUMA_Free_Surface_Object (SO);
03487
03488 return (0);
03489 }
03490 #endif
03491
03492 #ifdef SUMA_ConvertSurface_STAND_ALONE
03493 void usage_SUMA_ConvertSurface (SUMA_GENERIC_ARGV_PARSE *ps)
03494
03495 {
03496 static char FuncName[]={"usage_SUMA_ConvertSurface"};
03497 char * s = NULL, *sio=NULL;
03498
03499 s = SUMA_help_basics();
03500 sio = SUMA_help_IO_Args(ps);
03501
03502 printf ("\nUsage: ConvertSurface <-i_TYPE inSurf> <-o_TYPE outSurf> \n"
03503 " [<-sv SurfaceVolume [VolParam for sf surfaces]>] [-tlrc] [-MNI_rai/-MNI_lpi]\n"
03504 " reads in a surface and writes it out in another format.\n"
03505 " Note: This is a not a general utility conversion program. \n"
03506 " Only fields pertinent to SUMA are preserved.\n"
03507 "%s"
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542 " -orient_out STR: Output coordinates in STR coordinate system. \n"
03543 " STR is a three character string following AFNI's \n"
03544 " naming convention. The program assumes that the native \n"
03545 " orientation of the surface is RAI, unless you use the \n"
03546 " -MNI_lpi option. The coordinate transformation is carried \n"
03547 " out last, just before writing the surface to disk.\n"
03548 " -make_consistent: Check the consistency of the surface's mesh (triangle\n"
03549 " winding). This option will write out a new surface even \n"
03550 " if the mesh was consistent.\n"
03551 " See SurfQual -help for mesh checks.\n"
03552 " -acpc: Apply acpc transform (which must be in acpc version of \n"
03553 " SurfaceVolume) to the surface vertex coordinates. \n"
03554 " This option must be used with the -sv option.\n"
03555 " -tlrc: Apply Talairach transform (which must be a talairach version of \n"
03556 " SurfaceVolume) to the surface vertex coordinates. \n"
03557 " This option must be used with the -sv option.\n"
03558 " -MNI_rai/-MNI_lpi: Apply Andreas Meyer Lindenberg's transform to turn \n"
03559 " AFNI tlrc coordinates (RAI) into MNI coord space \n"
03560 " in RAI (with -MNI_rai) or LPI (with -MNI_lpi)).\n"
03561 " NOTE: -MNI_lpi option has not been tested yet (I have no data\n"
03562 " to test it on. Verify alignment with AFNI and please report\n"
03563 " any bugs.\n"
03564 " This option can be used without the -tlrc option.\n"
03565 " But that assumes that surface nodes are already in\n"
03566 " AFNI RAI tlrc coordinates .\n"
03567 " NOTE: The vertex coordinates coordinates of the input surfaces are only\n"
03568 " transformed if -sv option is used. If you do transform surfaces, \n"
03569 " take care not to load them into SUMA with another -sv option.\n"
03570 "\n"
03571 " Options for applying arbitrary affine transform:\n"
03572 " [xyz_new] = [Mr] * [xyz_old - cen] + D + cen\n"
03573 " -xmat_1D mat: Apply transformation specified in 1D file mat.1D.\n"
03574 " to the surface's coordinates.\n"
03575 " [mat] = [Mr][D] is of the form:\n"
03576 " r11 r12 r13 D1\n"
03577 " r21 r22 r23 D2\n"
03578 " r31 r32 r33 D3\n"
03579 " -xcenter x y z: Use vector cen = [x y z]' for rotation center.\n"
03580 " Default is cen = [0 0 0]'\n"
03581 "%s\n"
03582 , sio, s); SUMA_free(sio); sio = NULL; SUMA_free(s); s = NULL;
03583 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
03584 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \t Wed Jan 8 13:44:29 EST 2003 \n");
03585 exit (0);
03586 }
03587
03588 int main (int argc,char *argv[])
03589 {
03590 static char FuncName[]={"ConvertSurface"};
03591 int kar, volexists, i;
03592 float xcen[3], M[3][4];
03593 char *if_name = NULL, *of_name = NULL, *if_name2 = NULL,
03594 *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL,
03595 *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL,
03596 *acpc_name=NULL, *xmat_name = NULL, *ifpar_name = NULL, *ifpar_name2 = NULL;
03597 SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, iparType = SUMA_FT_NOT_SPECIFIED,
03598 oType = SUMA_FT_NOT_SPECIFIED;
03599 SUMA_SO_File_Format iForm = SUMA_FF_NOT_SPECIFIED, iparForm = SUMA_FF_NOT_SPECIFIED;
03600 SUMA_SurfaceObject *SO = NULL, *SOpar = NULL, *SOsurf = NULL;
03601 SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL;
03602 SUMA_SFname *SF_name = NULL;
03603 void *SO_name = NULL;
03604 char orsurf[3], orcode[3];
03605 THD_warp *warp=NULL ;
03606 THD_3dim_dataset *aset=NULL;
03607 SUMA_Boolean brk, Do_tlrc, Do_mni_RAI, Do_mni_LPI, Do_acpc, Docen, Doxmat, Do_wind, onemore;
03608 SUMA_GENERIC_ARGV_PARSE *ps=NULL;
03609 SUMA_Boolean exists;
03610 SUMA_Boolean LocalHead = NOPE;
03611
03612 SUMA_mainENTRY;
03613 SUMA_STANDALONE_INIT;
03614
03615
03616 SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
03617 ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;-ipar;");
03618
03619 if (argc < 4)
03620 {
03621 usage_SUMA_ConvertSurface (ps);
03622 exit (1);
03623 }
03624
03625
03626 kar = 1;
03627 xmat_name = NULL;
03628 xcen[0] = 0.0; xcen[1] = 0.0; xcen[2] = 0.0;
03629 brk = NOPE;
03630 orcode[0] = '\0';
03631 sprintf(orsurf,"RAI");
03632 Docen = NOPE;
03633 Doxmat = NOPE;
03634 Do_tlrc = NOPE;
03635 Do_mni_RAI = NOPE;
03636 Do_mni_LPI = NOPE;
03637 Do_acpc = NOPE;
03638 Do_wind = NOPE;
03639 onemore = NOPE;
03640 while (kar < argc) {
03641
03642 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
03643 usage_SUMA_ConvertSurface(ps);
03644 exit (0);
03645 }
03646
03647 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
03648
03649 SUMA_TO_LOWER(argv[kar]);
03650
03651 #if 0
03652 if (!brk && (strcmp(argv[kar], "-i_bv") == 0)) {
03653 kar ++;
03654 if (kar >= argc) {
03655 fprintf (SUMA_STDERR, "need argument after -i_bv\n ");
03656 exit (1);
03657 }
03658 if_name = argv[kar];
03659 iType = SUMA_BRAIN_VOYAGER;
03660 iForm = SUMA_BINARY;
03661 brk = YUP;
03662 }
03663
03664 if (!brk && (strcmp(argv[kar], "-i_fs") == 0)) {
03665 kar ++;
03666 if (kar >= argc) {
03667 fprintf (SUMA_STDERR, "need argument after -i_fs\n ");
03668 exit (1);
03669 }
03670 if_name = argv[kar];
03671 iType = SUMA_FREE_SURFER;
03672 if (SUMA_isExtension(if_name, ".asc"))
03673 iparForm = SUMA_ASCII;
03674 else
03675 iparForm = SUMA_BINARY_BE;
03676 brk = YUP;
03677 }
03678
03679 if (!brk && (strcmp(argv[kar], "-i_sf") == 0)) {
03680 kar ++;
03681 if (kar+1 >= argc) {
03682 fprintf (SUMA_STDERR, "need 2 arguments after -i_sf\n");
03683 exit (1);
03684 }
03685 if_name = argv[kar]; kar ++;
03686 if_name2 = argv[kar];
03687 iType = SUMA_SUREFIT;
03688 iForm = SUMA_ASCII;
03689 brk = YUP;
03690 }
03691
03692 if (!brk && ( (strcmp(argv[kar], "-i_vec") == 0) || (strcmp(argv[kar], "-i_1d") == 0) ) ) {
03693 kar ++;
03694 if (kar+1 >= argc) {
03695 fprintf (SUMA_STDERR, "need 2 argument after -i_vec (or -i_1D)\n");
03696 exit (1);
03697 }
03698 if_name = argv[kar]; kar ++;
03699 if_name2 = argv[kar];
03700 iType = SUMA_VEC;
03701 iForm = SUMA_ASCII;
03702 brk = YUP;
03703 }
03704
03705 if (!brk && (strcmp(argv[kar], "-i_ply") == 0)) {
03706 kar ++;
03707 if (kar >= argc) {
03708 fprintf (SUMA_STDERR, "need argument after -i_ply \n");
03709 exit (1);
03710 }
03711 if_name = argv[kar];
03712 iType = SUMA_PLY;
03713 iForm = SUMA_FF_NOT_SPECIFIED;
03714 brk = YUP;
03715 }
03716
03717 if (!brk && (strcmp(argv[kar], "-ipar_bv") == 0)) {
03718 kar ++;
03719 if (kar >= argc) {
03720 fprintf (SUMA_STDERR, "need argument after -ipar_bv \n");
03721 exit (1);
03722 }
03723 ifpar_name = argv[kar];
03724 iparType = SUMA_BRAIN_VOYAGER;
03725 iparForm = SUMA_BINARY;
03726 brk = YUP;
03727 }
03728
03729 if (!brk && (strcmp(argv[kar], "-ipar_fs") == 0)) {
03730 kar ++;
03731 if (kar >= argc) {
03732 fprintf (SUMA_STDERR, "need argument after -ipar_fs \n");
03733 exit (1);
03734 }
03735 ifpar_name = argv[kar];
03736 iparType = SUMA_FREE_SURFER;
03737 if (SUMA_isExtension(ifpar_name, ".asc"))
03738 iparForm = SUMA_ASCII;
03739 else
03740 iparForm = SUMA_BINARY_BE;
03741 brk = YUP;
03742 }
03743
03744 if (!brk && (strcmp(argv[kar], "-ipar_sf") == 0)) {
03745 kar ++;
03746 if (kar+1 >= argc) {
03747 fprintf (SUMA_STDERR, "need 2 arguments after -ipar_sf\n");
03748 exit (1);
03749 }
03750 ifpar_name = argv[kar]; kar ++;
03751 ifpar_name2 = argv[kar];
03752 iparType = SUMA_SUREFIT;
03753 iparForm = SUMA_ASCII;
03754 brk = YUP;
03755 }
03756
03757 if (!brk && ( (strcmp(argv[kar], "-ipar_vec") == 0) || (strcmp(argv[kar], "-ipar_1d") == 0) ) ) {
03758 kar ++;
03759 if (kar+1 >= argc) {
03760 fprintf (SUMA_STDERR, "need 2 argument after -ipar_vec (or -ipar_1D)\n");
03761 exit (1);
03762 }
03763 ifpar_name = argv[kar]; kar ++;
03764 ifpar_name2 = argv[kar];
03765 iparType = SUMA_VEC;
03766 iparForm = SUMA_ASCII;
03767 brk = YUP;
03768 }
03769
03770 if (!brk && (strcmp(argv[kar], "-ipar_ply") == 0)) {
03771 kar ++;
03772 if (kar >= argc) {
03773 fprintf (SUMA_STDERR, "need argument after -ipar_ply \n");
03774 exit (1);
03775 }
03776 ifpar_name = argv[kar];
03777 iparType = SUMA_PLY;
03778 iparForm = SUMA_FF_NOT_SPECIFIED;
03779 brk = YUP;
03780 }
03781
03782 if (!brk && (strcmp(argv[kar], "-sv") == 0)) {
03783 if (iType == SUMA_FT_NOT_SPECIFIED) {
03784 fprintf (SUMA_STDERR, " -sv option must be preceeded by -i_TYPE option.\n");
03785 exit(1);
03786 }
03787 kar ++;
03788 if (iType == SUMA_SUREFIT) {
03789 if (kar+1 >= argc) {
03790 fprintf (SUMA_STDERR, "need 2 argument after -sv (SurfaceVolume and VolumeParent)\n");
03791 exit (1);
03792 }
03793 sv_name = argv[kar]; kar ++;
03794 vp_name = argv[kar];
03795 } else {
03796 if (kar >= argc) {
03797 fprintf (SUMA_STDERR, "need argument after -sv \n");
03798 exit (1);
03799 }
03800 sv_name = argv[kar];
03801 }
03802 brk = YUP;
03803 }
03804
03805 if (!brk && (strcmp(argv[kar], "-o_fs") == 0)) {
03806 kar ++;
03807 if (kar >= argc) {
03808 fprintf (SUMA_STDERR, "need argument after -o_fs \n");
03809 exit (1);
03810 }
03811 of_name = argv[kar];
03812 oType = SUMA_FREE_SURFER;
03813 brk = YUP;
03814 }
03815
03816 if (!brk && (strcmp(argv[kar], "-o_sf") == 0)) {
03817 kar ++;
03818 if (kar+1 >= argc) {
03819 fprintf (SUMA_STDERR, "need 2 arguments after -o_sf\n");
03820 exit (1);
03821 }
03822 of_name = argv[kar]; kar ++;
03823 of_name2 = argv[kar];
03824 oType = SUMA_SUREFIT;
03825 brk = YUP;
03826 }
03827
03828 if (!brk && (strcmp(argv[kar], "-o_fsp") == 0)) {
03829 kar ++;
03830 if (kar >= argc) {
03831 fprintf (SUMA_STDERR, "need 1 argument after -o_fsp\n");
03832 exit (1);
03833 }
03834 of_name = argv[kar];
03835 oType = SUMA_FREE_SURFER_PATCH;
03836 brk = YUP;
03837 }
03838
03839 if (!brk && ( (strcmp(argv[kar], "-o_vec") == 0) || (strcmp(argv[kar], "-o_1d") == 0) ) ) {
03840 kar ++;
03841 if (kar+1 >= argc) {
03842 fprintf (SUMA_STDERR, "need 2 argument after -o_vec\n");
03843 exit (1);
03844 }
03845 of_name = argv[kar]; kar ++;
03846 of_name2 = argv[kar];
03847 oType = SUMA_VEC;
03848 brk = YUP;
03849 }
03850
03851 if (!brk && (strcmp(argv[kar], "-o_ply") == 0)) {
03852 kar ++;
03853 if (kar >= argc) {
03854 fprintf (SUMA_STDERR, "need argument after -o_ply\n");
03855 exit (1);
03856 }
03857 of_name = argv[kar];
03858 oType = SUMA_PLY;
03859 brk = YUP;
03860 }
03861 #endif
03862
03863 if (!brk && (strcmp(argv[kar], "-xmat_1d") == 0)) {
03864 kar ++;
03865 if (kar >= argc) {
03866 fprintf (SUMA_STDERR, "need 1 argument after -xmat_1D\n");
03867 exit (1);
03868 }
03869 xmat_name = argv[kar];
03870 Doxmat = YUP;
03871 brk = YUP;
03872 }
03873
03874 if (!brk && (strcmp(argv[kar], "-make_consistent") == 0)) {
03875 Do_wind = YUP;
03876 brk = YUP;
03877 }
03878
03879 if (!brk && (strcmp(argv[kar], "-xcenter") == 0)) {
03880 kar ++;
03881 if (kar+2>= argc) {
03882 fprintf (SUMA_STDERR, "need 3 arguments after -xcenter\n");
03883 exit (1);
03884 }
03885 xcen[0] = atof(argv[kar]); ++kar;
03886 xcen[1] = atof(argv[kar]); ++kar;
03887 xcen[2] = atof(argv[kar]);
03888 Docen = YUP;
03889 brk = YUP;
03890 }
03891
03892 if (!brk && (strcmp(argv[kar], "-orient_out") == 0)) {
03893 kar ++;
03894 if (kar>= argc) {
03895 fprintf (SUMA_STDERR, "need 1 argument after -orient_out\n");
03896 exit (1);
03897 }
03898 snprintf(orcode, 4*sizeof(char), "%s", argv[kar]);
03899 if (!SUMA_ok_orstring(orcode)) {
03900 fprintf (SUMA_STDERR, "%s is a bad orientation string\n", orcode);
03901 exit (1);
03902 }
03903 brk = YUP;
03904 }
03905
03906 if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) {
03907 Do_tlrc = YUP;
03908 brk = YUP;
03909 }
03910
03911 if (!brk && (strcmp(argv[kar], "-acpc") == 0)) {
03912 Do_acpc = YUP;
03913 brk = YUP;
03914 }
03915
03916 if (!brk && (strcmp(argv[kar], "-mni_rai") == 0)) {
03917 Do_mni_RAI = YUP;
03918 brk = YUP;
03919 }
03920
03921 if (!brk && (strcmp(argv[kar], "-mni_lpi") == 0)) {
03922 Do_mni_LPI = YUP;
03923 brk = YUP;
03924 }
03925
03926 if (!brk && !ps->arg_checked[kar]) {
03927 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
03928 exit (1);
03929 } else {
03930 brk = NOPE;
03931 kar ++;
03932 }
03933 }
03934
03935
03936 if (ps->o_N_surfnames) {
03937 of_name = ps->o_surfnames[0];
03938 of_name2 = ps->o_surftopo[0];
03939 oType = ps->o_FT[0];
03940 }
03941 if (ps->i_N_surfnames) {
03942 if_name = ps->i_surfnames[0];
03943 if_name2 = ps->i_surftopo[0];
03944 iType = ps->i_FT[0];
03945 iForm = ps->i_FF[0];
03946 }
03947 if (ps->ipar_N_surfnames) {
03948 ifpar_name = ps->ipar_surfnames[0];
03949 ifpar_name2 = ps->ipar_surftopo[0];
03950 iparType = ps->ipar_FT[0];
03951 iparForm = ps->ipar_FF[0];
03952 }
03953
03954 if (ps->N_sv) sv_name = ps->sv[0];
03955 if (ps->N_vp) vp_name = ps->vp[0];
03956
03957
03958 if (Do_mni_LPI && Do_mni_RAI) {
03959 fprintf (SUMA_STDERR,"Error %s:\nCombining -MNI_lpi and -MNI_rai options.\nNot good.", FuncName);
03960 exit(1);
03961 }
03962
03963 if (!if_name) {
03964 fprintf (SUMA_STDERR,"Error %s: input surface not specified.\n", FuncName);
03965 exit(1);
03966 }
03967 if (!of_name) {
03968 fprintf (SUMA_STDERR,"Error %s: output surface not specified.\n", FuncName);
03969 exit(1);
03970 }
03971 if (iType == SUMA_FT_NOT_SPECIFIED) {
03972 fprintf (SUMA_STDERR,"Error %s: input type not recognized.\n", FuncName);
03973 exit(1);
03974 }
03975 if (oType == SUMA_FT_NOT_SPECIFIED) {
03976 fprintf (SUMA_STDERR,"Error %s: output type not recognized.\n", FuncName);
03977 exit(1);
03978 }
03979 if (iType == SUMA_SUREFIT) {
03980 if (!if_name2) {
03981 fprintf (SUMA_STDERR,"Error %s: input SureFit surface incorrectly specified.\n", FuncName);
03982 exit(1);
03983 }
03984 if (sv_name && !vp_name) {
03985 fprintf (SUMA_STDERR,"Error %s: VolParent must specified with -sv potion for SureFit surfaces. \n", FuncName);
03986 exit(1);
03987 }
03988 }
03989 if (iType == SUMA_VEC) {
03990 if (!if_name2) {
03991 fprintf (SUMA_STDERR,"Error %s: input vec surface incorrectly specified.\n", FuncName);
03992 exit(1);
03993 }
03994 }
03995
03996 if (( Do_mni_RAI || Do_mni_LPI) && !Do_tlrc) {
03997 SUMA_SL_Warn ("I hope you know what you're doing.\nThe MNI transform should only be applied to a\nSurface in the AFNI tlrc coordinate space.\n");
03998 }
03999
04000 if (Do_acpc && Do_tlrc) {
04001 fprintf (SUMA_STDERR,"Error %s: You can't do -tlrc and -acpc simultaneously.\n", FuncName);
04002 exit(1);
04003 }
04004
04005 if ((Doxmat || Docen) && (Do_acpc || Do_tlrc)) {
04006 fprintf (SUMA_STDERR,"Error %s: You can't do -tlrc or -acpc with -xmat_1D and -xcenter.\n", FuncName);
04007 exit(1);
04008 }
04009
04010 if ((!Doxmat && Docen)) {
04011 fprintf (SUMA_STDERR,"Error %s: You can't use -xcenter without -xmat_1D.\n", FuncName);
04012 exit(1);
04013 }
04014 if (oType == SUMA_SUREFIT) {
04015 if (!of_name2) {
04016 fprintf (SUMA_STDERR,"Error %s: output SureFit surface incorrectly specified. \n", FuncName);
04017 exit(1);
04018 }
04019 }
04020
04021 if (oType == SUMA_VEC) {
04022 if (!of_name2) {
04023 fprintf (SUMA_STDERR,"Error %s: output vec surface incorrectly specified. \n", FuncName);
04024 exit(1);
04025 }
04026 }
04027
04028
04029
04030 if (!SUMA_filexists(if_name)) {
04031 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, if_name);
04032 exit(1);
04033 }
04034
04035 if (if_name2) {
04036 if (!SUMA_filexists(if_name2)) {
04037 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, if_name2);
04038 exit(1);
04039 }
04040 }
04041
04042 if (ifpar_name2) {
04043 if (!SUMA_filexists(ifpar_name2)) {
04044 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, ifpar_name2);
04045 exit(1);
04046 }
04047 }
04048
04049 if (ifpar_name) {
04050 if (!SUMA_filexists(ifpar_name)) {
04051 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, ifpar_name);
04052 exit(1);
04053 }
04054 }
04055
04056 if (xmat_name) {
04057 if (!SUMA_filexists(xmat_name)) {
04058 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, xmat_name);
04059 exit(1);
04060 }
04061 }
04062
04063 if (sv_name) {
04064 char *head = NULL, view[10];
04065 head = SUMA_AfniPrefix(sv_name, view, NULL, &volexists);
04066 if (!SUMA_AfniExistsView(volexists, view)) {
04067 fprintf (SUMA_STDERR,"Error %s: volume %s not found.\n", FuncName, head);
04068 exit(1);
04069 }
04070 if (head) SUMA_free(head); head = NULL;
04071 }
04072
04073
04074 if ((Do_tlrc || Do_acpc) && (!sv_name)) {
04075 fprintf (SUMA_STDERR,"Error %s: -tlrc must be used with -sv option.\n", FuncName);
04076 exit(1);
04077 }
04078
04079 if (vp_name) {
04080 if (!SUMA_filexists(vp_name)) {
04081 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, vp_name);
04082 exit(1);
04083 }
04084 }
04085
04086
04087 if (of_name2) {
04088 SUMA_SFname *SFname;
04089
04090 SO_name = SUMA_2Prefix2SurfaceName (of_name, of_name2, NULL, vp_name, oType, &exists);
04091 SFname = (SUMA_SFname *)SO_name;
04092 OF_name2 = SUMA_copy_string(SFname->name_topo);
04093 OF_name = SUMA_copy_string(SFname->name_coord);
04094 } else {
04095 SO_name = SUMA_Prefix2SurfaceName (of_name, vp_name, NULL, oType, &exists);
04096 OF_name = SUMA_copy_string((char *) SO_name);
04097 }
04098
04099 if (exists) {
04100 if (OF_name2) fprintf (SUMA_STDERR,"Error %s: output file(s) %s and/or %s exist already.\n", FuncName, OF_name, OF_name2);
04101 else fprintf (SUMA_STDERR,"Error %s: output file %s exists already.\n", FuncName, OF_name);
04102 exit(1);
04103 }
04104
04105
04106 if (Doxmat) {
04107 MRI_IMAGE *im = NULL;
04108 float *far=NULL;
04109 int ncol, nrow;
04110
04111 im = mri_read_1D (xmat_name);
04112
04113 if (!im) {
04114 SUMA_SLP_Err("Failed to read 1D file");
04115 exit(1);
04116 }
04117 far = MRI_FLOAT_PTR(im);
04118 ncol = im->nx;
04119 nrow = im->ny;
04120 if (nrow < 4 ) {
04121 SUMA_SL_Err("Mat file must have\n"
04122 "at least 4 columns.");
04123 mri_free(im); im = NULL;
04124 exit(1);
04125 }
04126 if (ncol < 3 ) {
04127 SUMA_SL_Err("Mat file must have\n"
04128 "at least 3 rows.");
04129 mri_free(im); im = NULL;
04130 exit(1);
04131 }
04132 if (nrow > 4) {
04133 SUMA_SL_Warn( "Ignoring entries beyond 4th \n"
04134 "column in transform file.");
04135 }
04136 if (ncol > 3) {
04137 SUMA_SL_Warn( "Ignoring entries beyond 3rd\n"
04138 "row in transform file.\n");
04139 }
04140 for (i=0; i < 3; ++i) {
04141 M[i][0] = far[i];
04142 M[i][1] = far[i+ncol];
04143 M[i][2] = far[i+2*ncol];
04144 M[i][3] = far[i+3*ncol];
04145 }
04146 mri_free(im); im = NULL;
04147 }
04148
04149 SO = SUMA_Load_Surface_Object_Wrapper ( if_name, if_name2, vp_name, iType, iForm, sv_name, 1);
04150 if (!SO) {
04151 fprintf (SUMA_STDERR,"Error %s: Failed to read input surface.\n", FuncName);
04152 exit (1);
04153 }
04154
04155 if (ifpar_name) {
04156 SOpar = SUMA_Load_Surface_Object_Wrapper ( ifpar_name, ifpar_name2, vp_name, iparType, iparForm, sv_name, 1);
04157 if (!SOpar) {
04158 fprintf (SUMA_STDERR,"Error %s: Failed to read input parent surface.\n", FuncName);
04159 exit (1);
04160 }
04161
04162 if (!SUMA_SurfaceMetrics_eng (SOpar,"EdgeList", NULL, 0, SUMAg_CF->DsetList)) {
04163 SUMA_SL_Err("Failed to create edgelist for parent");
04164 exit(1);
04165 }
04166 }
04167
04168
04169
04170 if (Do_wind) {
04171 fprintf (SUMA_STDOUT,"Checking and repairing mesh's winding consistency...\n");
04172
04173
04174 if (!SUMA_SurfaceMetrics_eng (SO, "CheckWind", NULL, 0, SUMAg_CF->DsetList)) {
04175 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
04176 exit(1);
04177 }
04178 }
04179
04180 if (Do_tlrc) {
04181 fprintf (SUMA_STDOUT,"Performing talairach transform...\n");
04182
04183
04184 tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+strlen(SO->VolPar->prefix)+60, sizeof(char));
04185 sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix);
04186 if (!SUMA_filexists(tlrc_name)) {
04187 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name);
04188 exit(1);
04189 }
04190
04191
04192 aset = THD_open_dataset(tlrc_name) ;
04193 if( !ISVALID_DSET(aset) ){
04194 fprintf (SUMA_STDERR,"Error %s: %s is not a valid data set.\n", FuncName, tlrc_name) ;
04195 exit(1);
04196 }
04197 if( aset->warp == NULL ){
04198 fprintf (SUMA_STDERR,"Error %s: tlrc_name does not contain a talairach transform.\n", FuncName);
04199 exit(1);
04200 }
04201
04202 warp = aset->warp ;
04203
04204
04205 if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
04206 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName);
04207 exit(1);
04208 }
04209
04210
04211 }
04212
04213 if (Do_acpc) {
04214 fprintf (SUMA_STDOUT,"Performing acpc transform...\n");
04215
04216
04217 acpc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+strlen(SO->VolPar->prefix)+60, sizeof(char));
04218 sprintf (acpc_name, "%s%s+acpc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix);
04219 if (!SUMA_filexists(acpc_name)) {
04220 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, acpc_name);
04221 exit(1);
04222 }
04223
04224
04225 aset = THD_open_dataset(acpc_name) ;
04226 if( !ISVALID_DSET(aset) ){
04227 fprintf (SUMA_STDERR,"Error %s: %s is not a valid data set.\n", FuncName, acpc_name) ;
04228 exit(1);
04229 }
04230 if( aset->warp == NULL ){
04231 fprintf (SUMA_STDERR,"Error %s: acpc_name does not contain an acpc transform.\n", FuncName);
04232 exit(1);
04233 }
04234
04235 warp = aset->warp ;
04236
04237
04238 if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
04239 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName);
04240 exit(1);
04241 }
04242
04243
04244 }
04245
04246 if (Do_mni_RAI) {
04247 fprintf (SUMA_STDOUT,"Performing MNI_RAI transform...\n");
04248
04249 if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "RAI")) {
04250 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName);
04251 exit(1);
04252 }
04253 sprintf(orsurf,"RAI");
04254 }
04255
04256 if (Do_mni_LPI) {
04257 fprintf (SUMA_STDOUT,"Performing MNI_LPI transform...\n");
04258
04259 if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "LPI")) {
04260 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName);
04261 exit(1);
04262 }
04263 sprintf(orsurf,"LPI");
04264 }
04265
04266 if (Doxmat) {
04267 fprintf (SUMA_STDOUT,"Performing affine transform...\n");
04268 if (LocalHead) {
04269 for (i=0; i<3 ; ++i) {
04270 fprintf (SUMA_STDERR,"M[%d][:] = %f %f %f %f\n", i, M[i][0], M[i][1], M[i][2], M[i][3]);
04271 }
04272 fprintf (SUMA_STDERR,"Cen[:] %f %f %f\n", xcen[0], xcen[1], xcen[2]);
04273 }
04274 if (Docen) {
04275 if (!SUMA_ApplyAffine (SO->NodeList, SO->N_Node, M, xcen)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); }
04276 } else {
04277 if (!SUMA_ApplyAffine (SO->NodeList, SO->N_Node, M, NULL)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); }
04278 }
04279 }
04280
04281 if (orcode[0] != '\0') {
04282 if (LocalHead) fprintf (SUMA_STDERR,"%s: Changing coordinates from %s to %s\n", FuncName, orsurf, orcode);
04283 if (!SUMA_CoordChange(orsurf, orcode, SO->NodeList, SO->N_Node)) {
04284 SUMA_S_Err("Failed to change coords.");
04285 exit(1);
04286 }
04287 }
04288
04289 if (LocalHead) SUMA_Print_Surface_Object (SO, stderr);
04290
04291 fprintf (SUMA_STDOUT,"Writing surface...\n");
04292
04293
04294
04295 switch (oType) {
04296 case SUMA_SUREFIT:
04297 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_SUREFIT, SUMA_ASCII, NULL)) {
04298 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
04299 exit (1);
04300 }
04301 break;
04302 case SUMA_VEC:
04303 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_VEC, SUMA_ASCII, NULL)) {
04304 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
04305 exit (1);
04306 }
04307 break;
04308 case SUMA_FREE_SURFER:
04309 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_FREE_SURFER, SUMA_ASCII, NULL)) {
04310 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
04311 exit (1);
04312 }
04313 break;
04314 case SUMA_FREE_SURFER_PATCH:
04315 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_FREE_SURFER_PATCH, SUMA_ASCII, SOpar)) {
04316 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
04317 exit (1);
04318 }
04319 break;
04320 case SUMA_OPENDX_MESH:
04321 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_OPENDX_MESH, SUMA_ASCII, NULL)) {
04322 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
04323 exit (1);
04324 }
04325 break;
04326 case SUMA_PLY:
04327 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_PLY, SUMA_FF_NOT_SPECIFIED, NULL)) {
04328 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
04329 exit (1);
04330 }
04331 break;
04332 default:
04333 fprintf (SUMA_STDERR,"Error %s: Bad format.\n", FuncName);
04334 exit(1);
04335 }
04336
04337
04338
04339 if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip);
04340 if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip);
04341 if (OF_name) SUMA_free(OF_name);
04342 if (OF_name2) SUMA_free(OF_name2);
04343 if (SF_name) SUMA_free(SF_name);
04344 if (SO_name) SUMA_free(SO_name);
04345 if (SO) SUMA_Free_Surface_Object(SO);
04346 if (SOpar) SUMA_Free_Surface_Object(SOpar);
04347 if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
04348 return (0);
04349 }
04350 #endif
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360 void SUMA_OpenDrawnROI (char *filename, void *data)
04361 {
04362 static char FuncName[]={"SUMA_OpenDrawnROI"};
04363 DList *list=NULL;
04364 SUMA_DRAWN_ROI **ROIv=NULL;
04365 int i, N_ROI;
04366 SUMA_SurfaceObject *SO=NULL;
04367
04368 SUMA_Boolean LocalHead = NOPE;
04369
04370 SUMA_ENTRY;
04371
04372 SUMA_LH("Called");
04373
04374
04375
04376 if (SUMA_isExtension(filename, ".niml.roi")) {
04377
04378 if (!( ROIv = SUMA_OpenDrawnROI_NIML (filename, &N_ROI, YUP))) {
04379 SUMA_SLP_Err("Failed to read NIML ROI.");
04380 SUMA_RETURNe;
04381 }
04382 }else if (SUMA_isExtension(filename, ".1D.roi")) {
04383
04384
04385 SUMA_SLP_Warn("Assuming parent surface.");
04386 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SUMAg_SVv[0].Focus_SO_ID].OP);
04387 if (!( ROIv = SUMA_OpenDrawnROI_1D (filename, SO->idcode_str, &N_ROI, YUP))) {
04388 SUMA_SLP_Err("Failed to read NIML ROI.");
04389 SUMA_RETURNe;
04390 }
04391 }else {
04392 SUMA_SLP_Err( "Failed to recognize\n"
04393 "ROI type from filename.");
04394 SUMA_RETURNe;
04395 }
04396
04397
04398 for (i=0; i < N_ROI; ++i) {
04399
04400 if (!SUMA_AddDO (SUMAg_DOv, &SUMAg_N_DOv, (void *)ROIv[i], ROIdO_type, SUMA_LOCAL)) {
04401 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_AddDO.\n", FuncName);
04402 }
04403 }
04404
04405 if (ROIv) SUMA_free(ROIv); ROIv = NULL;
04406
04407
04408
04409 if (!SUMAg_CF->X->DrawROI->curDrawnROI) {
04410 i = 0;
04411 do {
04412 if (SUMAg_DOv[i].ObjectType == ROIdO_type) SUMAg_CF->X->DrawROI->curDrawnROI =
04413 (SUMA_DRAWN_ROI *)SUMAg_DOv[i].OP;
04414 ++i;
04415 } while (i < SUMAg_N_DOv && !SUMAg_CF->X->DrawROI->curDrawnROI);
04416 }
04417
04418 if (SUMAg_CF->X->DrawROI->curDrawnROI) {
04419 SUMA_InitializeDrawROIWindow(SUMAg_CF->X->DrawROI->curDrawnROI);
04420 }
04421
04422
04423 if (!SUMA_Paint_SO_ROIplanes_w (
04424 SUMA_findSOp_inDOv(SUMAg_CF->X->DrawROI->curDrawnROI->Parent_idcode_str,
04425 SUMAg_DOv, SUMAg_N_DOv), SUMAg_DOv, SUMAg_N_DOv)) {
04426 SUMA_SLP_Err("Failed in SUMA_Paint_SO_ROIplanes_w.");
04427 SUMA_RETURNe;
04428 }
04429
04430
04431 if (!list) list = SUMA_CreateList ();
04432 SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible, SES_Suma, NULL);
04433 if (!SUMA_Engine(&list)) {
04434 SUMA_SLP_Err("Failed to redisplay.");
04435 SUMA_RETURNe;
04436 }
04437
04438 SUMA_RETURNe;
04439 }
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474
04475
04476
04477
04478
04479
04480
04481 SUMA_DRAWN_ROI ** SUMA_OpenDrawnROI_1D (char *filename, char *Parent_idcode_str,
04482 int *N_ROI, SUMA_Boolean ForDisplay)
04483 {
04484 static char FuncName[]={"SUMA_OpenDrawnROI_1D"};
04485 MRI_IMAGE *im = NULL;
04486 int ncol, nrow, *iLabel=NULL, *iNode = NULL, *isort=NULL,
04487 i, N_Labels = 0, *iStart=NULL, *iStop=NULL, cnt = 0;
04488 float *far=NULL, *r=NULL, *g=NULL, *b=NULL, *RGB=NULL;
04489 SUMA_DRAWN_ROI **ROIv=NULL;
04490 SUMA_Boolean LocalHead = NOPE;
04491
04492 SUMA_ENTRY;
04493
04494 SUMA_LH("Called");
04495
04496 *N_ROI = 0;
04497
04498 im = mri_read_1D (filename);
04499
04500 if (!im) {
04501 SUMA_SLP_Err("Failed to read 1D file");
04502 SUMA_RETURN(NULL);
04503 }
04504
04505 far = MRI_FLOAT_PTR(im);
04506 ncol = im->nx;
04507 nrow = im->ny;
04508
04509 if (!ncol) {
04510 SUMA_SL_Err("Empty file");
04511 SUMA_RETURN(NULL);
04512 }
04513 if (nrow != 1 && nrow != 2 && nrow != 4 && nrow != 5) {
04514 SUMA_SL_Err("File must have\n"
04515 " 1,2,4 or 5 columns.");
04516 mri_free(im); im = NULL;
04517 SUMA_RETURN(NULL);
04518 }
04519
04520 if (0 && LocalHead) {
04521 SUMA_disp_vect(far, ncol*nrow);
04522 }
04523
04524 switch (nrow) {
04525 case 1:
04526
04527 SUMA_LH ("1D format: i");
04528 iNode = (int *)SUMA_malloc(ncol*sizeof(int));
04529 iLabel = (int *)SUMA_malloc(1*sizeof(int));
04530 if (!iNode ||!iLabel) {
04531 SUMA_SL_Err("Failed to allocate");
04532 SUMA_RETURN(NULL);
04533 }
04534 for (i=0; i < ncol; ++i) iNode[i] = (int)far[i];
04535 mri_free(im); im = NULL;
04536
04537 iLabel[0] = 0;
04538 N_Labels = 1;
04539 iStart = (int *)SUMA_malloc(1*sizeof(int));
04540 iStop = (int *)SUMA_malloc(1*sizeof(int));
04541 RGB = (float *)SUMA_malloc(3*1*sizeof(float));
04542 iStart[0] = 0;
04543 iStop[0] = ncol-1;
04544 RGB[0] = 1.0; RGB[1] = 1.0; RGB[2] = 0;
04545 break;
04546 case 2:
04547
04548 SUMA_LH("1D format: i l");
04549
04550 iLabel = (int *)SUMA_malloc(ncol*sizeof(int));
04551 iNode = (int *)SUMA_malloc(ncol*sizeof(int));
04552 if (!iNode || !iLabel) {
04553 SUMA_SL_Err("Failed to allocate");
04554 SUMA_RETURN(NULL);
04555 }
04556 for (i=0; i < ncol; ++i) iLabel[i] = (int)far[i+ncol];
04557
04558 isort = SUMA_z_dqsort( iLabel, ncol);
04559 for (i=0; i < ncol; ++i) iNode[i] = (int)far[isort[i]];
04560
04561 mri_free(im); im = NULL;
04562
04563
04564 N_Labels = 1;
04565 for (i=1; i < ncol; ++i) if (iLabel[i] != iLabel[i-1]) ++N_Labels;
04566
04567 iStart = (int *)SUMA_malloc(N_Labels*sizeof(int));
04568 iStop = (int *)SUMA_malloc(N_Labels*sizeof(int));
04569 RGB = (float *)SUMA_malloc(3*N_Labels*sizeof(float));
04570 if (!iStart || !iStop) {
04571 SUMA_SL_Err("Failed to allocate");
04572 SUMA_RETURN(NULL);
04573 }
04574 cnt = 0;
04575 iStart[cnt] = 0;
04576 iStop[cnt] = ncol -1;
04577 RGB[3*cnt] = 1.0; RGB[3*cnt+1] = 1.0; RGB[3*cnt+2] = 0;
04578 for (i=1; i < ncol; ++i) {
04579 if (iLabel[i] != iLabel[i-1]) {
04580 iStop[cnt] = i-1;
04581 ++cnt;
04582 iStart[cnt] = i;
04583 iStop[cnt] = ncol -1;
04584 RGB[3*cnt] = 1.0; RGB[3*cnt+1] = 1.0; RGB[3*cnt+2] = 0;
04585 }
04586 }
04587 break;
04588 case 4:
04589
04590 SUMA_LH("1D format: i R G B");
04591 iNode = (int *)SUMA_malloc(ncol*sizeof(int));
04592 iLabel = (int *)SUMA_malloc(1*sizeof(int));
04593 r = (float *)SUMA_malloc(ncol*sizeof(float));
04594 g = (float *)SUMA_malloc(ncol*sizeof(float));
04595 b = (float *)SUMA_malloc(ncol*sizeof(float));
04596 if (!iNode || !iLabel || !r || !g || !b) {
04597 SUMA_SL_Err("Failed to allocate");
04598 SUMA_RETURN(NULL);
04599 }
04600
04601 for (i=0; i < ncol; ++i) {
04602 iNode[i] = (int)far[i];
04603 r[i] = (float)far[i+ncol];
04604 g[i] = (float)far[i+2*ncol];
04605 b[i] = (float)far[i+3*ncol];
04606 }
04607
04608 iLabel[0] = 0;
04609 N_Labels = 1;
04610 iStart = (int *)SUMA_malloc(1*sizeof(int));
04611 iStop = (int *)SUMA_malloc(1*sizeof(int));
04612 RGB = (float *)SUMA_malloc(3*1*sizeof(float));
04613 mri_free(im); im = NULL;
04614
04615 iStart[0] = 0;
04616 iStop[0] = ncol-1;
04617 RGB[0] = r[0]; RGB[1] = g[0]; RGB[2] = b[0];
04618 break;
04619 case 5:
04620
04621 SUMA_LH("1D format: i l R G B");
04622
04623 iLabel = (int *)SUMA_malloc(ncol*sizeof(int));
04624 iNode = (int *)SUMA_malloc(ncol*sizeof(int));
04625 r = (float *)SUMA_malloc(ncol*sizeof(float));
04626 g = (float *)SUMA_malloc(ncol*sizeof(float));
04627 b = (float *)SUMA_malloc(ncol*sizeof(float));
04628 if (!iNode || !iLabel || !r || !g || !b) {
04629 SUMA_SL_Err("Failed to allocate");
04630 SUMA_RETURN(NULL);
04631 }
04632 for (i=0; i < ncol; ++i) iLabel[i] = (int)far[i+ncol];
04633
04634 isort = SUMA_z_dqsort( iLabel, ncol);
04635 for (i=0; i < ncol; ++i) {
04636 iNode[i] = (int)far[isort[i]];
04637 r[i] = (float)far[isort[i]+2*ncol];
04638 g[i] = (float)far[isort[i]+3*ncol];
04639 b[i] = (float)far[isort[i]+4*ncol];
04640 }
04641 mri_free(im); im = NULL;
04642
04643
04644 N_Labels = 1;
04645 for (i=1; i < ncol; ++i) if (iLabel[i] != iLabel[i-1]) ++N_Labels;
04646
04647 iStart = (int *)SUMA_malloc(N_Labels*sizeof(int));
04648 iStop = (int *)SUMA_malloc(N_Labels*sizeof(int));
04649 RGB = (float *)SUMA_malloc(3*N_Labels*sizeof(float));
04650 if (!iStart || !iStop || !RGB) {
04651 SUMA_SL_Err("Failed to allocate");
04652 SUMA_RETURN(NULL);
04653 }
04654 cnt = 0;
04655 iStart[cnt] = 0;
04656 iStop[cnt] = ncol -1;
04657 RGB[3*cnt] = r[0]; RGB[3*cnt+1] = g[0]; RGB[3*cnt+2] = b[0];
04658 for (i=1; i < ncol; ++i) {
04659 if (iLabel[i] != iLabel[i-1]) {
04660 iStop[cnt] = i-1;
04661 ++cnt;
04662 iStart[cnt] = i;
04663 iStop[cnt] = ncol -1;
04664 RGB[3*cnt] = r[i]; RGB[3*cnt+1] = g[i]; RGB[3*cnt+2] = b[i];
04665 }
04666 }
04667 break;
04668 default:
04669 SUMA_SLP_Err("Unrecognized 1D format");
04670 mri_free(im); im = NULL;
04671 break;
04672 }
04673
04674
04675 ROIv = (SUMA_DRAWN_ROI **)SUMA_malloc(N_Labels*sizeof(SUMA_DRAWN_ROI*));
04676
04677 for (i=0; i < N_Labels; ++i) {
04678 int Value, N_Node, *Node=NULL;
04679 float fillcolor[3], edgecolor[3];
04680 int edgethickness;
04681 char stmp[20], *Label=NULL;
04682 SUMA_PARSED_NAME *NewName=NULL;
04683
04684 edgethickness = 3;
04685 fillcolor[0] = RGB[3*i]; fillcolor[1] = RGB[3*i+1]; fillcolor[2] = RGB[3*i+2];
04686 edgecolor[0] = 0; edgecolor[1] = 0; edgecolor[2] = 1;
04687 Value = iLabel[iStart[i]];
04688 N_Node = iStop[i] - iStart[i] + 1;
04689 Node = &(iNode[iStart[i]]);
04690
04691 NewName = SUMA_ParseFname (filename);
04692 if (!NewName) {
04693 Label = SUMA_copy_string("BadLabel");
04694 }else {
04695 sprintf(stmp,"(%d)", Value);
04696 Label = SUMA_append_string(stmp,NewName->FileName_NoExt);
04697 }
04698 SUMA_LH("Transforming to Drawn ROIs...");
04699 ROIv[i] = SUMA_1DROI_to_DrawnROI( Node, N_Node ,
04700 Value, Parent_idcode_str,
04701 Label, NULL,
04702 fillcolor, edgecolor, edgethickness,
04703 SUMAg_DOv, SUMAg_N_DOv,
04704 ForDisplay);
04705 if (nrow == 5 || nrow == 4) {
04706 SUMA_LH("Marking as color by fillcolor");
04707 ROIv[i]->ColorByLabel = NOPE;
04708 }
04709 if (Label) SUMA_free(Label); Label = NULL;
04710 if (NewName) SUMA_Free_Parsed_Name(NewName); NewName = NULL;
04711 if (LocalHead) fprintf (SUMA_STDERR, "%s: ROI->Parent_idcode_str %s\n", FuncName, ROIv[i]->Parent_idcode_str);
04712
04713 }
04714
04715 SUMA_LH("Freeing...");
04716
04717 if (iLabel) SUMA_free(iLabel); iLabel = NULL;
04718 if (isort) SUMA_free(isort); isort = NULL;
04719 if (iNode) SUMA_free(iNode); iNode = NULL;
04720 if (iStart) SUMA_free(iStart); iStart = NULL;
04721 if (iStop) SUMA_free(iStop); iStop = NULL;
04722 if (r) SUMA_free(r); r = NULL;
04723 if (g) SUMA_free(g); g = NULL;
04724 if (b) SUMA_free(b); b = NULL;
04725 if (RGB) SUMA_free(RGB); RGB = NULL;
04726
04727 *N_ROI = N_Labels;
04728 SUMA_RETURN(ROIv);
04729
04730 }
04731
04732
04733
04734
04735
04736
04737
04738
04739 SUMA_DRAWN_ROI ** SUMA_OpenDrawnROI_NIML (char *filename, int *N_ROI, SUMA_Boolean ForDisplay)
04740 {
04741 static char FuncName[]={"SUMA_OpenDrawnROI_NIML"};
04742 char stmp[SUMA_MAX_NAME_LENGTH+100], *nel_idcode;
04743 NI_element *nel = NULL;
04744 NI_element **nelv=NULL;
04745 NI_stream ns ;
04746 int n_read=0, idat, answer, inel, iDO, N_nel;
04747 SUMA_NIML_ROI_DATUM *niml_ROI_datum_buff=NULL;
04748 SUMA_NIML_DRAWN_ROI * nimlROI=NULL;
04749 SUMA_DRAWN_ROI **ROIv=NULL;
04750 SUMA_Boolean found = YUP, AddNel = YUP, AlwaysReplace = NOPE, NeverReplace = NOPE;
04751 SUMA_Boolean LocalHead = NOPE;
04752
04753 SUMA_ENTRY;
04754
04755 *N_ROI = 0;
04756
04757 if (SUMAg_CF->nimlROI_Datum_type < 0) {
04758 SUMA_SL_Err("Bad niml type code");
04759 SUMA_RETURN(NULL);
04760 }
04761 if (LocalHead) fprintf(SUMA_STDERR, "%s: roi_type code = %d\n", FuncName, SUMAg_CF->nimlROI_Datum_type) ;
04762
04763 sprintf(stmp,"file:%s", filename);
04764 ns = NI_stream_open( stmp , "r" ) ;
04765 if( ns == NULL ){
04766 SUMA_SL_Err("Can't open ROI file");
04767 SUMA_RETURN(NULL);
04768 }
04769
04770 nelv = (NI_element **) SUMA_calloc(SUMA_MAX_DISPLAYABLE_OBJECTS, sizeof(NI_element *));
04771 if (!nelv) {
04772 SUMA_SLP_Crit("Failed to allocate");
04773 SUMA_RETURN(NULL);
04774 }
04775
04776 NeverReplace = NOPE;
04777 AlwaysReplace = NOPE;
04778 inel = 0;
04779 do {
04780 nel = NI_read_element(ns,1) ;
04781
04782 if (nel) {
04783 found = YUP;
04784
04785 if (LocalHead && 0) SUMA_nel_stdout (nel);
04786
04787 if (strcmp(nel->name,SUMA_Dset_Type_Name(SUMA_NODE_ROI))) {
04788 SUMA_SLP_Err ("ni element not of the \n Node ROI variety.\nElement discarded.");
04789 NI_free_element(nel) ; nel = NULL;
04790 SUMA_RETURN(NULL);
04791 }
04792
04793 if (nel->vec_typ[0] != SUMAg_CF->nimlROI_Datum_type) {
04794 SUMA_SLP_Err ("Datum type mismatch.");
04795 NI_free_element(nel) ; nel = NULL;
04796 SUMA_RETURN(NULL);
04797 }
04798
04799 if (ForDisplay) {
04800
04801 nel_idcode = NI_get_attribute( nel , "idcode_str");
04802 if (!nel_idcode) nel_idcode = NI_get_attribute( nel , "Object_ID");
04803 if (SUMA_existDO(nel_idcode, SUMAg_DOv, SUMAg_N_DOv)) {
04804 if (AlwaysReplace) {
04805 AddNel = YUP;
04806 }
04807 if (NeverReplace) {
04808 AddNel = NOPE;
04809 }
04810 if (!AlwaysReplace && !NeverReplace) {
04811 sprintf(stmp, "Found duplicate ROIs.\n"\
04812 "Replace ROI %s (%s) by\n" \
04813 "version in file ?",
04814 NI_get_attribute( nel , "Label"), nel_idcode);
04815
04816 answer = SUMA_ForceUser_YesNo (SUMAg_SVv[0].X->TOPLEVEL,
04817 stmp,
04818 0, SWP_DONT_CARE);
04819 if (LocalHead) fprintf (SUMA_STDERR,"%s: Got %d, You ?\n", FuncName, answer);
04820 switch (answer) {
04821 case SUMA_YES:
04822 SUMA_LH("YES");
04823 AddNel = YUP;
04824 break;
04825
04826 case SUMA_NO:
04827 SUMA_LH("NO");
04828
04829 AddNel = NOPE;
04830 break;
04831
04832 case SUMA_YES_ALL:
04833 SUMA_LH("YES ALL");
04834
04835 AddNel = YUP;
04836 AlwaysReplace = YUP;
04837 break;
04838
04839 case SUMA_NO_ALL:
04840 SUMA_LH("NO ALL");
04841
04842 AddNel = NOPE;
04843 NeverReplace = YUP;
04844 break;
04845
04846 default:
04847 SUMA_SLP_Crit("Don't know what to do with this button.");
04848 SUMA_RETURN(NULL);
04849 break;
04850 }
04851 }
04852 } else {
04853 AddNel = YUP;
04854 }
04855
04856
04857 if (AddNel) {
04858 SUMA_LH("Checking for Parent surface...");
04859 iDO = SUMA_whichDO(NI_get_attribute( nel , "Parent_idcode_str"), SUMAg_DOv, SUMAg_N_DOv);
04860 if (iDO < 0) iDO = SUMA_whichDO(NI_get_attribute( nel , "Parent_ID"), SUMAg_DOv, SUMAg_N_DOv);
04861
04862 if (iDO < 0) {
04863 SUMA_SLP_Err( "ROI's parent surface\n"
04864 "is not loaded. ROI is\n"
04865 "discarded." );
04866 AddNel = NOPE;
04867 }
04868 }
04869 } else {
04870 AddNel = YUP;
04871 }
04872
04873 if (AddNel) {
04874 SUMA_LH("Adding Nel");
04875 nelv[inel] = nel;
04876 ++inel;
04877 }else {
04878 SUMA_LH("Skipping Nel");
04879 }
04880
04881 ++n_read;
04882 }else {
04883 found = NOPE;
04884 }
04885
04886 } while (found);
04887
04888 NI_stream_close(ns) ;
04889 N_nel = inel;
04890
04891 if( !n_read){
04892 SUMA_SL_Err("Found no elements in file!");
04893 SUMA_free(nelv);
04894 SUMA_RETURN(NULL);
04895 }
04896
04897
04898 ROIv = (SUMA_DRAWN_ROI **) SUMA_malloc(N_nel*sizeof(SUMA_DRAWN_ROI*));
04899 for (inel=0; inel < N_nel; ++inel) {
04900 if (LocalHead) fprintf (SUMA_STDERR,"%s: Processing nel %d/%d...\n", FuncName, inel, N_nel);
04901 nel = nelv[inel];
04902 nel_idcode = NI_get_attribute( nel , "idcode_str");
04903 if (!nel_idcode) nel_idcode = NI_get_attribute( nel , "Object_ID");
04904
04905
04906
04907
04908 nimlROI = (SUMA_NIML_DRAWN_ROI *)SUMA_malloc(sizeof(SUMA_NIML_DRAWN_ROI));
04909 nimlROI->Type = (int)strtod(NI_get_attribute( nel , "Type"), NULL);
04910 nimlROI->idcode_str = SUMA_copy_string(NI_get_attribute( nel , "idcode_str"));
04911 if (SUMA_IS_EMPTY_STR_ATTR(nimlROI->idcode_str)) nimlROI->idcode_str = SUMA_copy_string(NI_get_attribute( nel , "Object_ID"));
04912 nimlROI->Parent_idcode_str = SUMA_copy_string(NI_get_attribute( nel , "Parent_idcode_str"));
04913 if (SUMA_IS_EMPTY_STR_ATTR(nimlROI->Parent_idcode_str)) nimlROI->Parent_idcode_str = SUMA_copy_string(NI_get_attribute( nel , "Parent_ID"));
04914 nimlROI->Label = SUMA_copy_string(NI_get_attribute( nel , "Label"));
04915 nimlROI->iLabel = (int)strtod(NI_get_attribute( nel , "iLabel"), NULL);
04916 nimlROI->N_ROI_datum = nel->vec_len;
04917 nimlROI->ColPlaneName = SUMA_copy_string(NI_get_attribute( nel , "ColPlaneName"));
04918 if (SUMA_StringToNum (NI_get_attribute( nel , "FillColor"),
04919 nimlROI->FillColor, 3) < 0) {
04920 SUMA_SLP_Err("Failed in reading FillColor.");
04921 SUMA_free(nelv);
04922 SUMA_RETURN(NULL);
04923 }
04924 if (SUMA_StringToNum (NI_get_attribute( nel , "EdgeColor"),
04925 nimlROI->EdgeColor, 3) < 0) {
04926 SUMA_SLP_Err("Failed in reading EdgeColor.");
04927 SUMA_free(nelv);
04928 SUMA_RETURN(NULL);
04929 }
04930 nimlROI->EdgeThickness = (int)strtod(NI_get_attribute( nel , "EdgeThickness"), NULL);
04931
04932 if (LocalHead) {
04933 fprintf (SUMA_STDERR,"%s: vec_type[0] = %d (%d)\n",
04934 FuncName, nel->vec_typ[0], SUMAg_CF->nimlROI_Datum_type) ;
04935 fprintf (SUMA_STDERR,"%s: vec_len =%d\tvec_num = %d\nidcode_str %s, Parent_idcode_str %s\n",
04936 FuncName, nel->vec_len, nel->vec_num,
04937 nimlROI->idcode_str, nimlROI->Parent_idcode_str);
04938 }
04939
04940 nimlROI->ROI_datum = (SUMA_NIML_ROI_DATUM *)SUMA_malloc(nimlROI->N_ROI_datum*sizeof(SUMA_NIML_ROI_DATUM));
04941
04942
04943
04944
04945
04946
04947
04948
04949 niml_ROI_datum_buff = (SUMA_NIML_ROI_DATUM *)nel->vec[0];
04950
04951 SUMA_LH("Filling ROI datum structures...");
04952 for (idat=0; idat< nimlROI->N_ROI_datum ; ++idat) {
04953 if (LocalHead) fprintf (SUMA_STDERR,"%s: i=%d\n", FuncName, idat);
04954 nimlROI->ROI_datum[idat].action = niml_ROI_datum_buff[idat].action;
04955 nimlROI->ROI_datum[idat].Type = niml_ROI_datum_buff[idat].Type;
04956 nimlROI->ROI_datum[idat].N_n = niml_ROI_datum_buff[idat].N_n;
04957 if (nimlROI->ROI_datum[idat].N_n > 0) {
04958 if (LocalHead) fprintf (SUMA_STDERR,"%s: Copying nPath, %d values\n", FuncName, nimlROI->ROI_datum[idat].N_n);
04959 nimlROI->ROI_datum[idat].nPath = (int *)SUMA_malloc(sizeof(int)*nimlROI->ROI_datum[idat].N_n);
04960 memcpy(nimlROI->ROI_datum[idat].nPath, niml_ROI_datum_buff[idat].nPath, sizeof(int)*nimlROI->ROI_datum[idat].N_n);
04961 } else {
04962 SUMA_LH("Null nPath");
04963 nimlROI->ROI_datum[idat].nPath = NULL;
04964 }
04965 if (LocalHead) {
04966 fprintf (SUMA_STDERR,"%s: Segment %d\tType %d\tN_n %d\taction %d\n",
04967 FuncName, idat, nimlROI->ROI_datum[idat].Type,
04968 nimlROI->ROI_datum[idat].N_n,nimlROI->ROI_datum[idat].action);
04969 }
04970 }
04971
04972
04973
04974 SUMA_LH("Checking for duplicates...");
04975 if ((iDO = SUMA_whichDO(nel_idcode, SUMAg_DOv, SUMAg_N_DOv)) >= 0) {
04976 SUMA_LH("Duplicate found ... Deleteing old one...");
04977
04978 if (!SUMA_DeleteROI ((SUMA_DRAWN_ROI *)SUMAg_DOv[iDO].OP)) {
04979 SUMA_SLP_Err("Failed to delete ROI");
04980 SUMA_RETURN(NULL);
04981 }
04982 }
04983
04984
04985 SUMA_LH("Transforming ROI to a series of actions...");
04986 ROIv[inel] = SUMA_NIMLDrawnROI_to_DrawnROI (nimlROI, ForDisplay);
04987 if (LocalHead) fprintf (SUMA_STDERR, "%s: ROI->Parent_idcode_str %s\n", FuncName, ROIv[inel]->Parent_idcode_str);
04988
04989
04990 if (nimlROI->idcode_str) SUMA_free(nimlROI->idcode_str);
04991 if (nimlROI->Parent_idcode_str) SUMA_free(nimlROI->Parent_idcode_str);
04992 if (nimlROI->Label) SUMA_free(nimlROI->Label);
04993 if (nimlROI->ColPlaneName) SUMA_free(nimlROI->ColPlaneName);
04994
04995
04996
04997 nimlROI = SUMA_Free_NIMLDrawROI(nimlROI);
04998
04999
05000 NI_free_element(nel) ; nel = NULL;
05001
05002 }
05003
05004
05005 SUMA_free(nelv);
05006
05007 *N_ROI = N_nel;
05008 SUMA_RETURN(ROIv);
05009 }
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027 SUMA_DSET *SUMA_ROIv2Grpdataset (SUMA_DRAWN_ROI** ROIv, int N_ROIv, char *Parent_idcode_str, int Pad_to, int Pad_val)
05028 {
05029 static char FuncName[]={"SUMA_ROIv2Grpdataset"};
05030 int ii, i, nn, cnt, N_NodesTotal = 0, MaxIndex = 0,
05031 *ip=NULL, *NodesTotal=NULL, *LabelsTotal=NULL,
05032 *NodesTotal_p=NULL, *LabelsTotal_p=NULL;
05033 SUMA_DSET *dset =NULL;
05034 SUMA_Boolean LocalHead = NOPE;
05035
05036 SUMA_ENTRY;
05037
05038
05039
05040 N_NodesTotal = 0;
05041 for (ii=0; ii < N_ROIv; ++ii) {
05042 SUMA_ROI_CRUDE_COUNT_NODES(ROIv[ii], cnt);
05043 if (LocalHead) {
05044 fprintf (SUMA_STDERR,"%s: ROI #%d: %d nodes\n", FuncName, ii, cnt);
05045 }
05046 N_NodesTotal += cnt;
05047 }
05048 if (LocalHead) fprintf (SUMA_STDERR,"%s: %d nodes total.\n", FuncName, N_NodesTotal);
05049
05050 NodesTotal = (int *)SUMA_calloc(N_NodesTotal, sizeof(int));
05051 LabelsTotal = (int *)SUMA_calloc(N_NodesTotal, sizeof(int));
05052
05053 if (!NodesTotal || !LabelsTotal) {
05054 SUMA_S_Err("Failed to allocate.");
05055 SUMA_RETURN(dset);
05056 }
05057
05058 cnt = 0;
05059 N_NodesTotal = 0;
05060 MaxIndex = -1;
05061 for (ii=0; ii < N_ROIv; ++ii) {
05062 SUMA_LH("Appending ROI");
05063
05064
05065
05066
05067
05068
05069 ip = SUMA_NodesInROI (ROIv[ii], &nn, YUP);
05070 if (LocalHead) {
05071 fprintf (SUMA_STDERR,"%s: Nodes in ROI #%d\n", FuncName, ii);
05072 SUMA_disp_dvect (ip, nn);
05073 }
05074 for (i=0; i < nn; ++i) {
05075 NodesTotal[cnt] = ip[i];
05076 LabelsTotal[cnt] = ROIv[ii]->iLabel;
05077 if (ip[i] > MaxIndex) MaxIndex = ip[i];
05078 ++cnt;
05079 }
05080 N_NodesTotal += nn;
05081 SUMA_freeDrawnROI (ROIv[ii]); ROIv[ii] = NULL;
05082 SUMA_free(ip);ip=NULL;
05083 }
05084
05085 if (LocalHead) {
05086 SUMA_disp_dvect (NodesTotal, N_NodesTotal);
05087 }
05088
05089
05090
05091 { int *isort = NULL, *LabelsTotal_r = NULL,
05092 *NodesTotal_u = NULL, N_NodesTotal_u, *iu = NULL;
05093 char report[100];
05094
05095 isort = SUMA_z_dqsort(NodesTotal, N_NodesTotal);
05096 LabelsTotal_r = SUMA_reorder (LabelsTotal, isort, N_NodesTotal);
05097 SUMA_free(LabelsTotal);
05098 LabelsTotal = LabelsTotal_r; LabelsTotal_r = NULL;
05099 SUMA_free(isort); isort = NULL;
05100
05101
05102 NodesTotal_u = SUMA_UniqueInt_ind (NodesTotal, N_NodesTotal, &N_NodesTotal_u, &iu);
05103
05104 LabelsTotal_r = SUMA_reorder (LabelsTotal, iu, N_NodesTotal_u);
05105 SUMA_free(NodesTotal); NodesTotal = NULL;
05106 SUMA_free(LabelsTotal); LabelsTotal = NULL;
05107 SUMA_free(iu); iu = NULL;
05108 NodesTotal = NodesTotal_u; NodesTotal_u = NULL;
05109 LabelsTotal = LabelsTotal_r; LabelsTotal_r = NULL;
05110
05111 if (N_NodesTotal - N_NodesTotal_u) {
05112 sprintf(report, "%d/%d nodes had duplicate entries.\n"
05113 "(ie same node part of more than 1 ROI)\n"
05114 "Duplicate entries were eliminated.",
05115 N_NodesTotal - N_NodesTotal_u , N_NodesTotal);
05116
05117 N_NodesTotal = N_NodesTotal_u; N_NodesTotal_u = 0;
05118 SUMA_SLP_Warn(report);
05119 }
05120 }
05121
05122 if (Pad_to > 0) {
05123 SUMA_LH("Padding to desired length");
05124 if (Pad_to < MaxIndex) {
05125 SUMA_SL_Err("ROI contains node index > padding limit\nNo padding done.");
05126 if (NodesTotal) SUMA_free(NodesTotal); NodesTotal = NULL;
05127 if (LabelsTotal) SUMA_free(LabelsTotal); LabelsTotal = NULL;
05128 SUMA_RETURN(NULL);
05129 }else {
05130 NodesTotal_p = (int *)SUMA_calloc(Pad_to+1, sizeof(int));
05131 LabelsTotal_p = (int *)SUMA_calloc(Pad_to+1, sizeof(int));
05132 if (!NodesTotal_p || !LabelsTotal_p) {
05133 SUMA_SL_Crit("Failed to allocate for NodesTotal_p || LabelsTotal_p");
05134 if (NodesTotal) SUMA_free(NodesTotal); NodesTotal = NULL;
05135 if (LabelsTotal) SUMA_free(LabelsTotal); LabelsTotal = NULL;
05136 SUMA_RETURN(NULL);
05137 }
05138 if (Pad_val) for(i=0; i<=Pad_to; ++i) LabelsTotal_p[i] = Pad_val;
05139 for(i=0; i<=Pad_to; ++i) NodesTotal_p[i] = i;
05140 for(i=0; i<N_NodesTotal; ++i) {
05141 LabelsTotal_p[NodesTotal[i]] = LabelsTotal[i];
05142 }
05143 SUMA_free(NodesTotal); NodesTotal = NodesTotal_p; NodesTotal_p = NULL;
05144 SUMA_free(LabelsTotal); LabelsTotal = LabelsTotal_p; LabelsTotal_p = NULL;
05145 N_NodesTotal = Pad_to + 1;
05146 }
05147 }
05148
05149
05150 SUMA_LH("Creating dset ");
05151 dset = SUMA_CreateDsetPointer(
05152 NULL,
05153 SUMA_NODE_ROI,
05154 NULL,
05155 Parent_idcode_str,
05156 N_NodesTotal
05157 );
05158
05159
05160
05161 if (!dset) {
05162 SUMA_SL_Err("Failed in SUMA_CreateDsetPointer");
05163 SUMA_RETURN(NULL);
05164 }
05165
05166
05167 SUMA_LH("Adding index column...");
05168 if (!SUMA_AddDsetNelCol (dset, "node index", SUMA_NODE_INDEX, (void *)NodesTotal, NULL, 1)) {
05169 SUMA_SL_Err("Failed in SUMA_AddNelCol");
05170 SUMA_RETURN(dset);
05171 }
05172
05173
05174 SUMA_LH("Adding label column...");
05175 if (!SUMA_AddDsetNelCol (dset, "integer label", SUMA_NODE_ILABEL, (void *)LabelsTotal, NULL, 1)) {
05176 SUMA_SL_Err("Failed in SUMA_AddNelCol");
05177 SUMA_RETURN(dset);
05178 }
05179
05180
05181 dset->dnel = SUMA_FindDsetDataAttributeElement(dset);
05182
05183 SUMA_LH("cleanup ...");
05184 if (NodesTotal) SUMA_free(NodesTotal); NodesTotal = NULL;
05185 if (LabelsTotal) SUMA_free(LabelsTotal); LabelsTotal = NULL;
05186
05187 SUMA_RETURN(dset);
05188 }
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205 NI_element *SUMA_ROIv2dataset (SUMA_DRAWN_ROI** ROIv, int N_ROIv, char *Parent_idcode_str, int Pad_to, int Pad_val)
05206 {
05207 static char FuncName[]={"SUMA_ROIv2dataset"};
05208 int ii, i, nn, cnt, N_NodesTotal = 0, MaxIndex = 0,
05209 *ip=NULL, *NodesTotal=NULL, *LabelsTotal=NULL,
05210 *NodesTotal_p=NULL, *LabelsTotal_p=NULL;
05211 NI_element *nel=NULL;
05212 SUMA_Boolean LocalHead = NOPE;
05213
05214 SUMA_ENTRY;
05215
05216 SUMA_SL_Err("Obsolete, use SUMA_ROIv2Grpdataset");
05217 SUMA_RETURN(NULL);
05218
05219
05220
05221 N_NodesTotal = 0;
05222 for (ii=0; ii < N_ROIv; ++ii) {
05223 SUMA_ROI_CRUDE_COUNT_NODES(ROIv[ii], cnt);
05224 if (LocalHead) {
05225 fprintf (SUMA_STDERR,"%s: ROI #%d: %d nodes\n", FuncName, ii, cnt);
05226 }
05227 N_NodesTotal += cnt;
05228 }
05229 if (LocalHead) fprintf (SUMA_STDERR,"%s: %d nodes total.\n", FuncName, N_NodesTotal);
05230
05231 NodesTotal = (int *)SUMA_calloc(N_NodesTotal, sizeof(int));
05232 LabelsTotal = (int *)SUMA_calloc(N_NodesTotal, sizeof(int));
05233
05234 if (!NodesTotal || !LabelsTotal) {
05235 SUMA_S_Err("Failed to allocate.");
05236 SUMA_RETURN(nel);
05237 }
05238
05239 cnt = 0;
05240 N_NodesTotal = 0;
05241 MaxIndex = -1;
05242 for (ii=0; ii < N_ROIv; ++ii) {
05243 SUMA_LH("Appending ROI");
05244
05245
05246
05247
05248
05249
05250 ip = SUMA_NodesInROI (ROIv[ii], &nn, YUP);
05251 if (LocalHead) {
05252 fprintf (SUMA_STDERR,"%s: Nodes in ROI #%d\n", FuncName, ii);
05253 SUMA_disp_dvect (ip, nn);
05254 }
05255 for (i=0; i < nn; ++i) {
05256 NodesTotal[cnt] = ip[i];
05257 LabelsTotal[cnt] = ROIv[ii]->iLabel;
05258 if (ip[i] > MaxIndex) MaxIndex = ip[i];
05259 ++cnt;
05260 }
05261 N_NodesTotal += nn;
05262 SUMA_freeDrawnROI (ROIv[ii]); ROIv[ii] = NULL;
05263 SUMA_free(ip);ip=NULL;
05264 }
05265
05266 if (LocalHead) {
05267 SUMA_disp_dvect (NodesTotal, N_NodesTotal);
05268 }
05269
05270
05271
05272 { int *isort = NULL, *LabelsTotal_r = NULL,
05273 *NodesTotal_u = NULL, N_NodesTotal_u, *iu = NULL;
05274 char report[100];
05275
05276 isort = SUMA_z_dqsort(NodesTotal, N_NodesTotal);
05277 LabelsTotal_r = SUMA_reorder (LabelsTotal, isort, N_NodesTotal);
05278 SUMA_free(LabelsTotal);
05279 LabelsTotal = LabelsTotal_r; LabelsTotal_r = NULL;
05280 SUMA_free(isort); isort = NULL;
05281
05282
05283 NodesTotal_u = SUMA_UniqueInt_ind (NodesTotal, N_NodesTotal, &N_NodesTotal_u, &iu);
05284
05285 LabelsTotal_r = SUMA_reorder (LabelsTotal, iu, N_NodesTotal_u);
05286 SUMA_free(NodesTotal); NodesTotal = NULL;
05287 SUMA_free(LabelsTotal); LabelsTotal = NULL;
05288 SUMA_free(iu); iu = NULL;
05289 NodesTotal = NodesTotal_u; NodesTotal_u = NULL;
05290 LabelsTotal = LabelsTotal_r; LabelsTotal_r = NULL;
05291
05292 if (N_NodesTotal - N_NodesTotal_u) {
05293 sprintf(report, "%d/%d nodes had duplicate entries.\n"
05294 "(ie same node part of more than 1 ROI)\n"
05295 "Duplicate entries were eliminated.",
05296 N_NodesTotal - N_NodesTotal_u , N_NodesTotal);
05297
05298 N_NodesTotal = N_NodesTotal_u; N_NodesTotal_u = 0;
05299 SUMA_SLP_Warn(report);
05300 }
05301 }
05302
05303 if (Pad_to > 0) {
05304 SUMA_LH("Padding to desired length");
05305 if (Pad_to < MaxIndex) {
05306 SUMA_SL_Err("ROI contains node index > padding limit\nNo padding done.");
05307 if (NodesTotal) SUMA_free(NodesTotal); NodesTotal = NULL;
05308 if (LabelsTotal) SUMA_free(LabelsTotal); LabelsTotal = NULL;
05309 SUMA_RETURN(NULL);
05310 }else {
05311 NodesTotal_p = (int *)SUMA_calloc(Pad_to+1, sizeof(int));
05312 LabelsTotal_p = (int *)SUMA_calloc(Pad_to+1, sizeof(int));
05313 if (!NodesTotal_p || !LabelsTotal_p) {
05314 SUMA_SL_Crit("Failed to allocate for NodesTotal_p || LabelsTotal_p");
05315 if (NodesTotal) SUMA_free(NodesTotal); NodesTotal = NULL;
05316 if (LabelsTotal) SUMA_free(LabelsTotal); LabelsTotal = NULL;
05317 SUMA_RETURN(NULL);
05318 }
05319 if (Pad_val) for(i=0; i<=Pad_to; ++i) LabelsTotal_p[i] = Pad_val;
05320 for(i=0; i<=Pad_to; ++i) NodesTotal_p[i] = i;
05321 for(i=0; i<N_NodesTotal; ++i) {
05322 LabelsTotal_p[NodesTotal[i]] = LabelsTotal[i];
05323 }
05324 SUMA_free(NodesTotal); NodesTotal = NodesTotal_p; NodesTotal_p = NULL;
05325 SUMA_free(LabelsTotal); LabelsTotal = LabelsTotal_p; LabelsTotal_p = NULL;
05326 N_NodesTotal = Pad_to + 1;
05327 }
05328 }
05329
05330
05331 SUMA_LH("Creating nel ");
05332 nel = SUMA_NewNel ( SUMA_NODE_ROI,
05333 Parent_idcode_str,
05334 NULL,
05335 N_NodesTotal,
05336 NULL,
05337 NULL);
05338
05339 if (!nel) {
05340 SUMA_SL_Err("Failed in SUMA_NewNel");
05341 SUMA_RETURN(nel);
05342 }
05343
05344
05345 SUMA_LH("Adding index column...");
05346 if (!SUMA_AddNelCol (nel, "node index", SUMA_NODE_INDEX, (void *)NodesTotal, NULL, 1)) {
05347 SUMA_SL_Err("Failed in SUMA_AddNelCol");
05348 SUMA_RETURN(nel);
05349 }
05350
05351
05352 SUMA_LH("Adding label column...");
05353 if (!SUMA_AddNelCol (nel, "integer label", SUMA_NODE_ILABEL, (void *)LabelsTotal, NULL, 1)) {
05354 SUMA_SL_Err("Failed in SUMA_AddNelCol");
05355 SUMA_RETURN(nel);
05356 }
05357
05358 SUMA_LH("cleanup ...");
05359 if (NodesTotal) SUMA_free(NodesTotal); NodesTotal = NULL;
05360 if (LabelsTotal) SUMA_free(LabelsTotal); LabelsTotal = NULL;
05361
05362 SUMA_RETURN(nel);
05363 }
05364
05365 #ifdef SUMA_ROI2dataset_STAND_ALONE
05366 void usage_ROI2dataset_Main ()
05367
05368 {
05369 static char FuncName[]={"usage_ROI2dataset_Main"};
05370 char * s = NULL;
05371 fprintf(SUMA_STDOUT,
05372 "\n"
05373 "Usage: \n"
05374 " ROI2dataset <-prefix dsetname> [...] <-input ROI1 ROI2 ...>\n"
05375 " [<-of ni_bi|ni_as|1D>] \n"
05376 " [<-dom_par_id idcode>] \n"
05377
05378 " This program transforms a series of ROI files\n"
05379 " to a node dataset. This data set will contain\n"
05380 " the node indices in the first column and their\n"
05381 " ROI values in the second column.\n"
05382 " Duplicate node entries (nodes that are part of\n"
05383 " multiple ROIs) will get ignored. You will be\n"
05384 " notified when this occurs. \n"
05385 "\n"
05386 "Mandatory parameters:\n"
05387 " -prefix dsetname: Prefix of output dataset.\n"
05388 " Program will not overwrite existing\n"
05389 " datasets.\n"
05390 " -input ROI1 ROI2....: ROI files to turn into a \n"
05391 " data set. This parameter MUST\n"
05392 " be the last one on command line.\n"
05393 "\n"
05394 "Optional parameters:\n"
05395 "(all optional parameters must be specified before the\n"
05396 " -input parameters.)\n"
05397 " -h | -help: This help message\n"
05398 " -of FORMAT: Output format of dataset. FORMAT is one of:\n"
05399 " ni_bi: NIML binary\n"
05400 " ni_as: NIML ascii (default)\n"
05401 " 1D : 1D AFNI format.\n"
05402 " -dom_par_id id: Idcode of domain parent.\n"
05403 " When specified, only ROIs have the same\n"
05404 " domain parent are included in the output.\n"
05405 " If id is not specified then the first\n"
05406 " domain parent encountered in the ROI list\n"
05407 " is adopted as dom_par_id.\n"
05408 " 1D roi files do not have domain parent \n"
05409 " information. They will be added to the \n"
05410 " output data under the chosen dom_par_id.\n"
05411 " -pad_to_node max_index: Output a full dset from node 0 \n"
05412 " to node max_index (a total of \n"
05413 " max_index + 1 nodes). Nodes that\n"
05414 " are not part of any ROI will get\n"
05415 " a default label of 0 unless you\n"
05416 " specify your own padding label.\n"
05417 " -pad_val padding_label: Use padding_label (an integer) to\n"
05418 " label nodes that do not belong\n"
05419 " to any ROI. Default is 0.\n"
05420 "\n");
05421 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
05422 fprintf(SUMA_STDOUT,
05423 " Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
05424 exit (0);
05425 }
05426
05427 int main (int argc,char *argv[])
05428 {
05429 static char FuncName[]={"ROI2dataset"};
05430 char *prefix_name, **input_name_v=NULL, *out_name=NULL,
05431 *Parent_idcode_str = NULL, *dummy_idcode_str = NULL, *stmp=NULL;
05432 int kar, brk, N_input_name, cnt = 0, N_ROIv, N_tROI, ii, i, nn, pad_to, pad_val;
05433 SUMA_DSET *dset=NULL;
05434 NI_stream ns;
05435 SUMA_DSET_FORMAT Out_Format = SUMA_ASCII_NIML;
05436 SUMA_DRAWN_ROI ** ROIv = NULL, **tROIv = NULL;
05437 SUMA_Boolean AddThis = NOPE;
05438 SUMA_Boolean LocalHead = NOPE;
05439
05440 SUMA_mainENTRY;
05441 SUMA_STANDALONE_INIT;
05442
05443 if (argc < 4) {
05444 usage_ROI2dataset_Main ();
05445 }
05446
05447
05448 kar = 1;
05449 brk = NOPE;
05450 prefix_name = NULL;
05451 input_name_v = NULL;
05452 N_input_name = 0;
05453 Out_Format = SUMA_ASCII_NIML;
05454 Parent_idcode_str = NULL;
05455 pad_to = -1;
05456 pad_val = 0;
05457 while (kar < argc) {
05458
05459
05460 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
05461 usage_ROI2dataset_Main();
05462 exit (1);
05463 }
05464
05465 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
05466
05467 if (!brk && (strcmp(argv[kar], "-prefix") == 0)) {
05468 kar ++;
05469 if (kar >= argc) {
05470 fprintf (SUMA_STDERR, "need argument after -prefix ");
05471 exit (1);
05472 }
05473 prefix_name = argv[kar];
05474 brk = YUP;
05475 }
05476
05477 if (!brk && (strcmp(argv[kar], "-of") == 0)) {
05478 kar ++;
05479 if (kar >= argc) {
05480 fprintf (SUMA_STDERR, "need argument after -of ");
05481 exit (1);
05482 }
05483 if (!strcmp(argv[kar], "ni_as")) Out_Format = SUMA_ASCII_NIML;
05484 else if (!strcmp(argv[kar], "ni_bi")) Out_Format = SUMA_BINARY_NIML;
05485 else if (!strcmp(argv[kar], "1D")) Out_Format = SUMA_1D;
05486 else {
05487 fprintf (SUMA_STDERR, "%s not a valid option with -of.\n", argv[kar]);
05488 exit (1);
05489 }
05490 brk = YUP;
05491 }
05492
05493 if (!brk && (strcmp(argv[kar], "-dom_par_id") == 0)) {
05494 kar ++;
05495 if (kar >= argc) {
05496 fprintf (SUMA_STDERR, "need argument after -dom_par_id");
05497 exit (1);
05498 }
05499 Parent_idcode_str = SUMA_copy_string(argv[kar]);
05500 brk = YUP;
05501 }
05502
05503 if (!brk && (strcmp(argv[kar], "-input") == 0)) {
05504 kar ++;
05505 if (kar >= argc) {
05506 fprintf (SUMA_STDERR, "need at least one argument after -input ");
05507 exit (1);
05508 }
05509 input_name_v = (char **)SUMA_malloc((argc-kar+1)*sizeof(char *));
05510
05511 cnt = 0;
05512 while (kar < argc) {
05513 input_name_v[cnt] = argv[kar];
05514 ++cnt; ++kar;
05515 }
05516 N_input_name = cnt;
05517 brk = YUP;
05518 }
05519
05520 if (!brk && (strcmp(argv[kar], "-pad_to_node") == 0)) {
05521 kar ++;
05522 if (kar >= argc) {
05523 fprintf (SUMA_STDERR, "need argument after -pad_to_node");
05524 exit (1);
05525 }
05526 pad_to = atoi(argv[kar]);
05527 brk = YUP;
05528 }
05529
05530 if (!brk && (strcmp(argv[kar], "-pad_label") == 0)) {
05531 kar ++;
05532 if (kar >= argc) {
05533 fprintf (SUMA_STDERR, "need argument after -pad_label");
05534 exit (1);
05535 }
05536 pad_val = atoi(argv[kar]);
05537 brk = YUP;
05538 }
05539
05540 if (!brk) {
05541 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
05542 exit (1);
05543 } else {
05544 brk = NOPE;
05545 kar ++;
05546 }
05547 }
05548
05549 if (!prefix_name) {
05550 fprintf (SUMA_STDERR,"Error %s: No output prefix was specified.\n", FuncName);
05551 exit(1);
05552 }
05553
05554
05555 switch (Out_Format) {
05556 case SUMA_ASCII_NIML:
05557 case SUMA_BINARY_NIML:
05558 out_name = SUMA_Extension(prefix_name, ".niml.dset", NOPE);
05559 break;
05560 case SUMA_1D:
05561 out_name = SUMA_Extension(prefix_name, ".1D.dset", NOPE);
05562 break;
05563 default:
05564 SUMA_S_Err("Output format not supported");
05565 exit(1);
05566 break;
05567 }
05568
05569 SUMA_LH (out_name);
05570
05571
05572 if (SUMA_filexists(out_name)) {
05573 fprintf(SUMA_STDERR,"Error %s:\n Output file %s exists.\n",
05574 FuncName, out_name);
05575 exit(1);
05576 }
05577
05578
05579 if (N_input_name <= 0) {
05580 fprintf(SUMA_STDERR,"Error %s:\n No ROI files specified.\n",
05581 FuncName);
05582 exit(1);
05583 }
05584
05585
05586
05587 N_ROIv = 0;
05588 Parent_idcode_str = NULL;
05589 dummy_idcode_str = UNIQ_hashcode("DummyNameNothingLikeIt");
05590 for (i=0; i < N_input_name; ++i) {
05591 if (SUMA_isExtension(input_name_v[i], ".niml.roi")) {
05592
05593 if (!( tROIv = SUMA_OpenDrawnROI_NIML (input_name_v[i], &N_tROI, NOPE))) {
05594 SUMA_S_Err("Failed to read NIML ROI.");
05595 exit(1);
05596 }
05597 }else if (SUMA_isExtension(input_name_v[i], ".1D.roi")) {
05598
05599 if (!( tROIv = SUMA_OpenDrawnROI_1D (input_name_v[i], dummy_idcode_str, &N_tROI, NOPE))) {
05600 SUMA_S_Err("Failed to read NIML ROI.");
05601 exit(1);
05602 }
05603 }else {
05604 SUMA_S_Err( "Failed to recognize\n"
05605 "ROI type from filename.");
05606 exit(1);
05607 }
05608
05609
05610 ROIv = (SUMA_DRAWN_ROI **)SUMA_realloc(ROIv, (N_ROIv + N_tROI) * sizeof(SUMA_DRAWN_ROI*));
05611 if (!ROIv) {
05612 SUMA_S_Err("Failed to allocate.");
05613 exit(1);
05614 }
05615
05616
05617 for (ii=0; ii < N_tROI; ++ii) {
05618 if (!Parent_idcode_str) {
05619
05620 if (strcmp(tROIv[ii]->Parent_idcode_str, dummy_idcode_str)) {
05621 fprintf (SUMA_STDERR,"%s: Adopting Parent_idcode_str (%s) in ROI %s\n",
05622 FuncName, tROIv[ii]->Parent_idcode_str, tROIv[ii]->Label);
05623
05624 Parent_idcode_str = SUMA_copy_string(tROIv[ii]->Parent_idcode_str);
05625 }
05626 }
05627
05628 AddThis = NOPE;
05629 if (!strcmp(tROIv[ii]->Parent_idcode_str, dummy_idcode_str)) {
05630 AddThis = YUP;
05631 } else {
05632 if (strcmp(tROIv[ii]->Parent_idcode_str, Parent_idcode_str)) {
05633 fprintf (SUMA_STDERR,"Warning %s:\n Ignoring ROI labeled %s\n"
05634 "because of Parent_idcode_str mismatch.\n",
05635 FuncName, tROIv[ii]->Label);
05636 AddThis = NOPE;
05637
05638 SUMA_freeDrawnROI (tROIv[ii]); tROIv[ii] = NULL;
05639 }
05640 else AddThis = YUP;
05641
05642 }
05643 if (AddThis) {
05644 if (LocalHead) fprintf (SUMA_STDERR,"%s: Adding %dth ROI to ROIv...\n",
05645 FuncName, N_ROIv);
05646 ROIv[N_ROIv] = tROIv[ii];
05647
05648 ++N_ROIv;
05649 }
05650
05651 }
05652
05653 if (tROIv) SUMA_free(tROIv); tROIv = NULL;
05654 }
05655
05656 if (LocalHead) {
05657 fprintf (SUMA_STDERR,"%s: Kept a total of %d ROIs with parent %s\n",
05658 FuncName, N_ROIv, Parent_idcode_str);
05659
05660 }
05661
05662 if (!(dset = SUMA_ROIv2Grpdataset (ROIv, N_ROIv, Parent_idcode_str, pad_to, pad_val))) {
05663 SUMA_SL_Err("Failed in SUMA_ROIv2Grpdataset");
05664 exit(1);
05665 }
05666
05667 if (LocalHead) {
05668 fprintf (SUMA_STDERR,"%s: Adding history\n",
05669 FuncName);
05670
05671 }
05672
05673
05674 if (!SUMA_AddNgrHist (dset->ngr, FuncName, argc, argv)) {
05675 SUMA_SL_Err("Failed in SUMA_AddNgrHist");
05676 exit(1);
05677 }
05678
05679
05680 if (LocalHead) {
05681 fprintf (SUMA_STDERR,"%s: preparing to write results\n",
05682 FuncName);
05683
05684 }
05685
05686
05687 stmp = SUMA_append_string ("file:", out_name);
05688 ns = NI_stream_open( stmp , "w" ) ;
05689 if( ns == NULL ){
05690 fprintf (stderr,"Error %s:\nCan't open %s!"
05691 , FuncName, stmp);
05692 exit(1);
05693 }
05694
05695
05696 switch (Out_Format) {
05697 case SUMA_ASCII_NIML:
05698 nn = NI_write_element( ns , dset->ngr , NI_TEXT_MODE );
05699 break;
05700 case SUMA_BINARY_NIML:
05701 nn = NI_write_element( ns , dset->ngr , NI_BINARY_MODE );
05702 break;
05703 case SUMA_1D:
05704 nn = NI_write_element( ns , dset->dnel , NI_TEXT_MODE | NI_HEADERSHARP_FLAG);
05705 break;
05706 default:
05707 SUMA_S_Err("Output format not supported");
05708 exit(1);
05709 break;
05710 }
05711
05712 if (nn < 0) {
05713 SUMA_S_Err ("Failed in NI_write_element");
05714 exit(1);
05715 }
05716
05717
05718 NI_stream_close( ns ) ;
05719
05720
05721 SUMA_FreeDset(dset); dset = NULL;
05722
05723
05724 if (stmp) SUMA_free(stmp);
05725 if (ROIv) SUMA_free (ROIv);
05726 if (out_name) SUMA_free(out_name);
05727 if (Parent_idcode_str) SUMA_free(Parent_idcode_str);
05728 if (dummy_idcode_str) free(dummy_idcode_str);
05729
05730 return(0);
05731 }
05732 #endif
05733
05734
05735
05736
05737
05738
05739
05740
05741
05742 void SUMA_SaveSOascii (char *filename, void *data)
05743 {
05744 static char FuncName[]={"SUMA_SaveSOascii"};
05745 char *newname = NULL, *newprefix = NULL, *tmp1= NULL, *tmp2= NULL;
05746 FILE *Fout = NULL;
05747 static int answer;
05748 int ND=-1, NP=-1, ii=-1, id=-1,ip=-1;
05749 GLfloat *glar_ColorList = NULL;
05750 SUMA_SAVESO_STRUCT *SaveSO_data = NULL;
05751 SUMA_Boolean LocalHead = NOPE;
05752
05753 SUMA_ENTRY;
05754
05755 SUMA_LH("Called");
05756
05757 if (!data) {
05758 SUMA_SLP_Err("NULL data");
05759 SUMA_RETURNe;
05760 }
05761
05762 SaveSO_data = (SUMA_SAVESO_STRUCT *)data;
05763 if (!SaveSO_data->SO || !SaveSO_data->sv) {
05764 SUMA_SLP_Err("Null SO or Null sv");
05765 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05766 SUMA_RETURNe;
05767 }
05768
05769
05770 tmp1 = SUMA_Extension(filename, ".1D.xyz", YUP);
05771 tmp2 = SUMA_Extension(tmp1, ".1D.tri", YUP);
05772 newprefix = SUMA_Extension(tmp2, ".1D.col", YUP);
05773 if (tmp1) SUMA_free(tmp1); tmp1 = NULL;
05774 if (tmp2) SUMA_free(tmp2); tmp2 = NULL;
05775
05776
05777 if (newname) SUMA_free(newname); newname = NULL;
05778 newname = SUMA_Extension(newprefix, ".1D.xyz", NOPE);
05779 if (!newname) {
05780 SUMA_SL_Err("Invalid filename");
05781 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05782 SUMA_RETURNe;
05783 }
05784 SUMA_LH(newname);
05785
05786 if (SUMA_filexists (newname)) {
05787 answer = SUMA_ForceUser_YesNo (SUMAg_SVv[0].X->TOPLEVEL,
05788 "Prefix exists, overwrite?",
05789 SUMA_NO, SWP_DONT_CARE);
05790 if (answer == SUMA_NO ||answer == SUMA_NO_ALL) {
05791 if (newname) SUMA_free(newname); newname = NULL;
05792 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05793 SUMA_RETURNe;
05794 }
05795 }
05796
05797
05798 if (answer != SUMA_YES_ALL && answer != SUMA_YES) {
05799 if (newname) SUMA_free(newname);newname = NULL;
05800 newname = SUMA_Extension(newprefix, ".1D.tri", NOPE);
05801 if (!newname) {
05802 SUMA_SL_Err("Invalid filename");
05803 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05804 SUMA_RETURNe;
05805 }
05806 SUMA_LH(newname);
05807
05808 if (SUMA_filexists (newname)) {
05809 answer = SUMA_ForceUser_YesNo (SUMAg_SVv[0].X->TOPLEVEL,
05810 "Prefix exists, overwrite?",
05811 SUMA_NO, SWP_DONT_CARE);
05812 if (answer == SUMA_NO ||answer == SUMA_NO_ALL) {
05813 if (newname) SUMA_free(newname);newname = NULL;
05814 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05815 SUMA_RETURNe;
05816 }
05817 }
05818 }
05819
05820
05821 if (answer != SUMA_YES_ALL && answer != SUMA_YES) {
05822 if (newname) SUMA_free(newname); newname = NULL;
05823 newname = SUMA_Extension(newprefix, ".1D.col", NOPE);
05824 if (!newname) {
05825 SUMA_SL_Err("Invalid filename");
05826 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05827 SUMA_RETURNe;
05828 }
05829 SUMA_LH(newname);
05830
05831 if (SUMA_filexists (newname)) {
05832 answer = SUMA_ForceUser_YesNo (SUMAg_SVv[0].X->TOPLEVEL,
05833 "Prefix exists, overwrite?",
05834 SUMA_NO, SWP_DONT_CARE);
05835 if (answer == SUMA_NO ||answer == SUMA_NO_ALL) {
05836 if (newname) SUMA_free(newname);newname = NULL;
05837 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05838 SUMA_RETURNe;
05839 }
05840 }
05841 }
05842
05843
05844 ND = SaveSO_data->SO->NodeDim;
05845 NP = SaveSO_data->SO->FaceSetDim;
05846
05847 if (newname) SUMA_free(newname);newname = NULL;
05848 newname = SUMA_Extension(newprefix, ".1D.xyz", NOPE);
05849 if (LocalHead) fprintf (SUMA_STDERR,"%s: Preparing to write .1D.xyz %s.\n", FuncName, newname);
05850 Fout = fopen(newname, "w");
05851 if (Fout == NULL) {
05852 fprintf(SUMA_STDERR, "Error %s: Could not open file %s for writing.\n", FuncName, newname);
05853 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05854 SUMA_RETURNe;
05855 }
05856
05857 fprintf(Fout, "#FileContents = Node coordinates\n#RowFormat = X Y Z\n#N_Nodes = %d\n#Source = SUMA, surface %s (idcode: %s)\n",
05858 SaveSO_data->SO->N_Node, SaveSO_data->SO->Label, SaveSO_data->SO->idcode_str);
05859 for (ii=0; ii < SaveSO_data->SO->N_Node; ++ii) {
05860 id = ND * ii;
05861 fprintf(Fout, "%f\t%f\t%f\n", \
05862 SaveSO_data->SO->NodeList[id], SaveSO_data->SO->NodeList[id+1],SaveSO_data->SO->NodeList[id+2]);
05863 }
05864 fclose (Fout);
05865
05866 if (newname) SUMA_free(newname);newname = NULL;
05867 newname = SUMA_Extension(newprefix, ".1D.tri", NOPE);
05868 if (LocalHead) fprintf (SUMA_STDERR,"%s: Preparing to write .1D.tri %s.\n", FuncName, newname);
05869 Fout = fopen(newname, "w");
05870 if (Fout == NULL) {
05871 fprintf(SUMA_STDERR, "Error %s: Could not open file %s for writing.\n", FuncName, newname);
05872 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05873 SUMA_RETURNe;
05874 }
05875
05876 fprintf(Fout, "#FileContents = Triangles\n#RowFormat = n1 n2 n3\n#N_Tri = %d\n#Source = SUMA, surface %s (idcode: %s)\n",
05877 SaveSO_data->SO->N_FaceSet, SaveSO_data->SO->Label, SaveSO_data->SO->idcode_str);
05878 for (ii=0; ii < SaveSO_data->SO->N_FaceSet; ++ii) {
05879 ip = NP * ii;
05880 fprintf(Fout, "%d\t%d\t%d\n", \
05881 SaveSO_data->SO->FaceSetList[ip], SaveSO_data->SO->FaceSetList[ip+1],SaveSO_data->SO->FaceSetList[ip+2]);
05882 }
05883 fclose (Fout);
05884
05885 if (newname) SUMA_free(newname);newname = NULL;
05886 newname = SUMA_Extension(newprefix, ".1D.col", NOPE);
05887 if (LocalHead) fprintf (SUMA_STDERR,"%s: Preparing to write .1D.col %s.\n", FuncName, newname);
05888 Fout = fopen(newname, "w");
05889 if (Fout == NULL) {
05890 fprintf(SUMA_STDERR, "Error %s: Could not open file %s for writing.\n", FuncName, newname);
05891 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05892 SUMA_RETURNe;
05893 }
05894 glar_ColorList = SUMA_GetColorList (SaveSO_data->sv, SaveSO_data->SO->idcode_str);
05895 if (!glar_ColorList) {
05896 fprintf(SUMA_STDERR, "Error %s: NULL glar_ColorList. BAD.\n", FuncName);
05897 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05898 SUMA_RETURNe;
05899 }
05900 fprintf(Fout, "#FileContents = Node Colors\n#RowFormat = n R G B\n#N_Nodes = %d\n#Source = SUMA, surface %s (idcode: %s)\n",
05901 SaveSO_data->SO->N_Node, SaveSO_data->SO->Label, SaveSO_data->SO->idcode_str);
05902 for (ii=0; ii < SaveSO_data->SO->N_Node; ++ii) {
05903 ip = 4 * ii;
05904 fprintf(Fout, "%d\t%f\t%f\t%f\n", \
05905 ii, glar_ColorList[ip], glar_ColorList[ip+1], glar_ColorList[ip+2]);
05906 }
05907 fclose (Fout);
05908
05909 if (LocalHead) fprintf(SUMA_STDERR, "%s: Wrote files to disk.\n",
05910 FuncName);
05911
05912 if (newname) SUMA_free(newname);newname = NULL;
05913 if (SaveSO_data) SUMA_free(SaveSO_data); SaveSO_data = NULL;
05914 if (newprefix) SUMA_free(newprefix);
05915 SUMA_RETURNe;
05916 }
05917
05918
05919
05920
05921
05922
05923
05924
05925 void SUMA_SaveDrawnROI (char *filename, void *data)
05926 {
05927 static char FuncName[]={"SUMA_SaveDrawnROI"};
05928 SUMA_DRAWN_ROI *DrawnROI=NULL;
05929 SUMA_SurfaceObject *SO= NULL;
05930 SUMA_Boolean LocalHead = NOPE;
05931
05932 SUMA_ENTRY;
05933
05934 SUMA_LH("Called");
05935 if (!data) {
05936 DrawnROI = SUMAg_CF->X->DrawROI->curDrawnROI;
05937 } else {
05938 DrawnROI = (SUMA_DRAWN_ROI *)data;
05939 }
05940
05941
05942 if (!DrawnROI) {
05943 SUMA_SLP_Err("No ROI selected.");
05944 SUMA_RETURNe;
05945 }
05946
05947
05948 SO = SUMA_findSOp_inDOv(DrawnROI->Parent_idcode_str, SUMAg_DOv, SUMAg_N_DOv);
05949 if (!SO) {
05950 SUMA_SLP_Err("No Parent surface found.");
05951 SUMA_RETURNe;
05952 }
05953
05954
05955 switch (SUMAg_CF->X->DrawROI->SaveMode) {
05956 case SW_DrawROI_SaveMode1D:
05957 if (!SUMA_SaveDrawnROI_1D (filename, SO, DrawnROI, SUMAg_CF->X->DrawROI->SaveWhat)) {
05958 SUMA_SLP_Err("Failed to save ROI to disk");
05959 SUMA_RETURNe;
05960 }
05961 break;
05962 case SW_DrawROI_SaveModeNIML:
05963 if (!SUMA_SaveDrawnROINIML (filename, SO, DrawnROI, SUMAg_CF->X->DrawROI->SaveWhat, SUMA_ASCII)) {
05964 SUMA_SLP_Err("Failed to save ROI to disk");
05965 SUMA_RETURNe;
05966 }
05967 break;
05968 case SW_DrawROI_SaveMode:
05969 case SW_N_DrawROI_SaveMode:
05970 default:
05971 SUMA_SL_Err("WhatYouTalkinAbout?");
05972 SUMA_RETURNe;
05973 break;
05974 }
05975
05976 SUMA_RETURNe;
05977 }
05978
05979 SUMA_Boolean SUMA_SaveDrawnROI_1D (char *filename, SUMA_SurfaceObject *SO, SUMA_DRAWN_ROI *DrawnROI, int SaveWhat)
05980 {
05981 static char FuncName[]={"SUMA_SaveDrawnROI_1D"};
05982 char stmp[SUMA_MAX_NAME_LENGTH+20];
05983 SUMA_DRAWN_ROI **ROIv = NULL;
05984 int N_ROI=0;
05985 SUMA_Boolean LocalHead = NOPE;
05986
05987 SUMA_ENTRY;
05988 SUMA_LH("Called");
05989
05990 if (SaveWhat == SW_DrawROI_SaveWhatThis) {
05991 if (!SUMA_Write_DrawnROI_1D (&DrawnROI, 1, filename)) {
05992 sprintf(stmp,"Failed to write %s", filename);
05993 SUMA_SLP_Err(stmp);
05994 SUMA_RETURN(NOPE);
05995 }
05996 }else if (SaveWhat == SW_DrawROI_SaveWhatRelated){
05997
05998 if (!(ROIv = SUMA_Find_ROIrelatedtoSO (SO, SUMAg_DOv, SUMAg_N_DOv, &N_ROI))) {
05999 SUMA_SLP_Err("Failed to write ROIs related to SO.");
06000 SUMA_RETURN(NOPE);
06001 }
06002 if (!SUMA_Write_DrawnROI_1D (ROIv, N_ROI, filename)) {
06003 sprintf(stmp,"Failed to write %s", filename);
06004 SUMA_SLP_Err(stmp);
06005 SUMA_RETURN(NOPE);
06006 }
06007
06008 if (ROIv) SUMA_free(ROIv);
06009 } else {
06010 SUMA_SLP_Err("SaveWhat option not nderstood");
06011 SUMA_RETURN(NOPE);
06012 }
06013
06014
06015
06016 SUMA_RETURN(YUP);
06017 }
06018
06019 SUMA_Boolean SUMA_SaveDrawnROINIML (char *filename, SUMA_SurfaceObject *SO, SUMA_DRAWN_ROI *DrawnROI, int SaveWhat, int Format)
06020 {
06021 static char FuncName[]={"SaveDrawnROINIML"};
06022 char stmp[SUMA_MAX_NAME_LENGTH+20];
06023 SUMA_DRAWN_ROI **ROIv = NULL;
06024 int N_ROI=0;
06025 SUMA_Boolean LocalHead = NOPE;
06026
06027 SUMA_ENTRY;
06028 SUMA_LH("Called");
06029
06030 if (SaveWhat == SW_DrawROI_SaveWhatThis) {
06031 if (!SUMA_Write_DrawnROI_NIML (&DrawnROI, 1, filename, Format)) {
06032 sprintf(stmp,"Failed to write %s", filename);
06033 SUMA_SLP_Err(stmp);
06034 SUMA_RETURN(NOPE);
06035 }
06036 }else if (SaveWhat == SW_DrawROI_SaveWhatRelated){
06037
06038 if (!(ROIv = SUMA_Find_ROIrelatedtoSO (SO, SUMAg_DOv, SUMAg_N_DOv, &N_ROI))) {
06039 SUMA_SLP_Err("Failed to write ROIs related to SO.");
06040 SUMA_RETURN(NOPE);
06041 }
06042 if (!SUMA_Write_DrawnROI_NIML (ROIv, N_ROI, filename, Format)) {
06043 sprintf(stmp,"Failed to write %s", filename);
06044 SUMA_SLP_Err(stmp);
06045 SUMA_RETURN(NOPE);
06046 }
06047
06048 if (ROIv) SUMA_free(ROIv);
06049 } else {
06050 SUMA_SLP_Err("SaveWhat option not nderstood");
06051 SUMA_RETURN(NOPE);
06052 }
06053
06054 SUMA_RETURN(YUP);
06055 }
06056
06057
06058
06059
06060
06061 SUMA_Boolean SUMA_Write_DrawnROI_NIML (SUMA_DRAWN_ROI **ROIv, int N_ROI, char *filename, int Format)
06062 {
06063 static char FuncName[]={"SUMA_Write_DrawnROI_NIML"};
06064 char stmp[SUMA_MAX_NAME_LENGTH+20];
06065 char *newname=NULL;
06066 int i;
06067 NI_element *nel ;
06068 NI_stream ns ;
06069 SUMA_NIML_DRAWN_ROI *niml_ROI = NULL;
06070 SUMA_DRAWN_ROI *ROI = NULL;
06071 SUMA_Boolean WriteBin = NOPE, LocalHead = NOPE;
06072
06073 SUMA_ENTRY;
06074
06075 if (Format == SUMA_ASCII) WriteBin = NOPE;
06076 else if (Format == SUMA_BINARY) WriteBin = YUP;
06077 else {
06078 SUMA_SL_Err("Wrong format");
06079 SUMA_RETURN(NOPE);
06080 }
06081
06082 if (SUMAg_CF->nimlROI_Datum_type < 0) {
06083 SUMA_SL_Err("Bad niml type code");
06084 SUMA_RETURN(NOPE);
06085 }
06086 if (LocalHead) fprintf(SUMA_STDERR, "%s: roi_type code = %d\n", FuncName, SUMAg_CF->nimlROI_Datum_type) ;
06087
06088
06089 if (strlen(filename) >= SUMA_MAX_NAME_LENGTH-20) {
06090 SUMA_SLP_Err("Give me a break, what kind of a filename is this ?");
06091 SUMA_RETURN(NOPE);
06092 }
06093
06094 sprintf(stmp,"file:%s", filename);
06095 newname = SUMA_Extension(stmp, ".niml.roi", NOPE);
06096 SUMA_LH(newname);
06097 ns = NI_stream_open( newname , "w" ) ;
06098
06099
06100 for (i=0; i < N_ROI; ++i) {
06101 ROI = ROIv[i];
06102 if (!ROI) {
06103 SUMA_SL_Err("NULL ROI!");
06104 NI_stream_close( ns ) ;
06105 SUMA_RETURN(NOPE);
06106 }
06107
06108 if (!(niml_ROI = SUMA_DrawnROI_to_NIMLDrawnROI (ROI))) {
06109 SUMA_SL_Err("NULL niml_ROI!");
06110 NI_stream_close( ns ) ;
06111 SUMA_RETURN(NOPE);
06112 }
06113
06114
06115 if (LocalHead) fprintf(SUMA_STDERR,"%s: Creating new element of %d segments\n", FuncName, niml_ROI->N_ROI_datum);
06116 nel = NI_new_data_element(SUMA_Dset_Type_Name(SUMA_NODE_ROI), niml_ROI->N_ROI_datum);
06117
06118 SUMA_LH("Adding column...");
06119 NI_add_column( nel , SUMAg_CF->nimlROI_Datum_type, niml_ROI->ROI_datum );
06120
06121 SUMA_LH("Setting attributes...");
06122 NI_set_attribute (nel, "Object_ID", niml_ROI->idcode_str);
06123 NI_set_attribute (nel, "Parent_ID", niml_ROI->Parent_idcode_str);
06124 NI_set_attribute (nel, "Label", niml_ROI->Label);
06125 sprintf(stmp,"%d", niml_ROI->iLabel);
06126 NI_set_attribute (nel, "iLabel", stmp);
06127 sprintf(stmp,"%d", niml_ROI->Type);
06128 NI_set_attribute (nel, "Type", stmp);
06129 NI_set_attribute (nel, "ColPlaneName", niml_ROI->ColPlaneName);
06130 sprintf(stmp,"%f %f %f", niml_ROI->FillColor[0], niml_ROI->FillColor[1],
06131 niml_ROI->FillColor[2]);
06132 NI_set_attribute (nel, "FillColor",stmp);
06133 sprintf(stmp,"%f %f %f", niml_ROI->EdgeColor[0], niml_ROI->EdgeColor[1],
06134 niml_ROI->EdgeColor[2]);
06135 NI_set_attribute (nel, "EdgeColor",stmp);
06136 sprintf(stmp,"%d", niml_ROI->EdgeThickness);
06137 NI_set_attribute (nel, "EdgeThickness", stmp);
06138
06139 if (LocalHead) SUMA_nel_stdout (nel);
06140
06141 if (!WriteBin) {
06142 SUMA_LH ("Writing element, Text mode.");
06143 if (NI_write_element( ns , nel , NI_TEXT_MODE | NI_HEADERSHARP_FLAG ) < 0) {
06144 SUMA_SL_Err("Badness, failed to write nel");
06145 NI_stream_close( ns ) ;
06146 SUMA_RETURN(NOPE);
06147 }
06148 } else {
06149 SUMA_LH ("Writing element, Binary mode.");
06150 if (NI_write_element( ns , nel , NI_BINARY_MODE) < 0) {
06151 SUMA_SL_Err("Badness, failed to write nel");
06152 NI_stream_close( ns ) ;
06153 SUMA_RETURN(NOPE);
06154 }
06155 }
06156
06157
06158 NI_free_element(nel) ; nel = NULL;
06159
06160
06161 niml_ROI = SUMA_Free_NIMLDrawROI (niml_ROI); niml_ROI = NULL;
06162
06163 }
06164
06165 NI_stream_close( ns ) ;
06166
06167 if (newname) SUMA_free(newname);
06168
06169 SUMA_RETURN(YUP);
06170 }
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182 SUMA_1D_DRAWN_ROI * SUMA_DrawnROI_to_1DDrawROI (SUMA_DRAWN_ROI *ROI)
06183 {
06184 static char FuncName[]={"SUMA_DrawnROI_to_1DDrawROI"};
06185 SUMA_1D_DRAWN_ROI *ROI_1D=NULL;
06186 SUMA_ROI_DATUM *ROI_Datum=NULL;
06187 DListElmt *Elm = NULL;
06188 int i = -1, cnt = 0, *isort=NULL, *iLabel=NULL, *iNode=NULL;
06189 SUMA_Boolean LocalHead = NOPE;
06190
06191 SUMA_ENTRY;
06192
06193 if (!ROI) {
06194 SUMA_SL_Err("Null ROI");
06195 SUMA_RETURN(NULL);
06196 }
06197
06198
06199
06200
06201 ROI_1D = (SUMA_1D_DRAWN_ROI *)SUMA_malloc(sizeof(SUMA_1D_DRAWN_ROI));
06202 Elm = NULL;
06203 ROI_1D->N = 0;
06204 do {
06205 if (!Elm) Elm = dlist_head(ROI->ROIstrokelist);
06206 else Elm = Elm->next;
06207 ROI_Datum = (SUMA_ROI_DATUM *)Elm->data;
06208 ROI_1D->N += ROI_Datum->N_n;
06209 } while (Elm != dlist_tail(ROI->ROIstrokelist));
06210
06211 ROI_1D->Type = (int)ROI->Type;
06212 ROI_1D->idcode_str = ROI->idcode_str;
06213 ROI_1D->Parent_idcode_str = ROI->Parent_idcode_str;
06214 ROI_1D->Label = ROI->Label;
06215 ROI_1D->iNode = NULL;
06216 ROI_1D->iLabel = NULL;
06217 iNode = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
06218 iLabel = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
06219 if (!iNode || !iLabel) {
06220 SUMA_SL_Err("Failed to allocate");
06221 SUMA_RETURN(NULL);
06222 }
06223
06224
06225 Elm = NULL;
06226 cnt = 0;
06227 do {
06228 if (!Elm) Elm = dlist_head(ROI->ROIstrokelist);
06229 else Elm = Elm->next;
06230 ROI_Datum = (SUMA_ROI_DATUM *)Elm->data;
06231 for (i=0; i < ROI_Datum->N_n; ++i) {
06232 iNode[cnt] = ROI_Datum->nPath[i];
06233 iLabel[cnt] = ROI->iLabel;
06234 ++cnt;
06235 }
06236 } while (Elm != dlist_tail(ROI->ROIstrokelist));
06237
06238
06239
06240 isort = SUMA_z_dqsort( iNode, ROI_1D->N);
06241
06242
06243 ROI_1D->iLabel = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
06244 ROI_1D->iNode = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
06245 if (!ROI_1D->iNode || !ROI_1D->iLabel) {
06246 SUMA_SL_Err("Failed to allocate");
06247 SUMA_RETURN(NULL);
06248 }
06249
06250 for (i=0; i < ROI_1D->N; ++i) {
06251 ROI_1D->iLabel[i] = iLabel[isort[i]];
06252 }
06253 if (iLabel) SUMA_free(iLabel); iLabel = NULL;
06254
06255
06256 cnt = 0;
06257 ROI_1D->iNode[cnt] = iNode[0];
06258 ROI_1D->iLabel[cnt] = ROI_1D->iLabel[0];
06259 ++cnt;
06260 for (i=1;i<ROI_1D->N;++i)
06261 {
06262 if ((iNode[i] != iNode[i- 1]))
06263 {
06264 ROI_1D->iNode[cnt] = iNode[i];
06265 ROI_1D->iLabel[cnt] = ROI_1D->iLabel[i];
06266 ++cnt;
06267 }
06268 }
06269
06270
06271
06272
06273
06274
06275
06276 ROI_1D->N = cnt;
06277
06278 if (isort) SUMA_free(isort); isort = NULL;
06279 if (iNode) SUMA_free(iNode); iNode = NULL;
06280
06281 SUMA_RETURN(ROI_1D);
06282 }
06283
06284
06285
06286
06287
06288
06289
06290 SUMA_1D_DRAWN_ROI * SUMA_Free_1DDrawROI (SUMA_1D_DRAWN_ROI *ROI_1D)
06291 {
06292 static char FuncName[]={"SUMA_Free_1DDrawROI"};
06293 SUMA_Boolean LocalHead = NOPE;
06294
06295 SUMA_ENTRY;
06296
06297 if (!ROI_1D) SUMA_RETURN(NULL);
06298
06299 if (ROI_1D->iLabel) SUMA_free(ROI_1D->iLabel);
06300 if (ROI_1D->iNode) SUMA_free(ROI_1D->iNode);
06301
06302 SUMA_free(ROI_1D);
06303
06304 SUMA_RETURN(NULL);
06305 }
06306
06307
06308
06309
06310
06311
06312 SUMA_Boolean SUMA_Write_DrawnROI_1D (SUMA_DRAWN_ROI **ROIv, int N_ROI, char *filename)
06313 {
06314 static char FuncName[]={"SUMA_Write_DrawnROI_1D"};
06315 char *newname=NULL;
06316 int i,j;
06317 SUMA_1D_DRAWN_ROI *ROI_1D = NULL;
06318 SUMA_DRAWN_ROI *ROI = NULL;
06319 FILE *fout=NULL;
06320 SUMA_Boolean LocalHead = NOPE;
06321
06322 SUMA_ENTRY;
06323
06324
06325 newname = SUMA_Extension(filename, ".1D.roi", NOPE);
06326 if (!newname) {
06327 SUMA_SL_Err("Invalid filename");
06328 SUMA_RETURN(NOPE);
06329 }
06330
06331 SUMA_LH(newname);
06332
06333 fout = fopen(newname,"w");
06334 if (!fout) {
06335 SUMA_SL_Err("Failed to open file for writing.");
06336 SUMA_RETURN(NOPE);
06337 }
06338
06339
06340 for (i=0; i < N_ROI; ++i) {
06341 ROI = ROIv[i];
06342 if (!ROI) {
06343 SUMA_SL_Err("NULL ROI!");
06344 fclose(fout);
06345 SUMA_RETURN(NOPE);
06346 }
06347
06348 if (!(ROI_1D = SUMA_DrawnROI_to_1DDrawROI (ROI))) {
06349 SUMA_SL_Err("NULL niml_ROI!");
06350 fclose(fout);
06351 SUMA_RETURN(NOPE);
06352 }
06353
06354
06355
06356 fprintf (fout,"# %s\n", SUMA_Dset_Type_Name(SUMA_NODE_ROI));
06357 fprintf (fout,"# ni_type = \"SUMA_1D_ROI_DATUMorint,int?\"\n");
06358 fprintf (fout,"# ni_dimen = \"%d\"\n", ROI_1D->N);
06359 fprintf (fout,"# ni_datasize = \"???\"\n");
06360 fprintf (fout,"# idcode_str = \"%s\"\n", ROI_1D->idcode_str);
06361 fprintf (fout,"# Parent_idcode_str = \"%s\"\n", ROI_1D->Parent_idcode_str);
06362 fprintf (fout,"# Label = \"%s\"\n", ROI_1D->Label);
06363 fprintf (fout,"# >\n");
06364 for (j=0; j < ROI_1D->N; ++j)
06365 fprintf (fout," %d %d\n", ROI_1D->iNode[j], ROI_1D->iLabel[j]);
06366 fprintf (fout,"# </%s>\n", SUMA_Dset_Type_Name(SUMA_NODE_ROI));
06367 fprintf (fout,"\n");
06368
06369
06370 ROI_1D = SUMA_Free_1DDrawROI (ROI_1D); ROI_1D = NULL;
06371 }
06372
06373 fclose(fout) ;
06374 if (newname) SUMA_free(newname);
06375
06376 SUMA_RETURN(YUP);
06377 }
06378
06379
06380 SUMA_FORM_AFNI_DSET_STRUCT *SUMA_New_FormAfniDset_Opt(void)
06381 {
06382 static char FuncName[]={"SUMA_New_FormAfniDset_Opt"};
06383 SUMA_FORM_AFNI_DSET_STRUCT *Opt=NULL;
06384
06385 SUMA_ENTRY;
06386
06387 Opt = (SUMA_FORM_AFNI_DSET_STRUCT*)SUMA_malloc(sizeof(SUMA_FORM_AFNI_DSET_STRUCT));
06388
06389 Opt->master = NULL;
06390 Opt->mset = NULL;
06391 Opt->mask = NULL;
06392 Opt->prefix = NULL;
06393 Opt->prefix_path = NULL;
06394 Opt->orcode = NULL;
06395 Opt->do_ijk = 1;
06396 Opt->dimen_ii=0;
06397 Opt->dimen_jj=0;
06398 Opt->dimen_kk=0;
06399 Opt->datum=MRI_short;
06400 Opt->dval=1.0;
06401 Opt->fval=0.0;
06402 Opt->mmask=NULL;
06403 Opt->full_list = 0;
06404
06405 SUMA_RETURN(Opt);
06406 }
06407
06408 SUMA_FORM_AFNI_DSET_STRUCT *SUMA_Free_FormAfniDset_Opt(SUMA_FORM_AFNI_DSET_STRUCT *Opt)
06409 {
06410 static char FuncName[]={"SUMA_Free_FormAfniDset_Opt"};
06411 SUMA_ENTRY;
06412
06413 if (!Opt) SUMA_RETURN(NULL);
06414
06415 if (Opt->master) SUMA_free(Opt->master);
06416 if (Opt->mask) SUMA_free(Opt->mask);
06417 if (Opt->mset) {
06418 SUMA_SL_Warn("mset is not freed in this function.\nMake sure it is not a lost pointer.\nSet mset to NULL to avoid seeing this message");
06419 }
06420 if (Opt->prefix) SUMA_free(Opt->prefix);
06421 if (Opt->prefix_path) SUMA_free(Opt->prefix_path);
06422 if (Opt->mmask) SUMA_free(Opt->mmask);
06423 if (Opt->orcode) SUMA_free(Opt->orcode);
06424 SUMA_free(Opt);
06425
06426 SUMA_RETURN(NULL);
06427 }
06428
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445
06446
06447
06448
06449
06450
06451
06452
06453
06454
06455
06456
06457
06458
06459
06460
06461
06462
06463
06464
06465
06466
06467
06468
06469 THD_3dim_dataset *SUMA_FormAfnidset (float *NodeList, float *vals, int N_vals, SUMA_FORM_AFNI_DSET_STRUCT *Opt)
06470 {
06471 static char FuncName[]={"SUMA_FormAfnidset"};
06472 THD_coorder cord;
06473 int ii=0,jj=0,kk=0,ll=0,ijk=0 , nx=0,ny=0,nz=0 , nxyz=0 ;
06474 float xx,yy,zz,vv=0.0 , dx,dy,dz;
06475 short sv=0 ;
06476 byte bv=0 ;
06477 float *fbr=NULL, fval_float, dval_float;
06478 byte *bbr=NULL, *mmask=NULL, fval_byte, dval_byte;
06479 short *sbr=NULL, fval_short, dval_short;
06480 char *orcode=NULL;
06481 float xxdown =0.0,xxup=0.0 , yydown=0.0,yyup=0.0 , zzdown=0.0,zzup=0.0 ;
06482
06483 THD_3dim_dataset *dset=NULL, *mset=NULL, *maskset=NULL;
06484
06485
06486 if( Opt->do_ijk == 0 && Opt->master == NULL ) {
06487 SUMA_SL_Err("Can't use mm coords without master.") ;
06488 SUMA_RETURN(NULL);
06489 }
06490 if( (Opt->master == NULL && Opt->mset == NULL) && Opt->dimen_ii < 2 ) {
06491 SUMA_SL_Err("Must use exactly one of Opt->master or Opt->dimen options");
06492 SUMA_RETURN(NULL);
06493 }
06494 if (Opt->master && Opt->mset) {
06495 SUMA_SL_Err("Cannot use Opt->master and Opt->mset");
06496 SUMA_RETURN(NULL);
06497 }
06498
06499 fval_byte = (byte)Opt->fval;
06500 fval_short = (short)Opt->fval;
06501 fval_float = (float)Opt->fval;
06502 dval_byte = (byte)Opt->dval;
06503 dval_short = (short)Opt->dval;
06504 dval_float = (float)Opt->dval;
06505
06506 if( (Opt->datum == MRI_short && dval_short == fval_short) ||
06507 (Opt->datum == MRI_float && dval_float == fval_float) ||
06508 (Opt->datum == MRI_byte && dval_byte == fval_byte ) ){
06509
06510 SUMA_SL_Warn("dval and fval are the same!") ;
06511 }
06512
06513 if (Opt->full_list && NodeList) {
06514 SUMA_SL_Err("Opt->full_list && NodeList");
06515 SUMA_RETURN(NULL);
06516 }
06517 if (!Opt->full_list && !NodeList &&!Opt->mmask) {
06518 SUMA_SL_Err("!Opt->full_list && !NodeList && !Opt->mmask");
06519 SUMA_RETURN(NULL);
06520 }
06521
06522 if (!Opt->prefix || !Opt->prefix_path) {
06523 SUMA_SL_Err("Need a prefix and a prefix_path Joe.");
06524 SUMA_RETURN(NULL);
06525 }
06526
06527 if (!NodeList && !vals && !Opt->mmask) {
06528 SUMA_SL_Warn("Creating a dataset of constants. (!NodeList && !vals && !Opt->mmask)");
06529 }
06530
06531 if (Opt->master) {
06532 mset = THD_open_dataset(Opt->master);
06533 if( mset == NULL ) {
06534 SUMA_SL_Err("-master: can't open dataset" ) ;
06535 SUMA_RETURN(dset);
06536 }
06537 }
06538 if (Opt->mset) mset = Opt->mset;
06539
06540 if ((Opt->master || Opt->mset) && Opt->orcode) {
06541 SUMA_SL_Err("Cannot have bothpt->master && Opt->orcode");
06542 SUMA_RETURN(dset);
06543 }
06544
06545 if (Opt->mask && Opt->mmask) {
06546 SUMA_SL_Err("Cannot have both Opt->mask && Opt->mmask");
06547 SUMA_RETURN(dset);
06548 }
06549
06550 if (Opt->mask) {
06551 maskset = THD_open_dataset( Opt->mask) ;
06552 if( maskset == NULL ) {
06553 SUMA_SL_Err("-mask: can't open dataset" ) ;
06554 if (mset) { DSET_delete(mset); mset = NULL; }
06555 SUMA_RETURN(dset);
06556 }
06557 }
06558
06559
06560
06561
06562 if( mset != NULL ){
06563 orcode = malloc(4) ;
06564 orcode[0] = ORIENT_typestr[mset->daxes->xxorient][0] ;
06565 orcode[1] = ORIENT_typestr[mset->daxes->yyorient][0] ;
06566 orcode[2] = ORIENT_typestr[mset->daxes->zzorient][0] ;
06567 orcode[3] = '\0' ;
06568 } else if (Opt->orcode) {
06569 orcode = malloc(4) ; orcode = strcpy(orcode, Opt->orcode);
06570 } else {
06571 SUMA_SL_Err("Huh?");
06572 if (mset) { DSET_delete(mset); mset = NULL; }
06573 if (maskset) { DSET_delete(maskset); maskset = NULL; }
06574 SUMA_RETURN(dset);
06575 }
06576
06577 THD_coorder_fill( orcode , &cord ) ;
06578
06579
06580 if( mset != NULL ){
06581
06582 dset = EDIT_empty_copy( mset ) ;
06583 EDIT_dset_items( dset ,
06584 ADN_prefix , Opt->prefix ,
06585 ADN_datum_all , Opt->datum ,
06586 ADN_nvals , 1 ,
06587 ADN_ntt , 0 ,
06588 ADN_func_type , ISANAT(mset) ? mset->func_type
06589 : FUNC_FIM_TYPE ,
06590
06591 ADN_directory_name , Opt->prefix_path ,
06592 ADN_none ) ;
06593
06594 } else {
06595 THD_ivec3 iv_nxyz , iv_xyzorient ;
06596 THD_fvec3 fv_xyzorg , fv_xyzdel ;
06597
06598 LOAD_IVEC3( iv_nxyz , Opt->dimen_ii , Opt->dimen_jj , Opt->dimen_kk ) ;
06599 LOAD_IVEC3( iv_xyzorient , cord.xxor , cord.yyor , cord.zzor ) ;
06600 LOAD_FVEC3( fv_xyzdel ,
06601 ORIENT_sign[iv_xyzorient.ijk[0]]=='+' ? 1.0 : -1.0 ,
06602 ORIENT_sign[iv_xyzorient.ijk[1]]=='+' ? 1.0 : -1.0 ,
06603 ORIENT_sign[iv_xyzorient.ijk[2]]=='+' ? 1.0 : -1.0 ) ;
06604 LOAD_FVEC3( fv_xyzorg ,
06605 ORIENT_sign[iv_xyzorient.ijk[0]]=='+' ? -0.5*Opt->dimen_ii : 0.5*Opt->dimen_ii,
06606 ORIENT_sign[iv_xyzorient.ijk[1]]=='+' ? -0.5*Opt->dimen_jj : 0.5*Opt->dimen_jj,
06607 ORIENT_sign[iv_xyzorient.ijk[2]]=='+' ? -0.5*Opt->dimen_kk : 0.5*Opt->dimen_kk ) ;
06608
06609 dset = EDIT_empty_copy( NULL ) ;
06610
06611 EDIT_dset_items( dset ,
06612 ADN_nxyz , iv_nxyz ,
06613 ADN_xyzdel , fv_xyzdel ,
06614 ADN_xyzorg , fv_xyzorg ,
06615 ADN_xyzorient , iv_xyzorient ,
06616 ADN_prefix , Opt->prefix ,
06617 ADN_datum_all , Opt->datum ,
06618 ADN_nvals , 1 ,
06619 ADN_ntt , 0 ,
06620 ADN_type , HEAD_FUNC_TYPE ,
06621 ADN_func_type , FUNC_FIM_TYPE ,
06622 ADN_directory_name , Opt->prefix_path ,
06623 ADN_none ) ;
06624
06625 }
06626
06627 if( THD_is_file(DSET_HEADNAME(dset)) ) {
06628 SUMA_SL_Err("Output dataset already exists -- can't overwrite") ;
06629 exit(1);
06630 }
06631
06632
06633 EDIT_substitute_brick( dset , 0 , Opt->datum , NULL ) ;
06634
06635 nx = DSET_NX(dset); ny = DSET_NY(dset); nz = DSET_NZ(dset); nxyz = nx*ny*nz;
06636
06637 if (Opt->full_list && N_vals != nxyz) {
06638 SUMA_SL_Err("Opt->full_list && N_vals != nx*ny*nz");
06639 SUMA_RETURN(NULL);
06640 }
06641
06642
06643 if( maskset != NULL &&
06644 ( DSET_NX(maskset) != nx ||
06645 DSET_NY(maskset) != ny ||
06646 DSET_NZ(maskset) != nz ) ) {
06647 SUMA_SL_Err("mask dataset doesn't match dimension of output dataset") ;
06648 if (mset) { DSET_delete(mset); mset = NULL; }
06649 if (maskset) { DSET_delete(maskset); maskset = NULL; }
06650 SUMA_RETURN(NULL);
06651 }
06652
06653 if( maskset != NULL ){
06654 mmask = THD_makemask( maskset , 0 , 1.0,-1.0 ) ;
06655 SUMA_SL_Warn("can't create mask for some reason!") ;
06656 DSET_delete(maskset) ;
06657 } else mmask = Opt->mmask;
06658
06659 if( mmask == NULL ){
06660 } else {
06661 int nmask = THD_countmask( nxyz , mmask ) ;
06662 if( nmask == 0 ){
06663 SUMA_SL_Warn("0 voxels in mask -- ignoring it!") ;
06664 if (!Opt->mmask) free((void *)mmask) ; mmask = NULL ;
06665 } else {
06666 fprintf(SUMA_STDERR,"%s:++ %d voxels found in mask\n", FuncName, nmask) ;
06667 }
06668 }
06669
06670
06671 switch( Opt->datum ){
06672 case MRI_short:
06673 if (0) fprintf(SUMA_STDERR,"%s: Filling with %d\n", FuncName, fval_short);
06674 sbr = (short *) DSET_BRICK_ARRAY(dset,0) ;
06675 for( ii=0 ; ii < nxyz ; ii++ ) sbr[ii] = fval_short ;
06676 break ;
06677
06678 case MRI_float:
06679 fbr = (float *) DSET_BRICK_ARRAY(dset,0) ;
06680 for( ii=0 ; ii < nxyz ; ii++ ) fbr[ii] = fval_float ;
06681 break ;
06682
06683 case MRI_byte:
06684 bbr = (byte *) DSET_BRICK_ARRAY(dset,0) ;
06685 for( ii=0 ; ii < nxyz ; ii++ ) bbr[ii] = fval_byte ;
06686 break ;
06687 }
06688
06689
06690
06691 dx = fabs(dset->daxes->xxdel) ; if( dx <= 0.0 ) dx = 1.0 ;
06692 dy = fabs(dset->daxes->yydel) ; if( dy <= 0.0 ) dy = 1.0 ;
06693 dz = fabs(dset->daxes->zzdel) ; if( dz <= 0.0 ) dz = 1.0 ;
06694
06695 if( !Opt->do_ijk ){
06696 #ifndef EXTEND_BBOX
06697 xxdown = dset->daxes->xxmin - 0.501 * dx ;
06698 xxup = dset->daxes->xxmax + 0.501 * dx ;
06699 yydown = dset->daxes->yymin - 0.501 * dy ;
06700 yyup = dset->daxes->yymax + 0.501 * dy ;
06701 zzdown = dset->daxes->zzmin - 0.501 * dz ;
06702 zzup = dset->daxes->zzmax + 0.501 * dz ;
06703 #else
06704 xxdown = dset->daxes->xxmin ;
06705 xxup = dset->daxes->xxmax ;
06706 yydown = dset->daxes->yymin ;
06707 yyup = dset->daxes->yymax ;
06708 zzdown = dset->daxes->zzmin ;
06709 zzup = dset->daxes->zzmax ;
06710 #endif
06711 }
06712
06713 for (ll=0; ll<N_vals; ++ll) {
06714
06715 if (!Opt->full_list) {
06716 xx = NodeList[3*ll]; yy = NodeList[3*ll+1]; zz = NodeList[3*ll+2];
06717 if (Opt->do_ijk) {
06718 ii = (int) rint(xx) ; jj = (int) rint(yy) ; kk = (int) rint(zz) ;
06719 if( ii < 0 || ii >= nx ){
06720 fprintf(stderr,
06721 "Warning %s: entry %d: i index=%d is invalid, ignoring...\n",
06722 FuncName,ll,ii) ;
06723 continue ;
06724 }
06725 if( jj < 0 || jj >= ny ){
06726 fprintf(stderr,
06727 "Warning %s: entry %d: j index=%d is invalid, ignoring...\n",
06728 FuncName, ll,jj) ;
06729 continue ;
06730 }
06731 if( kk < 0 || kk >= nz ){
06732 fprintf(stderr,
06733 "Warning %s: entry %d: k index=%d is invalid\n",
06734 FuncName,ll,kk) ;
06735 continue ;
06736 }
06737 } else {
06738
06739 THD_fvec3 mv , dv ;
06740 THD_ivec3 iv ;
06741
06742 THD_coorder_to_dicom( &cord , &xx,&yy,&zz ) ;
06743 LOAD_FVEC3( dv , xx,yy,zz ) ;
06744 mv = THD_dicomm_to_3dmm( dset , dv ) ;
06745
06746
06747
06748 if( mv.xyz[0] < xxdown || mv.xyz[0] > xxup ){
06749 fprintf(stderr,"+++ Warning %s: line %d: x coord=%g is outside %g .. %g\n" ,
06750 FuncName,ll,mv.xyz[0] , xxdown,xxup ) ;
06751 continue ;
06752 }
06753 if( mv.xyz[1] < yydown || mv.xyz[1] > yyup ){
06754 fprintf(stderr,"+++ Warning %s: line %d: y coord=%g is outside %g .. %g\n" ,
06755 FuncName,ll,mv.xyz[1] , yydown , yyup ) ;
06756 continue ;
06757 }
06758 if( mv.xyz[2] < zzdown || mv.xyz[2] > zzup ){
06759 fprintf(stderr,"+++ Warning %s: line %d: z coord=%g is outside %g .. %g\n" ,
06760 FuncName,ll,mv.xyz[2] , zzdown , zzup ) ;
06761 continue ;
06762 }
06763
06764 iv = THD_3dmm_to_3dind( dset , mv ) ;
06765 ii = iv.ijk[0]; jj = iv.ijk[1]; kk = iv.ijk[2];
06766 }
06767
06768 ijk = ii + jj*nx + kk*nx*ny ;
06769 } else {
06770 ijk = ll;
06771 }
06772
06773 if (vals) vv = vals[ll];
06774 else vv = dval_float ;
06775
06776 if( mmask == NULL || mmask[ijk] ){
06777 switch( Opt->datum ){
06778 case MRI_float:{
06779 if( fbr[ijk] != fval_float && fbr[ijk] != vv )
06780 fprintf(stderr,"Overwrite voxel %d %d %d\n",ii,jj,kk) ;
06781 fbr[ijk] = vv ;
06782 }
06783 break ;
06784 case MRI_short:{
06785 sv = SHORTIZE(vv) ;
06786 if( sbr[ijk] != fval_short && sbr[ijk] != sv )
06787 fprintf(stderr,"Overwrite voxel %d %d %d\n",ii,jj,kk) ;
06788 sbr[ijk] = sv ;
06789 }
06790 break ;
06791 case MRI_byte:{
06792 bv = BYTEIZE(vv) ;
06793 if( bbr[ijk] != fval_byte && bbr[ijk] != bv )
06794 fprintf(stderr,"Overwrite voxel %d %d %d\n",ii,jj,kk) ;
06795 bbr[ijk] = bv ;
06796 }
06797 break ;
06798 }
06799 }
06800
06801 }
06802
06803 if (orcode) free(orcode); orcode = NULL;
06804 if (mmask && !Opt->mmask) free(mmask); mmask = NULL;
06805 if (mset && !Opt->mset) DSET_delete(mset); mset = NULL;
06806
06807 SUMA_RETURN(dset);
06808 }
06809
06810
06811
06812
06813
06814
06815
06816
06817
06818
06819
06820
06821
06822
06823
06824
06825 NI_group *SUMA_SO2nimlSO(SUMA_SurfaceObject *SO, char *optlist, int nlee)
06826 {
06827 static char FuncName[]={"SUMA_SO2nimlSO"};
06828 NI_group *ngr = NULL;
06829 NI_element *nel = NULL;
06830 char stmp[500];
06831 SUMA_Boolean LocalHead = NOPE;
06832
06833 SUMA_ENTRY;
06834
06835 if (!SO) {
06836 SUMA_SL_Err("Null SO"); SUMA_RETURN(ngr);
06837 }
06838
06839
06840 ngr = NI_new_group_element();
06841 NI_rename_group(ngr, "SurfaceObject");
06842
06843
06844
06845
06846 switch (SO->FaceSetDim) {
06847 case 3:
06848 NI_set_attribute(ngr, "Object_Type", "Triangulated_Surface");
06849 break;
06850 default:
06851 NI_set_attribute(ngr, "Object_Type", SUMA_EMPTY_ATTR);
06852 SUMA_SL_Warn("FaceSetDim not supported");
06853 break;
06854 }
06855
06856
06857 if (SO->idcode_str) {
06858 NI_set_attribute(ngr, "Object_ID", SO->idcode_str);
06859 } else {
06860 NI_set_attribute(ngr, "Object_ID", SUMA_EMPTY_ATTR);
06861 }
06862
06863
06864 if (SO->Label) {
06865 NI_set_attribute(ngr, "Object_Label", SO->Label);
06866 } else {
06867 NI_set_attribute(ngr, "Object_Label", SUMA_EMPTY_ATTR);
06868 }
06869
06870
06871
06872 if (SO->LocalDomainParentID) {
06873 NI_set_attribute(ngr, "Parent_ID", SO->LocalDomainParentID);
06874 } else {
06875 NI_set_attribute(ngr, "Parent_ID", SUMA_EMPTY_ATTR);
06876 }
06877
06878
06879 if (SO->DomainGrandParentID) {
06880 NI_set_attribute(ngr, "Grand_Parent_ID", SO->DomainGrandParentID);
06881 } else {
06882 NI_set_attribute(ngr, "Grand_Parent_ID", SUMA_EMPTY_ATTR);
06883 }
06884
06885
06886
06887
06888 if (SO->Group_idcode_str) {
06889 NI_set_attribute(ngr, "Subject_ID", SO->Group_idcode_str);
06890 } else {
06891 NI_set_attribute(ngr, "Subject_ID", SUMA_EMPTY_ATTR);
06892 }
06893
06894 if (SO->Group) {
06895 NI_set_attribute(ngr, "Subject_Label", SO->Group);
06896 } else {
06897 NI_set_attribute(ngr, "Subject_Label", SUMA_EMPTY_ATTR);
06898 }
06899
06900 if (SO->OriginatorID) {
06901 NI_set_attribute(ngr, "Instance_ID", SO->OriginatorID);
06902 } else {
06903 NI_set_attribute(ngr, "Instance_ID", SUMA_EMPTY_ATTR);
06904 }
06905
06906 if (SO->OriginatorLabel) {
06907 NI_set_attribute(ngr, "Instance_Label", SO->OriginatorLabel);
06908 } else {
06909 NI_set_attribute(ngr, "Instance_Label", SUMA_EMPTY_ATTR);
06910 }
06911
06912 if (SO->ModelName) {
06913 NI_set_attribute(ngr, "Model_Name", SO->ModelName);
06914 } else {
06915 NI_set_attribute(ngr, "Model_Name", SUMA_EMPTY_ATTR);
06916 }
06917
06918 switch (SO->Side) {
06919 case SUMA_NO_SIDE:
06920 NI_set_attribute(ngr, "Side", "none");
06921 break;
06922 case SUMA_LEFT:
06923 NI_set_attribute(ngr, "Side", "left");
06924 break;
06925 case SUMA_RIGHT:
06926 NI_set_attribute(ngr, "Side", "right");
06927 break;
06928 default:
06929 NI_set_attribute(ngr, "Side", SUMA_EMPTY_ATTR);
06930 break;
06931 }
06932
06933 if (SO->State) {
06934 NI_set_attribute(ngr, "Layer_Name", SO->State);
06935 } else {
06936 NI_set_attribute(ngr, "Layer_Name", SUMA_EMPTY_ATTR);
06937 }
06938
06939 if (SO->AnatCorrect) {
06940 NI_set_attribute(ngr, "Anatomically_Correct", "yes");
06941 } else {
06942 NI_set_attribute(ngr, "Anatomically_Correct", "no");
06943 }
06944
06945 sprintf(stmp,"%d", SO->EmbedDim);
06946 NI_set_attribute(ngr, "Embedding_Dimension", stmp);
06947
06948 if (SO->FileType >=0) {
06949 sprintf(stmp,"%s", SUMA_SurfaceTypeString(SO->FileType));
06950 NI_set_attribute(ngr, "Surface_Creation_Software", stmp);
06951 } else {
06952 NI_set_attribute(ngr, "Surface_Creation_Software", SUMA_EMPTY_ATTR);
06953 }
06954
06955 NI_set_attribute(ngr, "Surface_Creation_History", SUMA_EMPTY_ATTR);
06956
06957 if (SO->StandardSpace) {
06958 NI_set_attribute(ngr, "Standard_Space", SO->StandardSpace);
06959 } else {
06960 NI_set_attribute(ngr, "Standard_Space", SUMA_EMPTY_ATTR);
06961 }
06962
06963 if (!nlee || SUMA_iswordin(optlist,"FaceSetList")) {
06964 if (SO->facesetlist_idcode_str) {
06965 NI_set_attribute(ngr, "Mesh_Element_ID", SO->facesetlist_idcode_str);
06966 } else {
06967 if (SO->idcode_str) {
06968 sprintf(stmp, "facesetlist_idcode_str_%s", SO->idcode_str);
06969 SUMA_NEW_ID(SO->facesetlist_idcode_str, stmp);
06970 NI_set_attribute(ngr, "Mesh_Element_ID", SO->facesetlist_idcode_str);
06971 } else {
06972 NI_set_attribute(ngr, "Mesh_Element_ID", SUMA_EMPTY_ATTR);
06973 }
06974 }
06975 }
06976
06977 if (!nlee || SUMA_iswordin(optlist,"NodeList")) {
06978 if (SO->nodelist_idcode_str) {
06979 NI_set_attribute(ngr, "NodeList_Element_ID", SO->nodelist_idcode_str);
06980 } else {
06981 if (SO->idcode_str) {
06982 sprintf(stmp, "nodelist_idcode_str_%s", SO->idcode_str);
06983 SUMA_NEW_ID(SO->nodelist_idcode_str, stmp);
06984 NI_set_attribute(ngr, "NodeList_Element_ID", SO->nodelist_idcode_str);
06985 } else {
06986 NI_set_attribute(ngr, "NodeList_Element_ID", SUMA_EMPTY_ATTR);
06987 }
06988 }
06989 }
06990 if (!nlee || SUMA_iswordin(optlist,"facenormals")) {
06991 if (SO->facenormals_idcode_str) {
06992 NI_set_attribute(ngr, "Polygon_Normals_Element_ID", SO->facenormals_idcode_str);
06993 } else {
06994 if (SO->idcode_str) {
06995 sprintf(stmp, "facenormals_idcode_str_%s", SO->idcode_str);
06996 SUMA_NEW_ID(SO->facenormals_idcode_str, stmp);
06997 NI_set_attribute(ngr, "Polygon_Normals_Element_ID", SO->facenormals_idcode_str);
06998 } else {
06999 NI_set_attribute(ngr, "Polygon_Normals_Element_ID", SUMA_EMPTY_ATTR);
07000 }
07001 }
07002 }
07003
07004 if (!nlee || SUMA_iswordin(optlist,"NodeNormals")) {
07005 if (SO->nodenormals_idcode_str) {
07006 NI_set_attribute(ngr, "Node_Normals_Element_ID", SO->nodenormals_idcode_str);
07007 } else {
07008 if (SO->idcode_str) {
07009 sprintf(stmp, "nodenormals_idcode_str_%s", SO->idcode_str);
07010 SUMA_NEW_ID(SO->nodenormals_idcode_str, stmp);
07011 NI_set_attribute(ngr, "Node_Normals_Element_ID", SO->nodenormals_idcode_str);
07012 } else {
07013 NI_set_attribute(ngr, "Node_Normals_Element_ID", SUMA_EMPTY_ATTR);
07014 }
07015 }
07016 }
07017
07018 if (!nlee || SUMA_iswordin(optlist,"PolyArea")) {
07019 if (SO->polyarea_idcode_str) {
07020 NI_set_attribute(ngr, "Polygon_Area_Element_ID", SO->polyarea_idcode_str);
07021 } else {
07022 if (SO->idcode_str) {
07023 sprintf(stmp, "polyarea_idcode_str_%s", SO->idcode_str);
07024 SUMA_NEW_ID(SO->polyarea_idcode_str, stmp);
07025 NI_set_attribute(ngr, "Polygon_Area_Element_ID", SO->polyarea_idcode_str);
07026 } else {
07027 NI_set_attribute(ngr, "Polygon_Area_Element_ID", SUMA_EMPTY_ATTR);
07028 }
07029 }
07030 }
07031
07032 if (!nlee || SUMA_iswordin(optlist,"EdgeList")) {
07033
07034 if (SO->EL && SO->EL->idcode_str) {
07035 NI_set_attribute(ngr, "SUMA_Edge_List_Element_ID", SO->EL->idcode_str);
07036 } else {
07037 NI_set_attribute(ngr, "SUMA_Edge_List_Element_ID", SUMA_EMPTY_ATTR);
07038 }
07039 }
07040
07041 if (!nlee || SUMA_iswordin(optlist,"MemberFace")) {
07042 if (SO->MF && SO->MF->idcode_str) {
07043 NI_set_attribute(ngr, "SUMA_Node_Face_Member_Element_ID", SO->MF->idcode_str);
07044 } else {
07045 NI_set_attribute(ngr, "SUMA_Node_Face_Member_Element_ID", SUMA_EMPTY_ATTR);
07046 }
07047 }
07048
07049 if (!nlee || SUMA_iswordin(optlist,"NodeNeighb")) {
07050 if (SO->FN && SO->FN->idcode_str) {
07051 NI_set_attribute(ngr, "SUMA_Node_First_Neighb_Element_ID", SO->FN->idcode_str);
07052 } else {
07053 NI_set_attribute(ngr, "SUMA_Node_First_Neighb_Element_ID", SUMA_EMPTY_ATTR);
07054 }
07055 }
07056
07057 if (!nlee) {
07058
07059
07060
07061
07062 if (SO->parent_vol_idcode_str) {
07063 NI_set_attribute(ngr, "SUMA_Afni_Parent_Vol_ID", SO->parent_vol_idcode_str);
07064 } else {
07065 NI_set_attribute(ngr, "SUMA_Afni_Parent_Vol_ID", SUMA_EMPTY_ATTR);
07066 }
07067 }
07068
07069
07070
07071
07072
07073
07074 if (SUMA_iswordin(optlist,"NodeList")) {
07075 SUMA_LH("Adding Nodelist nel...");
07076 nel = SUMA_NodeXYZ2NodeXYZ_nel (SO, SO->NodeList, 0, SUMA_NEW_NODE_XYZ);
07077 if (!nel) { SUMA_SL_Err("Failed to create nel"); NI_free_element(ngr); SUMA_RETURN(NULL); }
07078 NI_add_to_group( ngr, nel);
07079 }
07080
07081
07082 if (SUMA_iswordin(optlist,"FaceSetList")) {
07083 SUMA_LH("Adding Nodelist nel...");
07084 nel = SUMA_Mesh_IJK2Mesh_IJK_nel (SO, SO->FaceSetList, 0, SUMA_NEW_MESH_IJK);
07085 if (!nel) { SUMA_SL_Err("Failed to create nel"); NI_free_element(ngr); SUMA_RETURN(NULL); }
07086 NI_add_to_group( ngr, nel);
07087 }
07088
07089
07090 if (SUMA_iswordin(optlist,"EdgeList")) {
07091 SUMA_LH("Adding EdgeList nel...");
07092 SUMA_SL_Warn("Option not implemented yet.");
07093 if (SO->EL) {
07094
07095
07096 }
07097 }
07098
07099
07100 if (SUMA_iswordin(optlist,"MemberFace")) {
07101 SUMA_LH("Adding Member of FaceSet nel...");
07102 SUMA_SL_Warn("Option not implemented yet.");
07103 if (SO->MF) {
07104
07105
07106 }
07107 }
07108
07109
07110 if (SUMA_iswordin(optlist,"NodeNeighb")) {
07111 SUMA_LH("Adding node neighbors nel...");
07112 SUMA_SL_Warn("Option not implemented yet.");
07113 if (SO->FN) {
07114
07115
07116 }
07117 }
07118
07119
07120 if (SUMA_iswordin(optlist,"VolPar")) {
07121 SUMA_LH("Adding VolPar nel ...");
07122 if (SO->VolPar) {
07123 nel = SUMA_SOVolPar2VolPar_nel (SO, SO->VolPar, SUMA_SURFACE_VOLUME_PARENT);
07124 if (!nel) { SUMA_SL_Err("Failed to create nel"); NI_free_element(ngr); SUMA_RETURN(NULL); }
07125 NI_add_to_group( ngr, nel);
07126 }
07127 }
07128
07129
07130 if (1) {
07131 int suc;
07132 SUMA_SL_Warn("writing SO group to DISK!");
07133 NEL_WRITE_TX(ngr, "file:Test_SO2NIML_write_asc_1D", suc);
07134 }
07135
07136 SUMA_RETURN(ngr);
07137 }
07138
07139 SUMA_SurfaceObject *SUMA_nimlSO2SO(NI_group *ngr)
07140 {
07141 static char FuncName[]={"SUMA_nimlSO2SO"};
07142 NI_element *nel = NULL;
07143 char stmp[500], *tmp;
07144 int ip;
07145 SUMA_SurfaceObject *SO=NULL;
07146 SUMA_Boolean LocalHead = NOPE;
07147
07148 SUMA_ENTRY;
07149
07150 if (!ngr) { SUMA_SL_Err("Null ngr"); SUMA_RETURN(SO); }
07151
07152 if (strcmp(ngr->name, "SurfaceObject")) {
07153 fprintf (SUMA_STDERR,"Error %s: group name (%s) is not (SUMA_SurfaceObject)\nObject does not appear to be a surface.", FuncName, ngr->name);
07154 }
07155
07156
07157 SO = SUMA_Alloc_SurfObject_Struct(1);
07158 if (!SO) { SUMA_SL_Err("Failed to create SO."); SUMA_RETURN(SO); }
07159
07160
07161 tmp = SUMA_copy_string(NI_get_attribute(ngr,"Object_ID"));
07162 if (SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07163 SUMA_SL_Warn("No ID in nel.\nThat's not cool yall.\n I'll be adding a new one now."); SUMA_NEW_ID(SO->idcode_str, NULL);
07164 NI_set_attribute(ngr, "Group_ID", SO->idcode_str);
07165 } else SO->idcode_str = SUMA_copy_string(tmp);
07166
07167 tmp = NI_get_attribute(ngr, "Object_Type");
07168 if (SUMA_IS_EMPTY_STR_ATTR(tmp)) { SUMA_SL_Err("Missing Object Type."); SUMA_Free_Surface_Object(SO); SO = NULL; SUMA_RETURN(SO); }
07169 if (!strcmp(tmp, "Triangulated_Surface")) SO->FaceSetDim = 3;
07170 else {
07171 fprintf (SUMA_STDERR,"Error %s: Object_Type %s not recognized.\n", FuncName, tmp);
07172 SUMA_Free_Surface_Object(SO); SO = NULL; SUMA_RETURN(SO);
07173 }
07174
07175 tmp = NI_get_attribute(ngr, "Object_Label");
07176 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->Label = SUMA_copy_string(tmp);
07177
07178
07179 tmp = NI_get_attribute(ngr, "Parent_ID");
07180 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->LocalDomainParentID = SUMA_copy_string(tmp);
07181
07182
07183
07184 tmp = NI_get_attribute(ngr, "Grand_Parent_ID");
07185 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->DomainGrandParentID = SUMA_copy_string(tmp);
07186
07187
07188
07189
07190
07191 tmp = NI_get_attribute(ngr, "Subject_ID");
07192 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->Group_idcode_str = SUMA_copy_string(tmp);
07193
07194 tmp = NI_get_attribute(ngr, "Subject_Label");
07195 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->Group = SUMA_copy_string(tmp);
07196
07197 tmp = NI_get_attribute(ngr, "Instance_ID");
07198 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->OriginatorID = SUMA_copy_string(tmp);
07199
07200 tmp = NI_get_attribute(ngr, "Instance_Label");
07201 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->OriginatorLabel = SUMA_copy_string(tmp);
07202
07203 tmp = NI_get_attribute(ngr, "Model_Name");
07204 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->ModelName = SUMA_copy_string(tmp);
07205
07206 tmp = NI_get_attribute(ngr, "Side");
07207 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07208 if (!strcmp(tmp,"none")) SO->Side = SUMA_NO_SIDE;
07209 else if (!strcmp(tmp,"left")) SO->Side = SUMA_LEFT;
07210 else if (!strcmp(tmp,"right")) SO->Side = SUMA_RIGHT;
07211 }
07212
07213 tmp = NI_get_attribute(ngr, "Layer_Name");
07214 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->State = SUMA_copy_string(tmp);
07215
07216 tmp = NI_get_attribute(ngr, "Anatomically_Correct");
07217 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07218 if (!strcmp(tmp,"yes")) SO->AnatCorrect = 1;
07219 else SO->AnatCorrect = 0;
07220 }
07221
07222 tmp = NI_get_attribute(ngr, "Embedding_Dimension");
07223 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->EmbedDim = atoi(tmp);
07224
07225 tmp = NI_get_attribute(ngr, "Surface_Creation_Software");
07226 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->FileType = SUMA_SurfaceTypeCode(tmp);
07227
07228 tmp = NI_get_attribute(ngr, "Standard_Space");
07229 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->StandardSpace = SUMA_copy_string(tmp);
07230
07231 tmp = NI_get_attribute(ngr, "SUMA_Afni_Parent_Vol_ID");
07232 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) SO->parent_vol_idcode_str = SUMA_copy_string(tmp);
07233
07234
07235
07236
07237
07238 for( ip=0 ; ip < ngr->part_num ; ip++ ){
07239 switch( ngr->part_typ[ip] ){
07240
07241 case NI_GROUP_TYPE:
07242 SUMA_SL_Err("Not ready from groups inside surface group. Group ignored");
07243 break ;
07244 case NI_ELEMENT_TYPE:
07245 nel = (NI_element *)ngr->part[ip] ;
07246 if (LocalHead) {
07247 fprintf(SUMA_STDERR,"%s: name=%s vec_len=%d vec_filled=%d, vec_num=%d\n", FuncName,\
07248 nel->name, nel->vec_len, nel->vec_filled, nel->vec_num );
07249 }
07250
07251
07252 if( strcmp(nel->name,"Node_XYZ") == 0 || strcmp(nel->name,"NewNode_XYZ") == 0) {
07253 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nGetting NodeList...\n",
07254 FuncName);
07255 if (!SUMA_NodeXYZ_nel2NodeXYZ(SO, nel)) {
07256 SUMA_SL_Err("Failed in SUMA_NodeXYZ_nel2NodeXYZ");
07257 SUMA_Free_Surface_Object(SO); SO = NULL; SUMA_RETURN(SO);
07258 }
07259 } else if ( strcmp(nel->name,"Mesh_IJK") == 0 || strcmp(nel->name,"NewMesh_IJK") == 0) {
07260 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nGetting FaceSetList...\n",
07261 FuncName);
07262 if (!SUMA_Mesh_IJK_nel2Mesh_IJK(SO, nel)) {
07263 SUMA_SL_Err("Failed in SUMA_Mesh_IJK_nel2Mesh_IJK");
07264 SUMA_Free_Surface_Object(SO); SO = NULL; SUMA_RETURN(SO);
07265 }
07266 } else if ( strcmp(nel->name,"SurfaceVolumeParent") == 0) {
07267 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nGetting VolPar...\n",
07268 FuncName);
07269 if (!SUMA_VolPar_nel2SOVolPar(SO, nel)) {
07270 SUMA_SL_Err("Failed in SUMA_VolPar_nel2SOVolPar");
07271 SUMA_Free_Surface_Object(SO); SO = NULL; SUMA_RETURN(SO);
07272 }
07273 } else {
07274 fprintf (SUMA_STDERR,"Warning %s:\n nel (%s) unknown, ignoring it.\n", FuncName, nel->name);
07275 }
07276 break;
07277 default:
07278 SUMA_SL_Err("Don't know what to make of this group element, ignoring.");
07279 break;
07280 }
07281 }
07282
07283 if (!SO->NodeList || !SO->FaceSetList) {
07284 SUMA_SL_Err("Looks like NodeList and/or FaceSetList not in group. Balking.\n");
07285 SUMA_Free_Surface_Object(SO); SO = NULL; SUMA_RETURN(SO);
07286 }
07287
07288
07289 tmp = NI_get_attribute(ngr, "Mesh_Element_ID");
07290 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07291 if (!SO->FaceSetList) {
07292 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for FaceSetList element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07293
07294
07295
07296
07297 }
07298 }
07299
07300 tmp = NI_get_attribute(ngr, "NodeList_Element_ID");
07301 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07302 if (!SO->NodeList) {
07303 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for NodeList element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07304
07305
07306
07307
07308 }
07309 }
07310
07311 tmp = NI_get_attribute(ngr, "facenormals_idcode_str");
07312 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07313 if (!SO->FaceNormList) {
07314 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for facenormals element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07315
07316
07317
07318
07319 }
07320 }
07321
07322 tmp = NI_get_attribute(ngr, "Node_Normals_Element_ID");
07323 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07324 if (!SO->NodeNormList) {
07325 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for Node_Normals element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07326
07327
07328
07329
07330 }
07331 }
07332
07333 tmp = NI_get_attribute(ngr, "Polygon_Area_Element_ID");
07334 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07335 if (!SO->PolyArea) {
07336 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for Polygon_Area element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07337
07338
07339
07340
07341 }
07342 }
07343
07344 tmp = NI_get_attribute(ngr, "SUMA_Edge_List_Element_ID");
07345 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07346 if (!SO->EL) {
07347 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for Edge_List element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07348
07349
07350
07351
07352 }
07353 }
07354
07355 tmp = NI_get_attribute(ngr, "SUMA_Node_Face_Member_Element_ID");
07356 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07357 if (!SO->MF) {
07358 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for Node_Face_Member element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07359
07360
07361
07362
07363 }
07364 }
07365
07366 tmp = NI_get_attribute(ngr, "SUMA_Node_First_Neighb_Element_ID");
07367 if (!SUMA_IS_EMPTY_STR_ATTR(tmp)) {
07368 if (!SO->FN) {
07369 fprintf (SUMA_STDERR,"Warning %s:\n group %s called for Node_First_Neighb element_ID %s which was not found.\n", FuncName, ngr->name, tmp);
07370
07371
07372
07373
07374 }
07375 }
07376
07377
07378 if (SO->MF && SO->MF->idcode_str) {
07379 NI_set_attribute(ngr, "SUMA_Node_Face_Member_Element_ID", SO->MF->idcode_str);
07380 } else {
07381 NI_set_attribute(ngr, "SUMA_Node_Face_Member_Element_ID", SUMA_EMPTY_ATTR);
07382 }
07383
07384 if (SO->FN && SO->FN->idcode_str) {
07385 NI_set_attribute(ngr, "SUMA_Node_First_Neighb_Element_ID", SO->FN->idcode_str);
07386 } else {
07387 NI_set_attribute(ngr, "SUMA_Node_First_Neighb_Element_ID", SUMA_EMPTY_ATTR);
07388 }
07389
07390
07391
07392 SUMA_RETURN(SO);
07393 }
07394
07395
07396
07397 SUMA_OPEN_DX_STRUCT *SUMA_Alloc_OpenDX_Struct(void)
07398 {
07399 static char FuncName[]={"SUMA_Alloc_OpenDX_Struct"};
07400 int i;
07401 SUMA_OPEN_DX_STRUCT *dx = NULL;
07402
07403 SUMA_ENTRY;
07404
07405 dx = (SUMA_OPEN_DX_STRUCT *)SUMA_malloc(sizeof(SUMA_OPEN_DX_STRUCT));
07406 dx->rank = 0;
07407 dx->shape = 0;
07408 dx->items = 0;
07409 dx->bad_data = 0;
07410 dx->object = NULL;
07411 dx->class = NULL;
07412 dx->type = NULL;
07413 dx->data = NULL;
07414 dx->data_format = 0;
07415 dx->data_off = NULL;
07416 dx->datap = NULL;
07417 dx->n_comp = 0;
07418 dx->counts = NULL;
07419 dx->n_counts = 0;
07420 dx->origin = NULL;
07421 dx->n_origin = 0;
07422 dx->delta = NULL;
07423 dx->n_delta = 0;
07424 for (i=0; i<SUMA_MAX_OPEN_DX_FIELD_COMPONENTS; ++i) { dx->comp_name[i] = dx->comp_value[i] =NULL; }
07425 dx->n_attr = 0;
07426 for (i=0; i<SUMA_MAX_OPEN_DX_FIELD_ATTRIBUTES; ++i) { dx->attr_name[i] = dx->attr_string[i] =NULL; }
07427 SUMA_RETURN(dx);
07428 }
07429
07430 SUMA_OPEN_DX_STRUCT ** SUMA_Free_OpenDX_StructVec(SUMA_OPEN_DX_STRUCT **dxv, int nobj)
07431 {
07432 static char FuncName[]={"SUMA_Free_OpenDX_StructVec"};
07433 int i;
07434
07435 SUMA_ENTRY;
07436
07437 if (!dxv) SUMA_RETURN(NULL);
07438 for (i=0; i<nobj; ++i) {
07439 dxv[i] = SUMA_Free_OpenDX_Struct(dxv[i]);
07440 }
07441 SUMA_free(dxv);
07442 SUMA_RETURN(NULL);
07443 }
07444
07445 SUMA_OPEN_DX_STRUCT *SUMA_Free_OpenDX_Struct(SUMA_OPEN_DX_STRUCT *dx)
07446 {
07447 static char FuncName[]={"SUMA_Free_OpenDX_Struct"};
07448 int i;
07449
07450 SUMA_ENTRY;
07451
07452 if (!dx) SUMA_RETURN(dx);
07453 if (dx->object) SUMA_free(dx->object); dx->object = NULL;
07454 if (dx->class) SUMA_free(dx->class); dx->class = NULL;
07455 if (dx->data) SUMA_free(dx->data); dx->data = NULL;
07456 if (dx->data_off) SUMA_free(dx->data_off); dx->data_off = NULL;
07457 if (dx->datap) {
07458 if ( SUMA_OK_OPENDX_DATA_TYPE(SUMA_VarType2TypeCast (dx->type)) ) {
07459 SUMA_free(dx->datap); dx->datap = NULL;
07460 } else {
07461 SUMA_SL_Warn("Do not know how to free datap.\nYou now possibly have a leak on your hands.");
07462 }
07463 }
07464 if (dx->type) SUMA_free(dx->type); dx->type = NULL;
07465 for (i=0; i<SUMA_MAX_OPEN_DX_FIELD_COMPONENTS; ++i) {
07466 if (dx->comp_name[i]) SUMA_free(dx->comp_name[i]); dx->comp_name[i] = NULL;
07467 if (dx->comp_value[i]) SUMA_free(dx->comp_value[i]); dx->comp_value[i] =NULL;
07468 }
07469 for (i=0; i<SUMA_MAX_OPEN_DX_FIELD_ATTRIBUTES; ++i) {
07470 if (dx->attr_name[i]) SUMA_free(dx->attr_name[i]); dx->attr_name[i] = NULL;
07471 if (dx->attr_string[i]) SUMA_free(dx->attr_string[i]); dx->attr_string[i] =NULL;
07472 }
07473 if (dx->origin) SUMA_free(dx->origin);
07474 if (dx->delta) SUMA_free(dx->delta);
07475 if (dx->counts) SUMA_free(dx->counts);
07476 SUMA_free(dx); dx = NULL;
07477 SUMA_RETURN(dx);
07478 }
07479
07480 void SUMA_Show_OpenDX_Struct(SUMA_OPEN_DX_STRUCT **dxv, int N_dxv, FILE *out)
07481 {
07482 static char FuncName[]={"SUMA_Show_OpenDX_Struct"};
07483 int i, idx;
07484 SUMA_STRING *SS=NULL;
07485 char *s = NULL;
07486 SUMA_OPEN_DX_STRUCT *dx=NULL;
07487
07488 SUMA_ENTRY;
07489
07490 SS = SUMA_StringAppend(NULL, NULL);
07491 if (!dxv) SS = SUMA_StringAppend(SS, "NULL dxv\n");
07492 for (idx = 0; idx < N_dxv; ++idx) {
07493 dx = dxv[idx];
07494 SS = SUMA_StringAppend_va(SS, "Object Struct %d/%d\n", idx+1, N_dxv);
07495 if (!dx) SS = SUMA_StringAppend(SS, "NULL dx\n");
07496 else {
07497 if (dx->object) SS = SUMA_StringAppend_va(SS, "object: %s\n", dx->object);
07498 else SS = SUMA_StringAppend_va(SS, "object: NULL\n");
07499 if (dx->class) SS = SUMA_StringAppend_va(SS, "class: %s\n", dx->class);
07500 else SS = SUMA_StringAppend_va(SS, "class: NULL\n");
07501 if (dx->type) SS = SUMA_StringAppend_va(SS, "type: %s\n", dx->type);
07502 else SS = SUMA_StringAppend_va(SS, "type: NULL\n");
07503 if (dx->rank) SS = SUMA_StringAppend_va(SS, "rank: %d\n", dx->rank);
07504 else SS = SUMA_StringAppend_va(SS, "rank: 0\n");
07505 if (dx->shape) SS = SUMA_StringAppend_va(SS, "shape: %d\n", dx->shape);
07506 else SS = SUMA_StringAppend_va(SS, "shape: 0\n");
07507 if (dx->items) SS = SUMA_StringAppend_va(SS, "items: %d\n", dx->items);
07508 else SS = SUMA_StringAppend_va(SS, "items: 0\n");
07509 if (dx->counts) {
07510 SS = SUMA_StringAppend_va(SS, "counts: (%d vals)\n", dx->n_counts);
07511 s = SUMA_ShowMeSome(dx->counts, SUMA_int, dx->n_counts, 5);
07512 SS = SUMA_StringAppend_va(SS, "\t%s\n", s); SUMA_free(s); s = NULL;
07513 } else SS = SUMA_StringAppend_va(SS, "counts: NULL\n");
07514 if (dx->origin) {
07515 SS = SUMA_StringAppend_va(SS, "origin: (%d vals)\n", dx->n_origin);
07516 s = SUMA_ShowMeSome(dx->origin, SUMA_float, dx->n_origin, 5);
07517 SS = SUMA_StringAppend_va(SS, "\t%s\n", s); SUMA_free(s); s = NULL;
07518 } else SS = SUMA_StringAppend_va(SS, "origin: NULL\n");
07519 if (dx->delta) {
07520 SS = SUMA_StringAppend_va(SS, "delta: (%d vals)\n", dx->n_delta);
07521 s = SUMA_ShowMeSome(dx->delta, SUMA_float, dx->n_delta, 9);
07522 SS = SUMA_StringAppend_va(SS, "\t%s\n", s); SUMA_free(s); s = NULL;
07523 }else SS = SUMA_StringAppend_va(SS, "delta: NULL\n");
07524
07525 if (dx->data) SS = SUMA_StringAppend_va(SS, "data: %s (Data load error %d)\n", dx->data, dx->bad_data);
07526 else SS = SUMA_StringAppend_va(SS, "data: NULL\n");
07527 if (dx->data_off) SS = SUMA_StringAppend_va(SS, "data_off: %s \n", dx->data_off);
07528 else SS = SUMA_StringAppend_va(SS, "data_off: NULL\n");
07529 SS = SUMA_StringAppend_va(SS, "data_format: %d \n", dx->data_format);
07530 if (dx->datap) {
07531 s = SUMA_ShowMeSome(dx->datap, SUMA_VarType2TypeCast(dx->type), dx->items * SUMA_NCOL_OPENDX(dx), 5);
07532 SS = SUMA_StringAppend_va(SS, "\t%s\n", s); SUMA_free(s); s = NULL;
07533 }
07534 if (dx->n_comp) {
07535 SS = SUMA_StringAppend_va(SS, "components: %d\n", dx->n_comp);
07536 for (i=0; i<dx->n_comp; ++i) {
07537 if (dx->comp_name[i]) SS = SUMA_StringAppend_va(SS, "\tname: %s\t", dx->comp_name[i]);
07538 else SS = SUMA_StringAppend_va(SS, "\tname: NULL\t");
07539 if (dx->comp_value[i]) SS = SUMA_StringAppend_va(SS, "\ttype: %s\n", dx->comp_value[i]);
07540 else SS = SUMA_StringAppend_va(SS, "\ttype: NULL\n");
07541 }
07542 } else {
07543 SS = SUMA_StringAppend_va(SS, "components: %d\n", dx->n_comp);
07544 }
07545 if (dx->n_attr) {
07546 SS = SUMA_StringAppend_va(SS, "attributes: %d\n", dx->n_attr);
07547 for (i=0; i<dx->n_attr; ++i) {
07548 if (dx->attr_name[i]) SS = SUMA_StringAppend_va(SS, "\tname: %s\t", dx->attr_name[i]);
07549 else SS = SUMA_StringAppend_va(SS, "\tname: NULL\t");
07550 if (dx->attr_string[i]) SS = SUMA_StringAppend_va(SS, "\tstring: %s\n", dx->attr_string[i]);
07551 else SS = SUMA_StringAppend_va(SS, "\tstring: NULL\n");
07552 }
07553 } else {
07554 SS = SUMA_StringAppend_va(SS, "attributes: %d\n", dx->n_attr);
07555 }
07556 }
07557 }
07558
07559 SUMA_SS2S(SS,s);
07560 if (!out) fprintf(stdout, "%s", s);
07561 else fprintf(out, "%s", s);
07562
07563 SUMA_free(s); s = NULL;
07564
07565 SUMA_RETURNe;
07566 }
07567
07568 SUMA_Boolean SUMA_OpenDX_Write(char *fname, SUMA_SurfaceObject *SO)
07569 {
07570 static char FuncName[]={"SUMA_OpenDX_Write"};
07571
07572 SUMA_ENTRY;
07573
07574 SUMA_SL_Err("Not supported yet");
07575
07576 SUMA_RETURN(NOPE);
07577 }
07578
07579
07580
07581
07582
07583 SUMA_Boolean SUMA_OpenDx_Object_Data(char *op, int nchar, SUMA_OPEN_DX_STRUCT *dx)
07584 {
07585 static char FuncName[]={"SUMA_OpenDx_Object_Data"};
07586 int i, Found = 0, ival;
07587 char *op_end, cend, *op2, *sval;
07588 char *op_orig;
07589 SUMA_Boolean LocalHead = NOPE;
07590
07591 SUMA_ENTRY;
07592
07593
07594 op_orig = op;
07595 cend = op_orig[nchar-1]; op_orig[nchar-1] = '\0';
07596 op_end = op_orig + nchar - 1;
07597 if (LocalHead) {
07598 int j, show;
07599 show = 500;
07600 fprintf(SUMA_STDERR,"%s Object\n", FuncName);
07601 j=0; while (op[j] && j<500) { fprintf(SUMA_STDERR,"%c", op[j]); ++j; }
07602 fprintf(SUMA_STDERR,"\n");
07603 }
07604 SUMA_ADVANCE_PAST(op,op_end,"data",Found,1);
07605 sval = NULL;
07606 if (Found) {
07607
07608 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07609 if (op2 == op) {
07610 SUMA_LH("Empty data?");
07611 dx->data=NULL;
07612 } else {
07613 SUMA_COPY_TO_STRING(op, op2, sval);
07614 dx->data = sval; sval = NULL;
07615 }
07616 op = op2;
07617
07618 if (dx->data && strstr(dx->data,"follows")){
07619 int nread=0;
07620 SUMA_LH("data inside");
07621 if (LocalHead) {
07622 int j, show;
07623 show = 500;
07624 fprintf(SUMA_STDERR,"%s Object\n", FuncName);
07625 j=0; while (op[j] && j<500) { fprintf(SUMA_STDERR,"%c", op[j]); ++j; }
07626 fprintf(SUMA_STDERR,"\n");
07627 }
07628 dx->datap = SUMA_strtol_vec(op, dx->items*SUMA_NCOL_OPENDX(dx), &nread, SUMA_VarType2TypeCast (dx->type));
07629 if (LocalHead) {
07630 fprintf(SUMA_STDERR,"%s: Read %d/%d values\n", FuncName, nread, dx->items*SUMA_NCOL_OPENDX(dx));
07631 }
07632 if (nread != dx->items*SUMA_NCOL_OPENDX(dx)) {
07633 fprintf(SUMA_STDERR,"Error %s: read in %d values, expected %d \n", FuncName, nread, dx->items*SUMA_NCOL_OPENDX(dx));
07634 op_orig[nchar-1] = cend;
07635 SUMA_RETURN(NOPE);
07636 }
07637 }else {
07638 SUMA_LH("data does not follow");
07639 if (LocalHead) {
07640 for (i=0; i < 500; ++i) { fprintf(SUMA_STDERR,"%c", op[i]); } fprintf(SUMA_STDERR,"\n"); fflush(SUMA_STDERR);
07641 }
07642
07643 if (strstr(dx->data,"file")) {
07644 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07645 if (op2 > op) {
07646 SUMA_free(dx->data);
07647 SUMA_COPY_TO_STRING(op, op2, sval);
07648 dx->data = sval; sval = NULL;
07649
07650 i=strlen(dx->data)-1; Found = -1;
07651 while(i>=0 && Found <0) { if (dx->data[i] == ',') Found = i; --i; }
07652 if (Found >= 0) {
07653 dx->data_off = SUMA_copy_string(&(dx->data[Found+1]));
07654 dx->data[Found]='\0';
07655 }
07656
07657 dx->data_format = 0;
07658 op = op_orig; SUMA_ADVANCE_PAST(op,op_end,"binary",Found,1);
07659 if (Found) {
07660 dx->data_format = MSB_FIRST;
07661 }
07662
07663 op = op_orig; SUMA_ADVANCE_PAST(op,op_end,"msb",Found,1);
07664 if (Found) { dx->data_format = MSB_FIRST; }
07665 else {
07666 op = op_orig; SUMA_ADVANCE_PAST(op,op_end,"lsb",Found,1);
07667 if (Found) { dx->data_format = LSB_FIRST; }
07668 }
07669 }
07670 }
07671 }
07672 } else {
07673 SUMA_LH("No data for this object");
07674 }
07675
07676 op_orig[nchar-1] = cend;
07677 SUMA_RETURN(YUP);
07678 }
07679
07680
07681
07682
07683
07684 SUMA_Boolean SUMA_OpenDx_Object_Attr(char *op, int nchar, SUMA_OPEN_DX_STRUCT *dx)
07685 {
07686 static char FuncName[]={"SUMA_OpenDx_Object_Attr"};
07687 int i, Found, ival,imax;
07688 char *op_end, cend, *op2, *sval;
07689 char *op_orig;
07690 SUMA_Boolean LocalHead = NOPE;
07691
07692 SUMA_ENTRY;
07693
07694
07695
07696 op_orig = op;
07697 cend = op_orig[nchar-1]; op_orig[nchar-1] = '\0';
07698 op_end = op_orig + nchar - 1;
07699
07700 SUMA_ADVANCE_PAST(op,op_end,"attribute",Found, 1);
07701 sval = NULL;
07702 while (Found) {
07703
07704 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07705 if (op2 == op) {
07706 SUMA_LH("Empty attribute?");
07707 } else {
07708 imax = op2 - op;
07709 if (imax > 5000) {
07710 SUMA_SL_Err("Unexpectedly large field!");
07711 op_orig[nchar-1] = cend;
07712 SUMA_RETURN(NOPE);
07713 }else if (imax < 0) {
07714 SUMA_SL_Err("Negative imax!");
07715 op_orig[nchar-1] = cend;
07716 SUMA_RETURN(NOPE);
07717 }
07718 sval = (char *)SUMA_calloc(imax + 2, sizeof(char));
07719
07720 for (i=0; i < imax; ++i) sval[i] = op[i];
07721 sval[imax] = '\0';
07722 dx->attr_name[dx->n_attr] = sval;
07723 }
07724 op = op2;
07725
07726 SUMA_ADVANCE_PAST(op,op_end,"string",Found,1);
07727 if (Found) {
07728 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07729 if (op2 == op) {
07730 SUMA_LH("Empty string?");
07731 } else {
07732 imax = op2 - op;
07733 if (imax > 5000) {
07734 SUMA_SL_Err("Unexpectedly large field!");
07735 op_orig[nchar-1] = cend;
07736 SUMA_RETURN(NOPE);
07737 }else if (imax < 0) {
07738 SUMA_SL_Err("Negative imax!");
07739 op_orig[nchar-1] = cend;
07740 SUMA_RETURN(NOPE);
07741 }
07742 sval = (char *)SUMA_calloc(imax + 2, sizeof(char));
07743
07744 for (i=0; i < imax; ++i) sval[i] = op[i];
07745 sval[imax] = '\0';
07746 dx->attr_string[dx->n_attr] = sval;
07747 }
07748 }
07749 ++dx->n_attr;
07750
07751 op = op2;
07752 SUMA_ADVANCE_PAST(op,op_end,"attribute",Found,1);
07753 }
07754
07755 op_orig[nchar-1] = cend;
07756 SUMA_RETURN(YUP);
07757 }
07758
07759
07760
07761 SUMA_Boolean SUMA_OpenDx_Object_Components(char *op, int nchar, SUMA_OPEN_DX_STRUCT *dx)
07762 {
07763 static char FuncName[]={"SUMA_OpenDx_Object_Components"};
07764 int i, Found, ival,imax;
07765 char *op_end, cend, *op2, *sval;
07766 char *op_orig;
07767 SUMA_Boolean LocalHead = NOPE;
07768
07769 SUMA_ENTRY;
07770
07771
07772
07773 op_orig = op;
07774 cend = op_orig[nchar-1]; op_orig[nchar-1] = '\0';
07775 op_end = op_orig + nchar - 1;
07776
07777 SUMA_ADVANCE_PAST(op,op_end,"component",Found,1);
07778 while (Found) {
07779
07780 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07781 if (op2 == op) {
07782 SUMA_LH("Empty component?");
07783 } else {
07784 imax = op2 - op;
07785 if (imax > 5000) {
07786 SUMA_SL_Err("Unexpectedly large field!");
07787 op_orig[nchar-1] = cend;
07788 SUMA_RETURN(NOPE);
07789 }else if (imax < 0) {
07790 SUMA_SL_Err("Negative imax!");
07791 op_orig[nchar-1] = cend;
07792 SUMA_RETURN(NOPE);
07793 }
07794 sval = (char *)SUMA_calloc(imax + 2, sizeof(char));
07795
07796 for (i=0; i < imax; ++i) sval[i] = op[i];
07797 sval[imax] = '\0';
07798 dx->comp_name[dx->n_comp] = sval;
07799 }
07800 op = op2;
07801
07802 SUMA_ADVANCE_PAST(op,op_end,"value",Found,1);
07803 if (Found) {
07804 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07805 if (op2 == op) {
07806 SUMA_SL_Err("No value!");
07807 } else {
07808 imax = op2 - op;
07809 if (imax > 5000) {
07810 SUMA_SL_Err("Unexpectedly large field!");
07811 op_orig[nchar-1] = cend;
07812 SUMA_RETURN(NOPE);
07813 }else if (imax < 0) {
07814 SUMA_SL_Err("Negative imax!");
07815 op_orig[nchar-1] = cend;
07816 SUMA_RETURN(NOPE);
07817 }
07818 sval = (char *)SUMA_calloc(imax + 2, sizeof(char));
07819
07820 for (i=0; i < imax; ++i) sval[i] = op[i];
07821 sval[imax] = '\0';
07822 dx->comp_value[dx->n_comp] = sval;
07823 }
07824 }else {
07825 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07826 if (op2 == op) {
07827 SUMA_SL_Err("No value at all");
07828 } else {
07829 imax = op2 - op;
07830 if (imax > 5000) {
07831 SUMA_SL_Err("Unexpectedly large field!");
07832 op_orig[nchar-1] = cend;
07833 SUMA_RETURN(NOPE);
07834 }else if (imax < 0) {
07835 SUMA_SL_Err("Negative imax!");
07836 op_orig[nchar-1] = cend;
07837 SUMA_RETURN(NOPE);
07838 }
07839 sval = (char *)SUMA_calloc(imax + 2, sizeof(char));
07840
07841 for (i=0; i < imax; ++i) sval[i] = op[i];
07842 sval[imax] = '\0';
07843 dx->comp_value[dx->n_comp] = sval;
07844 }
07845 }
07846 ++dx->n_comp;
07847
07848 op = op2;
07849 SUMA_ADVANCE_PAST(op,op_end,"component",Found,1);
07850 }
07851
07852 op_orig[nchar-1] = cend;
07853 SUMA_RETURN(YUP);
07854 }
07855
07856
07857
07858
07859
07860
07861
07862
07863
07864
07865
07866
07867 void * SUMA_OpenDx_Object_Header_Field(char *op, int nchar, const char *attr, char **opeofield)
07868 {
07869 static char FuncName[]={"SUMA_OpenDx_Object_Header_Field"};
07870 void *ans=NULL;
07871 int i, Found, ival, imax, nread;
07872 char *op_end = NULL, cend, *op2, *sval, *pp1, *pp2;
07873 char *op_orig;
07874 SUMA_Boolean LocalHead = NOPE;
07875
07876 SUMA_ENTRY;
07877
07878 if (opeofield) *opeofield = op;
07879
07880 if (!attr) SUMA_RETURN(ans);
07881 op_orig = op;
07882 cend = op_orig[nchar-1]; op_orig[nchar-1] = '\0';
07883
07884 op_end = NULL;
07885 pp1 = strstr(op, "data");
07886 if (pp1) {
07887 pp2 = strstr(op, "follows");
07888 if (pp2) op_end = pp2;
07889 }
07890 if (!op_end) op_end = op_orig + nchar - 1;
07891
07892 if (LocalHead) {
07893 fprintf(SUMA_STDERR,"%s: Object of %d chars, looking for >>>%s<<<\n", FuncName, nchar, attr );
07894 }
07895
07896
07897 SUMA_ADVANCE_PAST(op,op_end,attr,Found,1);
07898 if (Found) {
07899 SUMA_GET_BETWEEN_BLANKS(op, op_end, op2);
07900 if (op2 == op) {
07901 SUMA_LH("No field");
07902 } else {
07903
07904 if (strstr(attr,"rank") || strstr(attr,"shape") || strstr(attr,"items")) {
07905 ival = (int)strtol(op, NULL , 10);
07906 ans = (void*)&ival;
07907 } else if (strstr(attr,"counts")) {
07908 ans = SUMA_AdvancePastNumbers(op, &op2, SUMA_int);
07909 } else if (strstr(attr,"origin") || strstr(attr,"delta")) {
07910 ans = SUMA_AdvancePastNumbers(op, &op2, SUMA_float);
07911 } else {
07912 imax = op2 - op;
07913 if (imax > 5000) {
07914 SUMA_SL_Err("Unexpectedly large field!");
07915 op_orig[nchar-1] = cend;
07916 SUMA_RETURN(ans);
07917 }else if (imax < 0) {
07918 SUMA_SL_Err("Negative imax!");
07919 op_orig[nchar-1] = cend;
07920 SUMA_RETURN(ans);
07921 }
07922 sval = (char *)SUMA_calloc(imax + 2, sizeof(char));
07923
07924 for (i=0; i < imax; ++i) sval[i] = op[i];
07925 sval[imax] = '\0';
07926 ans = (void*)&sval;
07927 }
07928 if (LocalHead) {
07929 fprintf(SUMA_STDERR,"%s: attribute >>>%s<<< is:\n", FuncName, attr);
07930 i = 0;
07931 while (op[i] && op+i != op2) {
07932 fprintf(SUMA_STDERR,"%c", op[i]);
07933 ++i;
07934 }
07935 fprintf(SUMA_STDERR,"\n");
07936 }
07937
07938 }
07939 op = op2;
07940 } else {
07941 if (strstr(attr,"class")) {
07942
07943 SUMA_ADVANCE_PAST(op,op_end,"field", Found,1);
07944 if (Found) sval = SUMA_copy_string("field");
07945 ans = (void*)&sval;
07946 } else {
07947 SUMA_LH("No such attribute");
07948 }
07949 }
07950
07951 op_orig[nchar-1] = cend;
07952 if (opeofield) *opeofield = op;
07953 SUMA_RETURN(ans);
07954 }
07955
07956
07957
07958 SUMA_OPEN_DX_STRUCT **SUMA_OpenDX_Read(char *fname, int *nobj)
07959 {
07960 static char FuncName[]={"SUMA_OpenDX_Read"};
07961 int nread = 0, i = 0, iop, *ivalp=NULL, shft=0;
07962 char *fl=NULL, **opv = NULL, *op = NULL,*sbuf=NULL, **svalp=NULL, *ope;
07963 int *nchar = NULL;
07964 SUMA_OPEN_DX_STRUCT **dxv=NULL;
07965 SUMA_FVEC *fvec=NULL;
07966 SUMA_IVEC *ivec=NULL;
07967 SUMA_Boolean LocalHead = NOPE;
07968
07969 SUMA_ENTRY;
07970
07971 *nobj = 0;
07972
07973 SUMA_LH("Sucking file");
07974 nread = SUMA_suck_file( fname , &fl ) ;
07975 if (!fl) {
07976 SUMA_SL_Err("Failed to read file.");
07977 SUMA_RETURN(dxv);
07978 }
07979
07980 if (LocalHead) fprintf(SUMA_STDERR,"%s: Read in %d chars\n", FuncName, nread);
07981
07982 opv = (char **)SUMA_calloc(SUMA_MAX_OPEN_DX_OBJECTS, sizeof(char*));
07983 nchar = (int*)SUMA_calloc(SUMA_MAX_OPEN_DX_OBJECTS, sizeof(int));
07984 dxv = (SUMA_OPEN_DX_STRUCT **)SUMA_calloc(SUMA_MAX_OPEN_DX_OBJECTS, sizeof(SUMA_OPEN_DX_STRUCT *));
07985
07986
07987 op = fl;
07988 iop = 0;
07989 shft = 0;
07990 do {
07991 op = strstr((op+shft), "object");
07992 if (op) {
07993 opv[iop] = op;
07994 if (iop) nchar[iop-1] = opv[iop] - opv[iop-1];
07995 if (LocalHead) {
07996 fprintf(SUMA_STDERR,"%s: Object found.\n", FuncName);
07997 i = 0;
07998 while (i<20 && op[i] !='\0') { fprintf(SUMA_STDERR,"%c",op[i]); ++i; } fprintf(SUMA_STDERR,"\n");
07999 }
08000
08001
08002 shft = strlen("object");
08003 ++iop;
08004 }
08005 } while (op && iop < SUMA_MAX_OPEN_DX_OBJECTS);
08006 if (iop >= SUMA_MAX_OPEN_DX_OBJECTS) {
08007 SUMA_SL_Warn("Too many objects, processing first SUMA_MAX_OPEN_DX_OBJECTS only");
08008 }
08009
08010 if (iop) {
08011 op = opv[iop-1];
08012 while (*op !='\0') { ++op; }
08013 nchar[iop-1] = op - opv[iop-1];
08014 }
08015
08016 if (LocalHead) {
08017 fprintf(SUMA_STDERR,"%s: %d Objects found.\n", FuncName, iop);
08018 }
08019
08020 for (i=0; i<iop; ++i) {
08021 if ( 0 && LocalHead) {
08022 int j, nmax;
08023 nmax = 500;
08024 fprintf(SUMA_STDERR,"%s Object %d\n", FuncName, i);
08025 op = opv[i]; for (j=0; j<nmax; ++j) fprintf(SUMA_STDERR,"%c", op[j]);
08026 fprintf(SUMA_STDERR,"\n");
08027 }
08028
08029 dxv[i] = SUMA_Alloc_OpenDX_Struct();
08030 ivalp = (int *)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "rank", NULL);
08031 if (ivalp) dxv[i]->rank = *ivalp;
08032 ivalp = (int *)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "shape", NULL);
08033 if (ivalp) dxv[i]->shape = *ivalp;
08034 ivalp = (int *)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "items", NULL);
08035 if (ivalp) dxv[i]->items = *ivalp;
08036 svalp = (char **)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "object", NULL);
08037 if (svalp) dxv[i]->object = *svalp;
08038 svalp = (char **)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "class", NULL);
08039 if (svalp) dxv[i]->class = *svalp;
08040 svalp = (char **)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "type", NULL);
08041 if (svalp) dxv[i]->type = *svalp;
08042 ivec = (SUMA_IVEC*)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "counts", NULL);
08043 if (ivec) { dxv[i]->counts = ivec->v; dxv[i]->n_counts = ivec->n; SUMA_free(ivec); ivec = NULL;}
08044 fvec = (SUMA_FVEC*)SUMA_OpenDx_Object_Header_Field(opv[i], nchar[i], "origin", NULL);
08045 if (fvec) { dxv[i]->origin = fvec->v; dxv[i]->n_origin = fvec->n; SUMA_free(fvec); fvec = NULL;}
08046 {
08047 int j, k;
08048 char *rf=opv[i];
08049 j=0;
08050 while (j<dxv[i]->n_counts) {
08051 fvec = (SUMA_FVEC*)SUMA_OpenDx_Object_Header_Field(rf, nchar[i], "delta", &ope);
08052 if (fvec && fvec->v) {
08053 if (fvec->n < dxv[i]->n_counts) { SUMA_SL_Warn("Bad assumption about delta field.\nExpect disasters!"); }
08054 if (fvec->n > dxv[i]->n_counts) {
08055 SUMA_SL_Err("More values in delta that counts! Limiting to counts.\nExpect tragedy.");
08056 fvec->n = dxv[i]->n_counts;
08057 }
08058 if (j==0) {
08059 dxv[i]->n_delta = dxv[i]->n_counts*dxv[i]->n_counts;
08060 dxv[i]->delta = (float *)SUMA_calloc(dxv[i]->n_delta, sizeof(float));
08061 }
08062 for (k=0; k<fvec->n; ++k) {
08063 dxv[i]->delta[(j*dxv[i]->n_counts) + k] = fvec->v[k];
08064 }
08065 SUMA_free(fvec->v); SUMA_free(fvec); fvec = NULL;
08066 } else {
08067 if (j) {
08068 SUMA_SL_Warn("Expect as many deltas as counts!\nThat was not the case.");
08069 } else { }
08070 j = dxv[i]->n_counts;
08071 }
08072 ++j; rf = ope;
08073 }
08074 }
08075
08076 if (!SUMA_OpenDx_Object_Data(opv[i], nchar[i], dxv[i])) {
08077 SUMA_SL_Err("Failed to get data");
08078 dxv[i]->bad_data = 1;
08079 }
08080 }
08081
08082 for (i=0; i<iop; ++i) {
08083 if (!SUMA_OpenDx_Object_Attr(opv[i], nchar[i], dxv[i])) {
08084 SUMA_SL_Err("Failed in SUMA_OpenDx_Object_Attr");
08085 }
08086 if (!SUMA_OpenDx_Object_Components(opv[i], nchar[i], dxv[i])) {
08087 SUMA_SL_Err("Failed in SUMA_OpenDx_Object_Components");
08088 }
08089 }
08090
08091 if (LocalHead) {
08092 SUMA_Show_OpenDX_Struct(dxv, iop, NULL); fflush(stdout);
08093 }
08094
08095 if (opv) SUMA_free(opv); opv = NULL;
08096 if (nchar) SUMA_free(nchar); nchar = NULL;
08097 if (fl) SUMA_free(fl); fl = NULL;
08098 *nobj = iop;
08099 SUMA_RETURN(dxv);
08100 }
08101
08102
08103
08104
08105
08106 SUMA_OPEN_DX_STRUCT *SUMA_Find_OpenDX_Object_Name(SUMA_OPEN_DX_STRUCT **dxv, int iop, char *nm, int *nf)
08107 {
08108 static char FuncName[]={"SUMA_Find_OpenDX_Object_Name"};
08109 int i;
08110 SUMA_OPEN_DX_STRUCT *dx = NULL;
08111 SUMA_Boolean LocalHead = NOPE;
08112
08113 SUMA_ENTRY;
08114
08115 *nf = 0;
08116 for (i=0; i<iop; ++i) {
08117 if (strstr(dxv[i]->object, nm)) {
08118 if (!dx) dx = dxv[i];
08119 ++ (*nf);
08120 }
08121 }
08122
08123 if (LocalHead) fprintf(SUMA_STDERR,"%s: Found %d objects\n", FuncName, *nf);
08124 SUMA_RETURN(dx);
08125 }
08126
08127
08128
08129
08130 SUMA_OPEN_DX_STRUCT *SUMA_Find_OpenDX_Object_Class(SUMA_OPEN_DX_STRUCT **dxv, int iop, char *nm, int *nf)
08131 {
08132 static char FuncName[]={"SUMA_Find_OpenDX_Object_Class"};
08133 int i;
08134 SUMA_OPEN_DX_STRUCT *dx = NULL;
08135 SUMA_Boolean LocalHead = NOPE;
08136
08137 SUMA_ENTRY;
08138
08139 *nf = 0;
08140 for (i=0; i<iop; ++i) {
08141 if (strstr(dxv[i]->class, nm)) {
08142 if (!dx) dx = dxv[i];
08143 ++ (*nf);
08144 }
08145 }
08146
08147 if (LocalHead) fprintf(SUMA_STDERR,"%s: Found %d objects\n", FuncName, *nf);
08148 SUMA_RETURN(dx);
08149 }
08150
08151
08152 char * SUMA_OpenDX_Read_CruiseVolHead(char *fname, THD_3dim_dataset *dset, int LoadData)
08153 {
08154 static char FuncName[]={"SUMA_OpenDX_Read_CruiseVolHead"};
08155 int i = 0, nf, iop, chunk, End, bs, doff, data_type=SUMA_notypeset;
08156 THD_ivec3 iv3;
08157 THD_mat33 m33;
08158 THD_ivec3 orixyz , nxyz ;
08159 THD_fvec3 dxyz , orgxyz ;
08160 float ep[3], sp[3];
08161 char *scom=NULL, form[10], swp[10], orstr[10], xfov[100], yfov[100], zfov[100], *prefix = NULL, *dsetheadname = NULL;
08162 SUMA_OPEN_DX_STRUCT **dxv=NULL, *dxp=NULL, *dxc=NULL, *dxf=NULL, *dxa=NULL;
08163 SUMA_Boolean LocalHead = NOPE;
08164
08165 SUMA_ENTRY;
08166
08167 if (!dset || !fname) {
08168 SUMA_SL_Err("NULL fname || NULL dset!");
08169 SUMA_RETURN(NOPE);
08170 }
08171
08172 prefix = SUMA_AfniPrefix(fname, NULL, NULL, NULL);
08173 if( !THD_filename_ok(prefix) ) {
08174 SUMA_SL_Err("Bad prefix");
08175 SUMA_RETURN(NOPE);
08176 }
08177 dsetheadname = SUMA_append_string(prefix,"+orig.HEAD");
08178 if (SUMA_filexists(dsetheadname)) {
08179 SUMA_SL_Err("Bad prefix, output dset exists");
08180 SUMA_RETURN(NOPE);
08181 }
08182 SUMA_free(dsetheadname); dsetheadname = NULL;
08183
08184 SUMA_LH("Reading objects");
08185 dxv = SUMA_OpenDX_Read(fname, &iop);
08186 if (!dxv) {
08187 SUMA_SL_Err("Failed to read DX file.");
08188 SUMA_RETURN(NOPE);
08189 }
08190
08191 SUMA_LH("Checking for field object");
08192 dxf = SUMA_Find_OpenDX_Object_Class(dxv, iop, "field", &nf);
08193 if (!dxf || nf != 1) { SUMA_SL_Err("Failed to find one and only one field object"); goto CLEAN_EXIT; }
08194 dxp = dxc = NULL;
08195 for (i=0; i<dxf->n_comp; ++i) {
08196 if (strstr(dxf->comp_name[i],"positions")) {
08197 dxp = SUMA_Find_OpenDX_Object_Name(dxv, iop, dxf->comp_value[i], &nf);
08198 if (!dxp || nf != 1) { SUMA_SL_Err("Failed to find one and only one positions object"); goto CLEAN_EXIT; }
08199 }
08200 if (strstr(dxf->comp_name[i],"connections")) {
08201 dxc = SUMA_Find_OpenDX_Object_Name(dxv, iop, dxf->comp_value[i], &nf);
08202 if (!dxc || nf != 1) { SUMA_SL_Err("Failed to find one and only one connections object"); goto CLEAN_EXIT; }
08203 }
08204 if (strstr(dxf->comp_name[i],"data")) {
08205 dxa = SUMA_Find_OpenDX_Object_Name(dxv, iop, dxf->comp_value[i], &nf);
08206 if (!dxa || nf != 1) { SUMA_SL_Err("Failed to find one and only one data object"); goto CLEAN_EXIT; }
08207 }
08208 }
08209
08210 if (!dxp || !dxv || !dxa) {
08211 SUMA_SL_Err("Failed to find necessary objects"); SUMA_RETURN(NOPE);
08212 }
08213
08214
08215 SUMA_LH("Sanity checks");
08216 if (!dxa->data_format) {
08217 SUMA_SL_Err("Not a binary data file!");
08218 goto CLEAN_EXIT;
08219 }
08220 if (!dxa->data) {
08221 SUMA_SL_Err("No data file!");
08222 goto CLEAN_EXIT;
08223 }
08224 if (dxp->n_counts != 3) {
08225 SUMA_SL_Err("counts field must have 3 values");
08226 goto CLEAN_EXIT;
08227 }
08228 if (dxp->n_delta != 9) {
08229 SUMA_SL_Err("delta must contain 9 elements!");
08230 goto CLEAN_EXIT;
08231 }
08232
08233
08234 SUMA_LH("Forming command");
08235
08236 chunk = 0;
08237 form[0] = '\0';
08238 data_type = SUMA_VarType2TypeCast(dxa->type);
08239 switch (data_type) {
08240 case SUMA_float:
08241 sprintf(form,"3Df");
08242 chunk = sizeof(float);
08243 break;
08244 case SUMA_double:
08245 sprintf(form,"3Dd");
08246 chunk = sizeof(double);
08247 break;
08248 case SUMA_int:
08249 sprintf(form,"3Di");
08250 chunk = sizeof(int);
08251 break;
08252 case SUMA_short:
08253 sprintf(form,"3Ds");
08254 chunk = sizeof(short);
08255 break;
08256 case SUMA_byte:
08257 sprintf(form,"3Db");
08258 chunk = sizeof(byte);
08259 break;
08260 default:
08261 SUMA_SL_Err("No support for this type");
08262 goto CLEAN_EXIT;
08263 break;
08264 }
08265
08266 SUMA_WHAT_ENDIAN(End);
08267 bs = 0;
08268 swp[0] = '\0';
08269 if (End != dxa->data_format) {
08270 SUMA_LH("swapping needed");
08271 bs = 1;
08272 switch (chunk) {
08273 case 1:
08274 break;
08275 case 2:
08276 sprintf(swp,"-2swap");
08277 break;
08278 case 4:
08279 sprintf(swp,"-4swap");
08280 break;
08281 case 8:
08282 sprintf(swp,"-8swap");
08283 break;
08284 default:
08285 SUMA_SL_Err("Patchunk!");
08286 break;
08287 }
08288 }
08289 if (dxa->data_off) doff = (int)strtol(dxa->data_off,NULL, 10);
08290 else doff = 0;
08291
08292
08293
08294
08295
08296
08297
08298
08299 LOAD_IVEC3( nxyz , dxp->counts[2] , dxp->counts[1] , dxp->counts[0] ) ;
08300
08301
08302
08303 LOAD_MAT(m33,
08304 dxp->delta[6], dxp->delta[7], dxp->delta[8],
08305 dxp->delta[3], dxp->delta[4], dxp->delta[5],
08306 dxp->delta[0], dxp->delta[1], dxp->delta[2] );
08307 orixyz = THD_matrix_to_orientation( m33 );
08308
08309
08310 {
08311 float fb[3];
08312 SUMA_NORM_VEC((&(dxp->delta[6])),3, fb[0]);
08313 SUMA_NORM_VEC((&(dxp->delta[3])),3, fb[1]);
08314 SUMA_NORM_VEC((&(dxp->delta[0])),3, fb[2]);
08315 LOAD_FVEC3( dxyz , fb[0] , fb[1] , fb[2] ) ;
08316 SUMA_sizeto3d_2_deltaHEAD(orixyz, &dxyz);
08317 }
08318
08319
08320 LOAD_FVEC3( orgxyz , dxp->origin[2] , dxp->origin[1] , dxp->origin[0] ) ;
08321 SUMA_originto3d_2_originHEAD(orixyz, &orgxyz);
08322
08323
08324 sp[0] = dxp->origin[2] + SUMA_ABS(dxyz.xyz[0]) / 2.0;
08325 sp[1] = dxp->origin[1] + SUMA_ABS(dxyz.xyz[1]) / 2.0;
08326 sp[2] = dxp->origin[0] + SUMA_ABS(dxyz.xyz[2]) / 2.0;
08327 ep[0] = dxp->origin[2] + (nxyz.ijk[0] - 0.5) * SUMA_ABS(dxyz.xyz[0]);
08328 ep[1] = dxp->origin[1] + (nxyz.ijk[1] - 0.5) * SUMA_ABS(dxyz.xyz[1]);
08329 ep[2] = dxp->origin[0] + (nxyz.ijk[2] - 0.5) * SUMA_ABS(dxyz.xyz[2]);
08330 SUMA_orcode_to_orstring (orixyz.ijk[0], orixyz.ijk[1], orixyz.ijk[2], orstr);
08331 sprintf(xfov," -xFOV %.2f%c-%.2f%c", sp[0], orstr[0], ep[0], orstr[3]);
08332 sprintf(yfov," -yFOV %.2f%c-%.2f%c", sp[1], orstr[1], ep[1], orstr[4]);
08333 sprintf(zfov," -zFOV %.2f%c-%.2f%c", sp[2], orstr[2], ep[2], orstr[5]);
08334
08335
08336 scom = (char *)SUMA_calloc((strlen(dxa->data)+500), sizeof(char));
08337 sprintf(scom,"to3d %s %s %s %s -prefix %s %s:%d:0:%d:%d:%d:%s ", swp, xfov, yfov, zfov, prefix, form, doff, dxp->counts[2], dxp->counts[1], dxp->counts[0], dxa->data);
08338
08339
08340 if (dset) {
08341 int nvals_read = 0;
08342 EDIT_dset_items( dset ,
08343 ADN_prefix , prefix ,
08344 ADN_datum_all , data_type ,
08345 ADN_nxyz , nxyz ,
08346 ADN_xyzdel , dxyz ,
08347 ADN_xyzorg , orgxyz ,
08348 ADN_xyzorient , orixyz ,
08349 ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
08350 ADN_view_type , VIEW_ORIGINAL_TYPE ,
08351 ADN_type , HEAD_ANAT_TYPE ,
08352 ADN_func_type , ANAT_BUCK_TYPE ,
08353 ADN_none ) ;
08354
08355 if (LoadData) {
08356 void *vec=NULL;
08357 if (!(vec = SUMA_BinarySuck(dxa->data, data_type, dxa->data_format, doff, -1, &nvals_read))) {
08358 SUMA_SL_Err("Failed to read data file"); goto CLEAN_EXIT;
08359 }
08360 EDIT_substitute_brick( dset , 0 , data_type , vec) ;
08361 if (LocalHead) fprintf(SUMA_STDERR,"%s: Read %d values from file.\n", FuncName, nvals_read);
08362
08363 }
08364 }
08365
08366
08367
08368 CLEAN_EXIT:
08369 dxv = SUMA_Free_OpenDX_StructVec(dxv, iop);
08370 if (prefix) SUMA_free(prefix); prefix = NULL;
08371
08372 SUMA_RETURN(scom);
08373 }
08374
08375
08376
08377
08378
08379
08380
08381
08382
08383
08384
08385
08386
08387
08388
08389
08390 SUMA_Boolean SUMA_OpenDX_Read_SO(char *fname, SUMA_SurfaceObject *SO)
08391 {
08392 static char FuncName[]={"SUMA_OpenDX_Read_SO"};
08393 int i = 0, nf, iop;
08394 SUMA_OPEN_DX_STRUCT **dxv=NULL, *dxp=NULL, *dxc = NULL, *dxf = NULL, *dxo = NULL;
08395 SUMA_Boolean ans = NOPE;
08396 SUMA_Boolean LocalHead = NOPE;
08397
08398 SUMA_ENTRY;
08399
08400 if (!SO || !fname) {
08401 SUMA_SL_Err("NULL fname || NULL SO!");
08402 SUMA_RETURN(NOPE);
08403 }
08404
08405 SUMA_LH("Reading objects");
08406 dxv = SUMA_OpenDX_Read(fname, &iop);
08407 if (!dxv) {
08408 SUMA_SL_Err("Failed to read DX file.");
08409 SUMA_RETURN(NOPE);
08410 }
08411
08412
08413 SUMA_LH("Checking for field object");
08414 dxf = SUMA_Find_OpenDX_Object_Class(dxv, iop, "field", &nf);
08415 if (!dxf || nf != 1) { SUMA_SL_Err("Failed to find one and only one field object"); goto CLEAN_EXIT; }
08416
08417 dxp = dxc = dxo = NULL;
08418 for (i=0; i<dxf->n_comp; ++i) {
08419 if (strstr(dxf->comp_name[i],"positions")) {
08420 dxp = SUMA_Find_OpenDX_Object_Name(dxv, iop, dxf->comp_value[i], &nf);
08421 if (!dxp || nf != 1) { SUMA_SL_Err("Failed to find one and only one positions object"); goto CLEAN_EXIT; }
08422 }
08423 if (strstr(dxf->comp_name[i],"connections")) {
08424 dxc = SUMA_Find_OpenDX_Object_Name(dxv, iop, dxf->comp_value[i], &nf);
08425 if (!dxc || nf != 1) { SUMA_SL_Err("Failed to find one and only one connections object"); goto CLEAN_EXIT; }
08426 }
08427 if (strstr(dxf->comp_name[i],"origin")) {
08428 dxo = SUMA_Find_OpenDX_Object_Name(dxv, iop, dxf->comp_value[i], &nf);
08429 if (!dxo || nf != 1) { SUMA_SL_Err("Failed to find one and only one origin object.\nOrigin ignored"); }
08430 }
08431 }
08432
08433 if (!dxp || !dxv) {
08434 SUMA_SL_Err("Failed to find necessary objects"); goto CLEAN_EXIT;
08435 }
08436
08437 SUMA_LH("checking...");
08438 if (SUMA_VarType2TypeCast (dxp->type) != SUMA_float) {
08439 SUMA_SL_Err("Expected floats for positions"); goto CLEAN_EXIT;
08440 }
08441 if (dxp->bad_data) {
08442 SUMA_SL_Err("Problem reading data for positions"); goto CLEAN_EXIT;
08443 }
08444 if (dxp->rank != 1) {
08445 SUMA_SL_Err("Expected rank of 1 for positions"); goto CLEAN_EXIT;
08446 }
08447 if (dxp->shape != 3) {
08448 SUMA_SL_Err("Expected rank of 3 for positions"); goto CLEAN_EXIT;
08449 }
08450 if (SUMA_VarType2TypeCast (dxc->type) != SUMA_int) {
08451 SUMA_SL_Err("Expected ints for connections"); goto CLEAN_EXIT;
08452 }
08453 if (dxc->bad_data) {
08454 SUMA_SL_Err("Problem reading data for connections"); goto CLEAN_EXIT;
08455 }
08456 if (dxc->rank != 1) {
08457 SUMA_SL_Err("Expected rank of 1 for connections"); goto CLEAN_EXIT;
08458 }
08459 if (dxc->shape != 3) {
08460 SUMA_SL_Err("Expected rank of 3 for connections"); goto CLEAN_EXIT;
08461 }
08462
08463 if (dxo) {
08464 if (SUMA_VarType2TypeCast (dxo->type) != SUMA_float) {
08465 SUMA_SL_Err("Expected floats for origin.\nOrigin ignored"); dxo = NULL;
08466 }
08467 if (!dxo->datap || dxo->shape * dxo->items != 3) {
08468 SUMA_SL_Err("Unknown origin format, ignoring origin"); dxo = NULL;
08469 }
08470 }
08471
08472 SUMA_LH("Take the gold");
08473 SO->FileType = SUMA_OPENDX_MESH;
08474 SO->FileFormat = SUMA_ASCII;
08475
08476 SO->NodeDim = dxp->shape;
08477 SO->NodeList = (float *)dxp->datap; dxp->datap = NULL;
08478 SO->N_Node = dxp->items;
08479
08480 SO->FaceSetDim = dxc->shape;
08481 SO->FaceSetList = (int *)dxc->datap; dxc->datap = NULL;
08482 SO->N_FaceSet = dxc->items;;
08483 SO->Name = SUMA_StripPath(fname);
08484
08485 if (dxo) {
08486 float *fvec=(float*)dxo->datap;
08487 SUMA_LH("Adding origin");
08488 i = 0;
08489 while (i < dxp->items*dxp->shape) {
08490 SO->NodeList[i] += fvec[0]; ++i;
08491 SO->NodeList[i] += fvec[1]; ++i;
08492 SO->NodeList[i] += fvec[2]; ++i;
08493 }
08494 }
08495
08496
08497 ans = YUP;
08498
08499 CLEAN_EXIT:
08500 SUMA_LH("Frenching dxv");
08501 for (i=0; i<iop; ++i) {
08502 dxv[i] = SUMA_Free_OpenDX_Struct(dxv[i]);
08503 }
08504 if (dxv) SUMA_free(dxv); dxv = NULL;
08505 SUMA_RETURN(YUP);
08506 }
08507