#include "SUMA_suma.h" void usage_SUMA_quickspec(SUMA_GENERIC_ARGV_PARSE *ps) { static char FuncName[]={"usage_SUMA_quickspec"}; char * s = NULL, *sio=NULL; sio = SUMA_help_IO_Args(ps); printf ( "\nUsage: quickspec \n" " <-tn TYPE NAME> ...\n" " <-tsn TYPE STATE NAME> ...\n" " [<-spec specfile>] [-h/-help]\n" " Use this spec file for quick and dirty way of \n" " loading a surface into SUMA or the command line programs.\n" "\n" "Options:\n" "%s\n" " -tsnad TYPE STATE NAME ANATFLAG LDP: \n" " specify surface type, state, name, anatomical correctness, \n" " and its Local Domain Parent.\n" " ANATFLAG: 'Y' if surface is anatomically correct (default).\n" " 'N' if it is not anatomically correct.\n" " LDP: Name of Local Domain Parent surface.\n" " Use SAME (default) if surface is its own LDP.\n" " -tsnadm TYPE STATE NAME ANATFLAG LDP MARKER: \n" " specify surface type, state, name, anatomical correctness, \n" " Local Domain Parent, and node marker file.\n" " MARKER: A niml.do Displayable Object (DO) to put at every\n" " node of the surface. See @DO.examples for information\n" " about displayable objects\n" " -tsnadl TYPE STATE NAME ANATFLAG LDP LABELDSET: \n" " specify surface type, state, name, anatomical correctness, \n" " Local Domain Parent, and a label dataset file.\n" " LABELDSET: A surface dataset containing node labels.\n" " -spec specfile: Name of spec file output.\n" " Default is quick.spec\n" " The program will only overwrite \n" " quick.spec (the default) spec file.\n" " -h or -help: This message here.\n" "\n" " You can use any combination of -tn and -tsn options.\n" " Fields in the spec file that are (or cannot) be specified\n" " by this program are set to default values.\n" "\n This program was written to ward off righteous whiners and is\n" " not meant to replace the venerable @SUMA_Make_Spec_XX scripts.\n" "\n" , sio); SUMA_free(sio); sio = NULL; s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL; printf(" Ziad S. Saad SSCC/NIMH/NIH saadz@mail.nih.gov \n\t\t Tue Dec 30\n" "\n"); return; } int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"quickspec"}; int detail, kar, i, j, N_surf, N_name, idefstate; FILE *fid = NULL; char *spec_name, stmp[500], *Unique_st; SUMA_SO_File_Type TypeC[SUMA_MAX_N_SURFACE_SPEC]; static char *State[SUMA_MAX_N_SURFACE_SPEC], *Name_coord[SUMA_MAX_N_SURFACE_SPEC], *Name_topo[SUMA_MAX_N_SURFACE_SPEC], Anat[SUMA_MAX_N_SURFACE_SPEC], *LDP[SUMA_MAX_N_SURFACE_SPEC], *MARK[SUMA_MAX_N_SURFACE_SPEC], *LABEL[SUMA_MAX_N_SURFACE_SPEC]; SUMA_GENERIC_ARGV_PARSE *ps; SUMA_Boolean brk; SUMA_mainENTRY; /* allocate space for CommonFields structure */ SUMAg_CF = SUMA_Create_CommonFields (); if (SUMAg_CF == NULL) { fprintf( SUMA_STDERR, "Error %s: Failed in SUMA_Create_CommonFields\n", FuncName); exit(1); } ps = SUMA_Parse_IO_Args(argc, argv, "-t;"); if (argc < 3) { usage_SUMA_quickspec (ps); exit (0); /* status 0 on -help 18 Sep 2018 [rickr] */ } kar = 1; brk = NOPE; detail = 1; N_surf = 0; N_name = 0; spec_name = NULL; while (kar < argc) { /* loop across command line options */ /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { usage_SUMA_quickspec(ps); exit (0); /* status 0 on -help 18 Sep 2018 [rickr] */ } if (!brk && (strcmp(argv[kar], "-spec") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -spec \n"); exit (1); } spec_name = argv[kar]; if (!THD_ok_overwrite() && SUMA_filexists(spec_name)) { fprintf (SUMA_STDERR, "File %s exists, choose another one.\n", spec_name); exit(1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-tn") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Type argument must follow -tn \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if (TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file type.\n", argv[kar]); exit(1); } /* get the name */ if (TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } State[N_surf] = NULL; Anat[N_surf] = 'Y'; LDP[N_surf] = NULL; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsn") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsn \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsn \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } Anat[N_surf] = 'Y'; LDP[N_surf] = NULL; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsnad") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsnad \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } /* get the anatomical flag */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Anatomical flag must follow NAME with -tsnad \n"); exit (1); } Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]); if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') { SUMA_S_Err("Anatomical flag must be either 'y' or 'n'"); exit (1); } /* get the LDP */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LDP[N_surf] = argv[kar]; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsnadm") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsnad \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } /* get the anatomical flag */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Anatomical flag must follow NAME with -tsnad \n"); exit (1); } Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]); if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') { SUMA_S_Err("Anatomical flag must be either 'y' or 'n'"); exit (1); } /* get the LDP */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LDP[N_surf] = argv[kar]; /* get the nodeMarker */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } MARK[N_surf] = argv[kar]; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsnadl") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsnad \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } /* get the anatomical flag */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Anatomical flag must follow NAME with -tsnad \n"); exit (1); } Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]); if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') { SUMA_S_Err("Anatomical flag must be either 'y' or 'n'"); exit (1); } /* get the LDP */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LDP[N_surf] = argv[kar]; /* get the nodeMarker */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LABEL[N_surf] = argv[kar]; ++N_surf; brk = YUP; } if (!brk) { fprintf (SUMA_STDERR, "Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]); exit (1); } else { brk = NOPE; kar ++; } } /* write out the comments */ if (!spec_name) { fid = fopen("quick.spec", "w"); } else { fid = fopen(spec_name,"w"); } if (!fid){ SUMA_SL_Err("Failed to open file for output"); exit(1); } fprintf(fid,"# define the group\n"); fprintf(fid,"\tGroup = QuickSpec\n"); /* now create a list of unique states */ idefstate = 0; if (!State[0]) { Unique_st = SUMA_copy_string ("\tStateDef = S_1\n"); idefstate = 1; } else { sprintf(stmp, "\tStateDef = %s\n", State[0]); Unique_st = SUMA_copy_string (stmp); } for (i=1; i < N_surf; ++i) { if (!State[i]) { ++idefstate; sprintf(stmp,"\tStateDef = S_%d\n", idefstate); Unique_st = SUMA_append_replace_string (Unique_st, stmp, "", 1); } else { if (SUMA_iswordin(Unique_st, State[i]) != 1) { sprintf(stmp, "\tStateDef = %s\n", State[i]); Unique_st = SUMA_append_replace_string(Unique_st, stmp, "", 1); } } } fprintf (fid, "# define the various States\n"); fprintf (fid, "%s\n", Unique_st); /* check on LDP correctness */ for (i=0; i < N_surf; ++i) { if (LDP[i]) { if (!strcmp(LDP[i],"same") || !strcmp(LDP[i],"Same")) SUMA_TO_UPPER(LDP[i]); if (strcmp(LDP[i],"SAME")) { j= 0; while (j