1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <assert.h>
4 #include <string.h>
5 #include <sys/time.h>
6 #include <math.h>
7 #include "mrilib.h"
8 #include "niml.h"
9 #include "../niml/niml_private.h"
10 #include "xutil.h"
11
12
13 #include "SUMA_suma.h"
14
usage_ConverDset(SUMA_GENERIC_ARGV_PARSE * ps,int detail)15 void usage_ConverDset(SUMA_GENERIC_ARGV_PARSE *ps, int detail)
16 {
17 static char FuncName[]={"usage_ConverDset"};
18 char *s = NULL, *sd=NULL, *sm=NULL;
19 s = SUMA_help_basics();
20 sd = SUMA_help_dset();
21 sm = SUMA_help_mask();
22 printf (
23 "Usage: \n"
24 " ConvertDset -o_TYPE -input DSET [-i_TYPE] [-prefix OUT_PREF]\n"
25 " Converts a surface dataset from one format to another.\n"
26 "\n%s", detail ? "":"use -h or -help for more help detail.\n");
27 if (detail) {
28 printf (
29 " Mandatory parameters:\n"
30 " -o_TYPE: TYPE of output datasets\n"
31 " where TYPE is one of:\n"
32 " niml_asc (or niml): for ASCII niml format.\n"
33 " niml_bi: for BINARY niml format.\n"
34 " 1D: for AFNI's 1D ascii format.\n"
35 " 1Dp: like 1D but with no comments\n"
36 " or other 1D formatting gimmicks.\n"
37 " 1Dpt: like 1Dp but transpose the output.\n"
38 " gii: GIFTI format default .\n"
39 " gii_asc: GIFTI format with ascii DataArrays.\n"
40 " gii_b64: GIFTI format with Base 64 encoded DataArrays.\n"
41 " gii_b64gz: GIFTI format with B64 enconding and gzipping.\n"
42 " For stderr and stdout output use one of:\n"
43 " 1D_stderr, 1D_stdout, niml_stderr, or niml_stdout, \n"
44 " 1Dp_stdout, 1Dp_stderr, 1Dpt_stdout, 1Dpt_stderr\n"
45 " Actually, this parameter is not that mandatory, the program\n"
46 " can look at extensions on the prefix to guess the output\n"
47 " format. If the prefix has no extension and o_TYPE is not\n"
48 " specified, then the output format is the same as that of the\n"
49 " input.\n"
50 " -input DSET: Input dataset to be converted.\n"
51 " See more on input datasets below.\n"
52 " -dset_labels 'SB_LABEL_0 SB_LABEL_1 ...'\n"
53 " Label the columns (sub-bricks) of the output dataset\n"
54 " You must have as many labels as you have sub-bricks in\n"
55 " the output dataset."
56 " Optional parameters:\n"
57 " -add_node_index: Add a node index element if one does not exist\n"
58 " in the input dset. With this option, the indexing\n"
59 " is assumed to be implicit (0,1,2,3.... for rows 0,1\n"
60 " 2,3,...). If that is not the case, use -node_index_1D\n"
61 " option below. \n"
62 " ** NOTE: It is highly recommended you use one of -node_index_1D\n"
63 " or -add_node_index when going from 1D format to NIML \n"
64 " GIFTI formats.\n"
65 " -node_index_1D INDEX.1D: Specify file containing node indices\n"
66 " Use this to provide node indices with \n"
67 " a .1D dset. In many cases for .1D data\n"
68 " this option is DSET.1D'[0]'\n"
69 " -node_select_1D MASK.1D: Specify the nodes you want to keep in the\n"
70 " output. \n"
71 " The order of the rows in the output dataset \n"
72 " reflects the order of the nodes in MASK.1D.\n"
73 " Note that the presence of duplicate nodes in\n"
74 " MASK.1D is not allowed, so if MASK.1D came\n"
75 " from ROI2dataset's -nodelist, recreate it with\n"
76 " option -nodelist.nodups instead. \n"
77 " Also, node indices that do not have data in the\n"
78 " input dataset will be ignored.\n"
79 " When in doubt, use the 1D output format along \n"
80 " with -prepend_node_index_1D and spot check your\n"
81 " results.\n"
82 " -prepend_node_index_1D: Add a node index column to the data, rather\n"
83 " than keep it as part of the metadata.\n"
84 " -pad_to_node MAX_INDEX: Output a full dset from node 0 \n"
85 " to node MAX_INDEX (a total of \n"
86 " MAX_INDEX + 1 nodes). Nodes that\n"
87 " get no value from input DSET are\n"
88 " assigned a value of 0\n"
89 " If MAX_INDEX is set to 0 it means you want\n"
90 " to pad the maximum node in the input dataset.\n"
91 " ** Notice that padding gets done at the very end.\n"
92 " ** Instead of directly setting MAX_INDEX to an integer you \n"
93 " can set MAX_INDEX to something like:\n"
94 " ld120 (or rd17) which sets MAX_INDEX to be the maximum \n"
95 " node index on an Icosahedron with -ld 120. See \n"
96 " CreateIcosahedron for details.\n"
97 " d:DSET.niml.dset which sets MAX_INDEX to the maximum node found\n"
98 " in dataset DSET.niml.dset.\n"
99 "\n"
100 " -labelize CMAP: Turn the dataset into a labeled set per the colormap in\n"
101 " CMAP. A CMAP can easily be generated with MakeColorMap's\n"
102 " options -usercolorlutfile and -suma_cmap.\n"
103 "\n"
104 " -graphize: Turn the dataset into a SUMA graph dataset.\n"
105 " See input format constraints under -onegraph and -multigraph\n"
106 " -graph_nodelist_1D NODEINDLIST.1D NODELIST.1D: Two files specifying the \n"
107 " indices and the coordinates of the graph's\n"
108 " nodes. In sum you need I X Y Z (RAI mm).\n"
109 " but the I comes from NODEINDLIST.1D and the\n"
110 " X Y Z coordinates from NODELIST.1D\n"
111 " If you have everything in one file, use\n"
112 " the same filename twice with proper column\n"
113 " selectors.\n"
114 " -graph_full_nodelist_1D NODELIST.1D: Same as above, but without the need\n"
115 " for NODEINDLIST.1D. In that case, indices\n"
116 " will implicitly go from 0 to N-1, with N\n"
117 " being the number of nodes.\n"
118 " -graph_named_nodelist_txt NODENAMES.txt NODELIST.1D: Two files used to \n"
119 " specify graph node indices, string labels, \n"
120 " and their coordinates.\n"
121 " In sum you need I LABEL X Y Z (RAI mm).\n"
122 " The I and LABEL come from NODENAMES.txt and\n"
123 " the X Y Z coordinates from NODELIST.1D\n"
124 " Also, you can assign to each graph node a group ID\n"
125 " and nodes with the same group ID can be \n"
126 " displayed with the same color in SUMA.\n"
127 " To do so, add a third column to \n"
128 " NODENAMES.txt so that you have: I LABEL GID\n"
129 " with GID being the integer group ID.\n"
130 " Color selection for the different group IDs\n"
131 " is done automatically with ConvertDset, but\n"
132 " you can set your own by appending three \n"
133 " more columns to NODENAMES.txt to have:\n"
134 " I LABEL GID R G B\n"
135 " with R, G, and B values between 0 and 1.0\n"
136 " -graph_XYZ_LPI: Coords in NodeList.1D are in LPI instead of RAI \n"
137 " -graph_edgelist_1D EDGELIST.1D: i j indices of graph nodes defining edge\n"
138 " with each row matching the input dset row.\n"
139 " This option only works with -multigraph\n"
140 " This option also marks the graph as being\n"
141 " a sparse matrix, even if a square matrix \n"
142 " is provided.\n"
143 " -onegraph: Expect input dataset to be one square matrix defining the\n"
144 " graph (default).\n"
145 " -multigraph: Expect each column in input dataset to define an entire\n"
146 " graph. Each column in this case should be a column-stacked\n"
147 " square matrix.\n"
148 "\n"
149 " -i_TYPE: TYPE of input datasets\n"
150 " where TYPE is one of:\n"
151 " niml: for niml data sets.\n"
152 " 1D: for AFNI's 1D ascii format.\n"
153 " dx: OpenDX format, expects to work on 1st\n"
154 " object only.\n"
155 " If no format is specified, the program will \n"
156 " guess using the extension first and the file\n"
157 " content next. However the latter operation might \n"
158 " slow operations down considerably.\n"
159 " -prefix OUT_PREF: Output prefix for data set.\n"
160 " Default is something based\n"
161 " on the input prefix.\n"
162 " -split N: Split a multi-column dataset into about N output datasets\n"
163 " with all having the same number of columns, except perhaps\n"
164 " for the last one. Confused? try:\n"
165 " ConvertDset -i v2s.lh.TS.niml.dset -split 3 \\\n"
166 " -prefix Split3\n"
167 " 3dinfo -n4 -label Split3.000* v2s.lh.TS.niml.dset\\\n"
168 " -no_history: Do not include a history element in the output\n"
169 " Notes:\n"
170 " -This program will not overwrite pre-existing files.\n"
171 " -The new data set is given a new idcode.\n"
172 "\n"
173 "%s"
174 "\n"
175 "%s"
176 "\n"
177 "%s"
178 "\n"
179 "Examples:\n"
180 "1- Plot a node's time series from a niml dataset:\n"
181 " ConvertDset -input DemoSubj_EccCntavir.niml.dset'#5779#' \\\n"
182 " -o_1D_stdout | 1dplot -nopush -stdin \n"
183 "\n"
184 "2- Change a dataset to a labeled dataset using the colormap generated \n"
185 " in Example 5 of MakeColorMap's help\n"
186 " ConvertDset -i you_look_marvellous.niml.dset \\\n"
187 " -o you_look_labeled.niml.dset -labelize toylut.niml.cmap\n"
188 " The advantage of having a labeled dataset is that you can see the label \n"
189 " of a node when you click on it in SUMA, and you can extract\n"
190 " regions based on their labels. For example, with the dataset created\n"
191 " above you can run the following command to extract a mask of the \n"
192 " nodes labeled 'Small_Face' with something like:\n"
193 " 3dcalc -a you_look_labeled.niml.dset'<Small_Face>' \\\n"
194 " -expr 'a' -prefix Small_Face.only\n"
195 " This assumes of course that your colormap toylut.niml.cmap does have \n"
196 " an entry labeled 'Small_Face'\n"
197 "\n"
198 "\n"
199 "\n",(detail > 1) ? sd : "Use -help for more detail.",
200 (detail > 1) ? sm : "",
201 (detail > 1) ? s : "");
202 }
203 SUMA_free(s); s = NULL; SUMA_free(sd); sd = NULL; SUMA_free(sm); sm = NULL;
204 if (detail) {
205 #ifdef SUMA_COMPILED
206 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
207 #endif
208 fprintf (SUMA_STDOUT,
209 " Ziad S. Saad SSCC/NIMH/NIH saadz@mail.nih.gov\n\n");
210 }
211 return;
212 }
main(int argc,char * argv[])213 int main (int argc,char *argv[])
214 {/* Main */
215 static char FuncName[]={"ConvertDset"};
216 int kar, brk, i_input, i, j, *Ti=NULL,
217 *indexmap = NULL, add_node_index, prepend_node_index,
218 no_hist ;
219 byte *Tb=NULL, *auto_nmask=NULL;
220 float *fv = NULL, *cols=NULL;
221 SUMA_DSET_FORMAT iform, oform;
222 SUMA_DSET *dset = NULL, *dseti=NULL, *dset_m = NULL;
223 char *NameOut, *prfx = NULL, *prefix = NULL, *cmapfile,
224 *graph_nodelist_1D=NULL, *graph_nodeindlist_1D=NULL,
225 *graph_edgelist_1D=NULL, *graph_nodeindlist_txt=NULL, **names=NULL;
226 char *ooo=NULL, *node_index_1d = NULL, *node_mask = NULL;
227 int overwrite = 0, exists = 0, N_inmask=-1, pad_to_node = -1, *ivec=NULL;
228 SUMA_GENERIC_ARGV_PARSE *ps=NULL;
229 int orderednodelist = 1, split=0, toGDSET=0, OneMat, *clan=NULL;
230 float fv5[5];
231 int nv, mxgrp, RAI;
232 char *stmp=NULL, colnm[32];
233 SUMA_COLOR_MAP *SM=NULL;
234 NI_str_array *dlabs=NULL;
235 SUMA_Boolean LocalHead = NOPE;
236
237 SUMA_STANDALONE_INIT;
238 SUMA_mainENTRY;
239
240 ps = SUMA_Parse_IO_Args(argc, argv, "-mask;");
241
242 pad_to_node = -1;
243 add_node_index = 0;
244 prepend_node_index=0;
245 iform = SUMA_NO_DSET_FORMAT;
246 oform = SUMA_NO_DSET_FORMAT;
247 overwrite = 0;
248 i_input = -1;
249 prfx = NULL;
250 node_index_1d = NULL;
251 node_mask = NULL;
252 exists = 0;
253 split = 0;
254 no_hist = 0;
255 cmapfile=NULL;
256 toGDSET=0;
257 OneMat=1;
258 RAI = 1;
259 kar = 1;
260 brk = NOPE;
261 while (kar < argc) { /* loop accross command ine options */
262 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
263 usage_ConverDset (ps, strlen(argv[kar]) > 3 ? 2:1);
264 exit (0);
265 }
266
267 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
268
269 SUMA_TO_LOWER(argv[kar]);
270
271 if (SUMA_isOutputFormatFromArg(argv[kar], &oform)) {
272 brk = YUP;
273 }
274
275
276 if (!brk && (strcmp(argv[kar], "-i_1d") == 0))
277 {
278 if (iform != SUMA_NO_DSET_FORMAT) {
279 SUMA_SL_Err("input type already specified.");
280 exit(1);
281 }
282 iform = SUMA_1D;
283 brk = YUP;
284 }
285
286 if (!brk && (strcmp(argv[kar], "-no_history") == 0))
287 {
288 no_hist = 1;
289 brk = YUP;
290 }
291
292 if (!brk && (strcmp(argv[kar], "-graph_xyz_lpi") == 0))
293 {
294 RAI = 0;
295 brk = YUP;
296 }
297
298
299 if (!brk && (strcmp(argv[kar], "-graphize") == 0))
300 {
301 toGDSET = 1;
302 brk = YUP;
303 }
304
305 if (!brk && (strcmp(argv[kar], "-onegraph") == 0))
306 {
307 OneMat = 1;
308 brk = YUP;
309 }
310 if (!brk && (strcmp(argv[kar], "-multigraph") == 0))
311 {
312 OneMat = 0;
313 brk = YUP;
314 }
315 if (!brk && (strcmp(argv[kar], "-i_niml") == 0))
316 {
317 if (iform != SUMA_NO_DSET_FORMAT) {
318 SUMA_SL_Err("input type already specified.");
319 exit(1);
320 }
321 iform = SUMA_NIML;
322 brk = YUP;
323 }
324
325 if (!brk && (strcmp(argv[kar], "-i_dx") == 0))
326 {
327 if (iform != SUMA_NO_DSET_FORMAT) {
328 SUMA_SL_Err("input type already specified.");
329 exit(1);
330 }
331 iform = SUMA_ASCII_OPEN_DX_DSET;
332 brk = YUP;
333 }
334
335
336 if ( !brk &&
337 ( strcmp(argv[kar], "-input") == 0 ||
338 strcmp(argv[kar], "-i") == 0 ||
339 strcmp(argv[kar], "-i_") == 0) )
340 {
341 if (kar+1 >= argc) {
342 SUMA_SL_Err("Need argument after -input");
343 exit(1);
344 }
345 if (i_input >= 0) {
346 SUMA_SL_Err("-input already specified.");
347 exit(1);
348 }
349 i_input = kar+1;
350 ++kar;
351 brk = YUP;
352 }
353
354 if (!brk && (strcmp(argv[kar], "-labelize") == 0))
355 {
356 if (kar+1 >= argc) {
357 SUMA_SL_Err("Need colrmap after -labelize");
358 exit(1);
359 }
360 ++kar;
361 cmapfile = argv[kar];
362 if (!(SM = SUMA_LoadCmapFile_eng(cmapfile))) {
363 SUMA_S_Errv("Failed to load cmap file %s\n", cmapfile);
364 exit(1);
365 }
366 brk = YUP;
367 }
368
369 if (!brk && (strcmp(argv[kar], "-graph_nodelist_1d") == 0))
370 {
371 if (kar+2 >= argc) {
372 SUMA_SL_Err("Need 2 arguments after -graph_nodelist_1D");
373 exit(1);
374 }
375 ++kar;
376 graph_nodeindlist_1D = argv[kar];
377 ++kar;
378 graph_nodelist_1D = argv[kar];
379 brk = YUP;
380 }
381
382 if (!brk && (strcmp(argv[kar], "-graph_full_nodelist_1d") == 0))
383 {
384 if (kar+1 >= argc) {
385 SUMA_SL_Err("Need 1 arguments after -graph_full_nodelist_1D");
386 exit(1);
387 }
388 graph_nodeindlist_1D = NULL;
389 ++kar;
390 graph_nodelist_1D = argv[kar];
391 brk = YUP;
392 }
393
394 if (!brk && (strcmp(argv[kar], "-graph_named_nodelist_txt") == 0))
395 {
396 if (kar+2 >= argc) {
397 SUMA_SL_Err("Need 2 arguments after -graph_named_nodelist_txt");
398 exit(1);
399 }
400 ++kar;
401 graph_nodeindlist_txt = argv[kar];
402 ++kar;
403 graph_nodelist_1D = argv[kar];
404 brk = YUP;
405 }
406
407 if (!brk && (strcmp(argv[kar], "-graph_edgelist_1d") == 0))
408 {
409 if (kar+1 >= argc) {
410 SUMA_SL_Err("Need argument after -graph_edgelist_1D");
411 exit(1);
412 }
413 ++kar;
414 graph_edgelist_1D = argv[kar];
415 brk = YUP;
416 }
417
418 if (!brk && (strcmp(argv[kar], "-node_index_1d") == 0))
419 {
420 if (kar+1 >= argc) {
421 SUMA_SL_Err("Need argument after -node_index_1D");
422 exit(1);
423 }
424 ++kar;
425 node_index_1d = argv[kar];
426 brk = YUP;
427 }
428
429 if (!brk && (strcmp(argv[kar], "-node_select_1d") == 0))
430 {
431 if (kar+1 >= argc) {
432 SUMA_SL_Err("Need argument after -node_select_1D");
433 exit(1);
434 }
435 ++kar;
436 node_mask = argv[kar];
437 brk = YUP;
438 }
439
440 if (!brk && (strcmp(argv[kar], "-add_node_index") == 0))
441 {
442
443 add_node_index = 1;
444 brk = YUP;
445 }
446 if (!brk && (strcmp(argv[kar], "-prepend_node_index_1d") == 0))
447 {
448
449 prepend_node_index = 1;
450 brk = YUP;
451 }
452 if ( !brk &&
453 ( strcmp(argv[kar], "-prefix") == 0 ||
454 strcmp(argv[kar], "-o") == 0 ||
455 strcmp(argv[kar], "-o_") == 0 ) )
456 {
457 if (kar+1 >= argc) {
458 SUMA_SL_Err("Need argument after -prefix/-o* options");
459 exit(1);
460 }
461 ++kar;
462 prfx = argv[kar];
463 brk = YUP;
464 }
465
466 if (!brk && (strcmp(argv[kar], "-split") == 0))
467 {
468 if (kar+1 >= argc) {
469 SUMA_SL_Err("Need positive integer after -split");
470 exit(1);
471 }
472 ++kar;
473 split = atoi(argv[kar]);
474 brk = YUP;
475 }
476
477 if (!brk && (strcmp(argv[kar], "-dset_labels") == 0)) {
478 kar ++;
479 if (kar >= argc) {
480 fprintf (stderr, "need argument after -dset_labels \n");
481 exit (1);
482 }
483 dlabs = NI_strict_decode_string_list(argv[kar] ,";, ");
484 brk = 1;
485 }
486
487 if (!brk && !ps->arg_checked[kar]) {
488 fprintf (SUMA_STDERR,
489 "Error %s: Option %s not understood. Try -help for usage\n",
490 FuncName, argv[kar]);
491 suggest_best_prog_option(argv[0], argv[kar]);
492 exit (1);
493 } else {
494 brk = NOPE;
495 kar ++;
496 }
497
498 }/* loop accross command ine options */
499 if (argc < 3) {
500 usage_ConverDset (ps, 0);
501 exit (1);
502 }
503
504
505 if (!prfx) {
506 prfx = "you_look_marvellous.niml.dset";
507 overwrite = 1;
508 } else {
509 overwrite = THD_ok_overwrite();
510 }
511 pad_to_node = MRILIB_DomainMaxNodeIndex;
512
513 if (oform == SUMA_NO_DSET_FORMAT) {
514 if (prfx) {
515 /* try to guess */
516 oform = SUMA_GuessFormatFromExtension(prfx, argv[i_input]);
517 SUMA_LHv("Guessing output format to be: %s\n",
518 SUMA_Dset_Format_Name(oform));
519 if (oform == SUMA_NO_DSET_FORMAT) {
520 SUMA_SL_Err("Output format MUST be specified, or should be\n"
521 "obvious from prefix or the first input file.\n");
522 exit(1);
523 }
524 } else {
525 SUMA_S_Err("You need to specify either -o_TYPE or -prefix\n");
526 exit(1);
527 }
528 }
529
530 exists = SUMA_WriteDset_NameCheck_s (prfx, NULL, oform, 0, &ooo);
531 if (exists != 0 && !overwrite) {
532 SUMA_S_Errv("Output dataset %s exists.\n", ooo);
533 SUMA_free(ooo); ooo=NULL;
534 exit(1);
535 }
536
537 for (i=i_input; i<i_input + 1; ++i) {
538 if (LocalHead)
539 fprintf(SUMA_STDERR,"%s:\n Reading %s...\n", FuncName, argv[i]);
540 dset = SUMA_LoadDset_s (argv[i], &iform, 0);
541 if (!dset) { SUMA_SL_Err( "Failed to load dataset.\n"
542 "Make sure file exists\n"
543 "and is of the specified\n"
544 "format."); exit(1); }
545 if (LocalHead) {
546 fprintf(SUMA_STDERR,"%s:\n Read dset of format %s\n",
547 FuncName, SUMA_Dset_Format_Name(iform));
548 SUMA_ShowDset(dset, 0, NULL);
549 }
550
551 if (dlabs) {
552 if (dlabs->num != SDSET_VECNUM(dset)) {
553 SUMA_S_Err("You have %d labels but %d sub-bricks in dset %s",
554 dlabs->num, SDSET_VECNUM(dset), SDSET_LABEL(dset));
555 } else {
556 int ii;
557 for (ii=0; ii<SDSET_VECNUM(dset); ++ii) {
558 SUMA_UpdateDsetColLabel(dset, ii, dlabs->str[ii]);
559 }
560 }
561 NI_delete_str_array(dlabs); dlabs = NULL;
562 }
563
564 if (toGDSET) {
565 SUMA_LH("Going to graph format");
566 if (graph_edgelist_1D) {
567 int *ie=NULL;
568 SUMA_DSET *dsetc=NULL;
569 iform = SUMA_1D;
570 if (!(dseti = SUMA_LoadDset_s (graph_edgelist_1D, &iform, 0))) {
571 SUMA_S_Err("Failed to load nodelist ");
572 exit(1);
573 }
574 if (SDSET_VECNUM(dseti) != 3 && SDSET_VECNUM(dseti) != 2 ) {
575 SUMA_S_Err("Bad edgelist source, only 2or 3 columns allowed");
576 exit(1);
577 }
578 if (!(dsetc = SUMA_CoercedCopyofDset(dseti, SUMA_int, NULL))) {
579 SUMA_S_Err("Failed to copy to ints?");
580 exit(1);
581 }
582 SUMA_FreeDset(dseti); dseti = dsetc; dsetc = NULL;
583 switch (SDSET_VECNUM(dseti)){
584 case 2:
585 if (!(SUMA_Dset_to_GDSET(&dset, NULL, OneMat,
586 NULL,
587 (int *)SDSET_VEC(dseti,0),
588 (int *)SDSET_VEC(dseti,1)))) {
589 SUMA_S_Err("Failed to graphize");
590 }
591 break;
592 case 3:
593 if (!(SUMA_Dset_to_GDSET(&dset, NULL, OneMat,
594 (int *)SDSET_VEC(dseti,0),
595 (int *)SDSET_VEC(dseti,1),
596 (int *)SDSET_VEC(dseti,2)))) {
597 SUMA_S_Err("Failed to graphize");
598 }
599 break;
600 default:
601 SUMA_S_Err("More infidel than an infidel!");
602 break;
603 }
604 SUMA_FreeDset(dseti); dseti = NULL;
605 } else {
606 if (!(SUMA_Dset_to_GDSET(&dset, NULL, OneMat, NULL, NULL, NULL))) {
607 SUMA_S_Err("Failed to graphize");
608 }
609 }
610
611 if (graph_nodelist_1D) {
612 SUMA_DSET *dsetind=NULL;
613 SUMA_LH("Set Aux shape");
614 if (!SUMA_GDSET_Set_Aux_matrix_shape(dset)) {
615 SUMA_S_Err("Need my matrix params");
616 exit(1);
617 }
618
619 SUMA_LH("Now the nodelist");
620 iform = SUMA_1D;
621 if (!(dseti = SUMA_LoadDset_s (graph_nodelist_1D, &iform, 0))) {
622 SUMA_S_Err("Failed to load nodelist %s", graph_nodelist_1D);
623 exit(1);
624 }
625 if (SDSET_VECNUM(dseti) != 3) {
626 SUMA_S_Err("Bad nodelist source\n"
627 "Only 3 column allowed, have %d of them in %s",
628 SDSET_VECNUM(dseti), graph_nodelist_1D);
629 exit(1);
630 }
631 if (graph_nodeindlist_1D) {
632 if (!(dsetind =
633 SUMA_LoadDset_s (graph_nodeindlist_1D, &iform, 0))) {
634 SUMA_S_Err("Failed to load node index list %s",
635 graph_nodeindlist_1D);
636 exit(1);
637 }
638 if (SDSET_VECNUM(dsetind) != 1) {
639 SUMA_S_Err("Bad nodelist index source\n"
640 "Only 1 column allowed, have %d of them in %s",
641 SDSET_VECNUM(dsetind), graph_nodeindlist_1D);
642 exit(1);
643 }
644 if (SDSET_VECFILLED(dseti) != SDSET_VECFILLED(dsetind)) {
645 SUMA_S_Errv(
646 "mismatch in number of values between %s and %s\n",
647 graph_nodelist_1D, graph_nodeindlist_1D);
648 exit(1);
649 }
650 /* coerce index input to int */
651 {
652 SUMA_DSET *dsetc=NULL;
653 if (!(dsetc = SUMA_CoercedCopyofDset(dsetind,
654 SUMA_int, NULL))) {
655 SUMA_S_Err("Failed coerce");
656 exit(1);
657 }
658 SUMA_FreeDset(dsetind); dsetind = dsetc; dsetc = NULL;
659 }
660 ivec = SDSET_VEC(dsetind,0);
661 dsetind->dnel->vec[0] = NULL;
662 SUMA_FreeDset(dsetind); dsetind = NULL;
663 } else if (graph_nodeindlist_txt) {
664 char *fl=NULL, *fle=NULL, *fl2=NULL;
665 int ok=0, cnt=0, mxcol=0, nalloc=0, nchar, ans;
666 float dum;
667
668 /* Load file that has node indices and labels */
669 if (!(fl = SUMA_file_suck(graph_nodeindlist_txt, &nchar))) {
670 SUMA_S_Errv("Faile to read %s\n", graph_nodeindlist_txt);
671 exit(1);
672 }
673 fle = fl+nchar;
674 ok = 1;
675 cnt = 0; mxcol = 0, nalloc=0;
676 while (ok && fl < fle) {
677 SUMA_SKIP_BLANK(fl, fle);
678 do {
679 /* skip comment, if any */
680 SUMA_IS_COMMENT_LINE(fl, fle, '#', ans);
681 if (ans) {
682 SUMA_LH("Skipping comment...");
683 SUMA_SKIP_LINE(fl, fle);
684 }
685 } while (ans);
686 SUMA_SKIP_BLANK(fl, fle); if (fl == fle) break;
687 SUMA_LHv("Now at >>%s<<\n", fl);
688 /* read first number */
689 SUMA_ADVANCE_PAST_NUM(fl, dum, ok);
690 if (!ok && fl!=fle) {
691 SUMA_S_Errv("Failed to read i, stuck at >>%s<<\n",
692 fl); exit(1);
693 }
694 if (cnt >= nalloc) {
695 nalloc = nalloc+256;
696 ivec = (int *)SUMA_realloc(ivec, nalloc*sizeof(int));
697 names = (char **)SUMA_realloc(names, nalloc*sizeof(char *));
698 clan = (int *)SUMA_realloc(clan, nalloc*sizeof(int));
699 cols = (float *)SUMA_realloc(cols, 3*nalloc*sizeof(int));
700 }
701 SUMA_LHv("index[%d] %f\n", cnt, dum);
702 ivec[cnt] = (int)dum;
703 /* Now get the label */
704 SUMA_GET_BETWEEN_BLANKS(fl, fle, fl2);
705 if (fl2 > fl) {
706 names[cnt]=NULL;
707 SUMA_COPY_TO_STRING(fl, fl2, names[cnt]);
708 SUMA_LHv(" Name[%d] %s, fl2[0] is >%c<\n",
709 cnt, names[cnt], fl2[0]);
710 fl = fl2;
711 } else {
712 SUMA_S_Errv("Failed to get label associated with index %d\n"
713 ,ivec[cnt]);
714 exit(1);
715 }
716 /* And lastly, do we have numbers left? */
717 SUMA_SKIP_PURE_BLANK(fl, fle);
718 SUMA_GET_TO_EOL(fl, fle, fl2);
719 if (fl2 > fl) {
720 SUMA_COPY_TO_STRING(fl, fl2, stmp);
721 SUMA_LH("Parsing %s", stmp);
722 /* colors anyone? */
723 nv = SUMA_StringToNum(stmp, (void *)fv5, 4, 1);
724 switch (nv) {
725 case 0:
726 clan[cnt] = -2;
727 case 1:
728 clan[cnt] = (int)fv5[0];
729 cols[3*cnt ] = -1.0;
730 cols[3*cnt+1] = -1.0;
731 cols[3*cnt+2] = -1.0;
732 break;
733 case 4:
734 clan[cnt] = (int)fv5[0];
735 cols[3*cnt ] = fv5[1];
736 cols[3*cnt+1] = fv5[2];
737 cols[3*cnt+2] = fv5[3];
738 break;
739 default:
740 SUMA_S_Err(
741 "Expected 1 or 4 values after name %s, got %d"
742 "Replacing with special group",
743 names[cnt], nv);
744 clan[cnt] = -1;
745 cols[3*cnt ] = -1.0;
746 cols[3*cnt+1] = -1.0;
747 cols[3*cnt+2] = -1.0;
748 break;
749 }
750 fl = fl2;
751 } else {
752 clan[cnt] = -2;
753 }
754 SUMA_ifree(stmp);
755 ++cnt;
756 }
757 if (cnt != SDSET_VECFILLED(dseti)) {
758 SUMA_S_Errv("Have %d entries in %s but %d enties in %s\n",
759 cnt, graph_nodeindlist_txt,
760 SDSET_VECFILLED(dseti), graph_nodelist_1D);
761 exit(1);
762 }
763 /* check on colors and grouping */
764 if (clan[0] == -2) {/* No grouping, no colors */
765 SUMA_ifree(clan); SUMA_ifree(cols);
766 } else {
767 mxgrp = -1;
768 for (cnt=0; cnt <SDSET_VECFILLED(dseti); ++cnt) {
769 if (clan[cnt] > mxgrp) mxgrp = clan[cnt];
770 }
771 for (cnt=0; cnt <SDSET_VECFILLED(dseti); ++cnt) {
772 if (clan[cnt] < 0) clan[cnt] = mxgrp + 1;
773 }
774 sprintf(colnm, "%d", SUMA_MIN_PAIR(mxgrp+2,255));
775 for (cnt=0; cnt <SDSET_VECFILLED(dseti); ++cnt) {
776 if (cols[3*cnt] < 0) {
777 SUMA_a_good_col(colnm, clan[cnt], fv5);
778 cols[3*cnt ] = fv5[0];
779 cols[3*cnt+1] = fv5[1];
780 cols[3*cnt+2] = fv5[1];
781 }
782 }
783 }
784 } else {
785 ivec = NULL; /* SUMA_AddGDsetNodeListElement will generate one */
786 }
787
788 SUMA_LH( "Have %d node indices %d .. %d in %s\n"
789 "Graph %s has %ld segment nodes, %ld nodes defined.\n",
790 SDSET_VECFILLED(dseti), ivec[0],
791 ivec[SDSET_VECFILLED(dseti)-1], SDSET_LABEL(dseti),
792 SDSET_LABEL(dset), GDSET_N_SEG_POINTS(dset),
793 GDSET_N_ALL_POINTS(dset));
794 if (!RAI) {
795 int cnt;
796 float *fvx = (float *)SDSET_VEC(dseti,0);
797 float *fvy = (float *)SDSET_VEC(dseti,1);
798 SUMA_LH("Flipping to LPI");
799 for (cnt=0; cnt <SDSET_VECFILLED(dseti); ++cnt) {
800 fvx[cnt] = -fvx[cnt];
801 fvy[cnt] = -fvy[cnt];
802 }
803 }
804 if (!(SUMA_AddGDsetNodeListElement(dset, ivec,
805 SDSET_VEC(dseti,0),
806 SDSET_VEC(dseti,1),
807 SDSET_VEC(dseti,2),
808 names,
809 clan,
810 cols,
811 SDSET_VECFILLED(dseti)))) {
812 SUMA_S_Err("Failed to add node list");
813 exit(1);
814 }
815 SUMA_FreeDset(dseti); dseti = NULL;
816 if (ivec) free(ivec); ivec=NULL;
817 if (names) SUMA_free(names); names = NULL;
818 SUMA_ifree(cols); SUMA_ifree(clan);
819 }
820 if (LocalHead) SUMA_ShowDset(dset,0, NULL);
821 }
822
823 SUMA_LH("Checking on inel...");
824 /* make sure inel is initialized*/
825 if (!dset->inel || !SDSET_NODEINDLEN(dset)) {
826 SUMA_SL_Err("Bad dset->inel\nOld niml dset?");
827 SUMA_ShowDset(dset,0, NULL);
828 SUMA_DUMP_TRACE("Bad dset->inel, dumping trace for debug:");
829 SUMA_FreeDset(dset); dset = NULL;
830 SUMA_RETURN(1);
831 }
832
833 SUMA_LH("On to node index stuff...");
834 if (node_index_1d) { /* add a node index column */
835 iform = SUMA_1D;
836 if (!(dseti = SUMA_LoadDset_s (node_index_1d, &iform, 0))) {
837 SUMA_S_Err("Failed to load node index dset");
838 exit(1);
839 }
840 if (SDSET_VECNUM(dseti) != 1) {
841 SUMA_S_Err("Bad node index source, only one column allowed");
842 exit(1);
843 }
844 if (SDSET_VECFILLED(dseti) != SDSET_VECFILLED(dset)) {
845 SUMA_S_Err(
846 "mismatch in number of values in index source and dataset");
847 exit(1);
848 }
849 Ti = (int *) SUMA_calloc(SDSET_VECFILLED(dseti), sizeof(int));
850 fv = (float *)dseti->dnel->vec[0];
851 for (j=0; j<SDSET_VECFILLED(dseti); ++j) {
852 Ti[j] = (int)fv[j];
853 }
854 if (!SUMA_AddDsetNelCol ( dset, "Node Index",
855 SUMA_NODE_INDEX, (void *)Ti, NULL, 1)) {
856 SUMA_SL_Err("Failed to add column");
857 if (Ti) SUMA_free(Ti); Ti = NULL;
858 exit(1);
859 }
860 SUMA_free(Ti); Ti = NULL;
861 SUMA_FreeDset(dseti); dseti = NULL;
862 }
863
864
865 if (add_node_index) {
866 if (!SUMA_PopulateDsetNodeIndexNel(dset, 1)) {
867 SUMA_S_Err("Failed to add node index column");
868 exit(1);
869 }
870 }
871
872 if (pad_to_node == 0) {
873 DSET_MAX_NODE_INDEX(dset, pad_to_node);
874 if (pad_to_node < 0) {
875 SUMA_S_Err( "Failed to get max node index in input dset.\n"
876 "Cannot set pad_to_node automatically\n");
877 exit(1);
878 }
879 }
880 if (pad_to_node > 0) {
881 SUMA_S_Notev("Padding output dset until node %d\n", pad_to_node);
882 }
883
884 SUMA_LHv("On to auto_nmask ...%p %p %p\n",
885 ps->bmaskname,ps->nmaskname,ps->cmask);
886 if (!(auto_nmask =
887 SUMA_load_all_command_masks( ps->bmaskname,
888 ps->nmaskname,
889 ps->cmask,
890 SDSET_VECFILLED(dset),
891 &N_inmask))
892 && N_inmask < 0) {
893 SUMA_S_Err("Failed loading mask");
894 exit(1);
895 }
896 if (auto_nmask) { /* mask input here */
897 SUMA_LH("Masking here ...");
898 if (!(dset_m = SUMA_MaskedCopyofDset(dset, auto_nmask, NULL, 1, 0))){
899 SUMA_S_Err("Failed to mask dset by mask options\n");
900 exit(1);
901 }
902 SUMA_FreeDset(dset); dset = NULL;
903 dset = dset_m; dset_m = NULL;
904 }
905
906 SUMA_LH("On to node_mask ...");
907 if (node_mask) { /* mask dataset */
908 iform = SUMA_1D;
909 if (!(dseti = SUMA_LoadDset_s (node_mask, &iform, 0))) {
910 SUMA_S_Err("Failed to load node_selection dset");
911 exit(1);
912 }
913 if (SDSET_VECNUM(dseti) != 1) {
914 SUMA_S_Err("Bad node index source, only one column allowed");
915 exit(1);
916 }
917
918 Ti = (int *) SUMA_calloc(SDSET_VECFILLED(dseti), sizeof(int));
919 fv = (float *)dseti->dnel->vec[0];
920 for (j=0; j<SDSET_VECFILLED(dseti); ++j) Ti[j] = (int)fv[j];
921
922 if (orderednodelist) {
923 int *inlu=NULL, N_inlu=0;
924 /* make sure indexlist is unique */
925 inlu = SUMA_UniqueInt(Ti, SDSET_VECFILLED(dseti),
926 &N_inlu, 0);
927 SUMA_free(inlu); inlu = NULL;
928 if (N_inlu != SDSET_VECFILLED(dseti)) {
929 SUMA_S_Err( "Indexlist contains duplicate entries.\n"
930 "This is not supported.");
931 exit(1);
932 }
933
934
935 if (!(dset_m = SUMA_MaskedByOrderedNodeIndexCopyofDset(
936 dset, Ti, SDSET_VECFILLED(dseti), NULL, 1, 0))) {
937 SUMA_S_Err("Failed to mask dset by node indices\n");
938 SUMA_S_Note("If your input dataset did not have a node index \n"
939 "explicitly defined, use -add_node_index or\n"
940 "-node_index_1D options to specify node indices.\n" )
941 exit(1);
942 }
943 } else {
944 if (!(dset_m = SUMA_MaskedByNodeIndexCopyofDset(
945 dset, Ti, SDSET_VECFILLED(dseti), NULL, 1, 0))) {
946 SUMA_S_Err("Failed to mask dset by node indices\n");
947 SUMA_S_Note("If your input dataset did not have a node index \n"
948 "explicitly defined, use -add_node_index or\n"
949 "-node_index_1D options to specify node indices.\n" )
950 exit(1);
951 }
952 }
953
954 SUMA_free(Ti); Ti = NULL;
955 SUMA_free(indexmap); indexmap = NULL;
956 SUMA_FreeDset(dseti); dseti = NULL;
957 SUMA_FreeDset(dset); dset = NULL;
958 dset = dset_m; dset_m = NULL;
959 }
960
961
962 if (pad_to_node >= 0) {
963 dset_m = SUMA_PaddedCopyofDset ( dset, pad_to_node );
964 SUMA_FreeDset(dset); dset = NULL;
965 dset = dset_m; dset_m = NULL;
966 }
967
968 SUMA_LH("On to prefix ...");
969
970 if (!prfx) {
971 /* don't use iform because some 1Ds are NIML compatible and they get
972 read-in as such unless you specifically order otherwise. */
973 prefix = SUMA_RemoveDsetExtension_s(argv[i], SUMA_NO_DSET_FORMAT);
974 } else {
975 prefix = SUMA_copy_string(prfx);
976 }
977
978 /* set a new ID for the dset */
979 SUMA_NEWDSET_ID_LABEL_HIST(dset, prefix) ;
980
981
982 if (no_hist) {
983 SUMA_RemoveDsetHist(dset);
984 }
985
986 if (prepend_node_index) {/* prepend node index? */
987 if (!SUMA_InsertDsetNelCol ( dset, "Node Index Copy",
988 SUMA_NODE_INT,
989 (void *)(dset->inel->vec[0]),
990 NULL ,1, 0)) {
991 SUMA_S_Err("Failed to insert column");
992 }
993 if (LocalHead) SUMA_ShowDset(dset,0, NULL);
994 }
995
996 if (cmapfile && SM) { /* labelize */
997 SUMA_DSET *idset;
998 if (!SUMA_is_AllConsistentCastType_dset(dset, SUMA_int)) {
999 idset = SUMA_CoercedCopyofDset(dset, SUMA_int, NULL);
1000 } else {
1001 idset = dset;
1002 }
1003 if (!(SUMA_dset_to_Label_dset_cmap(idset, SM))) {
1004 SUMA_S_Err("Failed to make change");
1005 exit(1);
1006 }
1007
1008 if (idset != dset) {
1009 SUMA_FreeDset(dset); dset = idset; idset=NULL;
1010 }
1011 }
1012
1013 SUMA_LHv("About to write dset to %s\n", prefix);
1014 if (!split) {
1015 NameOut = SUMA_WriteDset_s (prefix, dset, oform, overwrite, 0);
1016 if (!NameOut && !SUMA_IS_DSET_STDXXX_FORMAT(oform)) {
1017 SUMA_SL_Err("Failed to write dataset."); exit(1);
1018 } else {
1019 if (NameOut) SUMA_free(NameOut); NameOut = NULL;
1020 }
1021 } else {
1022 int ksp, ikp, ikps, nsplits=(int)ceil((float)SDSET_VECNUM(dset)/split);
1023 SUMA_DSET *ds=NULL;
1024 char cbuf[12]={""}, *prefs = NULL;
1025 byte *colmask=NULL;
1026 colmask=(byte*)SUMA_malloc(sizeof(byte)*SDSET_VECNUM(dset));
1027 for (ksp=0; ksp<split; ++ksp) {
1028 sprintf(cbuf,"%04d",ksp);
1029 memset(colmask, 0, sizeof(byte)*SDSET_VECNUM(dset));
1030 ikp = ksp*nsplits;
1031 ikps = SUMA_MIN_PAIR(SDSET_VECNUM(dset), (ksp+1)*nsplits);
1032 if (ikp == ikps) continue; /* all one */
1033 while (ikp < ikps) colmask[ikp++]=1;
1034 prefs = SUMA_RemoveDsetExtension_s(prefix,SUMA_NO_DSET_FORMAT);
1035 prefs = SUMA_append_replace_string(prefs,cbuf,".", 1);
1036 if (!(ds = SUMA_MaskedCopyofDset(dset, NULL, colmask, 1, 1))) {
1037 SUMA_S_Err("Failed to get masked copy");
1038 exit(1);
1039 }
1040 NameOut = SUMA_WriteDset_s (prefs, ds, oform, overwrite, 0);
1041 if (!NameOut && !SUMA_IS_DSET_STDXXX_FORMAT(oform)) {
1042 SUMA_SL_Err("Failed to write dataset."); exit(1);
1043 } else {
1044 if (NameOut) SUMA_free(NameOut); NameOut = NULL;
1045 }
1046 if (prefs) SUMA_free(prefs);
1047 SUMA_FreeDset(ds); ds=NULL;
1048 }
1049 SUMA_free(colmask); colmask=NULL;
1050 }
1051
1052 if (SM) SUMA_Free_ColorMap(SM); SM = NULL;
1053 if (prefix) SUMA_free(prefix); prefix = NULL;
1054 if (dset) SUMA_FreeDset((void *)dset); dset = NULL;
1055 if (NameOut) SUMA_free(NameOut); NameOut = NULL;
1056 }
1057
1058 SUMA_RETURN(0);
1059 }
1060