int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SpharmReco"}; SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_SurfSpecFile *Spec = NULL; int *isin=NULL; int i = -1, ii, jj, kk, il, N_Spec=0, i3, OK, l, lc, ncol=0, nrow=0, dims[20], N_dims=0, N_surfs=0, j, j_l; SUMA_Boolean exists=NOPE; float *far=NULL, *xbuf=NULL, *ybuf=NULL, *zbuf=NULL; double *dv=NULL, fac = 0.0; complex *cv=NULL; SUMA_FORM_AFNI_DSET_STRUCT *OptDs = NULL; SUMA_SurfaceObject *SO = NULL, *SOt=NULL; SUMA_VOLPAR *vp = NULL; SUMA_MX_VEC *y_l=NULL, *y_l_t=NULL; SUMA_MX_VEC *betal=NULL; SUMA_MX_VEC *xe=NULL, *sm=NULL, *yc=NULL; SUMA_MX_VEC **axe=NULL, **abeta=NULL; char *oname=NULL, stmp[100], *pref=NULL; SUMA_SO_File_Format form=SUMA_FF_NOT_SPECIFIED; SUMA_SO_File_Type tp=SUMA_FT_NOT_SPECIFIED; SUMA_OPT_SPHERICAL_BASES optb; void *SO_name=NULL; struct timeval tt; int oform= SUMA_NO_DSET_FORMAT; char *ooo=NULL; float *fbuf=NULL; SUMA_DSET *out_dset = NULL; SUMA_Boolean do_surf_xyz = NOPE; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-i;-spec;-talk;-o;"); if (argc < 2) { usage_SpharmReco(ps); exit (1); } Opt = SUMA_SpharmReco_ParseInput (argv, argc, ps); if (Opt->debug) LocalHead = YUP; if (Opt->n_in_namev < 1) { SUMA_S_Err("No Coef!"); exit (1); } if (ps->o_N_surfnames) do_surf_xyz = YUP; if (!ps->o_N_surfnames && !Opt->out_prefix) { SUMA_S_Notev("Using default prefix of %s\n", "spharm_sm"); Opt->out_prefix = SUMA_copy_string("spharm_sm"); } if ((Opt->n_in_namev % 3) && do_surf_xyz) { SUMA_S_Errv("Number of coefficient options (%d) must be\n" "a multiple of three if output is \n" "to be treated as x, y, z coordinates\n", Opt->n_in_namev); exit(1); } /* decide on output form */ if (Opt->out_prefix) { oform = SUMA_GuessFormatFromExtension(Opt->out_prefix,"something.1D.dset"); } if (Opt->debug > 2) LocalHead = YUP; /* check on inputs */ optb.SOu=NULL; optb.BasesFileRoot=Opt->bases_prefix; optb.SaveBases=Opt->bases_prefix; optb.debug = Opt->debug; N_surfs = ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames; if (( N_surfs != 1)) { SUMA_S_Errv("You must provide only one surface.\n" "Have %d on command line.\n", N_surfs); exit(1); } Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec != 1) { SUMA_S_Err("Multiple spec at input."); exit(1); } for (i=0; i<N_surfs; ++i) { SO = SUMA_Load_Spec_Surf(Spec, i, ps->sv[i], 0); if (!SO) { fprintf (SUMA_STDERR,"Error %s:\n" "Failed to find surface\n" "in spec file. \n", FuncName ); exit(1); } if (Opt->debug > 2) SUMA_Print_Surface_Object(SO, SUMA_STDERR); if (!SO->normdir) SO->normdir = 1; /* set it to something */ SOt = SUMA_CreateChildSO( SO, NULL, -1, NULL, -1, 0); if (!SOt->State) {SOt->State = SUMA_copy_string("spharm_domain"); } if (!SOt->Group) {SOt->Group = SUMA_copy_string("spharm_domain"); } } /* see if SUMA talk is turned on */ if (ps->cs->talk_suma) { ps->cs->istream = SUMA_GEOMCOMP_LINE; if (!SUMA_SendToSuma (SO, ps->cs, NULL, SUMA_NO_DSET_TYPE, 0)) { SUMA_SL_Err("Failed to initialize SUMA_SendToSuma"); ps->cs->Send = NOPE; ps->cs->talk_suma = NOPE; } SUMA_SendSumaNewSurface(SO, ps->cs); } /* Number of coefficients */ axe = (SUMA_MX_VEC **)SUMA_calloc(Opt->n_in_namev, sizeof(SUMA_MX_VEC*)); abeta = (SUMA_MX_VEC **)SUMA_calloc(Opt->n_in_namev, sizeof(SUMA_MX_VEC*)); /* initialize output variables */ for (i=0; i<Opt->n_in_namev; ++i) { dims[0] = SO->N_Node; dims[1] = 1; N_dims = 2; axe[i] = SUMA_NewMxVec(SUMA_double, 2, dims, 1); if (Opt->debug > 1) SUMA_ShowMxVec(axe[i], 1, NULL, "\naxe[i]\n"); N_dims = -1; /* take whatever is in file, otherwise, should setup dims[0] and dims[1] */ abeta[i] = SUMA_Read1DMxVec(SUMA_double, Opt->in_namev[i], dims, &N_dims); if (Opt->debug > 1) SUMA_ShowMxVec(abeta[i], 1, NULL, "\nabeta[i]\n"); } SUMA_Spherical_Bases(&l, NULL); /* init SUMA_Spherical_Bases */ /* start timer*/ SUMA_etime2(FuncName, NULL, NULL); /* A record of matrices and processes to follow for spharm reconstruction Here y_l, for each l, and beta are loaded from files created by SpharmDeco N_Node : Number of points in parametrization of sphere sigma : the smoothing kernel 0 == No smoothing, 0.01 (quite a bit of smoothing). the higher the sigma the more the attenuation of higher degree harmonics. for l = 0; y_l : l th degree harmonic complex l+1 x N_Node turned to real since imaginary is all 0 y_l_t : y_l' double N_Node x l+1 XX vt : y_l * y_l_t double l+1 x l+1 XX vt2 : inv(vt) double l+1 x l+1 XX Ycommon : vt2 * y_l double l+1 x N_Node XX betal : Ycommon * x double l+1 x 1 betal : filled from beta(l,0:2l) double l+1 x 1 (beta(0,0), really) xe : y_l_t * betal double N_Node x 1 for l > 0; y_l : l th degree harmonic complex l+1 x N_Node turned to real of dimensions: double 2*l+1 x N_Node where the imaginary part of y_l is appended below the real part y_l_t : y_l' double N_Node x 2*l+1 XX vt : y_l * y_l_t double 2*l+1 x 2*l+1 XX vt2 : inv(vt) double 2*l+1 x 2*l+1 XX Ycommon : vt2 * y_l double 2*l+1 x N_Node XX dif_vec_x: x - xe double N_Node x 1 betal : filled from beta(l,0:2l) double 2*l+1 x 1 sm : y_l_t * betal double N_Node x 1 fac : exp((-l*(l+1))*sigma) double 1 x 1 xe : xe + fac * sm double N_Node x 1 xe is the estimate of x up to order l harmonics beta : lower triangular matrix where betal double l+1 x 2l+1 are stored for all l degrees */ l=0; do { lc = l; y_l = SUMA_Spherical_Bases(&lc, &optb); /* y_l is equal to Y' in Moo's SPHARsmooth.m function */ if (lc < l) { /* The function will read in the bases from disk */ Opt->iopt = lc; /* y_l is a (l+1 x N_Node) complex matrix. */ SUMA_S_Notev("Cannot go for order higher than %d\n.", lc); goto NEXT_L; } do { if (SO) { if ((LocalHead && l == 0) || Opt->debug > 1) SUMA_S_Notev("Using the mesh from %s for \n" "a reconstruction of degree %d.\n", SO->Label, l); if (Opt->debug > 2) SUMA_Print_Surface_Object (SO, SUMA_STDERR); } else { SUMA_S_Err("NULL SO!!!"); exit(1); } if (LocalHead || Opt->debug > 1) { fprintf(SUMA_STDERR,"%s: Doing l = %d\n", FuncName, l); SUMA_etime2(FuncName, "Entering loop", FuncName); } if (l==0) { yc = SUMA_CoerceMxVec(y_l, SUMA_double, 0, NULL); /* for l == 0, all imaginary comp. are 0 */ y_l = SUMA_FreeMxVec(y_l); y_l = yc; yc = NULL; y_l_t = SUMA_MxVecTranspose(y_l, NULL); /* y_l is equal to Y' in Moo's SPHARsmooth.m function*/ if (Opt->debug > 1) SUMA_ShowMxVec(y_l_t, 1, NULL, "\ny_l_t matrix\n"); dims[0] = 2*l+1; dims[1] = 1; betal = SUMA_NewMxVec(SUMA_double, 2, dims, 1); for (jj=0; jj<Opt->n_in_namev; ++jj) { for (i=0;i<=2*l;++i) { mxvd2(betal,i,0) = mxvd2(abeta[jj],l, i); } if (Opt->debug > 1) SUMA_ShowMxVec(betal, 1, NULL, "\nbetal matrix\n"); xe = SUMA_MxVecMult(y_l_t, betal, NULL, 0); if (Opt->debug > 1) { SUMA_ShowMxVec(xe, 1, NULL, "\nxe vector\n"); if (Opt->debug > 2) SUMA_WriteMxVec(xe, "xe_l0.1D", "#xe vector"); } axe[jj] = xe; xe = NULL; } } else { /* higher order, need to deal with real and imaginary parts*/ /* Catenate the columns of y_l with the real columns first (negative harmonics), followed by imaginary ones (positive harms.)*/ sprintf(stmp, "Starting with order l=%d", l); if (Opt->debug) SUMA_etime2(FuncName, stmp, FuncName); y_l = SUMA_YLcomp_to_YLdoub(&y_l, Opt->debug); /* Now y_l is real */ if (Opt->debug ) SUMA_etime2(FuncName, "Created y_l", FuncName); if (Opt->debug > 2) { SUMA_WriteMxVec(y_l, "y_l.1D.dset", "#y_l real matrix\n"); } y_l_t = SUMA_MxVecTranspose(y_l, NULL); /* y_l is equal to Y' in Moo's SPHARsmooth.m function*/ if (Opt->debug > 1) SUMA_ShowMxVec(y_l_t, 1, NULL, "\ny_l_t matrix\n"); if (Opt->debug ) SUMA_etime2(FuncName, "Trasnposed y_l", FuncName); fac = exp((double)(-l*(l+1))*Opt->v0); dims[0] = 2*l+1; dims[1] = 1; betal = SUMA_NewMxVec(SUMA_double, 2, dims, 1); for (jj=0; jj<Opt->n_in_namev; ++jj) { xe = axe[jj]; for (i=0;i<=2*l;++i) { mxvd2(betal,i,0) = mxvd2(abeta[jj],l, i); } if (Opt->debug > 1) SUMA_ShowMxVec(betal, 1, NULL, "\nbetal matrix\n"); sm = SUMA_MxVecMult(y_l_t, betal, sm, 0); if (Opt->debug > 1) { sprintf(stmp,"\nsm_%d vector\n", jj); SUMA_ShowMxVec(sm , 1, NULL, stmp); } for (i=0;i<xe->N_vals;++i) { mxvd1(xe,i) += fac * mxvd1(sm,i); } if (Opt->debug > 1) { sprintf(stmp,"\n%d_estimate vector\n", jj); SUMA_ShowMxVec(xe, 1, NULL, stmp); sprintf(stmp,"%d_estimate_l%d.1D.dset", jj, l); if (Opt->debug > 2) SUMA_WriteMxVec(xe, stmp, "#estimate at last l\n"); } } if (Opt->debug) SUMA_etime2(FuncName, "Refit residual", FuncName); } /* store new coordinates, in a temp surface, fun to update as we're progressing in case want to feed suma at some point*/ if (do_surf_xyz) { if (l==0 && ps->cs->Send && Opt->debug) { SUMA_S_Warn("Assuming coefficients are XYZ of surfaces !\n" "Only the 1st three data columns will be used\n" "in talk_suma mode.\n" "Warnings muted for l > 0\n"); } for (i=0; i<SO->N_Node; ++i) { i3 = 3*i; SOt->NodeList[i3 ] = mxvd1(axe[0], i); SOt->NodeList[i3+1] = mxvd1(axe[1], i); SOt->NodeList[i3+2] = mxvd1(axe[2], i); } } if (ps->cs->Send) { /* send the smoothed coords */ if (do_surf_xyz) { /* surface coordinates */ if (l > 0) { if (Opt->debug) { SUMA_S_Notev("[%f %f %f]\n", SOt->NodeList[0], SOt->NodeList[1], SOt->NodeList[2]); } if (!SUMA_SendToSuma ( SO, ps->cs, (void *)SOt->NodeList, SUMA_NODE_XYZ, 1)) { SUMA_SL_Warn( "Failed in SUMA_SendToSuma\n" "Communication halted."); } } } else { if (l > 0) { if (!fbuf) fbuf = (float *)SUMA_malloc(SO->N_Node* sizeof(float)); for (i=0; i<SO->N_Node; ++i) fbuf[i] = mxvd1(axe[0], i); if (!SUMA_SendToSuma ( SO, ps->cs, (void *)fbuf, SUMA_NODE_RGBAb, 1)) { SUMA_SL_Warn( "Failed in SUMA_SendToSuma\n" "Communication halted."); } } } } /* Done with order l */ if (y_l) y_l = SUMA_FreeMxVec(y_l); if (y_l_t) y_l_t = SUMA_FreeMxVec(y_l_t); if (betal) betal = SUMA_FreeMxVec(betal); if (Opt->debug ) { SUMA_S_Note("MemCheck:"); MCHECK; } } while (0); NEXT_L: ++l; } while (l <= Opt->iopt); --l; /* back to where you stopped, kid */ /* Now create an output data set for the reconstructed data */ out_dset = SUMA_CreateDsetPointer( Opt->out_prefix ? Opt->out_prefix:"spharm_reco", SUMA_NODE_BUCKET, /* mix and match */ NULL, /* no idcode, let the function create one from the filename*/ NULL, /* no domain str specified */ SO->N_Node /* Number of nodes allocated for */ ); /* add results */ for (jj=0; jj<Opt->n_in_namev; ++jj) { if (!fbuf) fbuf = (float *)SUMA_malloc(SO->N_Node*sizeof(float)); for (i=0; i<SO->N_Node; ++i) fbuf[i] = mxvd1(axe[jj], i); if (!SUMA_AddDsetNelCol( out_dset, "sp_reco", SUMA_NODE_FLOAT, fbuf, NULL, 1)) { SUMA_S_Err("Failed to update output."); exit(1); } axe[jj] = SUMA_FreeMxVec(axe[jj]); } if (Opt->out_prefix) { /* write out the data */ ooo = SUMA_WriteDset_s( Opt->out_prefix, out_dset, oform, THD_ok_overwrite(), 0); if (Opt->debug) SUMA_S_Notev("Wrote %s\n", ooo); SUMA_free(ooo); ooo=NULL; } /* do we need to write out surfaces? */ if (do_surf_xyz && ps->o_N_surfnames) { for (i=0; i<Opt->n_in_namev/3; ++i) { if (ps->o_N_surfnames == Opt->n_in_namev/3) { pref = SUMA_copy_string(ps->o_surfnames[i]); tp = ps->o_FT[i]; form = ps->o_FF[i]; } else { sprintf(stmp, "s%02d", i); pref = SUMA_append_string(ps->o_surfnames[0], stmp); tp = ps->o_FT[0]; form = ps->o_FF[0]; } if (Opt->debug) { SUMA_S_Notev("Prepping to write surface %s\n" "with X Y Z from cols. %d %d %d\n" , pref, i*3, 1+i*3, 2+i*3); } xbuf = (float*)out_dset->dnel->vec[0+i*3]; ybuf = (float*)out_dset->dnel->vec[1+i*3]; zbuf = (float*)out_dset->dnel->vec[2+i*3]; for (ii=0; ii<SO->N_Node; ++ii) { i3 = 3*ii; SO->NodeList[i3 ] = xbuf[ii]; SO->NodeList[i3+1] = ybuf[ii]; SO->NodeList[i3+2] = zbuf[ii]; } /* write the surface */ SO_name = SUMA_Prefix2SurfaceName(pref, NULL, NULL, tp, &exists); if (!THD_ok_overwrite() && exists) { fprintf(SUMA_STDERR,"Warning %s:\nOutput surface %s* on disk.\n" "Will not overwrite.\n", FuncName, pref); exit(1); } if (Opt->debug) { SUMA_S_Notev("Saving surface under prefix %s\n", pref); } if (!SUMA_Save_Surface_Object (SO_name, SO, tp, form, NULL)) { SUMA_S_Err("Failed to write reconstructed surface!"); exit(1); } } } /* clean and quit */ if (fbuf) SUMA_free(fbuf); for (i=0; i<Opt->n_in_namev; ++i) { SUMA_FreeMxVec(abeta[i]); } SUMA_free(axe); axe = NULL; SUMA_free(abeta); abeta = NULL; if (sm) sm = SUMA_FreeMxVec(sm); SUMA_Spherical_Bases(&l, NULL); /* clean SUMA_Spherical_Bases */ /* you don't want to exit rapidly because the SUMA might not be done processing the last elements*/ if (ps->cs->Send && !ps->cs->GoneBad) { /* cleanup and close connections */ if (!SUMA_SendToSuma (SO, ps->cs, NULL, SUMA_NODE_XYZ, 2)) { SUMA_SL_Warn("Failed in SUMA_SendToSuma\nCleanup failed"); } } if (N_Spec) { int k=0; for (k=0; k<N_Spec; ++k) { if (!SUMA_FreeSpecFields(&(Spec[k]))) { SUMA_S_Err("Failed to free spec fields"); } } SUMA_free(Spec); Spec = NULL; N_Spec = 0; } if (out_dset) SUMA_FreeDset(out_dset); out_dset = NULL; if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt); if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); exit(0); }
/*!\** File : SUMA.c \author : Ziad Saad Date : Thu Dec 27 16:21:01 EST 2001 Purpose : Input paramters : \param \param Usage : SUMA ( ) Returns : \return \return Support : \sa OpenGL prog. Guide 3rd edition \sa varray.c from book's sample code Side effects : ***/ int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"suma"}; int kar, i; SUMA_SFname *SF_name; SUMA_Boolean brk, SurfIn; char *NameParam, *AfniHostName = NULL, *s = NULL, *pdspec=NULL, *pdsv=NULL; char *specfilename[SUMA_MAX_N_GROUPS], *VolParName[SUMA_MAX_N_GROUPS]; byte InMem[SUMA_MAX_N_GROUPS]; SUMA_SurfSpecFile *Specp[SUMA_MAX_N_GROUPS]; SUMA_Axis *EyeAxis; SUMA_EngineData *ED= NULL; DList *list = NULL; DListElmt *Element= NULL; int iv15[15], N_iv15, ispec, nspec; struct stat stbuf; float fff=0.0; int Start_niml = 0; SUMA_Boolean Domemtrace = YUP; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; SUMAg_CF->isGraphical = YUP; ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-dset;-do;"); /* initialize Volume Parent and AfniHostName to nothing */ for (ispec=0; ispec < SUMA_MAX_N_GROUPS; ++ispec) { specfilename[ispec] = NULL; VolParName[ispec] = NULL; Specp[ispec] = NULL; InMem[ispec] = 0; } AfniHostName = NULL; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); /* call the function to parse the other surface mode inputs */ ispec = 0; if (LocalHead) SUMA_Show_IO_args(ps); if (ps->i_N_surfnames || ps->t_N_surfnames || ps->N_DO) { SUMA_LH("-i and/or -t surfaces on command line!"); Specp[ispec] = SUMA_IO_args_2_spec (ps, &nspec); if (Specp[ispec]) { ++ispec; if (nspec != 1) { SUMA_S_Errv("-spec is being parsed separately here, " "expecting one spec only from SUMA_IO_args_2_spec, \n" "got %d\n", nspec); exit (1); } } else { SUMA_S_Err("Failed to load -i/-t surfaces"); exit(1); } } /* Work the options */ kar = 1; brk = NOPE; SurfIn = NOPE; Domemtrace = YUP; while (kar < argc) { /* loop accross command ine options */ /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { SUMA_usage (ps, strlen(argv[kar]) > 3 ? 2:1); exit (0); /* return a good status on -help 12 Jul 2013 [rickr] */ } /* -list_ports list and quit */ if( strncmp(argv[kar],"-list_ports", 8) == 0) { show_ports_list(); exit(0); } /* -port_number and quit */ if( strncmp(argv[kar],"-port_number", 8) == 0) { int pp = 0; if( ++kar >= argc ) ERROR_exit("need an argument after -port_number!"); pp = get_port_named(argv[kar]); if (strcmp(argv[kar-1], "-port_number_quiet")) { fprintf(stdout, "\nPort %s: %d\n", argv[kar], pp); } else { fprintf(stdout, "%d\n", pp); } if (pp < 1) exit(1); else exit(0); } if (strcmp(argv[kar], "-visuals") == 0) { SUMA_ShowAllVisuals (); exit (0); } if (strcmp(argv[kar], "-brethren_windows") == 0) { Display *dd=NULL; Window ww; if (!(dd = XOpenDisplay(NULL))) { SUMA_S_Err("No display "); exit(1); } ww = XDefaultRootWindow(dd); SUMA_WindowsOnRootDisplay(dd, ww , 0); exit (0); } if (strcmp(argv[kar], "-version") == 0) { s = SUMA_New_Additions (0.0, 1); fprintf (SUMA_STDOUT,"%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-sources") == 0) { s = SUMA_sources_Info(); fprintf (SUMA_STDOUT,"%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-help_nido") == 0) { s = SUMA_NIDO_Info(); fprintf (SUMA_STDOUT,"%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-all_latest_news") == 0) { s = SUMA_New_Additions (-1.0, 0); fprintf (SUMA_STDOUT,"%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-help_sphinx_interactive") == 0) { FILE *fout = NULL; if( ++kar >= argc ) ERROR_exit("need a file name after -help_sphinx_interactive!"); fout = fopen(argv[kar],"w"); if (!fout) { SUMA_S_Err("Failed to open %s for writing", argv[kar]); exit(1); } SUMA_help_message(fout,SPX); fclose(fout); fout = NULL; exit (0); } if (strcmp(argv[kar], "-help_interactive") == 0) { FILE *fout = fopen("Mouse_Keyboard_Controls.txt","w"); if (!fout) { SUMA_S_Err("Failed to open Mouse_Keyboard_Controls.txt for writing"); exit(1); } SUMA_help_message(fout,TXT); fclose(fout); fout = NULL; exit (0); } if (strcmp(argv[kar], "-test_help_string_edit") == 0) { SUMA_Sphinx_String_Edit_Help(SUMA_STDOUT, 0); exit(0); } if (strcmp(argv[kar], "-test_help_string_edit_web") == 0) { SUMA_Sphinx_String_Edit_Help(SUMA_STDOUT, 1); exit(0); } if (strcmp(argv[kar], "-environment") == 0) { s = SUMA_env_list_help (0, TXT); fprintf (SUMA_STDOUT, "#SUMA ENVIRONMENT \n" "# If you do not have a ~/.sumarc file, cannot find a SUMA\n" "# environment variable that's been mentioned in documentation,\n" "# or fervently desire to update your current ~/.sumarc with \n" "# all the latest variables that SUMA uses, you should run: \n" "# \n" "# suma -update_env\n" "# \n" "# Unless you have setup SUMA environment variables outside of\n" "# your ~/.sumarc file, updating your ~/.sumarc file with \n" "# 'suma -update_env' WILL NOT ALTER changes you have already\n" "# made to the variables in your current ~/.sumarc. \n" "# For this reason consider running the update command after each \n" "# upgrade of your AFNI/SUMA binaries.\n" "***ENVIRONMENT\n" "%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-default_env") == 0) { s = SUMA_env_list_help (1, NO_FORMAT); fprintf (SUMA_STDOUT, "#SUMA DEFAULT ENVIRONMENT (user settings ignored)\n" "# see also suma -udate_env or suma -environment\n" "# \n" "***ENVIRONMENT\n" "%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-update_env") == 0) { if (system("suma -environment > ___sumarc")) { SUMA_S_Err("Failed to create env file."); exit(1); } if (SUMA_filexists("~/.sumarc")) { if (system("\\cp -f ~/.sumarc ~/.sumarc-bak")) { SUMA_S_Err("Failed to backup ~/.sumarc to ~/.sumarc-bak."); exit(1); } } if (system("\\mv ___sumarc ~/.sumarc")) { SUMA_S_Err("Failed to copy newrc (___sumarc) to ~/.sumarc"); exit(1); } SUMA_S_Note("Environment update done."); exit(0); } if (strcmp(argv[kar], "-latest_news") == 0) { s = SUMA_New_Additions (0.0, 0); fprintf (SUMA_STDOUT,"%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-progs") == 0) { s = SUMA_All_Programs(); fprintf (SUMA_STDOUT,"%s\n", s); SUMA_free(s); s = NULL; exit (0); } if (strcmp(argv[kar], "-motif_ver") == 0) { /* 9 Mar 2009 [rickr] */ show_motif_version_string(); exit (0); } if (!brk && (strcmp(argv[kar], "-iodbg") == 0)) { fprintf(SUMA_STDERR,"Error %s: Obsolete, use -trace\n", FuncName); exit (0); /* fprintf(SUMA_STDOUT, "Warning %s: SUMA running in in/out debug mode.\n", FuncName); SUMA_INOUT_NOTIFY_ON; brk = YUP; */ } SUMA_SKIP_COMMON_OPTIONS(brk, kar); #if SUMA_MEMTRACE_FLAG if (!brk && (strcmp(argv[kar], "-memdbg") == 0)) { fprintf(SUMA_STDOUT,"Error %s: -memdbg is obsolete, use -trace\n", FuncName); exit (0); fprintf( SUMA_STDOUT, "Warning %s: SUMA running in memory trace mode.\n", FuncName); SUMAg_CF->MemTrace = YUP; #ifdef USING_MCW_MALLOC #endif brk = YUP; } #endif if (!brk && (strcmp(argv[kar], "-dev") == 0)) { fprintf(SUMA_STDOUT, "Warning %s: SUMA running in developer mode, " "some options may malfunction.\n", FuncName); SUMAg_CF->Dev = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-fake_cmap") == 0)) { SUMA_S_Warn("-fake_cmap is for automatic selfies of the widgets.\n" "You should not use this option for any other reason\n"); SUMAg_CF->Fake_Cmap = YUP; brk = YUP; } if (!brk && SUMAg_CF->Dev && (strcmp(argv[kar], "-truth_table") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need expression after -truth_table \n"); exit (1); } SUMA_bool_eval_truth_table(argv[kar], 0); exit(0); brk = YUP; } if (!brk && (strcmp(argv[kar], "-niml") == 0)) { Start_niml = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-noniml") == 0)) { Start_niml = -1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-vp") == 0 || strcmp(argv[kar], "-sa") == 0 || strcmp(argv[kar], "-sv") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -vp|-sa|-sv \n"); exit (1); } if (ispec < 1) { fprintf (SUMA_STDERR, "a -spec option must precede the first -sv option\n"); exit (1); } if (!specfilename[ispec-1] && !Specp[ispec-1]) { fprintf (SUMA_STDERR, "a -spec option must precede each -sv option\n"); exit (1); } VolParName[ispec-1] = argv[kar]; if (LocalHead) { fprintf(SUMA_STDOUT, "Found: %s\n", VolParName[ispec]); } brk = YUP; } if (!brk && strcmp(argv[kar], "-drive_com") == 0) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -drive_com\n"); exit (1); } SUMAg_CF->dcom = (char **)SUMA_realloc(SUMAg_CF->dcom, (SUMAg_CF->N_dcom+1)*sizeof(char *)); SUMAg_CF->dcom[SUMAg_CF->N_dcom] = SUMA_copy_string(argv[kar]); ++SUMAg_CF->N_dcom; brk = YUP; } if (!brk && strcmp(argv[kar], "-ah") == 0) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -ah\n"); exit (1); } if (strcmp(argv[kar],"localhost") != 0) { AfniHostName = argv[kar]; }else { fprintf (SUMA_STDERR, "localhost is the default for -ah\n" "No need to specify it.\n"); } /*fprintf(SUMA_STDOUT, "Found: %s\n", AfniHostName);*/ brk = YUP; } if (!brk && strcmp(argv[kar], "-spec") == 0) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -spec \n"); exit (1); } if (ispec >= SUMA_MAX_N_GROUPS) { fprintf (SUMA_STDERR, "Cannot accept more than %d spec files.\n", SUMA_MAX_N_GROUPS); exit(1); } if (SUMA_is_predefined_SO_name(argv[kar], NULL, &pdspec, &pdsv, NULL) == 3) { specfilename[ispec] = pdspec; pdspec = NULL; /* Memory leak! */ VolParName[ispec] = pdsv; pdsv = NULL; /* Memory leak! */ } else { specfilename[ispec] = argv[kar]; } if (LocalHead) { fprintf(SUMA_STDOUT, "Found: %s\n", specfilename[ispec]); } ++ispec; brk = YUP; } if (!brk && !ps->arg_checked[kar]) { if ( !strcmp(argv[kar], "-i") || !strncmp(argv[kar], "-i_",3) ) { fprintf (SUMA_STDERR, "Error %s: Option %s not understood. \n" " Make sure parameter after -i or -i_ is the full name of a surface.\n" "%s", FuncName, argv[kar], strlen(argv[kar])==2 ? "For -i to work, SUMA needs to guess at the surface type from\n" " the filename extensions. If SUMA fails try the full -i_* option" " instead.\n" : "" ); } else { fprintf (SUMA_STDERR, "Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]); suggest_best_prog_option(argv[0], argv[kar]); } exit (1); } else { brk = NOPE; kar ++; } }/* loop accross command ine options */ /* -ah option now checked for in ps */ if (ps->cs->afni_host_name && !AfniHostName) { AfniHostName = SUMA_copy_string(ps->cs->afni_host_name); } #if 0 SUMA_S_Note("KILL ME"); { int i,j, nl; SUMA_TextBoxSize("Hello", &i,&j,&nl,NULL); SUMA_TextBoxSize("", &i,&j,&nl,GLUT_BITMAP_8_BY_13); SUMA_TextBoxSize("O", &i,&j,&nl,GLUT_BITMAP_8_BY_13); SUMA_TextBoxSize(NULL, &i,&j,&nl,GLUT_BITMAP_8_BY_13); } SUMA_ReadNIDO("/Users/ziad/SUMA_test_dirs/DO/TextDO/sample.niml.do", NULL); exit(1); #endif /* Make surface loading pacifying */ SetLoadPacify(1); #if 0 if (ps->N_DO) { /* Have DOs on command line */ if (Specp[0]) { /* Add to Specp[0] */ if (ps->N_DO + Specp[0]->N_DO > SUMA_MAX_DO_SPEC) { SUMA_S_Warn("Too many DOs, increase static limit.."); /* ignore extras for now */ ps->N_DO = SUMA_MAX_DO_SPEC - Specp[0]->N_DO; } for (i=0; i<ps->N_DO; ++i) { strcpy(Specp[0]->DO_name[Specp[0]->N_DO], ps->DO_name[i]); Specp[0]->DO_type[Specp[0]->N_DO] = ps->DO_type[i]; ++Specp[0]->N_DO; } } else { Specp[0] } } #endif /* any Specp to be found ?*/ if (specfilename[0] == NULL && Specp[0] == NULL) { SUMA_SurfaceObject **SOv=NULL; int N_SOv = 0; fprintf (SUMA_STDERR, "\n" "%s: \n" " No input specified, loading some toy surfaces...\n" " Use '.' and ',' to cycle between them.\n" " See suma -help for assistance.\n" "\n", FuncName); /* create your own surface and put it in a spec file */ SOv = SUMA_GimmeSomeSOs(&N_SOv); Specp[ispec] = SUMA_SOGroup_2_Spec (SOv, N_SOv); SUMA_free(SOv); SOv = NULL; InMem[ispec] = 1; ++ispec; } if(!SUMA_Assign_HostName (SUMAg_CF, AfniHostName, -1)) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Assign_HostName\n", FuncName); exit (1); } #ifdef SUMA_DISASTER /* a function to test Memtracing */ { int *jnk; jnk = SUMA_disaster(); SUMA_free(jnk); /* without the -trace, you'll get a warning here if jnk is corrupted */ } #endif /* create an Eye Axis DO */ EyeAxis = SUMA_Alloc_Axis ("Eye Axis", AO_type); if (EyeAxis == NULL) { SUMA_error_message (FuncName,"Error Creating Eye Axis",1); exit(1); } /* Store it into SUMAg_DOv */ if (!SUMA_AddDO( SUMAg_DOv, &SUMAg_N_DOv, (void *)EyeAxis, AO_type, SUMA_SCREEN)) { SUMA_error_message (FuncName,"Error Adding DO", 1); exit(1); } /*fprintf (SUMA_STDERR, "SUMAg_N_DOv = %d created\n", SUMAg_N_DOv); SUMA_Show_DOv(SUMAg_DOv, SUMAg_N_DOv, NULL);*/ /* Allocate space (and initialize) Surface Viewer Structure */ SUMAg_SVv = SUMA_Alloc_SurfaceViewer_Struct (SUMA_MAX_SURF_VIEWERS); /* SUMAg_N_SVv gets updated in SUMA_X_SurfaceViewer_Create and reflects not the number of elements in SUMAg_SVv which is SUMA_MAX_SURF_VIEWERS, but the number of viewers that were realized by X */ /* Check on initialization */ /*SUMA_Show_SurfaceViewer_Struct (SUMAg_cSV, stdout);*/ /* Create the Surface Viewer Window */ if (!SUMA_X_SurfaceViewer_Create ()) { fprintf(stderr,"Error in SUMA_X_SurfaceViewer_Create. Exiting\n"); return 1; } for (i=0; i<ispec; ++i) { if (!list) list = SUMA_CreateList(); ED = SUMA_InitializeEngineListData (SE_Load_Group); if (!( Element = SUMA_RegisterEngineListCommand ( list, ED, SEF_cp, (void *)specfilename[i], SES_Suma, NULL, NOPE, SEI_Head, NULL ))) { fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); exit (1); } if (!( Element = SUMA_RegisterEngineListCommand ( list, ED, SEF_ip, (void *)Specp[i], SES_Suma, NULL, NOPE, SEI_In, Element ))) { fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); exit (1); } fff = (float) InMem[i]; if (!( Element = SUMA_RegisterEngineListCommand ( list, ED, SEF_f, (void *)&fff, SES_Suma, NULL, NOPE, SEI_In, Element ))) { fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); exit (1); } if (!( Element = SUMA_RegisterEngineListCommand ( list, ED, SEF_vp, (void *)VolParName[i], SES_Suma, NULL, NOPE, SEI_In, Element ))) { fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); exit (1); } N_iv15 = SUMA_MAX_SURF_VIEWERS; if (N_iv15 > 15) { fprintf( SUMA_STDERR, "Error %s: trying to register more than 15 viewers!\n", FuncName); exit(1); } for (kar=0; kar<N_iv15; ++kar) iv15[kar] = kar; if (!( Element = SUMA_RegisterEngineListCommand ( list, ED, SEF_iv15, (void *)iv15, SES_Suma, NULL, NOPE, SEI_In, Element ))) { fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); exit (1); } if (!( Element = SUMA_RegisterEngineListCommand ( list, ED, SEF_i, (void *)&N_iv15, SES_Suma, NULL, NOPE, SEI_In, Element ))) { fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); exit (1); } } if (ispec > 0 && !SUMA_Engine (&list)) { fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Engine\n", FuncName); exit (1); } /* For some reason, I had to add the glLightfv line below to force the lightflipping done in SUMA_SetupSVforDOs to take place in the A viewer when first opened. I don't know why that is, especially since other controllers would show up lit correctly without this glLightfv line below. To make matters worse, the A controller's light0_position is correctly flipped. It is just that the shading is done as if the position was never flipped. Actually, without the line below, the first time you hit the F key (to manually flip the light), nothing changes, that's because the light's position is unflipped, which is supposed to show the incorrect lighting. You'll have to hit F again to have the lighting correctly flipped and the shading reflecting it.... ZSS, Aug. 05 04 */ glLightfv(GL_LIGHT0, GL_POSITION, SUMAg_SVv[0].light0_position); if (Start_niml != -1 && (Start_niml == 1|| AFNI_yesenv("SUMA_START_NIML"))) { if (!list) list = SUMA_CreateList(); SUMA_REGISTER_HEAD_COMMAND_NO_DATA( list, SE_StartListening, SES_Suma, NULL); if (!SUMA_Engine (&list)) { fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName); exit (1); } } /* load the datasets onto the first SO, if any, else hope that dset is some form of DO */ if (ps->N_dsetname>0) { SUMA_SurfaceObject *SO = SUMA_findanySOp_inDOv(SUMAg_DOv, SUMAg_N_DOv, NULL); if (!SO) { SUMA_LH("Could not find any SO, here is hoping dset is a DO"); } for (i=0; i<ps->N_dsetname; ++i) { if (!(SUMA_LoadDsetOntoSO_eng(ps->dsetname[i], SO, 1, 1, 1, NULL))) { SUMA_S_Errv("Failed to load %s onto %s\n", ps->dsetname[i], SO?SO->Label:"NULL"); } } } SUMA_FreeGenericArgParse(ps); ps = NULL; /* A Warning about no sumarc */ if (NoSumaRcFound()) { SUMA_S_Warn( "\n" " No sumarc file found. You should create one by running the following:\n" "\n" " suma -update_env\n" "\n" " I also recommend you run 'suma -update_env' whenever you update AFNI.\n" "\n" " See details for -environment and -update_env options in suma -help's output.\n" "\n"); } /*Main loop */ XtAppMainLoop(SUMAg_CF->X->App); /* Done, clean up time */ if (ispec) { int k=0; for (k=0; k<ispec; ++k) { if (!SUMA_FreeSpecFields((Specp[k]))) { SUMA_S_Err("Failed to free spec fields"); } Specp[k] = NULL; } } ispec = 0; if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) SUMA_error_message(FuncName,"DO Cleanup Failed!",1); if (!SUMA_Free_SurfaceViewer_Struct_Vect (SUMAg_SVv, SUMA_MAX_SURF_VIEWERS)) SUMA_error_message(FuncName,"SUMAg_SVv Cleanup Failed!",1); if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); SUMA_RETURN(0); /* ANSI C requires main to return int. */ }/* Main */
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"ScaleToMap"}; char *IntName = NULL, *Prfx, h[9], *CmapFileName = NULL, *dbfile = NULL, *MapName=NULL; MRI_IMAGE *im = NULL; float *far=NULL; int N_V, N_Int, kar, k, ii, i, icol=-1, vcol=-1, Sgn, interpmode, k3; int Vminloc, Vmaxloc, *iV = NULL; float Vmin, Vmax, brfact; float *V = NULL, *Vsort = NULL; float IntRange[2], MaskColor[3], MaskRange[2]={0.0, 0.0}, arange; SUMA_Boolean ApplyClip, ApplyMask, setMaskCol, ApplyPercClip, Vopt; SUMA_Boolean iVopt, inopt, NoMaskCol, MapSpecified, alaAFNI, MaskZero; SUMA_Boolean brk, frf, ShowMap, ShowMapdb; SUMA_COLOR_MAP *CM; SUMA_SCALE_TO_MAP_OPT * OptScl; int MapType, freecm = 1; SUMA_COLOR_SCALED_VECT * SV; SUMA_AFNI_COLORS *SAC=NULL; SUMA_Boolean FromAFNI = NOPE; int imap, isPmap, isNmap; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMAg_CF->isGraphical = YUP; SUMA_mainENTRY; /* this is placed down here to */ /* if (argc < 3) { SUMA_ScaleToMap_usage(); exit (1); } */ kar = 1; brfact = 1; /* the brightness factor */ MaskColor[0] = MaskColor[1] = MaskColor[2] = 0.3; ApplyClip = NOPE; ApplyPercClip = NOPE; ApplyMask = NOPE; NoMaskCol = NOPE; MaskZero = NOPE; setMaskCol = NOPE; Vopt = NOPE; iVopt = NOPE; inopt = NOPE; MapType = SUMA_CMAP_RGYBR20; brk = NOPE; MapSpecified = NOPE; CmapFileName = NULL; interpmode = SUMA_UNDEFINED_MODE; ShowMap = NOPE; alaAFNI = NOPE; /* applying the alaAFNI mapping */ frf = NOPE; arange = -1.0; /* afni range specified */ Sgn = 0; ShowMapdb = NOPE; while (kar < argc) { /* loop accross command ine options */ /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { SUMA_ScaleToMap_usage(); exit (1); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); if (!brk && strcmp(argv[kar], "-verb") == 0) { LocalHead = NOPE; brk = YUP; } if (!brk && strcmp(argv[kar], "-ionot") == 0) { SUMA_SL_Err("-ionot is obsolete. \n" "Use -trace option."); exit (1); SUMA_INOUT_NOTIFY_ON; brk = YUP; } if (!brk && strcmp(argv[kar], "-msk_zero") == 0) { MaskZero = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-input") == 0)) { kar ++; if (kar+2 >= argc) { fprintf (SUMA_STDERR, "need 3 arguments after -input \n"); exit (1); } IntName = argv[kar]; kar ++; icol = atoi(argv[kar]); kar ++; vcol = atoi(argv[kar]); inopt = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-apr") == 0)) { if (arange >= 0) { fprintf (SUMA_STDERR, "range has already been specified.\n"); exit (1); } kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -apr \n"); exit (1); } arange = atof(argv[kar]); if (arange < 0) { fprintf (SUMA_STDERR, "range must be positive.\n"); exit (1); } Sgn = 1; alaAFNI = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-anr") == 0)) { if (arange >= 0) { fprintf (SUMA_STDERR, "range has already been specified.\n"); exit (1); } kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -anr \n"); exit (1); } arange = atof(argv[kar]); if (arange < 0) { fprintf (SUMA_STDERR, "range must be positive.\n"); exit (1); } Sgn = -1; alaAFNI = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-v") == 0)) { fprintf (SUMA_STDERR, "\n -v option is now obsolete.\nUse -input option instead.\n"); exit (1); kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -v \n"); exit (1); } IntName = argv[kar]; Vopt = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-iv") == 0)) { fprintf (SUMA_STDERR, "\n -iv option is now obsolete.\nUse -input option instead.\n"); exit (1); kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -iv \n"); exit (1); } IntName = argv[kar]; iVopt = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-br") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -br \n"); exit (1); } brfact = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-frf") == 0)) { frf = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-showmap") == 0)) { ShowMap = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-showdb") == 0)) { ShowMapdb = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-nointerp") == 0)) { if (interpmode != SUMA_UNDEFINED_MODE) { fprintf (SUMA_STDERR, "Color interpolation mode already set.\n"); } interpmode = SUMA_NO_INTERP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-direct") == 0)) { if (interpmode != SUMA_UNDEFINED_MODE) { fprintf (SUMA_STDERR, "Color interpolation mode already set.\n"); } interpmode = SUMA_DIRECT; brk = YUP; } if (!brk && (strcmp(argv[kar], "-interp") == 0)) { if (interpmode != SUMA_UNDEFINED_MODE) { fprintf (SUMA_STDERR, "Color interpolation mode already set.\n(-nointerp, -direct and -interp are mutually exclusive.\n"); } interpmode = SUMA_INTERP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-clp") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 arguments after -clp \n"); exit (1); } ApplyClip = YUP; IntRange[0] = atof(argv[kar]); kar ++; IntRange[1] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-perc_clp") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 arguments after -perc_clp "); exit (1); } ApplyPercClip = YUP; IntRange[0] = atof(argv[kar]); kar ++; IntRange[1] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-msk") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 arguments after -msk "); exit (1); } ApplyMask = YUP; MaskRange[0] = atof(argv[kar]); kar ++; MaskRange[1] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-nomsk_col") == 0)) { NoMaskCol = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-msk_col") == 0)) { kar ++; if (kar+2 >= argc) { fprintf (SUMA_STDERR, "need 3 arguments after -msk_col "); exit (1); } setMaskCol = YUP; MaskColor[0] = atof(argv[kar]); kar ++; MaskColor[1] = atof(argv[kar]); kar ++; MaskColor[2] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-cmapfile") ==0)) { if (MapSpecified) { fprintf (SUMA_STDERR, "Color map already specified.\n-cmap and -cmapfile are mutually exclusive\n"); exit (1); } MapSpecified = YUP; kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 arguments after -cmapfile "); exit (1); } CmapFileName = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-cmapdb") ==0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 arguments after -cmapdb "); exit (1); } dbfile = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-cmap") ==0)) { if (MapSpecified) { fprintf (SUMA_STDERR, "Color map already specified.\n-cmap and -cmapfile are mutually exclusive\n"); exit (1); } MapSpecified = YUP; kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 arguments after -cmap "); exit (1); } MapName = argv[kar]; 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 ++; } }/* loop accross command ine options */ /* Get your colors straightened out */ if (!SUMAg_CF->scm) { SUMAg_CF->scm = SUMA_Build_Color_maps(); if (!SUMAg_CF->scm) { SUMA_SL_Err("Failed to build color maps.\n"); exit(1); } } SAC = SUMAg_CF->scm; /* are there database files to read */ if (dbfile) { SUMA_LH("Now trying to read db file"); if (SUMA_AFNI_Extract_Colors ( dbfile, SAC ) < 0) { SUMA_S_Errv("Failed to read %s colormap file.\n", dbfile); exit(1); } } FromAFNI = NOPE; /* assume colormap is not coming from SAC (the colormap database structure) */ if (CmapFileName) { /* load the color map */ CM = SUMA_Read_Color_Map_1D (CmapFileName); if (CM == NULL) { SUMA_S_Err("Could not load colormap.\n"); exit (1); } if (frf) { SUMA_LH("Flipping colormap"); SUMA_Flip_Color_Map (CM); } if (!CM->Sgn) CM->Sgn = Sgn; }else{ /* dunno what kind of map yet. Try default first */ if (MapName) { CM = SUMA_FindNamedColMap (MapName); freecm = 0; if (CM) { /* good, sign it and out you go */ CM->Sgn = Sgn; } else { SUMA_S_Err("Could not get standard colormap.\n"); exit (1); } } else { SUMA_LH("An AFNI color map "); /* a color from AFNI's maps */ FromAFNI = YUP; imap = SUMA_Find_ColorMap ( MapName, SAC->CMv, SAC->N_maps, -2); if (imap < 0) { SUMA_S_Errv("Could not find colormap %s.\n", MapName); exit (1); } CM = SAC->CMv[imap]; } } /* show the colromap on STDERR */ if (ShowMap) { fprintf (SUMA_STDERR, "%s: Colormap used:\n", FuncName); SUMA_Show_ColorMapVec (&CM, 1, NULL, 2); { SUMA_SurfaceObject *SO = NULL; float orig[3] = { SUMA_CMAP_ORIGIN }; float topright[3] = { SUMA_CMAP_TOPLEFT }; SO = SUMA_Cmap_To_SO (CM, orig, topright, 2); if (SO) SUMA_Free_Surface_Object(SO); } exit(0); } /* show all the colors and colormaps in SAC on STDERR */ if (ShowMapdb) { fprintf (SUMA_STDERR, "%s: AFNI colormaps found in db:\n", FuncName); SUMA_Show_ColorVec (SAC->Cv, SAC->N_cols, NULL); SUMA_Show_ColorMapVec (SAC->CMv, SAC->N_maps, NULL, 2); exit(0); } if (!IntName) { fprintf (SUMA_STDERR,"Error %s: No input file specified.\n", FuncName); exit(1); } /* default interpolation mode */ if (interpmode == SUMA_UNDEFINED_MODE) interpmode = SUMA_INTERP; /* check input */ if (!SUMA_filexists (IntName)) { fprintf (SUMA_STDERR,"Error %s: File %s could not be found.\n", FuncName, IntName); exit(1); } if (frf && !CmapFileName) { fprintf (SUMA_STDERR,"Error %s: -frf option is only valid with -cmapfile.\n", FuncName); exit(1); } if (ApplyPercClip && ApplyClip) { fprintf (SUMA_STDERR,"Error %s: Simultaneous use of -clp and -perc_clp. You should be punished.\n", FuncName); exit(1); } if ((ApplyPercClip || ApplyClip) && arange >= 0.0) { fprintf (SUMA_STDERR,"Error %s: Simultaneous use of -clp/-perc_clp and -apr/anr.\n Read the help.\n", FuncName); exit(1); } if (iVopt || Vopt) { fprintf (SUMA_STDERR,"Error %s: -v and -iv are obsolete.\n Use -input option instead.\n", FuncName); exit(1); } if (!inopt) { fprintf (SUMA_STDERR,"Error %s: -input option must be specified.\n", FuncName); exit(1); } im = mri_read_1D (IntName); if (!im) { SUMA_S_Err("Failed to read file"); exit (1); } if (vcol < 0) { fprintf (SUMA_STDERR,"Error %s: vcol must be > 0\n", FuncName); exit(1); } far = MRI_FLOAT_PTR(im); if (icol < 0 && icol != -1) { fprintf (SUMA_STDERR,"Error %s: icol(%d) can only have -1 for a negative value\n", FuncName, icol); exit(1); } if (icol >= im->ny || vcol >= im->ny) { fprintf (SUMA_STDERR,"Error %s: icol(%d) and vcol(%d) must be < %d\nwhich is the number of columns in %s\n", FuncName, icol, vcol, im->ny, IntName); exit(1); } if (brfact <=0 || brfact > 1) { fprintf (SUMA_STDERR,"Error %s: BrightFact must be > 0 and <= 1.\n", FuncName); exit (1); } if (MaskColor[0] < 0 || MaskColor[0] > 1 || MaskColor[1] < 0 || MaskColor[1] > 1 || MaskColor[2] < 0 || MaskColor[2] > 1) { fprintf (SUMA_STDERR,"Error %s: MaskColor values must be >=0 <=1.\n", FuncName); exit(1); } N_V = im->nx; V = (float *) SUMA_calloc (N_V, sizeof(float)); iV = (int *) SUMA_calloc (N_V, sizeof(int)); if (!V || !iV) { fprintf (SUMA_STDERR,"Error %s: Could not allocate for V or iV.\n", FuncName); exit(1); } if (icol < 0) { for (ii=0; ii < N_V; ++ii) { iV[ii] = ii; V[ii] = far[vcol*N_V+ii]; } } else { for (ii=0; ii < N_V; ++ii) { iV[ii] = (int)far[icol*N_V+ii]; V[ii] = far[vcol*N_V+ii]; } } mri_free(im); im = NULL; /* read values per node */ /* SUMA_disp_vect (V, 3); */ /* find the min/max of V */ SUMA_MIN_MAX_VEC(V, N_V, Vmin, Vmax, Vminloc, Vmaxloc) /* fprintf (SUMA_STDERR,"%s: Vmin=%f, Vmax = %f\n", FuncName, Vmin, Vmax);*/ if (arange == 0.0) { if (fabs((double)Vmin) > fabs((double)Vmax)) arange = (float)fabs((double)Vmin); else arange = (float)fabs((double)Vmax); } /* figure out the range if PercRange is used */ if (ApplyPercClip) { fprintf (SUMA_STDERR,"%s: Percentile range [%f..%f] is equivalent to ", FuncName, IntRange[0], IntRange[1]); Vsort = SUMA_PercRange (V, NULL, N_V, IntRange, IntRange, NULL); fprintf (SUMA_STDERR,"[%f..%f]\n", IntRange[0], IntRange[1]); ApplyClip = YUP; if (Vsort) SUMA_free(Vsort); else { fprintf (SUMA_STDERR,"Error %s: Error in SUMA_PercRange.\n", FuncName); exit(1); } } /* get the options for creating the scaled color mapping */ OptScl = SUMA_ScaleToMapOptInit(); if (!OptScl) { fprintf (SUMA_STDERR, "Error %s: Could not get scaling option structure.\n", FuncName); exit (1); } /* work the options a bit */ if (ApplyMask) { OptScl->ApplyMask = ApplyMask; OptScl->MaskRange[0] = MaskRange[0]; OptScl->MaskRange[1] = MaskRange[1]; OptScl->MaskColor[0] = MaskColor[0]; OptScl->MaskColor[1] = MaskColor[1]; OptScl->MaskColor[2] = MaskColor[2]; } if (ApplyClip) { OptScl->ApplyClip = YUP; OptScl->IntRange[0] = IntRange[0]; OptScl->IntRange[1] = IntRange[1]; } OptScl->interpmode = interpmode; OptScl->BrightFact = brfact; if (MaskZero) OptScl->MaskZero = YUP; /* map the values in V to the colormap */ /* allocate space for the result */ SV = SUMA_Create_ColorScaledVect(N_V, 0); if (!SV) { fprintf (SUMA_STDERR, "Error %s: Could not allocate for SV.\n", FuncName); exit(1); } /* finally ! */ if (alaAFNI) { if (LocalHead) { fprintf (SUMA_STDERR, "%s: Calling SUMA_ScaleToMap_alaAFNI\n", FuncName); fprintf (SUMA_STDERR,"%s: arange = %f\n", FuncName, arange); } if (CM->frac) { if (CM->frac[0] > 0 && CM->Sgn == -1) { SUMA_S_Err ("Color map fractions positive with -anr option"); exit(1); } if (CM->frac[0] < 0 && CM->Sgn == 1) { SUMA_S_Err ("Color map fractions negative with -apr option"); exit(1); } } if (Sgn) { if (Sgn != CM->Sgn) { SUMA_S_Warn ("Mixing positive maps (all fractions > 0) " "with -anr option\n" "or vice versa. That is allowed but know what" " you're doing.\n"); } } if (!SUMA_ScaleToMap_alaAFNI (V, N_V, arange, CM, OptScl, SV)) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_ScaleToMap_alaAFNI.\n", FuncName); exit(1); } } else { if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_ScaleToMap\n", FuncName); if (!SUMA_ScaleToMap (V, N_V, Vmin, Vmax, CM, OptScl, SV)) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_ScaleToMap.\n", FuncName); exit(1); } } /* Now write the colored vector back to disk */ if (NoMaskCol) { for (k=0; k < N_V; ++k) { k3 = 3*k; if (!SV->isMasked[k]) fprintf (SUMA_STDOUT, "%d %f %f %f\n", iV[k], SV->cV[k3 ], SV->cV[k3+1], SV->cV[k3+2]); } } else { for (k=0; k < N_V; ++k) { k3 = 3*k; fprintf (SUMA_STDOUT, "%d %f %f %f\n", iV[k], SV->cV[k3 ], SV->cV[k3+1], SV->cV[k3+2]); } } /* freeing time */ if (V) SUMA_free(V); if (iV) SUMA_free(iV); if (!FromAFNI && freecm) if (CM) SUMA_Free_ColorMap (CM); /* only free CM if it was a pointer copy from a map in SAC */ if (OptScl) SUMA_free(OptScl); if (SV) SUMA_Free_ColorScaledVect (SV); #if 0 if (SAC) SAC = SUMA_DestroyAfniColors(SAC); /* destroy SAC */ #else SAC = NULL; /* freeing is done in SUMAg_CF */ #endif SUMA_Free_CommonFields(SUMAg_CF); SUMA_RETURN (0); }
int SUMA_SegEngine(SEG_OPTS *Opt) { static char FuncName[]={"SUMA_SegEngine"}; THD_3dim_dataset *pygcbo=NULL; int iter=0, kk, UseK[500]; char sinf[256]; char sreport[512]={"unset_report_name.txt"}; SUMA_Boolean LocalHead = YUP; SUMA_ENTRY; #ifdef USE_OMP #pragma omp parallel { if( LocalHead && omp_get_thread_num() == 0 ) INFO_message("OpenMP thread count = %d",omp_get_num_threads()) ; } #endif if (Opt->cset) {/* Hide Classes not for analysis */ int mm; short *sc=NULL; sc= (short *)DSET_ARRAY (Opt->cset, 0); for (kk=0 ; kk<DSET_NVOX(Opt->cset); ++kk) { for (mm=0; mm<Opt->cs->N_label; ++mm) { if (sc[kk] == Opt->cs->keys[mm]) break; } if (mm >= Opt->cs->N_label) sc[kk] = 0; } } else { SUMA_S_Err("Need cset"); SUMA_RETURN(0); } if (!Opt->priCgALL) { if ((Opt->priCgA || Opt->priCgL)) { if (!SUMA_MergeCpriors( Opt->cs, Opt->cmask, Opt->aset, Opt->priCgA, Opt->wA, Opt->priCgL, Opt->wL, &Opt->priCgALL, Opt)) { SUMA_S_Err("NULL Opt->priCgALL"); SUMA_RETURN(0); } } else if ((Opt->priCgLname && !strcmp(Opt->priCgLname,"INIT_MIXFRAC")) || (Opt->priCgAname && !strcmp(Opt->priCgAname,"INIT_MIXFRAC")) ){ SUMA_S_Note("Forcing spatial priors at initial mixing fraction"); if (!SUMA_MergeCpriors( Opt->cs, Opt->cmask, Opt->aset, NULL, 0.0, NULL, 0.0, &Opt->priCgALL, Opt)) { SUMA_S_Err("NULL Opt->priCgALL"); SUMA_RETURN(0); } } if (Opt->priCgALL && Opt->debug > 1) { SUMA_Seg_Write_Dset(Opt->proot,"priCgALLmerged", Opt->priCgALL, -1, Opt->hist); } } /* split the classes */ if (Opt->Split) { THD_3dim_dataset *Scset=NULL; int N_split=0; SUMA_CLASS_STAT *Scs=NULL; SUMA_S_Warn("Splitting classes"); while (Opt->Split[N_split] > 0) ++N_split; if (N_split != Opt->cs->N_label) { SUMA_S_Errv("Split vector malformed.\n" "Have %d values in Split, but %d classes\n", N_split, Opt->cs->N_label); SUMA_RETURN(0); } if (!SUMA_Split_Classes(Opt->cs->label, Opt->cs->N_label, Opt->cs->keys, Opt->Split, Opt->aset, Opt->cset, Opt->cmask, &Scset, &Scs, Opt)) { SUMA_S_Err("Failed to split classes"); SUMA_RETURN(0); } /* Save old class stats and replace by split classes */ Opt->Gcs = Opt->cs; Opt->cs = Scs; Scs=NULL; DSET_delete(Opt->cset); Opt->cset = Scset; Scset=NULL; } /* get the initial parameters pstCgALL is still null here normally and priCgALL will not be used when that is the case. So these estimates are from cset alone */ if (!SUMA_Class_stats( Opt->aset, Opt->cset, Opt->cmask, Opt->cmask_count, Opt->pstCgALL, Opt->priCgALL, Opt->gold, Opt->cs, Opt->mix_frac_floor)) { SUMA_S_Err("Failed in class stats"); SUMA_RETURN(0); } if (Opt->debug) SUMA_show_Class_Stat(Opt->cs, "Class Stat At Input:\n", NULL); /* Make sure there are good estimates for all classes */ if (SUMA_ZeroSamp_from_ClassStat(Opt->cs)) { if (!Opt->debug) SUMA_show_Class_Stat(Opt->cs, "Class Stat At Input:\n", NULL); SUMA_S_Err("Have empty classes at initialization. Not cool\n"); SUMA_RETURN(0); } if (!Opt->pstCgALL) { /* Compute initial posterior distribution */ if (!(SUMA_pst_C_giv_ALL(Opt->aset, Opt->cmask, Opt->cmask_count, Opt->cs, Opt->priCgALL, Opt->pCgN, Opt->B, Opt->T, (!Opt->mixopt || strcmp(Opt->mixopt,"IGNORE")) ? 1:0, &Opt->pstCgALL))) { SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL"); SUMA_RETURN(0); } } if (!SUMA_Class_stats( Opt->aset, Opt->cset, Opt->cmask, Opt->cmask_count, Opt->pstCgALL, Opt->priCgALL, Opt->gold, Opt->cs, Opt->mix_frac_floor)) { SUMA_S_Err("Failed in class stats"); SUMA_RETURN(0); } if (Opt->debug) SUMA_show_Class_Stat(Opt->cs, "Posterior Weighted Class Stat At Input:\n", NULL); /* To begin iterations, we should have class stats and pstCgALL. Also, need an initial cset if B > 0.0 */ for (iter=0; iter<Opt->N_main; ++iter) { if (Opt->debug) { INFO_message("Iteration %d memory check:\n",iter);MCHECK; } /* improve parameters based on edge energy */ if (Opt->edge) { double en; float vv=1.0; int *UseK, N_kok; THD_3dim_dataset *skelset=NULL, *l_Bset=NULL, *l_aset=NULL; NEW_SHORTY(Opt->aset, Opt->cs->N_label*(Opt->cs->N_label-1)/2, "skelly", skelset); UseK = (int *)SUMA_calloc(Opt->cs->N_label, sizeof(int)); if ((N_kok = SUMA_Class_k_Selector(Opt->cs, "classes_string", "CSF; GM; WM", UseK))<0) { SUMA_S_Err("Failed to find classes"); SUMA_RETURN(0); } if (1) { /* It should be the case that edge energy should not be affected by the presence of bias field (METH2), for now, I will pass a constant field here for testing */ NEW_SHORTY(Opt->aset, 1, "l_Bset", l_Bset); if (!SUMA_InitDset(l_Bset, &vv, 1, Opt->cmask, 1)) { SUMA_S_Err("Failed to initialize l_Bset"); SUMA_RETURN(0); } if (iter == 0) l_aset = Opt->aset; else l_aset = Opt->xset; } else { /* old approach */ l_aset = Opt->aset; l_Bset = Opt->Bset; } en = SUMA_DsetEdgeEnergy(l_aset, Opt->cset, Opt->cmask, l_Bset, skelset, Opt->cs, Opt->edge, UseK, N_kok); SUMA_Seg_Write_Dset(Opt->proot, "PreSkel", skelset, iter, Opt->hist); SUMA_S_Notev("Edge Enenergy, Pre MAP : %f\n", en); #if 1 if (!SUMA_MAP_EdgeEnergy( l_aset, Opt->cmask, Opt->cmask_count, l_Bset, Opt->cs, Opt->cset, Opt->edge, Opt->priCgALL, Opt->pCgN, Opt->B, Opt->T, 0.4, 0.4, Opt)) { SUMA_S_Err("Failed in MAP_EdgeEnergy"); exit(1); } en = SUMA_DsetEdgeEnergy(l_aset, Opt->cset, Opt->cmask, l_Bset, skelset, Opt->cs, Opt->edge, UseK, N_kok); SUMA_Seg_Write_Dset(Opt->proot, "PstSkel", skelset, iter, Opt->hist); SUMA_S_Notev("Edge Enenergy, Post MAP : %f\n", en); #endif DSET_delete(skelset); skelset=NULL; if (l_Bset && l_Bset != Opt->Bset) DSET_delete(l_Bset); l_Bset=NULL; SUMA_ifree(UseK); } if (Opt->bias_param > 0) { if (Opt->debug > 1) SUMA_S_Notev("Wells Bias field correction, FWHM %f, iteration %d\n", Opt->bias_param, iter); if (!strcmp(Opt->bias_meth,"Wells")) { if (!(SUMA_estimate_bias_field_Wells(Opt, Opt->cmask, Opt->cs, Opt->bias_param, Opt->bias_classes, Opt->aset, Opt->pstCgALL, &Opt->Bset ))) { SUMA_S_Err("Failed to estimate bias"); SUMA_RETURN(0); } } else { SUMA_S_Errv("Only Wells is allowed for now, have %s\n", Opt->bias_meth); SUMA_RETURN(0); } if (!(SUMA_apply_bias_field(Opt, Opt->aset, Opt->Bset, &Opt->xset))) { SUMA_S_Err("Failed to apply field"); SUMA_RETURN(0); } } else { if (iter == 0) { if (Opt->debug > 1) SUMA_S_Note("Skipping bias field correction"); if (!Opt->xset) Opt->xset = EDIT_full_copy(Opt->aset, Opt->xrefix); if (!Opt->Bset) { float vv=1.0; NEW_SHORTY(Opt->aset,1, "ConstantField", Opt->Bset); if (!SUMA_InitDset(Opt->Bset, &vv, 1, Opt->cmask, 1)) { SUMA_S_Err("Failed to initialize Bset"); SUMA_RETURN(0); } } } } if (Opt->B > 0) { if (Opt->debug > 1 && iter==0) { SUMA_Seg_Write_Dset(Opt->proot, "MAPlabel.-1", Opt->cset, -1, Opt->hist); } if (!(SUMA_MAP_labels(Opt->xset, Opt->cmask, Opt->cs, 6, Opt->priCgALL, &Opt->cset, &Opt->pCgN, Opt))) { SUMA_S_Err("Failed in SUMA_MAP_labels"); SUMA_RETURN(0); } if (Opt->debug > 1) { SUMA_Seg_Write_Dset(Opt->proot, "MAPlabel", Opt->cset, iter, Opt->hist); SUMA_Seg_Write_Dset(Opt->proot, "pCgN", Opt->pCgN, iter, Opt->hist); } AFNI_FEED(Opt->ps->cs, "MAPlabel", iter, Opt->cset); } if (!(SUMA_pst_C_giv_ALL(Opt->xset, Opt->cmask, Opt->cmask_count, Opt->cs, Opt->priCgALL, Opt->pCgN, Opt->B, Opt->T, (!Opt->mixopt || strcmp(Opt->mixopt,"IGNORE")) ? 1:0, &Opt->pstCgALL))) { SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL"); SUMA_RETURN(0); } if (Opt->debug > 1) { SUMA_Seg_Write_Dset(Opt->proot, "pstCgALL", Opt->pstCgALL, iter, Opt->hist); } if (Opt->B <= 0.0f) { /* no need if B > 0 because cset is set in SUMA_MAP_labels*/ /* update class based on max(Opt->pstCgALL) */ if (!(SUMA_assign_classes( Opt->pstCgALL, Opt->cs, Opt->cmask, &Opt->cset))) { SUMA_S_Err("Failed in assign_classes"); SUMA_RETURN(0); } } /* Now update class stats */ if (!SUMA_Class_stats( Opt->xset, Opt->cset, Opt->cmask, Opt->cmask_count, Opt->pstCgALL, Opt->priCgALL, Opt->gold, Opt->cs, Opt->mix_frac_floor)) { SUMA_S_Err("Failed in class stats"); SUMA_RETURN(0); } if (Opt->debug || Opt->gold || Opt->gold_bias) { double bad_bias_thresh, bias_bad_count; char *sbig=NULL; sprintf(sinf, "Class Stat iter %d:\n", iter+1); if (iter == Opt->N_main-1 || Opt->debug) { SUMA_show_Class_Stat(Opt->cs, sinf, NULL); if (Opt->proot) sprintf(sreport, "%s/ClassStat.i%02d%s.txt", Opt->proot, iter+1, (iter==Opt->N_main-1) ? ".FINAL":""); else snprintf(sreport, 500, "%s.ClassStat.i%02d%s.txt", Opt->prefix, iter+1, (iter==Opt->N_main-1) ? ".FINAL":""); sbig = SUMA_append_replace_string(Opt->hist, sinf,"\n",0); SUMA_show_Class_Stat(Opt->cs, sbig, sreport); SUMA_ifree(sbig); } /* Report on bias correction */ bad_bias_thresh = 0.06; if ((Opt->gold_bias && Opt->Bset) && (iter == Opt->N_main-1 || Opt->debug)) { FILE *fout = fopen(sreport,"a"); bias_bad_count = SUMA_CompareBiasDsets(Opt->gold_bias, Opt->Bset, Opt->cmask, Opt->cmask_count, bad_bias_thresh, NULL); SUMA_S_Notev("bad_count at thresh %f = %f%% of mask.\n", bad_bias_thresh, bias_bad_count); if (fout) { fprintf(fout, "bad_count at thresh %f = %f%% of mask.\n", bad_bias_thresh, bias_bad_count); fclose(fout); fout = NULL; } } } } if (Opt->Split) { THD_3dim_dataset *Gcset=NULL; THD_3dim_dataset *GpstCgALL=NULL; /* need to put things back */ if (!SUMA_Regroup_classes(Opt, Opt->cs->label, Opt->cs->N_label, Opt->cs->keys, Opt->Gcs->label, Opt->Gcs->N_label, Opt->Gcs->keys, Opt->cmask, Opt->pstCgALL, Opt->cset, &GpstCgALL, &Gcset)) { } /* switch dsets */ DSET_delete(Opt->pstCgALL); Opt->pstCgALL = GpstCgALL; GpstCgALL = NULL; DSET_delete(Opt->cset); Opt->cset = Gcset; Gcset = NULL; } SUMA_RETURN(1); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"FSread_annot"}; int kar, Showct, testmode; char *fname = NULL, *fcmap = NULL, *fdset = NULL, *froi = NULL, *fcol = NULL, *ctfile=NULL, sbuf[1024]={""}; SUMA_Boolean SkipCoords = NOPE, brk; SUMA_DSET *dset=NULL; int lbl1,lbl2, ver, hemi, FSdefault; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; 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); } /* parse command line */ kar = 1; fname = NULL; froi = NULL; fcmap = NULL; fcol = NULL; brk = NOPE; ctfile = NULL; Showct = 0; testmode = 0; lbl1 = -1; lbl2 = -1; ver = -1; FSdefault = 0; hemi=0; while (kar < argc) { /* loop accross command ine options */ /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { usage_SUMA_FSread_annot_Main(); exit (0); } if (!brk && (strcmp(argv[kar], "-show_FScmap") == 0)) { Showct = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-testmode") == 0)) { testmode = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-input") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -input\n"); exit (1); } fname = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-FScmap") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -FScmap\n"); exit (1); } ctfile = argv[kar]; if (!strcmp(ctfile,"FS_DEFAULT")) { char *eee = getenv("FREESURFER_HOME"); if (!eee) { SUMA_S_Err("Environment variable FREESURFER_HOME not set.\n" "Cannot locate FreeSurferColorLUT.txt\n"); exit (1); } else { sprintf(sbuf, "%s/FreeSurferColorLUT.txt", eee); ctfile = sbuf; FSdefault = 1; SUMA_S_Notev("Using %s\n", ctfile); } } brk = YUP; } if (!brk && (strcmp(argv[kar], "-FSversion") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -FSversion\n"); exit (1); } if (strstr(argv[kar],"2009")) ver = 2009; else if (strstr(argv[kar],"2005")) ver = 2005; else { fprintf (SUMA_STDERR, "Bad value for -FSversion of %s (looking for 2005 or 2009)\n", argv[kar]); exit (1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-hemi") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -hemi\n"); exit (1); } if (strstr(argv[kar],"lh")) hemi = -1; else if (strstr(argv[kar],"rh")) hemi = 1; else { fprintf (SUMA_STDERR, "Bad value for -hemi of %s (looking for lh or rh)\n", argv[kar]); exit (1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-FScmaprange") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 argument after -FScmaprange\n"); exit (1); } lbl1 = atoi(argv[kar]); ++kar; lbl2 = atoi(argv[kar]); if (lbl1 > lbl2 || lbl1 < -1) { fprintf (SUMA_STDERR, "Bad value for -FScmaprange of [%d %d]\n", lbl1, lbl2); exit (1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-roi_1D") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -ROI_1D\n"); exit (1); } froi = argv[kar]; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-prefix") == 0) || (strcmp(argv[kar], "-dset") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -dset\n"); exit (1); } fdset = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-cmap_1D") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -cmap_1D\n"); exit (1); } fcmap = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-col_1D") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -col_1D\n"); exit (1); } fcol = argv[kar]; brk = YUP; } if (!brk) { fprintf (SUMA_STDERR, "Error %s:\n" "Option %s not understood. Try -help for usage\n", FuncName, argv[kar]); exit (1); } else { brk = NOPE; kar ++; } } if (!fname) { SUMA_SL_Err("No input file specified."); exit(1); } if (ver == -1) { /* guess at version */ if (strstr(fname,"2009")) { ver = 2009; SUMA_S_Notev("Guessed FS annot version of %d\n", ver); } else if (strstr(fname,"2005")) { ver = 2005; SUMA_S_Notev("Guessed FS annot version of %d\n", ver); } else { SUMA_S_Notev("Assuming FS annot version of %d\n", ver); } } if (hemi == 0) { if (strstr(fname,"lh.")) { hemi = -1; SUMA_S_Note("Guessed left hemisphere"); } else if (strstr(fname,"rh.")) { SUMA_S_Note("Guessed right hemisphere"); hemi = 1; } else { if (ver == 2009) { hemi = -1; SUMA_S_Note("Assuming left hemisphere.\n"); } else { /* leave it not set */ } } } if (ver == 2009 && !ctfile) { char *eee = getenv("FREESURFER_HOME"); if (!eee) { SUMA_S_Warn("Environment variable FREESURFER_HOME not set.\n" "Cannot locate FreeSurferColorLUT.txt\n"); } else { sprintf(sbuf, "%s/FreeSurferColorLUT.txt", eee); ctfile = sbuf; SUMA_S_Notev("Using %s\n", ctfile); } } if (lbl1 < 0 && lbl2 < 0) { /* need some setup */ if (ver == 2009) { if (hemi == -1) { lbl1 = 13100; lbl2 = 13199; SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n", lbl1, lbl2); } else if (hemi == 1) { lbl1 = 14100; lbl2 = 14199; SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n", lbl1, lbl2); } else { SUMA_S_Warn("-FScmaprange is not set.\n" "You may need to set it, check results.\n"); } } else if (ver == 2005 && FSdefault) { if (hemi == -1) { lbl1 = 3100; lbl2 = 3199; SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n", lbl1, lbl2); } else if (hemi == 1) { lbl1 = 4100; lbl2 = 4199; SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n", lbl1, lbl2); } else { SUMA_S_Warn("-FScmaprange is not set.\n" "You may need to set it, check results.\n"); } } } if (!fcmap && !froi && !fcol && !Showct && !fdset) { SUMA_SL_Err("Nothing to do.\n" "Use either -cmap_1D or \n" " -roi_1D or -col_1D or \n" " -show_FScmap options."); exit(1); } if (fdset) { int exists = 0; char *ooo=NULL; exists = SUMA_WriteDset_NameCheck_s (fdset, NULL, SUMA_ASCII_NIML, 0, &ooo); if (exists != 0 && !THD_ok_overwrite()) { SUMA_S_Errv("Output dataset %s exists.\n", ooo); SUMA_free(ooo); ooo=NULL; exit(1); } } if (froi) { if (SUMA_filexists(froi) && !THD_ok_overwrite()) { fprintf( SUMA_STDERR, "Error %s: File %s exists, will not overwrite.\n", FuncName, froi); SUMA_RETURN (NOPE); } } if (fcmap) { if (SUMA_filexists(fcmap) && !THD_ok_overwrite()) { fprintf( SUMA_STDERR, "Error %s: File %s exists, will not overwrite.\n", FuncName, fcmap); SUMA_RETURN (NOPE); } } if (fcol) { if (SUMA_filexists(fcol) && !THD_ok_overwrite()) { fprintf( SUMA_STDERR, "Error %s: File %s exists, will not overwrite.\n", FuncName, fcol); SUMA_RETURN (NOPE); } } if (!SUMA_readFSannot (fname, froi, fcmap, fcol, Showct, ctfile, lbl1, lbl2, &dset)) { SUMA_S_Err("Failed reading annotation file (or output file exists)"); exit(1); } if (!dset && fdset) { SUMA_S_Err("Have no dset to write"); exit(1); } if (fdset) { if (AFNI_yesenv("AFNI_NIML_TEXT_DATA")) { SUMA_WriteDset_eng(fdset, dset, SUMA_ASCII_NIML, 1, 1, 1); } else { SUMA_WriteDset_eng(fdset, dset, SUMA_BINARY_NIML, 1, 1, 1); } } if (testmode) { int key, indx, ism, suc; SUMA_COLOR_MAP *SM2=NULL, *SM=NULL; char *s=NULL, stmp[256]; SUMA_PARSED_NAME *sname=NULL; NI_group *ngr=NULL; SUMA_S_Note("Testing Chunk Begins"); /* check */ if (!SUMA_is_Label_dset(dset, &ngr)) { SUMA_S_Err("Dset is no label dset"); exit(1); } /* write it */ /* play with the colormap */ if (ngr) { if (!(SM = SUMA_NICmapToCmap(ngr))){ SUMA_S_Err("Failed to create SUMA colormap"); exit(1); } ngr = NULL; /* that's a copy of what was in dset, do not free it */ if (!SUMA_CreateCmapHash(SM)) { SUMA_S_Err("Failed to create hash"); exit(1); } /* Now pretend you are retrieving the index in cmap of some key */ for (ism=0; ism < SM->N_M[0]; ++ism) { /* the key is coming from SM, because I store all keys there But key normally comes from a certain node's value */ key = SM->idvec[ism]; indx = SUMA_ColMapKeyIndex(key, SM); if (indx < 0) { SUMA_S_Errv("Hashkey %d not found\n", key); } else { fprintf(SUMA_STDERR, "hashed id %d --> index %d\n" "known id %d --> index %d\n", key, indx, key, ism); } } /* Now try it with an unknown key */ key = -13; indx = SUMA_ColMapKeyIndex(key, SM); if (indx < 0) { fprintf(SUMA_STDERR, "id %d is not in the hash table, as expected\n", key); } else { SUMA_S_Errv("Should not have found %d\n", key); } SUMA_S_Note("Now Show it to me"); s = SUMA_ColorMapVec_Info (&SM, 1, 2); if (s) { fprintf(SUMA_STDERR,"%s", s); SUMA_free(s); s = NULL; } SUMA_S_Notev("Now turn it to niml (%s)\n", SM->Name); ngr = SUMA_CmapToNICmap(SM); sname = SUMA_ParseFname(SM->Name, NULL); snprintf(stmp, 128*sizeof(char), "file:%s.niml.cmap", sname->FileName_NoExt); NEL_WRITE_TX(ngr, stmp, suc); if (!suc) { SUMA_S_Errv("Failed to write %s\n", stmp); } SUMA_Free_Parsed_Name(sname); sname = NULL; SUMA_S_Note("Now turn niml colormap to SUMA's colormap"); SM2 = SUMA_NICmapToCmap(ngr); SUMA_S_Note("Now Show it to me2"); s = SUMA_ColorMapVec_Info (&SM2, 1, 2); if (s) { fprintf(SUMA_STDERR,"%s", s); SUMA_free(s); s = NULL; } NI_free_element(ngr); ngr=NULL; SUMA_Free_ColorMap(SM); SM = NULL; SUMA_Free_ColorMap(SM2); SM2 = NULL; } SUMA_S_Note("Testing Chunk End"); } if (dset) SUMA_FreeDset(dset); dset = NULL; exit(0); }
int GenFeatureDist_CheckOpts(SEG_OPTS *Opt) { static char FuncName[]={"GenFeatureDist_CheckOpts"}; int i=0, kk=0, nmatch; SUMA_ENTRY; if (!Opt->clss) { SUMA_S_Err("Need -classes option"); SUMA_RETURN(1); } if (!Opt->sig_names) { SUMA_S_Err("Need -sig option"); SUMA_RETURN(1); } if (!Opt->samp_names) { SUMA_S_Err("Need -samp option"); SUMA_RETURN(1); } if (Opt->samp_names->num != Opt->sig_names->num) { SUMA_S_Errv("Need as many -samp options (%d) as -sig options (%d)\n", Opt->samp_names->num, Opt->sig_names->num); SUMA_RETURN(1); } /* labeltable? */ if (Opt->labeltable_name) { Dtable *vl_dtable=NULL; char *labeltable_str=NULL; /* read the table */ if (!(labeltable_str = AFNI_suck_file( Opt->labeltable_name))) { ERROR_exit("Failed to read %s", Opt->labeltable_name); } if (!(vl_dtable = Dtable_from_nimlstring(labeltable_str))) { ERROR_exit("Could not parse labeltable"); } /* make sure all classes are in the labeltable */ for (i=0; i<Opt->clss->num; ++i) { if ((kk = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[i]))<0){ ERROR_exit("Key not found in %s for %s ", Opt->labeltable_name, Opt->clss->str[i]); } if (Opt->keys) { if (Opt->keys[i]!=kk) { ERROR_exit("Key mismatch %d %d", Opt->keys[i], kk); } } } if (!Opt->keys) { /* get them from table */ Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int)); for (i=0; i<Opt->clss->num; ++i) { if ((kk = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[i]))<0){ ERROR_exit("(should noy happen) Key not found in %s for %s ", Opt->labeltable_name, Opt->clss->str[i]); } Opt->keys[i] = kk; } } destroy_Dtable(vl_dtable); vl_dtable=NULL; } /* Make sure any histogram specs are for a class in use */ for (kk=0; kk<Opt->N_hspec; ++kk) { if ( (nmatch = SUMA_is_wild_hspec_label(Opt->hspec[kk]->label)) >= 0) { if (!nmatch) break; for (i=0; i<Opt->feats->num; ++i) { if (!strncmp(Opt->feats->str[i], Opt->hspec[kk]->label, nmatch)) break; } } else { for (i=0; i<Opt->feats->num; ++i) { if (!strcmp(Opt->feats->str[i], Opt->hspec[kk]->label)) break; } } if (i==Opt->feats->num) { SUMA_S_Warn("Feature %s in -hspec not found under -features and will have no impact on the output\n", Opt->hspec[kk]->label); } } if (!Opt->keys) { /* add default keys */ if (Opt->debug) SUMA_S_Note("Keys not available, assuming defaults"); Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int)); for (i=0; i<Opt->clss->num; ++i) { Opt->keys[i] = i+1; } } /* Show the match between keys and classes */ if (Opt->debug > 1) { SUMA_S_Note("Class-->key map"); SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys); } if( ! THD_is_directory(Opt->proot) ){ if( mkdir( Opt->proot , THD_MKDIR_MODE ) != 0 ){ SUMA_S_Errv("Failed to create %s\n", Opt->proot); SUMA_RETURN(0); } } SUMA_RETURN(1); }
int main (int argc,char *argv[]) { /* Main */ static char FuncName[]= {"SurfQual"}; char *OutName = NULL, ext[5], *prefix = NULL, *shist=NULL; SUMA_SURFQUAL_OPTIONS *Opt; int SO_read = -1; int i, cnt, trouble, consistent = -1, eu = -1, nsi = -1, N_Spec=0; SUMA_SurfaceObject *SO = NULL; SUMA_SurfSpecFile *Spec=NULL; void *SO_name = NULL; SUMA_Boolean DoConv = NOPE, DoSphQ = NOPE, DoSelfInt = NOPE; int N_bad_nodes, N_bad_facesets; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;"); /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = SUMA_SurfQual_ParseInput (argv, argc, ps); if (argc < 2) { SUMA_S_Err("Too few options"); usage_SUMA_SurfQual(ps, 0); exit (1); } /* read all surfaces */ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec > 1 ) { SUMA_S_Err( "Mike, you cannot mix -spec with -i or -t options " "for specifying surfaces."); exit(1); } if (Spec->N_Surfs < 1) { SUMA_S_Err("No surfaces"); exit(1); } if (Opt->self_intersect) DoSelfInt = YUP; DoConv = NOPE; DoSphQ = NOPE; if (Opt->surftype) { if (!strcmp(Opt->surftype, "-sphere")) { DoSphQ = YUP; } else { /* Don't complain anymore, maybe winding checking is all users need */ } } for (i=0; i < Spec->N_Surfs; ++i) {/* loop to read in surfaces */ /* now identify surface needed */ if (!(SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, i, ps->sv[0], 0))) { SUMA_S_Err("Failed to load surface .\n"); exit(1); } fprintf(SUMA_STDERR,"\nReport for Surface %s\n", SO->Label); /* do the quality thing based on the Opt->surftype */ if (!Opt->out_prefix) prefix = SUMA_copy_string(SO->Label); else prefix = SUMA_copy_string (Opt->out_prefix); /* check the winding */ if (!SUMA_MakeConsistent (SO->FaceSetList, SO->N_FaceSet, SO->EL, 0, &trouble)) { SUMA_S_Warn( "Failed to make sure surface's mesh is consistently wound.\n" "You should fix the mesh.\n"); consistent = 0; } { int iii=0, isbad=0, ht0; int *badedge=(int*)SUMA_calloc(SO->N_Node, sizeof(int)); /* check on troubled edges */ while (iii < SO->EL->N_EL) { ht0 = SO->EL->ELps[iii][1]; /* make sure edge is not part of three triangles, if it is,skip it*/ if (SO->EL->ELps[iii][2] > 2) { ++iii; fprintf( SUMA_STDERR, "%s: Bad edge (#%d: %d--%d), \n" " part of more than 2 triangles, skip it\n", FuncName, i, SO->EL->EL[iii][0], SO->EL->EL[iii][1]); ++badedge[SO->EL->EL[iii][0]]; ++badedge[SO->EL->EL[iii][1]]; isbad = 1; continue; } ++iii; } if (isbad) { if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_replace_string ( prefix, "_BadEdgeNodes.1D.dset", ext, 0); } else { OutName = SUMA_append_string (prefix, "_BadEdgeNodes.1D.dset"); } SUMA_WRITE_ARRAY_1D(badedge,SO->N_Node,1,OutName); if (OutName) SUMA_free(OutName); OutName = NULL; } SUMA_free(badedge); badedge = NULL; } if (DoConv) { float *Cx = NULL; if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_replace_string (prefix, "_Conv_detail.1D.dset", ext, 0); } else { OutName = SUMA_append_string (prefix, "_Conv_detail.1D.dset"); } Cx = SUMA_Convexity_Engine ( SO->NodeList, SO->N_Node, SO->NodeNormList, SO->FN, OutName, NULL); if (Cx) SUMA_free(Cx); Cx = NULL; if (OutName) SUMA_free(OutName); OutName = NULL; } if (DoSphQ) { if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_string (prefix, ext); } else { OutName = SUMA_copy_string (prefix); } shist = SUMA_HistString (NULL, argc, argv, NULL); SUMA_SphereQuality (SO, OutName, shist, &N_bad_nodes, &N_bad_facesets); if (shist) SUMA_free(shist); shist = NULL; if (OutName) SUMA_free(OutName); OutName = NULL; } if (trouble) { /* put winding problem here to make it visible */ fprintf (SUMA_STDERR,"\n"); SUMA_S_Warn( "Mesh is not consistent, use ConvertSurface's -make_consistent \n" "option to fix the problem before proceeding further.\n" "Other results reported by this and other programs\n" "may be incorrect if mesh is not consistently wound.\n" ); consistent = 0; } else { consistent = 1; fprintf (SUMA_STDERR,"\n"); fprintf (SUMA_STDERR,"Surface is consistently wound\n"); } { SUMA_EULER_SO(SO, eu); fprintf (SUMA_STDERR,"\n"); fprintf(SUMA_STDERR,"Surface Euler Characteristic is: %d\n", eu); } if ((SO->EL->min_N_Hosts == 1 || SO->EL->max_N_Hosts == 1)) { fprintf (SUMA_STDERR,"\n"); fprintf(SUMA_STDERR, "Warning %s:\n" " Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SO->EL->min_N_Hosts, SO->EL->max_N_Hosts); fprintf( SUMA_STDERR, " You have edges that form a border in the surface.\n"); } if (SO->EL->min_N_Hosts == 2 && SO->EL->max_N_Hosts == 2) { fprintf (SUMA_STDERR,"\n"); fprintf(SUMA_STDERR,"Surface is closed and is a 2-manifold."); } if (SO->EL->min_N_Hosts > 2 || SO->EL->max_N_Hosts > 2) { fprintf (SUMA_STDERR,"\n"); fprintf( SUMA_STDERR, "Warning %s:\n" "Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SO->EL->min_N_Hosts, SO->EL->max_N_Hosts); fprintf(SUMA_STDERR, "Warning %s:\n" " You have edges that belong to more than two triangles.\n" " Bad for analysis assuming surface is a 2-manifold.\n", FuncName); if (1) { int iii=0; fprintf( SUMA_STDERR, " These edges are formed by the following nodes:\n"); for (iii = 0; iii < SO->EL->N_EL; ++iii) { if (SO->EL->ELps[iii][2] > 2) fprintf (SUMA_STDERR, " %d: Edge [%d %d] shared by %d triangles.\n", iii+1, SO->EL->EL[iii][0], SO->EL->EL[iii][1] , SO->EL->ELps[iii][2] ); } } } if (DoSelfInt) { int iii; FILE *fout=NULL; byte *report = (byte *)SUMA_calloc(SO->N_Node, sizeof(byte)); if (!report) { SUMA_SL_Crit("Failed to allocate for report"); report = NULL; } fprintf( SUMA_STDERR, "\n\nChecking for intersections...:\n"); nsi = SUMA_isSelfIntersect(SO, 500, report); if (nsi) { fprintf( SUMA_STDERR, " Surface is self intersecting.\n" "%d segments were found to intersect the surface.\n", nsi); if (nsi >= 500) { fprintf( SUMA_STDERR, " It is possible that you have additional segments" " intersecting the surface.\n"); } if (report) { if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_replace_string ( prefix, "_IntersNodes.1D.dset", ext, 0); } else { OutName = SUMA_append_string (prefix, "_IntersNodes.1D.dset"); } fout = fopen(OutName, "w"); if (fout) { fprintf(fout, "#List of nodes that are part of segments which intersect " "the surface\n" "#%s\n" "#A total of %d segments (search limit is 500) were found to " "intersect the surface.\n" "#Col.1 : Node index\n" "#Col.2 : Dummy flag, always 1\n", SUMA_CHECK_NULL_STR(SO->Label), nsi ); for (iii=0; iii<SO->N_Node; ++iii) if (report[iii]) fprintf(fout, "%d\t1\n", iii); fclose(fout); fout = NULL; } else { SUMA_SL_Err("Failed to open file for output."); } if (OutName) SUMA_free(OutName); } } else { fprintf(SUMA_STDERR, " Surface is not self intersecting.\n"); } if (report) SUMA_free(report); report = NULL; } fprintf (SUMA_STDERR,"\n"); if (Opt->DoSum) { /* do not change syntax, scripts depend on this */ fprintf(stdout,"Summary for %s:\n", SO->Label); fprintf(stdout,"Euler_Charac. %d\n", eu); fprintf(stdout,"Consistent_Winding %d\n", consistent); if (DoSphQ) { fprintf(stdout,"Folding_Triangles %d\n", N_bad_facesets); fprintf(stdout,"Sketchy_nodes %d\n", N_bad_nodes); } if (DoSelfInt) fprintf(stdout,"Self_Intersections %d\n", nsi); fprintf(stdout,"\n"); } } SUMA_LH("clean up"); if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free spec fields"); } SUMA_free(Spec); Spec = NULL; if (prefix) SUMA_free(prefix); prefix = NULL; if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); SUMA_RETURN(0); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SurfPatch"}; SUMA_GETPATCH_OPTIONS *Opt; char *ppref=NULL, ext[5]; float *far=NULL; MRI_IMAGE *im = NULL; int SO_read = -1; int *NodePatch=NULL, N_NodePatch=-1, *FaceSetList=NULL , N_FaceSet = -1, N_Node = -1, N_Spec=0; int i, inodeoff=-1, ilabeloff=-1, nvec, ncol, cnt; SUMA_SurfaceObject *SO = NULL; SUMA_PATCH *ptch = NULL; SUMA_SurfSpecFile *Spec; SUMA_INDEXING_ORDER d_order; void *SO_name = NULL; SUMA_Boolean exists = NOPE; SUMA_SO_File_Type typetmp; SUMA_SurfaceObject *SOnew = NULL; float *NodeList = NULL; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;"); /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = SUMA_GetPatch_ParseInput (argv, argc, ps); if (argc < 2) { SUMA_S_Err("Too few options"); usage_SUMA_getPatch(ps, 0); exit (1); } /* read all surfaces */ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec > 1 ) { SUMA_S_Err( "Mike, you cannot mix -spec with -i or -t options " "for specifying surfaces."); exit(1); } if (Spec->N_Surfs < 1) { SUMA_S_Err("No surfaces"); exit(1); } if (Opt->DoVol && Spec->N_Surfs != 2) { SUMA_S_Errv("Must specify 2 and only 2 surfaces with -vol options\n" "Have %d from the command line\n",Spec->N_Surfs); exit(1); } if (Opt->oType != SUMA_FT_NOT_SPECIFIED && !Opt->VolOnly) { for (i=0; i < Spec->N_Surfs; ++i) { if (Spec->N_Surfs > 1) { sprintf(ext, "_%c", 65+i); ppref = SUMA_append_string(Opt->out_prefix, ext); } else { ppref = SUMA_copy_string(Opt->out_prefix); } SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, Opt->oType, &exists); if (exists && !THD_ok_overwrite()) { fprintf(SUMA_STDERR, "Error %s:\nOutput file(s) %s* on disk.\n" "Will not overwrite.\n", FuncName, ppref); exit(1); } if (ppref) SUMA_free(ppref); ppref = NULL; if (SO_name) SUMA_free(SO_name); SO_name = NULL; } } /* read in the file containing the node information */ im = mri_read_1D (Opt->in_name); if (!im) { SUMA_S_Errv("Failed to read 1D file '%s'\n", Opt->in_name); exit(1); } far = MRI_FLOAT_PTR(im); nvec = im->nx; ncol = im->ny; if (Opt->nodecol >= ncol || Opt->labelcol >= ncol) { fprintf(SUMA_STDERR, "\n" "Error %s: Input file has a total of %d columns.\n" "One or both user-specified node (%d) and \n" "label (%d) columns are too high. Maximum usable\n" "column index is %d.\n" , FuncName, ncol, Opt->nodecol, Opt->labelcol, ncol -1 ); exit(1); } d_order = SUMA_COLUMN_MAJOR; if (!nvec) { SUMA_SL_Err("Empty file"); exit(1); } /* form the node vector */ NodePatch = (int *)SUMA_malloc(sizeof(int)*nvec); if (!NodePatch) { SUMA_SL_Crit("Failed to allocate."); exit(1); } inodeoff = Opt->nodecol*nvec; if (Opt->labelcol < 0) { /* all listed nodes */ for (i=0; i<nvec; ++i) { NodePatch[i] = far[i+inodeoff]; } N_NodePatch = nvec; } else { ilabeloff = Opt->labelcol*nvec; if (Opt->thislabel < 0) { /* all nodes with non zero labels */ cnt = 0; for (i=0; i<nvec; ++i) { if (far[i+ilabeloff]) { NodePatch[cnt] = far[i+inodeoff]; ++cnt; } } N_NodePatch = cnt; } else { /* select labels */ cnt = 0; for (i=0; i<nvec; ++i) { if (far[i+ilabeloff] == Opt->thislabel) { NodePatch[cnt] = far[i+inodeoff]; ++cnt; } } N_NodePatch = cnt; } NodePatch = (int *) SUMA_realloc(NodePatch , sizeof(int)*N_NodePatch); } /* done with im, free it */ mri_free(im); im = NULL; if (Opt->DoVol) { SUMA_SurfaceObject *SO1 = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], 0); SUMA_SurfaceObject *SO2 = SUMA_Load_Spec_Surf_with_Metrics(Spec, 1, ps->sv[0], 0); double Vol = 0.0; SUMA_SurfaceObject *SOp = SUMA_Alloc_SurfObject_Struct(1); byte *adj_N=NULL; if (Opt->adjust_contour) adj_N = SUMA_calloc(SO1->N_Node, sizeof(byte)); if (!SO1 || !SO2) { SUMA_SL_Err("Failed to load surfaces."); exit(1); } /* a chunk used to test SUMA_Pattie_Volume */ Vol = SUMA_Pattie_Volume(SO1, SO2, NodePatch, N_NodePatch, SOp, Opt->minhits, Opt->FixBowTie, Opt->adjust_contour, adj_N, Opt->verb); fprintf (SUMA_STDOUT,"Volume = %f\n", fabs(Vol)); if (Opt->out_volprefix) { if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SOp->FileType = Opt->oType; if (Opt->flip) { if (Opt->verb > 1) SUMA_S_Note("Flipping stitched surf's triangles\n"); SUMA_FlipSOTriangles (SOp); } if (!(SUMA_Save_Surface_Object_Wrap ( Opt->out_volprefix, NULL, SOp, SUMA_PLY, SUMA_ASCII, NULL))) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); } if (Opt->adjust_contour && adj_N) { Opt->out_volprefix = SUMA_append_replace_string(Opt->out_volprefix, ".adjneighb","",1); ppref = SUMA_Extension(Opt->out_volprefix, ".1D.dset", NOPE); SUMA_WRITE_IND_ARRAY_1D(adj_N, NULL, SO1->N_Node, 1, ppref); SUMA_free(ppref); ppref=NULL; } } if (SOp) SUMA_Free_Surface_Object(SOp); SOp = NULL; } if (!Opt->VolOnly) { FaceSetList = NULL; N_FaceSet = -1; for (i=0; i < Spec->N_Surfs; ++i) {/* loop to read in surfaces */ /* now identify surface needed */ if (!(SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, i, ps->sv[0], 0))) { SUMA_S_Err("Failed to load surface .\n"); exit(1); } if (SO->aSO) { /* otherwise, when you reset the number of FaceSets for example, and you still write in GIFTI, the old contents of aSO will prevail */ SO->aSO = SUMA_FreeAfniSurfaceObject(SO->aSO); } /* extract the patch */ ptch = SUMA_getPatch (NodePatch, N_NodePatch, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->MF, Opt->minhits, Opt->FixBowTie, (!i && !Opt->DoVol)); /* verbose only for first patch, and if no volume computation was required This is to keep the warnings to a minimum*/ if (!ptch) { SUMA_SL_Err("Failed to form patch."); exit(1); } if (LocalHead) SUMA_ShowPatch(ptch, NULL); /* Now create a surface with that patch */ if (Spec->N_Surfs > 1) { sprintf(ext, "_%c", 65+i); ppref = SUMA_append_string(Opt->out_prefix, ext); } else { ppref = SUMA_copy_string(Opt->out_prefix); } /* save the original type */ typetmp = SO->FileType; if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SO->FileType = Opt->oType; SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, SO->FileType, &exists); if (ppref) SUMA_free(ppref); ppref = NULL; /* save the original pointers to the facesets and their number */ FaceSetList = SO->FaceSetList; N_FaceSet = SO->N_FaceSet; NodeList = SO->NodeList; N_Node = SO->N_Node; /* replace with Patch */ SO->FaceSetList = ptch->FaceSetList; SO->N_FaceSet = ptch->N_FaceSet; if (Opt->Do_p2s) { if (LocalHead) fprintf (SUMA_STDERR, "%s: Changing patch to surface...\n", FuncName); SOnew = SUMA_Patch2Surf(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, 3); if (!SOnew) { SUMA_S_Err("Failed to change patch to surface."); exit(1); } SO->FaceSetList = SOnew->FaceSetList; SO->N_FaceSet = SOnew->N_FaceSet; SO->N_Node = SOnew->N_Node; SO->NodeList = SOnew->NodeList; } if (SO->N_FaceSet <= 0) { SUMA_S_Warn("The patch is empty.\n" " Non existing surface not written to disk.\n"); } else { /* Is the gain wanted? */ if (Opt->coordgain) { SUMA_SL_Note("Applying coord gain to surface nodes!"); for (cnt=0; cnt < SO->NodeDim*SO->N_Node; ++cnt) SO->NodeList[cnt] *= Opt->coordgain; } if (Opt->flip) { if (Opt->verb > 1) SUMA_S_Note("Flipping triangles\n"); SUMA_FlipTriangles (SO->FaceSetList, SO->N_FaceSet); SUMA_RECOMPUTE_NORMALS(SO); } if (!SUMA_Save_Surface_Object (SO_name, SO, SO->FileType, SUMA_ASCII, NULL)) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } } /* bring SO back to shape */ SO->FileType = typetmp; SO->FaceSetList = FaceSetList; FaceSetList = NULL; SO->N_FaceSet = N_FaceSet; N_FaceSet = -1; SO->NodeList = NodeList; NodeList = NULL; SO->N_Node = N_Node; N_Node = -1; if (SO_name) SUMA_free(SO_name); SO_name = NULL; if (ptch) SUMA_freePatch(ptch); ptch = NULL; if (SOnew) SUMA_Free_Surface_Object(SOnew); SOnew = NULL; /* get rid of old surface object */ } } SUMA_LH("clean up"); if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free spec fields"); } SUMA_free(Spec); Spec = NULL; if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt->out_volprefix) SUMA_free(Opt->out_volprefix); Opt->out_volprefix = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (!SUMA_Free_CommonFields(SUMAg_CF)) { SUMA_SL_Err("SUMAg_CF Cleanup Failed!"); } SUMA_RETURN(0); }
/*! A function to call SUMA_qhull_wrap or SUMA_qdelaunay_wrap */ SUMA_SurfaceObject *SUMA_ConvexHullSurface( SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt) { static char FuncName[]={"SUMA_ConvexHullSurface"}; SUMA_SurfaceObject *SO=NULL; float *xyz=NULL, *xyzp=NULL, *txyz=NULL; int npt, *ijk=NULL, nf=0, cnt, i, j, k, nxx, nyy, nzz,N_txyz=-1; FILE *fid=NULL; THD_fvec3 fv, iv; SUMA_Boolean LocalHead = NOPE; SUMA_ENTRY; npt = 0; N_txyz=-1; if (Opt->UseThisBrain) { MRI_IMAGE *im = NULL; float *far=NULL; int nx2, i3; /* load the 1D file */ im = mri_read_1D (Opt->UseThisBrain); if (!im) { SUMA_S_Err("Failed to read file"); SUMA_RETURN(NULL); } far = MRI_FLOAT_PTR(im); if (im->nx == 0) { SUMA_S_Errv("Empty file %s.\n", Opt->UseThisBrain); SUMA_RETURN(NULL); } if (im->ny != 3) { SUMA_S_Errv("Found %d columns in %s. Expecting 3\n", im->ny, Opt->UseThisBrain); SUMA_RETURN(NULL); } /* copy the columns */ N_txyz = im->nx; txyz = (float *)SUMA_malloc(im->nx*im->ny*sizeof(float)); if (!txyz) { SUMA_S_Crit("Failed to allocate."); SUMA_RETURN(NULL); } nx2 = 2*im->nx; for (i=0; i<N_txyz; ++i) { i3 = 3*i; txyz[i3 ] = far[i]; txyz[i3+1] = far[i+im->nx]; txyz[i3+2] = far[i+nx2]; } /* done, clean up and out you go */ if (im) mri_free(im); im = NULL; } if (Opt->in_vol) { cnt = 0; npt = 0; nxx = (DSET_NX(Opt->in_vol)); nyy = (DSET_NY(Opt->in_vol)); nzz = (DSET_NZ(Opt->in_vol)); if (Opt->debug) fprintf(SUMA_STDERR,"%s:\nRunning qhull...\n", FuncName); xyz = (float *)SUMA_malloc(3*nxx*nyy*nzz*sizeof(float)); if (!xyz) { SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NULL); } for( k = 0 ; k < nzz ; k++ ) { for( j = 0 ; j < nyy ; j++ ) { for( i = 0 ; i < nxx ; i++ ) { if (Opt->mcdatav[cnt] == 1) { fv.xyz[0] = DSET_XORG(Opt->in_vol) + i * DSET_DX(Opt->in_vol); fv.xyz[1] = DSET_YORG(Opt->in_vol) + j * DSET_DY(Opt->in_vol); fv.xyz[2] = DSET_ZORG(Opt->in_vol) + k * DSET_DZ(Opt->in_vol); /* change mm to RAI coords */ iv = SUMA_THD_3dmm_to_dicomm( Opt->in_vol->daxes->xxorient, Opt->in_vol->daxes->yyorient, Opt->in_vol->daxes->zzorient, fv ); xyz[3*npt] = iv.xyz[0]; xyz[3*npt+1] = iv.xyz[1]; xyz[3*npt+2] = iv.xyz[2]; npt++; } ++cnt; } } } } else if (Opt->XYZ) { xyz = (float *)SUMA_malloc(3*Opt->N_XYZ*sizeof(float)); if (!xyz) { SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NULL); } for( k = 0 ; k < 3*Opt->N_XYZ ; k++ ) { xyz[k] = Opt->XYZ[k]; npt = Opt->N_XYZ; } } else { SUMA_S_Err("No input"); goto CLEANUP; } if (Opt->corder) { SUMA_PC_XYZ_PROJ *pcp=NULL; if (Opt->geom==1) { SUMA_S_Warn("PCA projection makes no sense for usual convex hull"); } if (!(pcp = SUMA_Project_Coords_PCA (xyz, npt, npt/2, NULL, E3_PLN_PRJ, ROT_2_Z,0))) { SUMA_S_Err("Failed to project"); goto CLEANUP; } xyzp = pcp->xyzp; pcp->xyzp = NULL; pcp = SUMA_Free_PC_XYZ_Proj(pcp); } else { xyzp = xyz; } if (N_txyz >= 0 && N_txyz != npt) { SUMA_S_Errv("Mismatch between number of coordinates for convex hull\n" "and number of coordinates to adopt in the end.\n" " %d, versus %d in -these_coords\n", npt, N_txyz); goto CLEANUP; } if (Opt->geom == 1) { /* convex hull */ if (! (nf = SUMA_qhull_wrap(npt, xyzp, &ijk, 1, Opt->s)) ) { fprintf(SUMA_STDERR,"%s:\nFailed in SUMA_qhull_wrap\n", FuncName); goto CLEANUP; } /* Other than unif==0 make no sense here, but leave it to the user */ switch (Opt->unif) { case 0: /* coordinates as passed to qhull, could be projected ones*/ SO = SUMA_Patch2Surf(xyzp, npt, ijk, nf, 3); break; case 1: /* Original corrdinates passed to qhull (pre-projections, if any) */ SO = SUMA_Patch2Surf(xyz, npt, ijk, nf, 3); break; case 2: /* special coordinates passed by user, never passed in any form to qhull */ SUMA_S_Warn("Makes no sense to mess with coords for convex hull..."); SO = SUMA_Patch2Surf(txyz, npt, ijk, nf, 3); break; default: SUMA_S_Err("pit of despair"); goto CLEANUP; } if (Opt->debug) fprintf(SUMA_STDERR,"%s:\n%d triangles.\n", FuncName, nf); } else if (Opt->geom == 2) { /* triangulation */ if (! (nf = SUMA_qdelaunay_wrap(npt, xyzp, &ijk, 1, Opt->s)) ) { fprintf(SUMA_STDERR,"%s:\nFailed in SUMA_qdelaunay_wrap\n", FuncName); goto CLEANUP; } switch (Opt->unif) { case 0: /* coordinates as passed to qdelaunay, could be projected ones*/ if (xyz == xyzp) xyz=NULL; /* xyzp will be set to null in next call, so xyz is treated the same here */ SO = SUMA_NewSO(&xyzp, npt, &ijk, nf, NULL); SUMA_LHv("xyzp %p, ijk %p\n", txyz, ijk); break; case 1: /* Original corrdinates passed to qdelaunay (pre-projections, if any) */ SO = SUMA_NewSO(&xyz, npt, &ijk, nf, NULL); SUMA_LHv("xyz %p, ijk %p\n", txyz, ijk); break; case 2: /* special coordinates passed by user, never passed in any form to qdelaunay */ SO = SUMA_NewSO(&txyz, npt, &ijk, nf, NULL); SUMA_LHv("txyz %p, ijk %p\n", txyz, ijk); break; default: SUMA_S_Err("pit of despair, again"); goto CLEANUP; } } else { SUMA_S_Errv("Opt->geom = %d not valid\n", Opt->geom); goto CLEANUP; } CLEANUP: if (ijk) SUMA_free(ijk); ijk=NULL; if(txyz) SUMA_free(txyz); txyz=NULL; if (xyzp != xyz && xyzp != NULL) SUMA_free(xyzp); xyzp = NULL; if (xyz) SUMA_free(xyz); xyz = NULL; SUMA_RETURN(SO); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"ConvexHull"}; int i, i3, nspec = 0; void *SO_name=NULL; SUMA_SurfaceObject *SO = NULL; SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt; char stmp[200]; SUMA_Boolean exists = NOPE; SUMA_Boolean LocalHead = NOPE; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;"); if (argc < 2) { usage_SUMA_ConvexHull(ps); exit (1); } Opt = SUMA_ConvexHull_ParseInput (argv, argc, ps); SO_name = SUMA_Prefix2SurfaceName(Opt->out_prefix, NULL, NULL, Opt->SurfFileType, &exists); if (exists && !THD_ok_overwrite()) { SUMA_S_Err("Output file(s) %s* on disk.\nWill not overwrite.\n", Opt->out_prefix); exit(1); } if (Opt->obj_type < 0) { if (Opt->in_name) { if (Opt->debug) { SUMA_S_Note("Creating mask..."); } if (!SUMA_Get_isosurface_datasets (Opt)) { SUMA_SL_Err("Failed to get data."); exit(1); } if (Opt->debug > 1) { if (Opt->debug == 2) { FILE *fout=fopen("inmaskvec.1D","w"); SUMA_S_Note("Writing masked values...\n"); if (!fout) { SUMA_SL_Err("Failed to write maskvec"); exit(1); } fprintf(fout, "#Col. 0 Voxel Index\n" "#Col. 1 Is a mask (all values here should be 1)\n" ); for (i=0; i<Opt->nvox; ++i) { if (Opt->mcdatav[i]) { fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]); } } fclose(fout); fout = NULL; } else { FILE *fout=fopen("maskvec.1D","w"); SUMA_S_Note("Writing all mask values...\n"); if (!fout) { SUMA_S_Err("Failed to write maskvec"); exit(1); } fprintf(fout, "#Col. 0 Voxel Index\n" "#Col. 1 Is in mask ?\n" ); for (i=0; i<Opt->nvox; ++i) { fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]); } fclose(fout); fout = NULL; } } } else if (Opt->in_1D) { MRI_IMAGE *im = NULL; float *far=NULL; int nx2; /* load the 1D file */ im = mri_read_1D (Opt->in_1D); if (!im) { SUMA_S_Err("Failed to read file"); exit(1); } far = MRI_FLOAT_PTR(im); if (im->nx == 0) { fprintf(SUMA_STDERR,"Error %s:\n Empty file %s.\n", FuncName, Opt->in_1D); exit(1); } if (im->ny != 3) { fprintf(SUMA_STDERR,"Error %s:\n Found %d columns in %s. Expecting 3\n", FuncName, im->ny, Opt->in_1D); exit(1); } /* copy the columns */ Opt->N_XYZ = im->nx; Opt->XYZ = (float *)SUMA_malloc(im->nx*im->ny*sizeof(float)); if (!Opt->XYZ) { SUMA_S_Crit("Failed to allocate."); exit(1); } nx2 = 2*im->nx; for (i=0;i<Opt->N_XYZ; ++i) { i3 = 3*i; Opt->XYZ[i3 ] = far[i]; Opt->XYZ[i3+1] = far[i+im->nx]; Opt->XYZ[i3+2] = far[i+nx2]; } /* done, clean up and out you go */ if (im) mri_free(im); im = NULL; } else if (ps->i_N_surfnames) { SUMA_SurfSpecFile *Spec=NULL; SUMA_SurfaceObject *SO=NULL; if (ps->i_N_surfnames > 1) { SUMA_S_Err("Only 1 input surface allowed!"); exit(1); } Spec = SUMA_IO_args_2_spec(ps, &nspec); if (!Spec) { SUMA_S_Err("Failed to create spec!"); exit(1); } if (nspec != 1) { SUMA_S_Warn("Expected one spec and nothing else"); } /* load the surface object */ SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0); if (!SO) { SUMA_S_Err("Failed to read surface."); exit(1); } /* transfer coords */ if(SO->NodeDim != 3) { SUMA_S_Err("bad node coords."); exit(1); } Opt->N_XYZ = SO->N_Node; Opt->XYZ = (float *)SUMA_malloc(SO->N_Node * SO->NodeDim * sizeof(float)); if (!Opt->XYZ) { SUMA_S_Crit("Failed to allocate."); exit(1); } for (i=0;i<SO->NodeDim*SO->N_Node; ++i) Opt->XYZ[i] = SO->NodeList[i]; if (nspec) { int k=0; for (k=0; k<nspec; ++k) { if (!SUMA_FreeSpecFields(&(Spec[k]))) { SUMA_S_Err("Failed to free spec fields"); } } SUMA_free(Spec); Spec = NULL; nspec = 0; } if (SO) SUMA_Free_Surface_Object(SO); SO = NULL; } else { SUMA_S_Err("No input!"); exit(1); } } else { SUMA_S_Err("Bad input!"); exit(1); } /* Now call Marching Cube functions */ if (!(SO = SUMA_ConvexHullSurface(Opt))) { SUMA_S_Err("Failed to create surface.\n"); exit(1); } /* write the surface to disk */ if (!SUMA_Save_Surface_Object (SO_name, SO, Opt->SurfFileType, Opt->SurfFileFormat, NULL)) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (Opt->fvec) SUMA_free(Opt->fvec); Opt->fvec = NULL; if (Opt->mcdatav) {SUMA_free(Opt->mcdatav); Opt->mcdatav = NULL;} if (Opt->in_vol) { DSET_delete( Opt->in_vol); Opt->in_vol = NULL;} if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt->XYZ) SUMA_free(Opt->XYZ); Opt->XYZ = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (SO_name) SUMA_free(SO_name); SO_name = NULL; if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); exit(0); }