/*! a function to test debugging */ int * SUMA_disaster(void) { static char FuncName[]={"SUMA_disaster"}; int *iv1=NULL, *iv2 = NULL, *iv3 = NULL; int N_iv1, N_iv2; int i; double v[7] = {-1.6, -1.5, -1.4, 0, 1.4, 1.5, 1.6}; SUMA_ENTRY; for (i=0; i<7; ++i) { fprintf (stderr,"%f : r %d, c %d\n", v[i], SUMA_ROUND(v[i]), SUMA_CEIL(v[i])); } SUMA_S_Notev("Domemtrace %d\n", get_Domemtrace()); N_iv1 = 5; N_iv2 = 5; iv1 = (int*) SUMA_calloc(N_iv1, sizeof(int)); iv2 = (int*) SUMA_calloc(N_iv2, sizeof(int)); /* overwrite iv1 */ iv1[N_iv1] = 3; /* overwrite iv2 */ iv2[N_iv2] = 7; /* MEMCHECK should give a warning */ SUMA_S_Note("Memcheck output"); MCHECK ; fflush(stdout) ; /* ZSS */ /* free iv1 (that should give a warning)*/ SUMA_S_Note("Now freeing iv1"); SUMA_free(iv1); /* without the -trace option, you'll get a warning of this corruption here */ /* try to free iv3 although it was not allocated for */ /* AFNI's functions do not check for this ...*/ /* SUMA_free(iv3);*/ /* don't free iv2, that should only give a warning when you exit with -trace option turned on */ SUMA_S_Note("Now dumping malloc table"); mcw_malloc_dump(); /* if you use -trace, you'll get a warning at the return for iv2 All allocated memory will be checked, at the return, not just iv2*/ SUMA_S_Note("Now returning"); SUMA_RETURN(iv2); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SUMA_TestDsetIO"}; int *NodeDef=NULL; byte *maskrow, *maskcol; int i, i3, N_NodeDef, N_Alloc, flg; float *r=NULL, *g=NULL, *b=NULL, *rgb=NULL; char stmp[500], idcode[50], **s, *si, *OutName = NULL; NI_element *nel=NULL; NI_stream ns; int found = 0, NoStride = 0; byte *bt=NULL; SUMA_DSET * dset = NULL, *ndset=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; LocalHead = YUP; /* turn on debugging */ SUMA_LH("Creating Data ..."); /* Create some sample data*/ /* let us create some colors to go on each node */ N_Alloc = 50; NodeDef = (int *)SUMA_malloc(N_Alloc * sizeof(int)); r = (float *)SUMA_malloc(N_Alloc * sizeof(float)); g = (float *)SUMA_malloc(N_Alloc * sizeof(float)); b = (float *)SUMA_malloc(N_Alloc * sizeof(float)); bt = (byte *)SUMA_malloc(N_Alloc * sizeof(byte)); s = (char **)SUMA_malloc(N_Alloc * sizeof(char *)); maskrow = (byte *)SUMA_malloc(N_Alloc * sizeof(byte)); maskcol = (byte *)SUMA_malloc(10*sizeof(byte)); for (i=0; i<10; ++i) { if (i==1 || i == 3) maskcol[i]=0; else maskcol[i] = 1; } N_NodeDef = N_Alloc; for (i=0; i<N_NodeDef; ++i) { NodeDef[i] = i; r[i] = sin((float)i/N_NodeDef*5); g[i] = sin((float)i/N_NodeDef*10); b[i] = cos((float)i/N_NodeDef*7); bt[i] = (byte)(4*b[i]); sprintf(stmp,"teststr_%d", i); s[i] = SUMA_copy_string(stmp); if (i==3 || i== 7 || i==33) maskrow[i] = 1; else maskrow[i]=0; } /* what if you had a vector of say, triplets */ rgb = (float *)SUMA_malloc(3 * N_Alloc * sizeof(float)); for (i=0; i<N_NodeDef; ++i) { i3 = 3*i; rgb[i3] = r[i]; rgb[i3+1] = g[i]; rgb[i3+2] = b[i]; } { float *xc, *de, *amp; int dof; float par[3]; /* store some statistics */ xc = (float *)SUMA_malloc(N_Alloc * sizeof(float)); de = (float *)SUMA_malloc(N_Alloc * sizeof(float)); amp = (float *)SUMA_malloc(N_Alloc * sizeof(float)); for (i=0; i<N_NodeDef; ++i) { xc[i] = rand()%1000/1000.0 * 1.0; de[i] = rand()%1000/1000.0 * 30; amp[i] = rand()%1000/1000.0 * 5.0; } SUMA_LH("Creating dset pointer"); dset = SUMA_CreateDsetPointer( "ExpandingRing_ResponseDelay", /* some label */ SUMA_NODE_BUCKET, /* mix and match */ NULL, /* no idcode, let the function create one from the filename*/ NULL, /* no domain str specified */ N_Alloc /* Number of nodes allocated for */ ); /* DO NOT free dset, if it is stored in DsetList */ #ifdef SUMA_COMPILED SUMA_LH("inserting dset pointer into list"); if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList,0)) { SUMA_SL_Err("Failed to insert dset into list"); exit(1); } #endif /* form the dataset */ SUMA_LH("Adding stat NodeDef column ..."); if (!SUMA_AddDsetNelCol ( dset, /* the famed nel */ "Node Indices", SUMA_NODE_INDEX, /* the column's type (description), one of SUMA_COL_TYPE */ (void *)NodeDef, /* column pointer p, here it is the list of node indices */ NULL /* that's an optional structure containing attributes of the added column. Not used at the moment */ ,1 /* stride, useful when you need to copy a column from a multiplexed vector. Say you have in p [rgb rgb rgb rgb], to set the g column you send in p+1 for the column pointer and a stride of 3 */ )) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } SUMA_LH("Adding stat other columns..."); par[0] = 120; par[1] = 2; par[2] = 2; if (!SUMA_AddDsetNelCol (dset, "XcorrCoef", SUMA_NODE_XCORR, (void *)xc, (void *)par ,1)) { fprintf (stderr, "Error %s:\nFailed in SUMA_AddDsetNelCol", FuncName); exit(1); } if (!SUMA_AddDsetNelCol (dset, "Delay", SUMA_NODE_FLOAT, (void *)de, NULL ,1)) { fprintf (stderr, "Error %s:\nFailed in SUMA_AddDsetNelCol", FuncName); exit(1); } if (!SUMA_AddDsetNelCol (dset, "Amplitude", SUMA_NODE_FLOAT, (void *)amp, NULL ,1)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddDsetNelCol", FuncName); exit(1); } SUMA_LH("History note"); if (!SUMA_AddNgrHist(dset->ngr, FuncName, argc, argv)) { SUMA_SL_Err("History addition failed."); exit(1); } #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("SampleDset", dset, SUMA_ASCII_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("SampleDset", dset, SUMA_ASCII_NIML, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } #ifdef SUMA_COMPILED /* Now create a new dataset nel no need to worry about loosing previous dset because it is in SUMAg_CF->DsetList*/ #else /* free dset by hand */ SUMA_LH("Freeing datasets ..."); if (dset) SUMA_FreeDset((void *)dset); dset = NULL; #endif } SUMA_LH("Creating dset pointer"); dset = SUMA_CreateDsetPointer( "SomethingLikeFileName", /* usually the filename */ SUMA_NODE_BUCKET, /* mix and match */ NULL, /* no idcode, let the function create one from the filename*/ NULL, /* no domain str specified */ N_Alloc /* Number of nodes allocated for */ ); /* DO NOT free dset, it is store in DsetList */ #ifdef SUMA_COMPILED SUMA_LH("inserting dset pointer into list"); if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList,0)) { SUMA_SL_Err("Failed to insert dset into list"); exit(1); } #endif /* form the dataset */ SUMA_LH("Adding NodeDef column ..."); if (!SUMA_AddDsetNelCol ( dset, /* the famed nel */ "le Node Def", SUMA_NODE_INDEX, /* the column's type (description), one of SUMA_COL_TYPE */ (void *)NodeDef, /* column pointer p, here it is the list of node indices */ NULL /* that's an optional structure containing attributes of the added column. Not used at the moment */ ,1 /* stride, useful when you need to copy a column from a multiplexed vector. Say you have in p [rgb rgb rgb rgb], to set the g column you send in p+1 for the column pointer and a stride of 3 */ )) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } SUMA_LH("Adding other columns..."); NoStride = 0; if (NoStride) { /* insert separate r, g and b column */ if (!SUMA_AddDsetNelCol (dset, "Le R", SUMA_NODE_R, (void *)r, NULL ,1)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } if (!SUMA_AddDsetNelCol (dset, "Le G", SUMA_NODE_G, (void *)g, NULL ,1)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } if (!SUMA_AddDsetNelCol (dset, "Le B", SUMA_NODE_B, (void *)b, NULL ,1)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } } else { /* insert from multiplexed rgb vector */ if (!SUMA_AddDsetNelCol (dset, "le R", SUMA_NODE_R, (void *)rgb, NULL ,3 )) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } if (!SUMA_AddDsetNelCol (dset, "Le G", SUMA_NODE_G, (void *)(rgb+1), NULL ,3)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } if (!SUMA_AddDsetNelCol (dset, "Le B", SUMA_NODE_B, (void *)(rgb+2), NULL ,3)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } #if 0 SUMA_LH("Testing insert column ..."); /* Test NI_inset_column_stride here please */ if (!SUMA_InsertDsetNelCol (dset, "Le G2", SUMA_NODE_G, (void *)(rgb+1), NULL ,3, 0)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } #endif } { int suc; SUMA_LH("Where are the attributes?"); NEL_WRITE_TX(dset->ngr,"fd:1",suc); } /* add the byte column, just to check multi type nightmares */ if (!SUMA_AddDsetNelCol (dset, "Le byte moi", SUMA_NODE_BYTE, (void *)bt, NULL ,1)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } SUMA_LH("Testing write ops before adding string columns ..."); /* before adding a string column ... */ #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_write_all_num", dset, SUMA_1D, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_write_all_num", dset, SUMA_1D, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_writebi_all_num", dset, SUMA_BINARY_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_writebi_all_num", dset, SUMA_BINARY_NIML, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_writeas_all_num", dset, SUMA_ASCII_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_writeas_all_num", dset, SUMA_ASCII_NIML, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } /* Now shuffle some columns (then put them back) */ SUMA_S_Note("NOTE THAT SHUFFLING here does not take care of attributes inside dset, but only dnel"); NI_move_column(dset->dnel, -1, 2); SUMA_ShowNel(dset->dnel); #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_writeas_all_shuff_num", dset, SUMA_ASCII_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_writeas_all_shuff_num", dset, SUMA_ASCII_NIML, 1, 1); #endif NI_move_column(dset->dnel, 2, -1); SUMA_ShowNel(dset->dnel); /* zero out some columns and test operations */ SUMA_LH("Trying masking operations"); ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 1, 0); SUMA_LH("Done"); /* try also: ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 0, 1); ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 0, 0); ndset = SUMA_MaskedCopyofDset(dset, maskrow, NULL, 1, 0); ndset = SUMA_MaskedCopyofDset(dset, NULL, NULL, 1, 0); ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 1, 0); */ if (!ndset) { SUMA_SL_Err("Failed in SUMA_MaskedCopyofDset"); } else { #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_writeas_MaskedCopy_num", ndset, SUMA_ASCII_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_writeas_MaskedCopy_num", ndset, SUMA_ASCII_NIML, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } SUMA_free(ndset); ndset = NULL; } SUMA_LH("Adding a string column"); /* add a string column, just for kicks ..*/ if (!SUMA_AddDsetNelCol (dset, "la string", SUMA_NODE_STRING, (void *)s, NULL, 1)) { fprintf (stderr,"Error %s:\nFailed in SUMA_AddNelCol", FuncName); exit(1); } /* now try to create a masked copy, this should fail */ fprintf (stderr,"%s: Attempting to mask a not all numeric dset, this should fail\n", FuncName); ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 1, 0); if (ndset) { fprintf (stderr,"Error %s:\nWhat the hell? This should not be supported.", FuncName); exit(1); }else{ fprintf (stderr,"%s: Good, failed.\n", FuncName); } /* after adding a string column ... */ SUMA_LH("Writing datasets ..."); #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_writeas", dset, SUMA_ASCII_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_writeas", dset, SUMA_ASCII_NIML, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_writebi", dset, SUMA_BINARY_NIML, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_writebi", dset, SUMA_BINARY_NIML, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } SUMA_LH("Writing to 1D a dataset that is not all numbers.\nThis should fail.\n"); #ifdef SUMA_COMPILED OutName = SUMA_WriteDset_s ("Test_write", dset, SUMA_1D, 1, 1); #else OutName = SUMA_WriteDset_ns ("Test_write", dset, SUMA_1D, 1, 1); #endif if (!OutName) { SUMA_SL_Err("Write Failed."); } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); SUMA_free(OutName); OutName = NULL; } /* How about loading some data */ #ifdef SUMA_COMPILED /* Now create a new dataset nel no need to worry about loosing previous dset because it is in SUMAg_CF->DsetList*/ #else /* free dset by hand */ SUMA_LH("Freeing datasets ..."); if (dset) SUMA_FreeDset((void *)dset); dset = NULL; #endif SUMA_LH("Fresh dataset ..."); dset = SUMA_NewDsetPointer(); SUMA_LH("Reading dataset ..."); DSET_READ(dset, "file:Test_writebi.niml.dset"); if (!dset->ngr) exit(1); /* insert the baby into the list */ #ifdef SUMA_COMPILED SUMA_LH("Inserting newly read element into list\n"); if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList, 0)) { char *newid = NULL; SUMA_SL_Err("Failed to insert dset into list"); /* Now change the idcode of that baby */ newid = UNIQ_hashcode(SDSET_ID(dset)); NI_set_attribute(dset->dnel, "self_idcode", newid); SUMA_free(newid); SUMA_LH("Trying to insert dset with a new id "); if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList, 0)) { SUMA_SL_Err("Failed to insert dset into list\nI failed to succeed, snif."); exit(1); } SUMA_LH("Lovely, that worked..."); } #endif /* show me the whole thing. Don't do this for an enormous nel */ /* SUMA_ShowNel((void*)dset->nel); */ /* I want the pointer to the green column but do not know its index */ { int j, *iv, N_i; float *fp; fprintf (stderr,"---Looking for green column ---\n"); iv = SUMA_GetDsetColIndex (dset, SUMA_NODE_G, &N_i); if (!iv) { fprintf (stderr,"Error %s: Failed to find column.\n" , FuncName); } else { fprintf (stderr,"\t%d columns of type SUMA_NODE_G found.\n", N_i); if (N_i) { fprintf (stderr,"\tReporting values at index %d\n", iv[0]); fp = (float *)dset->dnel->vec[iv[0]]; /* I know we only have one such col. here */ for (j=0; j < SDSET_VECLEN(dset); ++j) { fprintf (stderr,"%f, ", fp[j]); } SUMA_free(iv); iv = NULL; } } } /* Now show me that baby,*/ SUMA_LH("I wanna Show You Some Info"); si = SUMA_DsetInfo (dset, 0); fprintf (SUMA_STDERR,"Output of DsetInfo:\n%s\n", si); SUMA_free(si); si=NULL; if (LocalHead) fprintf(stderr," %s:-\nFrenching ...\n", FuncName); /* free other stuff */ if (r) SUMA_free(r); r = NULL; if (g) SUMA_free(g); g = NULL; if (b) SUMA_free(b); b = NULL; if (rgb) SUMA_free(rgb); rgb = NULL; if (maskrow) SUMA_free(maskrow); maskrow = NULL; if (maskcol) SUMA_free(maskcol); maskcol = NULL; if (NodeDef) SUMA_free(NodeDef); NodeDef = NULL; if (s) { for (i=0; i<N_NodeDef; ++i) { if (s[i]) SUMA_free(s[i]); } SUMA_free(s); } #ifdef SUMA_COMPILED /* dset and its contents are freed in SUMA_Free_CommonFields */ if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); #else /* free dset by hand */ if (dset) SUMA_FreeDset((void *)dset); #endif SUMA_RETURN (0); }/* Main */
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 */
/*! \brief parse the arguments for SurfSmooth program \param argv (char *) \param argc (int) \return Opt (SUMA_SURFCLUST_OPTIONS *) options structure. To free it, use SUMA_free(Opt->out_name); SUMA_free(Opt); */ SUMA_SURFCLUST_OPTIONS *SUMA_SurfClust_ParseInput (char *argv[], int argc, SUMA_GENERIC_ARGV_PARSE *ps) { static char FuncName[]={"SUMA_SurfClust_ParseInput"}; SUMA_SURFCLUST_OPTIONS *Opt=NULL; int kar, i, ind; char *outname; SUMA_Boolean brk = NOPE; SUMA_Boolean LocalHead = NOPE; SUMA_ENTRY; Opt = SUMA_create_SurfClust_Opt("SurfClust"); kar = 1; outname = NULL; BuildMethod = SUMA_OFFSETS2_NO_REC; brk = 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) { usage_SUMA_SurfClust(strlen(argv[kar]) > 3 ? 2:1); exit (0); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); if (!brk && (strcmp(argv[kar], "-no_cent") == 0)) { Opt->DoCentrality = 0; brk = YUP; } if (!brk && (strcmp(argv[kar], "-cent") == 0)) { Opt->DoCentrality = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-O2") == 0)) { BuildMethod = SUMA_OFFSETS2; brk = YUP; } if (!brk && (strcmp(argv[kar], "-O2_NR") == 0)) { BuildMethod = SUMA_OFFSETS2_NO_REC; brk = YUP; } if (!brk && (strcmp(argv[kar], "-Oll") == 0)) { BuildMethod = SUMA_OFFSETS_LL; brk = YUP; } if (!brk && (strcmp(argv[kar], "-update") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -update \n"); exit (1); } Opt->update = atof(argv[kar]); if (Opt->update < 1 || Opt->update > 100) { fprintf (SUMA_STDERR, "-update needs a parameter between " "1 and 50 (I have %.1f)\n", Opt->update); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-prefix") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -prefix \n"); exit (1); } Opt->oform = SUMA_GuessFormatFromExtension(argv[kar], NULL); if (Opt->oform == SUMA_NO_DSET_FORMAT) Opt->oform = SUMA_ASCII_NIML; Opt->out_prefix = SUMA_RemoveDsetExtension_s(argv[kar], Opt->oform); Opt->WriteFile = YUP; brk = YUP; } #if 0 if (!brk && (strcmp(argv[kar], "-spec") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -spec \n"); exit (1); } Opt->spec_file = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-sv") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -sv \n"); exit (1); } Opt->sv_name = argv[kar]; brk = YUP; } if (!brk && (strncmp(argv[kar], "-surf_", 6) == 0)) { if (kar + 1>= argc) { fprintf (SUMA_STDERR, "need argument after -surf_X SURF_NAME \n"); exit (1); } ind = argv[kar][6] - 'A'; if (ind < 0 || ind >= SURFCLUST_MAX_SURF) { fprintf (SUMA_STDERR, "-surf_X SURF_NAME option is out of range.\n" "Only %d surfaces are allowed. \n" "Must start with surf_A for first surface.\n", SURFCLUST_MAX_SURF); exit (1); } kar ++; Opt->surf_names[ind] = argv[kar]; Opt->N_surf = ind+1; brk = YUP; } #endif if (!brk && (strcmp(argv[kar], "-input") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 arguments after -input \n"); exit (1); } Opt->in_name = argv[kar]; kar ++; /* no need for that one Opt->nodecol = atoi(argv[kar]); kar ++; */ Opt->labelcol = atoi(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-rmm") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -rmm \n"); exit (1); } Opt->DistLim = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-in_range") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need two arguments after -in_range \n"); exit (1); } Opt->DoThreshold = SUMA_THRESH_INSIDE_RANGE; Opt->ThreshR[0] = atof(argv[kar]); ++kar; Opt->ThreshR[1] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-ex_range") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need two arguments after -ex_range \n"); exit (1); } Opt->DoThreshold = SUMA_THRESH_OUTSIDE_RANGE; Opt->ThreshR[0] = atof(argv[kar]); ++kar; Opt->ThreshR[1] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-thresh") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -thresh \n"); exit (1); } Opt->DoThreshold = SUMA_LESS_THAN; Opt->ThreshR[0] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-athresh") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -athresh \n"); exit (1); } Opt->DoThreshold = SUMA_ABS_LESS_THAN; Opt->ThreshR[0] = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-thresh_col") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -thresh_col \n"); exit (1); } Opt->tind = atoi(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-amm2") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -amm2 \n"); exit (1); } Opt->AreaLim = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-n") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -n \n"); exit (1); } Opt->NodeLim = atoi(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-out_roidset") == 0)) { Opt->OutROI = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-prepend_node_index") == 0)) { Opt->prepend_node_index = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-out_clusterdset") == 0)) { Opt->OutClustDset = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-out_fulllist") == 0)) { Opt->FullROIList = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-sort_none") == 0)) { Opt->SortMode = SUMA_SORT_CLUST_NO_SORT; brk = YUP; } if (!brk && (strcmp(argv[kar], "-sort_n_nodes") == 0)) { Opt->SortMode = SUMA_SORT_CLUST_BY_NUMBER_NODES; brk = YUP; } if (!brk && (strcmp(argv[kar], "-sort_area") == 0)) { Opt->SortMode = SUMA_SORT_CLUST_BY_AREA; brk = YUP; } if (!brk && !ps->arg_checked[kar]) { SUMA_S_Errv("Option %s not understood.\n" "Try -help for usage\n", argv[kar]); suggest_best_prog_option(argv[0], argv[kar]); exit (1); } else { brk = NOPE; kar ++; } } /* sanitorium */ if (Opt->DistLim == -1.5f) { fprintf (SUMA_STDERR, "must use option -rmm \n"); exit(1); } if (!Opt->out_prefix) { Opt->out_prefix = SUMA_RemoveDsetExtension_s(Opt->in_name, SUMA_NO_DSET_FORMAT); } if (Opt->SortMode == SUMA_SORT_CLUST_NOT_SET) { Opt->SortMode = SUMA_SORT_CLUST_BY_AREA; } if (BuildMethod == SUMA_OFFSETS2) { SUMA_S_Note("Using Offsets2"); } else if (BuildMethod == SUMA_OFFSETS_LL) { SUMA_S_Note("Using Offsets_ll"); } else if (BuildMethod == SUMA_OFFSETS2_NO_REC) { if (LocalHead) SUMA_S_Note("Using no recursion"); } else { SUMA_SL_Err("Bad BuildMethod"); exit(1); } SUMA_SurfClust_Set_Method(BuildMethod); if (Opt->FullROIList && !(Opt->OutROI || Opt->OutClustDset)) { SUMA_SL_Err("-out_fulllist must be used in conjunction " "with -out_ROIdset or -out_clusterdset"); exit(1); } SUMA_RETURN(Opt); }
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 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) { static char FuncName[]={"3dSeg"}; SEG_OPTS *Opt=NULL; char *atr=NULL; float *mixfrac= NULL; int i=0; double ff; SUMA_SEND_2AFNI SS2A; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = Seg_Default(argv, argc); Opt = Seg_ParseInput (Opt,argv, argc); Opt->hist = tross_commandline( FuncName , argc , argv ) ; /* load the input data */ if (!(Opt->aset = Seg_load_dset( Opt->aset_name ))) { SUMA_RETURN(1); } if (!Seg_CheckOpts(Opt)) { SUMA_S_Err("Failed on option check"); SUMA_RETURN(1); } /* Load mask dataset */ if (Opt->mset_name) { if (!strncasecmp(Opt->mset_name,"auto", 4)) { byte *mm=NULL; int j; short *sb=NULL; if (!(mm = THD_automask(Opt->aset))) { SUMA_RETURN(1); } NEW_SHORTY(Opt->aset, DSET_NVALS(Opt->aset), "automask.cp", Opt->mset); sb = (short *)DSET_ARRAY(Opt->mset,0); for (j=0; j<DSET_NVOX(Opt->mset); ++j) { sb[j] = (short)mm[j]; } free(mm); mm=NULL; } else if (!(Opt->mset = Seg_load_dset( Opt->mset_name ))) { SUMA_RETURN(1); } } /* reference classes */ if (Opt->gold_name) { if (!(Opt->gold = Seg_load_dset( Opt->gold_name ))) { SUMA_RETURN(1); } } if (Opt->gold_bias_name) { if (!(Opt->gold_bias = Seg_load_dset( Opt->gold_bias_name ))) { SUMA_RETURN(1); } } if (!Opt->clss) { SUMA_S_Err("Need -classes option"); SUMA_RETURN(1); } /* Talk ? */ if (Opt->ps->cs->talk_suma) { Opt->ps->cs->istream = SUMA_BRAINWRAP_LINE; Opt->ps->cs->afni_istream = SUMA_AFNI_STREAM_INDEX2; if (!SUMA_SendToAfni (Opt->ps->cs, NULL, 0)) { SUMA_SL_Err("Failed to initialize SUMA_SendToAfni"); Opt->ps->cs->afni_Send = NOPE; Opt->ps->cs->Send = NOPE; } else { /* send in_vol to afni */ SUMA_SL_Note("Sending anat volume to AFNI"); SS2A.dset = Opt->aset; SS2A.at_sb=-1; if (!SUMA_SendToAfni(Opt->ps->cs, &SS2A, 1)) { SUMA_SL_Err("Failed to send volume to AFNI"); Opt->ps->cs->afni_Send = NOPE; } } } /* classified set ? */ if (Opt->this_cset_name) { /* user supplied initializer */ if (!(Opt->cset = Seg_load_dset( Opt->this_cset_name ))) { SUMA_RETURN(1); } } /* labeltable? */ if (Opt->labeltable_name) { Dtable *vl_dtable=NULL; char *labeltable_str=NULL; int kk=0; /* 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"); } CLASS_KEYS_FROM_LT(vl_dtable); destroy_Dtable(vl_dtable); vl_dtable=NULL; } if (!Opt->keys) { Dtable *vl_dtable=NULL; if (Opt->cset && (vl_dtable = DSET_Label_Dtable(Opt->cset))) { if (Opt->debug) SUMA_S_Note("Getting keys from -cset dataset"); /* try getting keys from cset */ CLASS_KEYS_FROM_LT(vl_dtable); /* Do not delete vl_dtable, it is the same pointer in Opt->cset */ } else { /* 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; } } } /* Make sure you have no negative values and requesting bias field correction. The implementation uses log() for this so the negative values would be ill advised */ { float amin, amax; THD_subbrick_minmax(Opt->aset, 0, 1,&amin, &amax); if (amin < 0 && Opt->bias_param > 0) { SUMA_S_Err("Cannot use field bias correction on volumes with negative\n" "values. Either turn off bias field estimation with -bias_fwhm 0.0\n" "or shift the values of the input by something like:\n" " 3dcalc -a %s -expr 'a+bool(a)*%d' -prefix SHIFTED\n" "and rerun the segmentation on SHIFTED. Note the suggested shift\n" "leaves zero values unchanged.", DSET_HEADNAME(Opt->aset), (int)ceil(-amin+1.0)); exit(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 (Opt->clss->num < 2) { if (Opt->debug <= 1) { SUMA_S_Note("Class-->key map"); SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys); } SUMA_S_Err("Less than 2 classes? I am out of here"); SUMA_RETURN(0); } /* Mask setup */ if (Opt->debug > 1) { SUMA_S_Note("MaskSetup"); } Opt->cmask = MaskSetup(Opt, Opt->aset, 1, &(Opt->mset), &(Opt->cmask), Opt->dimcmask, Opt->mask_bot, Opt->mask_top, &(Opt->cmask_count)); if (Opt->VoxDbg >= 0) { SUMA_S_Note("DBG setup"); fprintf(Opt->VoxDbgOut, "Command:"); for (i=0; i<argc; ++i) { fprintf(Opt->VoxDbgOut, "%s ", argv[i]); } fprintf(Opt->VoxDbgOut, "\nDebug info for voxel %d\n", Opt->VoxDbg); } Opt->cs = SUMA_New_Class_Stat(Opt->clss->str, Opt->clss->num, Opt->keys, 3, NULL); /* Load prob. of class given features */ if (Opt->priCgAname && strcmp(Opt->priCgAname, "INIT_MIXFRAC")) { if (!(Opt->priCgA = Seg_load_dset(Opt->priCgAname))) { SUMA_S_Errv("Failed to read priCgA %s\n", Opt->priCgAname); SUMA_RETURN(1); } if (GRID_MISMATCH(Opt->priCgA, Opt->aset)) { SUMA_S_Err("All input data must have same grid (-priCgA != -aset)"); SUMA_RETURN(1); } /* Make sure dset is properly formatted */ if (!SUMA_ShortizeProbDset(&Opt->priCgA, Opt->cs, Opt->cmask, Opt->cmask_count, Opt, &Opt->priCgA)) { SUMA_S_Errv("Failed to shortize priCgA %s\n", Opt->priCgAname); SUMA_RETURN(1); } /* set the floor of the input dset */ if (0) { SUMA_S_Note("Setting probability floor, USEFULNESS NOT TESTED..."); if (!set_p_floor(Opt->priCgA, 0.1, Opt->cmask)) { SUMA_S_Errv("Failed to set p floor for priCgA %s\n", Opt->priCgAname); SUMA_RETURN(1); } } } else { /* uniform probability */ } /* Load prob. of class given location */ if (Opt->priCgLname && strcmp(Opt->priCgLname, "INIT_MIXFRAC")) { if (!(Opt->priCgL = Seg_load_dset(Opt->priCgLname))) { SUMA_S_Errv("Failed to read priCgL %s\n", Opt->priCgLname); SUMA_RETURN(1); } if (GRID_MISMATCH(Opt->priCgL, Opt->aset)) { SUMA_S_Err("All input data must have same grid (-priCgL != -aset)"); SUMA_RETURN(1); } /* Make sure dset is properly formatted */ if (!SUMA_ShortizeProbDset(&Opt->priCgL, Opt->cs, Opt->cmask, Opt->cmask_count, Opt, &Opt->priCgL)) { SUMA_S_Errv("Failed to shortize priCgL %s\n", Opt->priCgLname); SUMA_RETURN(1); } } else { /* uniform probability */ } /* check on weights of priors */ if (Opt->wA >= 0.0 && Opt->wL < 0.0) { Opt->wL = 1.0 - Opt->wA; } else if (Opt->wL >= 0.0 && Opt->wA < 0.0) { Opt->wA = 1.0 - Opt->wL; } else if (Opt->wA < 0.0 && Opt->wL < 0.0) { /* defaults */ Opt->wA = 0.5; Opt->wL = 0.5; } ff = Opt->wA+Opt->wL; Opt->wA = Opt->wA/ff; Opt->wL = Opt->wL/ff; if (!Opt->cset) { if (!SUMA_SegInitCset(Opt->aset, &Opt->cset, Opt->cmask, Opt->cmask_count, Opt->mixopt, Opt->cs, Opt)) { SUMA_S_Err("Failed to get initializer"); SUMA_RETURN(1); } } if (Opt->debug > 1) { SUMA_Seg_Write_Dset(Opt->proot, "classes_init", Opt->cset, -1, Opt->hist); } /* Now add the 'OTHER' class if needed */ if (Opt->Other) { if (!SUMA_AddOther( Opt->clss, &Opt->keys, Opt->cmask, Opt->cmask_count, Opt->cset, Opt->pstCgALL, Opt->priCgA, Opt->priCgL, Opt->cs)) { SUMA_S_Err("Failed to add other"); SUMA_RETURN(0); } } /* store mixfrac in class stats */ for (i=0;i<Opt->cs->N_label; ++i) { if ((ff = SUMA_mixopt_2_mixfrac(Opt->mixopt, Opt->cs->label[i], Opt->cs->keys[i], Opt->cs->N_label, Opt->cmask, Opt->cset))<0.0) { SUMA_S_Errv("Can't get mixfrac for %s\n", Opt->mixopt); SUMA_RETURN(1); } SUMA_set_Stat(Opt->cs, Opt->cs->label[i], "init.mix", ff); SUMA_set_Stat(Opt->cs, Opt->cs->label[i], "mix", ff); } /* Now call the workhorse */ if (!SUMA_SegEngine(Opt)) { SUMA_S_Err("Failed in SUMA_SegEngine"); exit(1); } /* write output */ if (Opt->Bset && !Opt->this_fset_name) { tross_Append_History(Opt->Bset, Opt->hist); SUMA_Seg_Write_Dset(Opt->proot, "BiasField", /* DSET_PREFIX(Opt->Bset) */ Opt->Bset, -1, Opt->hist); } if (Opt->xset && !Opt->this_xset_name) { AFNI_FEED(Opt->ps->cs, "BiasCorrect", -1, Opt->xset); SUMA_Seg_Write_Dset(Opt->proot, "AnatUB", /* DSET_PREFIX(Opt->xset)*/ Opt->xset, -1, Opt->hist); } if (Opt->cset) { SUMA_Seg_Write_Dset(Opt->proot, "Classes", /* Opt->crefix */ Opt->cset, -1, Opt->hist); AFNI_FEED(Opt->ps->cs, "FinalClasses", -1, Opt->cset); } if (Opt->pstCgALL) { SUMA_Seg_Write_Dset(Opt->proot, "Posterior", /* Opt->prefix */ Opt->pstCgALL, -1, Opt->hist); AFNI_FEED(Opt->ps->cs, "pstCgALL-final", -1, Opt->pstCgALL); } if (Opt->aset) { SUMA_Seg_Write_Dset(Opt->proot, "Anat", Opt->aset, -1, Opt->hist); } if (Opt->debug) SUMA_S_Note("Writing Unmodulated output"); if (!(SUMA_pst_C_giv_ALL(Opt->xset, Opt->cmask, Opt->cmask_count, Opt->cs, NULL, NULL, Opt->B, Opt->T, 0, &Opt->pstCgALL))) { SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL unmodulated"); SUMA_RETURN(1); } SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.p", Opt->pstCgALL, -1, Opt->hist); if (!(SUMA_assign_classes( Opt->pstCgALL, Opt->cs, Opt->cmask, &Opt->cset))) { SUMA_S_Err("Failed in assign_classes"); SUMA_RETURN(1); } SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.c", Opt->cset, -1, Opt->hist); /* all done, free */ Opt = free_SegOpts(Opt); PRINT_COMPILE_DATE ; SUMA_RETURN(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) { static char FuncName[]={"3dGenFeatureDist"}; SEG_OPTS *Opt=NULL; char *atr=NULL, sbuf[512], *methods=NULL; int cc, /* class counter */ kk, /* key counter */ aa, /* feature counter */ nn, /* sub-brick index */ vv, /* voxel index */ ss, /* subjects counter */ iii, /* dummy counter */ nbins, /* number of bins */ *ifeat=NULL, key, **N_alloc_FCset=NULL, /* Number of values allocated for each vector in FCset */ **N_FCset=NULL, /* Number of filled values for each vector in FCset */ N_ffalloc=0, N_ff, isneg=0, missfeatwarn=-1 /* Missing feature warning for some subject */; float fsf=0.0, fsb=0.0, ***FCset=NULL, /* Table holding samples for each feature/class combo */ hrange[2]={-3.0, 3.0}, bwidth1=0.05, bwidth=0.0, *ff=NULL; short *sf=NULL, *sb=NULL; byte **masks=NULL; SUMA_HIST ***hh=NULL, **hf=NULL; double ff_m, ff_s; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = GenFeatureDist_Default(argv, argc); Opt = GenFeatureDist_ParseInput (Opt, argv, argc); Opt->hist = tross_commandline( FuncName , argc , argv ) ; if (!GenFeatureDist_CheckOpts(Opt)) { ERROR_exit("Failed on option check"); } /* 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 (cc=0; cc<Opt->clss->num; ++cc) { if ((key = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[cc]))<0){ ERROR_exit("Key not found in %s for %s ", Opt->labeltable_name, Opt->clss->str[cc]); } if (Opt->keys) { if (Opt->keys[cc]!=key) { ERROR_exit("Key mismatch %d %d", Opt->keys[cc], key); } } } if (!Opt->keys) { /* get them from table */ Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int)); for (cc=0; cc<Opt->clss->num; ++cc) { if ((key = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[cc]))<0){ ERROR_exit("(should noy happen) Key not found in %s for %s ", Opt->labeltable_name, Opt->clss->str[cc]); } Opt->keys[cc] = key; } } destroy_Dtable(vl_dtable); vl_dtable=NULL; } if (!Opt->keys) { /* add default keys */ SUMA_S_Note("Keys not available, assuming defaults"); Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int)); for (cc=0; cc<Opt->clss->num; ++cc) { Opt->keys[cc] = cc+1; } } /* Show the match between keys and classes */ SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys); /* For each feature, each class, collect the values */ SUMA_S_Notev("Collecting data from %d subjects\n", Opt->sig_names->num); missfeatwarn = -1; for (ss=0; ss<Opt->sig_names->num; ++ss) { /* for each subject */ /* load the input data */ if (!(Opt->sig = Seg_load_dset( Opt->sig_names->str[ss] ))) { exit(1); } if (Opt->debug > 1) { SUMA_S_Notev("Have %d sub-bricks in signatures of dude %d\n", DSET_NVALS(Opt->sig), ss); } if (ss == 0) { /* some setup based on initial grid */ if (!Opt->feats) { /* create features from signature */ char *allfeats=NULL; for (nn=0; nn<DSET_NVALS(Opt->sig); ++nn) { allfeats = SUMA_append_replace_string(allfeats, DSET_BRICK_LABEL(Opt->sig,nn),";", 1); } Opt->feats = NI_strict_decode_string_list(allfeats,";, "); SUMA_free(allfeats); allfeats=NULL; } SUMA_S_Notev("Have to work with %d classes, %d features\n", Opt->clss->num, Opt->feats->num); SUMA_S_Note("Initializing storage"); /* Receptacles for all observations for each feature and class combination */ FCset = (float ***)SUMA_calloc(Opt->feats->num, sizeof(float **)); N_FCset = (int **)SUMA_calloc(Opt->feats->num, sizeof(int *)); N_alloc_FCset = (int **)SUMA_calloc(Opt->feats->num, sizeof(int *)); ifeat = (int *)SUMA_calloc(Opt->feats->num, sizeof(int)); for (aa=0; aa<Opt->feats->num; ++aa) { FCset[aa] = (float **)calloc(Opt->clss->num, sizeof(float *)); N_FCset[aa] = (int *)SUMA_calloc(Opt->clss->num, sizeof(int)); N_alloc_FCset[aa] = (int *)SUMA_calloc(Opt->clss->num, sizeof(int)); } masks = (byte **)SUMA_calloc(Opt->sig_names->num, sizeof (byte *)); /* Fix VoxDbg */ if (Opt->VoxDbg >= 0) { Vox1D2Vox3D(Opt->VoxDbg, DSET_NX(Opt->sig), DSET_NX(Opt->sig)*DSET_NY(Opt->sig), Opt->VoxDbg3); } else if (Opt->VoxDbg3[0]>=0) { Opt->VoxDbg = Opt->VoxDbg3[0] + Opt->VoxDbg3[1]*DSET_NX(Opt->sig) + Opt->VoxDbg3[2]*DSET_NX(Opt->sig)*DSET_NY(Opt->sig); } } /* allocate for mask which will be non-zero whenever a voxel is in at least 1 mask. It will have the 1st assignment */ masks[ss] = (byte *)SUMA_calloc(DSET_NVOX(Opt->sig), sizeof(byte)); /* create mapping between feature names and sub-briks */ for (aa=0; aa<Opt->feats->num; ++aa) { ifeat[aa] = 0; while (ifeat[aa] < DSET_NVALS(Opt->sig) && strcmp(DSET_BRICK_LABEL(Opt->sig,ifeat[aa]), Opt->feats->str[aa])) ++ifeat[aa]; if (ifeat[aa] >= DSET_NVALS(Opt->sig)) ifeat[aa]=-1; if (Opt->debug > 1) { SUMA_S_Notev("Have feature %s in sub-brick %d\n", Opt->feats->str[aa], ifeat[aa]); } } SUMA_S_Notev("Loading sample classes for subject #%d\n", ss); if (!(Opt->samp = Seg_load_dset( Opt->samp_names->str[ss] ))) { exit(1); } if (THD_dataset_mismatch(Opt->samp, Opt->sig)) { SUMA_S_Err( "Grid mismatch between -samp [%dx%dx%d] and \n" " -sig [%dx%dx%d] volumes for pair #%d\n", DSET_NX(Opt->samp), DSET_NY(Opt->samp), DSET_NZ(Opt->samp), DSET_NX(Opt->sig), DSET_NY(Opt->sig), DSET_NZ(Opt->sig), ss); exit(1); } if (Opt->debug > 1) { SUMA_S_Notev("Have %d sub-bricks in samples of dude %d\n", DSET_NVALS(Opt->samp), ss); } /* Now collect features for each class */ SUMA_S_Note("Collecting features for each class"); for (cc=0; cc<Opt->clss->num; ++cc) { if (Opt->debug > 1) { SUMA_S_Notev("Working class %s\n", Opt->clss->str[cc]); } key = Opt->keys[cc]; for (nn=0; nn<DSET_NVALS(Opt->samp); ++nn) { if (Opt->debug > 2) { SUMA_S_Notev("Looking for key %d for class %s in sb %d\n", key, Opt->clss->str[cc], nn); } sb = (short *)DSET_ARRAY(Opt->samp,nn); fsb = DSET_BRICK_FACTOR(Opt->samp,nn); if (fsb == 0.0) fsb = 1.0; if (fsb != 1.0) { SUMA_S_Err("Non-integral dset, possibly."); exit(1); } for (vv=0; vv<DSET_NVOX(Opt->samp); ++vv) { if (sb[vv] == key) { for (aa=0; aa<Opt->feats->num; ++aa) { if (ifeat[aa]>-1) { if (N_alloc_FCset[aa][cc] <= N_FCset[aa][cc]) { N_alloc_FCset[aa][cc] += 10000; FCset[aa][cc] = (float*)SUMA_realloc(FCset[aa][cc], N_alloc_FCset[aa][cc]*sizeof(float)); } sf = (short *)DSET_ARRAY(Opt->sig, ifeat[aa]); fsf = DSET_BRICK_FACTOR(Opt->sig,ifeat[aa]); if (fsf == 0.0) fsf = 1.0; FCset[aa][cc][N_FCset[aa][cc]] = sf[vv]*fsf; ++N_FCset[aa][cc]; if (!masks[ss][vv]) { masks[ss][vv] = (short)key; /* fcfs */ /* in case we exceed short range */ if (masks[ss][vv]) masks[ss][vv] = 1; } } else { if (missfeatwarn != ss) { SUMA_S_Warnv("Feature %s not found in subject %d\n", Opt->feats->str[aa], ss); missfeatwarn = ss; } } } } } } } DSET_delete(Opt->sig); Opt->sig=NULL; DSET_delete(Opt->samp); Opt->samp=NULL; } /* loop across all subjects */ /* compute histograms of features across all classes and save them */ hf = (SUMA_HIST **)SUMA_calloc(Opt->feats->num, sizeof(SUMA_HIST *)); SUMA_S_Note("Computing histograms of features across all classes"); ff = NULL; N_ffalloc = 0; for (aa=0; aa<Opt->feats->num; ++aa) { N_ff=0; for (cc=0; cc<Opt->clss->num; ++cc) { N_ff += N_FCset[aa][cc]; /* more than I need because same voxel can belong to multiple classes, but just to be safe */ } if (N_ffalloc < N_ff) { N_ffalloc = N_ff; if (ff) SUMA_free(ff); ff=NULL; if (!(ff = (float*)SUMA_calloc(N_ff, sizeof(float)))) { SUMA_S_Crit("Failed to allocate"); exit(1); } } N_ff=0; isneg = 0; ff_m=0.0; for (ss=0; ss<Opt->sig_names->num; ++ss) { /* Once again, unfortunately */ /* load the input data */ if (!(Opt->sig = Seg_load_dset( Opt->sig_names->str[ss] ))) { exit(1); } if (Opt->debug > 1) { SUMA_S_Notev("Have %d sub-bricks in signatures of dude %d\n", DSET_NVALS(Opt->sig), ss); } if (ifeat[aa]>-1) { sb = (short *)DSET_ARRAY(Opt->sig,ifeat[aa]); fsb = DSET_BRICK_FACTOR(Opt->sig,ifeat[aa]); if (fsb == 0.0) fsb = 1.0; for (vv=0; vv<DSET_NVOX(Opt->sig); ++vv) { if (masks[ss][vv]) { ff[N_ff] = sb[vv]*fsb; if (ff[N_ff] < 0) ++isneg; ff_m += ff[N_ff]; ++N_ff; } } } DSET_delete(Opt->sig); Opt->sig=NULL; } ff_m /= N_ff; ff_s=0.0; for (iii=0; iii<N_ff; ++iii) { ff_s += SUMA_POW2(ff[iii]-ff_m); } ff_s = sqrt(ff_s/N_ff); sprintf(sbuf, "h(%s)",Opt->feats->str[aa]); /* Check if you have user specified binning specs */ bwidth = -1; nbins = -1; for (iii=0; iii<Opt->N_hspec; ++iii) { if (!strcmp(Opt->feats->str[aa], Opt->hspec[iii]->label)) { hrange[0] = Opt->hspec[iii]->min; hrange[1] = Opt->hspec[iii]->max; nbins = Opt->hspec[iii]->K; bwidth = 0; methods = "hands off sir"; break; } } if (bwidth < 0) { int nmatch = -1; /* Check the wildcard option */ for (iii=0; iii<Opt->N_hspec; ++iii) { if ((nmatch = SUMA_is_wild_hspec_label(Opt->hspec[iii]->label))>=0) { if (!nmatch || !strncmp(Opt->feats->str[aa], Opt->hspec[iii]->label, nmatch)) { SUMA_S_Note("Feature %s matched with hspec %s\n", Opt->feats->str[aa], Opt->hspec[iii]->label); hrange[0] = Opt->hspec[iii]->min; hrange[1] = Opt->hspec[iii]->max; nbins = Opt->hspec[iii]->K; bwidth = 0; methods = "hands woff sir"; break; } } } } if (bwidth < 0) { /* no user specs found */ nbins = 0; methods = "Range|OsciBinWidth"; if ((float)isneg/(float)N_ff*100.0 > 1.0) { hrange[0] = ff_m-3*ff_s; hrange[1] = ff_m+3*ff_s; bwidth = bwidth1*ff_s; } else if (ff_m-3*ff_s > 0) { hrange[0] = ff_m-3*ff_s; hrange[1] = ff_m+3*ff_s; bwidth = bwidth1*ff_s; } else { hrange[0] = 0; hrange[1] = 6.0*ff_s/2.0; bwidth = bwidth1*ff_s/2.0; } } SUMA_S_Notev("Feature %s: mean %f, std %f\n" "Hist params: [%f %f], binwidth %f\n", Opt->feats->str[aa], ff_m, ff_s, hrange[0], hrange[1], bwidth); if (!(hf[aa] = SUMA_hist_opt(ff, N_ff, nbins, bwidth, hrange, sbuf, 1, 0.1, methods))) { SUMA_S_Errv("Failed to generate histogram for %s. \n" "This will cause trouble at classification.\n", Opt->feats->str[aa]); } else { if ((float)hf[aa]->N_ignored/(float)hf[aa]->n > 0.05) { SUMA_S_Warnv("For histogram %s, %.2f%% of the samples were\n" "ignored for being outside the range [%f %f]\n", Opt->feats->str[aa], 100*(float)hf[aa]->N_ignored/(float)hf[aa]->n, hf[aa]->min, hf[aa]->max); } if (Opt->debug > 1) SUMA_Show_hist(hf[aa], 1, NULL); /* save the histogram */ if (!SUMA_write_hist(hf[aa], SUMA_hist_fname(Opt->proot, Opt->feats->str[aa], NULL, 0))) { SUMA_S_Errv("Failed to write histog to %s\n", sbuf); } } } if (ff) SUMA_free(ff); ff = NULL; /* Compute histograms of features per class && save them*/ hh = (SUMA_HIST ***)SUMA_calloc(Opt->feats->num, sizeof(SUMA_HIST **)); for (aa=0; aa<Opt->feats->num; ++aa) { hh[aa] = (SUMA_HIST **)SUMA_calloc(Opt->clss->num, sizeof(SUMA_HIST *)); } SUMA_S_Note("Computing histograms of features per class"); for (cc=0; cc<Opt->clss->num; ++cc) { if (N_FCset[0][cc] < 10) { SUMA_S_Errv("Requested class %s (%d) has just %d samples.\n" "Not enough to grease your pan.\n", Opt->clss->str[cc], Opt->keys[cc], N_FCset[0][cc]); exit(1); } for (aa=0; aa<Opt->feats->num; ++aa) { sprintf(sbuf, "h(%s|%s)",Opt->feats->str[aa], Opt->clss->str[cc]); hrange[0] = hf[aa]->min; hrange[1] = hf[aa]->max; /* Do not optimize hist range and binwidth anymore, but allow smoothing. This is needed when a particular class has very few samples */ if (!(hh[aa][cc] = SUMA_hist_opt(FCset[aa][cc], N_FCset[aa][cc], hf[aa]->K, hf[aa]->W, hrange, sbuf, 1, 0.1, "OsciSmooth"))) { SUMA_S_Errv("Failed to generate histogram for %s|%s. \n" "This will cause trouble at classification.\n", Opt->feats->str[aa], Opt->clss->str[cc]) } else { if (Opt->debug > 1) SUMA_Show_hist(hh[aa][cc], 1, NULL); /* save the histogram */ if (!SUMA_write_hist(hh[aa][cc], SUMA_hist_fname(Opt->proot, Opt->feats->str[aa], Opt->clss->str[cc], 0))) { SUMA_S_Errv("Failed to write histog to %s\n", sbuf); } } } } SUMA_S_Note("Computing Correlation matrices"); /* L2 normalize all of FCset */ for (cc=0; cc<Opt->clss->num; ++cc) { for (aa=0; aa<Opt->feats->num; ++aa) { THD_normalize(N_FCset[aa][cc], FCset[aa][cc]); } } { NI_element **CC=NULL; float *fm=NULL, *fn=NULL; NI_element *nel = NULL; int suc; /* Compute the correlation matrices for each class */ CC = (NI_element **) SUMA_calloc(Opt->clss->num, sizeof(NI_element *)); for(cc=0; cc<Opt->clss->num; ++cc) { sprintf(sbuf, "CorrMat(%s)", Opt->clss->str[cc]); CC[cc] = NI_new_data_element(sbuf, Opt->feats->num); NI_set_attribute(CC[cc],"Measure","correlation"); atr = SUMA_NI_str_ar_2_comp_str(Opt->feats, " ; "); NI_set_attribute(CC[cc],"ColumnLabels", atr);SUMA_free(atr); atr = NULL; atr = SUMA_HistString (FuncName, argc, argv, NULL); NI_set_attribute(CC[cc],"CommandLine", atr);SUMA_free(atr); atr = NULL; for (aa=0; aa<Opt->feats->num; ++aa) { NI_add_column_stride ( CC[cc], NI_FLOAT, NULL, 1 ); } for (aa=0; aa<Opt->feats->num; ++aa) { fm = (float*)CC[cc]->vec[aa]; for (iii=0; iii<aa; ++iii) fm[iii] = 0.0; /* will fill later */ fm[aa]=1.0; for (iii=aa+1; iii<Opt->feats->num; ++iii) { if (N_FCset[aa][cc]!=N_FCset[iii][cc]) { SUMA_S_Errv("Sanity check failed, %d != %d\n", N_FCset[aa][cc], N_FCset[iii][cc]); } SUMA_DOTP_VEC(FCset[aa][cc], FCset[iii][cc], fm[iii], N_FCset[aa][cc], float, float); } } /* Now fill the remainder */ for (aa=0; aa<Opt->feats->num; ++aa) { fm = (float*)CC[cc]->vec[aa]; for (iii=0; iii<aa; ++iii) { fn = (float*)CC[cc]->vec[iii]; fm[iii] = fn[aa]; } } snprintf(sbuf, 510, "file:%s.niml.cormat", SUMA_corrmat_fname(Opt->proot, Opt->clss->str[cc], 0)); NEL_WRITE_TXH(CC[cc], sbuf, suc); } } /* free everything */ if (FCset) { for (aa=0; aa<Opt->feats->num; ++aa) { for (cc=0; cc<Opt->clss->num; ++cc) { if (FCset[aa][cc]) SUMA_free(FCset[aa][cc]); } SUMA_free(FCset[aa]); } SUMA_free(FCset); FCset=NULL; } if (N_FCset) { for (aa=0; aa<Opt->feats->num; ++aa) { SUMA_free(N_FCset[aa]); } SUMA_free(N_FCset); N_FCset=NULL; } if (N_alloc_FCset) { for (aa=0; aa<Opt->feats->num; ++aa) { SUMA_free(N_alloc_FCset[aa]); } SUMA_free(N_alloc_FCset); N_alloc_FCset=NULL; } if (ifeat) SUMA_free(ifeat); ifeat=NULL; if (hh) { for (aa=0; aa<Opt->feats->num; ++aa) { for (cc=0; cc<Opt->clss->num; ++cc) { if (hh[aa][cc]) hh[aa][cc] = SUMA_Free_hist(hh[aa][cc]); } SUMA_free(hh[aa]); } SUMA_free(hh); hh=NULL; } if (hf) { for (aa=0; aa<Opt->feats->num; ++aa) { if (hf[aa]) hf[aa] = SUMA_Free_hist(hf[aa]); } SUMA_free(hf); hf=NULL; } if (masks) { for (ss=0; ss<Opt->sig_names->num; ++ss) { if (masks[ss]) SUMA_free(masks[ss]); } masks[ss]=NULL; } SUMA_S_Notev("\n" "Consider running this script to examine the distributions:\n" " @ExamineGenFeatDists -fdir %s -odir %s\n", Opt->proot, Opt->proot); /* all done, free */ Opt = free_SegOpts(Opt); PRINT_COMPILE_DATE ; exit(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); }
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); }
byte *MaskSetup(SEG_OPTS *Opt, THD_3dim_dataset *aset, int mask_zero_aset, THD_3dim_dataset **msetp, byte **cmaskp, int dimcmask, float mask_bot, float mask_top, int *mcount) { static char FuncName[]={"MaskSetup"}; byte *mmm=NULL; int ii=0, kk=0, Fixit=0; byte *cmask = NULL; THD_3dim_dataset *mset = NULL; float *fa=NULL; MRI_IMAGE *imin=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_ENTRY; /* ------------- Mask business -----------------*/ if (!aset) { SUMA_S_Err("Null aset?"); SUMA_RETURN(NULL); } if (cmaskp) cmask = *cmaskp; if (msetp) mset = *msetp; if (Opt->mset_name && !strcmp(Opt->mset_name,"VOX_DEBUG")) { /* Just the debugging voxel man! */ if (Opt->VoxDbg >= 0) { if (Opt->VoxDbg < DSET_NVOX(aset)) { SUMA_S_Note("Mask consists of voxel %d only", Opt->VoxDbg); mmm = (byte *)calloc( DSET_NVOX(aset), sizeof(byte)); mmm[Opt->VoxDbg]=1; *mcount = 1; } else { SUMA_S_Err("VoxDbg (%d) > #voxels (%d) in dset", Opt->VoxDbg, DSET_NVOX(aset)); ERROR_exit("No reason to proceed"); } } else { SUMA_S_Err("Used VOX_DEBUG for -mask but no -vox_debug entry.\n" "Ignoring masking, all %d voxels in the dataset will\n" "be used.", DSET_NVOX(aset)) ; ERROR_exit("Goodbye cruel world"); } } else { if( mset == NULL ){ mmm = NULL ; if( Opt->debug ) INFO_message("%d voxels in the entire dataset (no mask)\n", DSET_NVOX(aset)) ; *mcount = DSET_NVOX(aset); } else { if( DSET_NVOX(mset) != DSET_NVOX(aset) ) ERROR_exit("Input and mask datasets are not same dimensions!\n"); mmm = THD_makemask( mset , 0 , mask_bot, mask_top ) ; *mcount = THD_countmask( DSET_NVOX(mset) , mmm ) ; if( *mcount <= 0 ) { ERROR_message("No voxels in the mask!\n") ; SUMA_RETURN(NULL); } if( Opt->debug ) INFO_message("%d voxels in the mask\n",*mcount) ; DSET_delete(mset); *msetp=NULL; } } if( cmask != NULL ){ SUMA_LH("Merging with cmask"); if( dimcmask != DSET_NVOX(aset) ) ERROR_exit("Input and cmask datasets are not same dimensions!\n"); if( mmm != NULL ){ for( ii=0 ; ii < DSET_NVOX(aset) ; ii++ ) mmm[ii] = (mmm[ii] && cmask[ii]) ; free(cmask) ; *cmaskp=NULL; *mcount = THD_countmask( DSET_NVOX(aset) , mmm ) ; if( *mcount <= 0 ) { ERROR_message("No voxels in the mask+cmask!\n") ; SUMA_RETURN(NULL); } if( Opt->debug ) INFO_message("%d voxels in the mask+cmask\n",*mcount) ; } else { mmm = cmask ; *mcount = THD_countmask( DSET_NVOX(aset) , mmm ) ; if( *mcount <= 0 ) { ERROR_message("No voxels in the cmask!\n") ; SUMA_RETURN(NULL); } if( Opt->debug ) INFO_message("%d voxels in the cmask\n",*mcount) ; } } /* Make sure that aset has no exact 0s that are in the mask Unless had VOX_DEBUG for mask */ if (mask_zero_aset) { if (Opt->mset_name && strcmp(Opt->mset_name,"VOX_DEBUG")) { imin = THD_extract_float_brick(0,aset) ; fa = MRI_FLOAT_PTR(imin); Fixit = 0; for( ii=0 ; ii < DSET_NVOX(aset) && !Fixit; ii++ ) { if (IN_MASK(mmm, ii) && fa[ii] == 0.0) { Fixit = 1; } } } if (Fixit) { SUMA_LH("Have to merge mask with anat"); if (!mmm) { mmm = (byte *)malloc(DSET_NVOX(aset)*sizeof(byte)); memset(mmm, 1, sizeof(byte)*DSET_NVOX(aset)); *mcount = DSET_NVOX(aset); } for( ii=0 ; ii < DSET_NVOX(aset); ii++ ) { if (IN_MASK(mmm, ii) && fa[ii] == 0.0) { mmm[ii] = 0; *mcount = *mcount - 1; } } } if (imin) mri_free(imin); imin = NULL; fa = NULL; } SUMA_RETURN(mmm); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"MakeColorMap"}; char *fscolutname = NULL, *FidName = NULL, *Prfx = NULL, h[9], *StdType=NULL, *dbfile=NULL, *MapName=NULL; int Ncols = 0, N_Fid = 0, kar, i, ifact, *Nind = NULL, imap = -1, MapSpecified = 0; int fsbl0, fsbl1, showfscolut, exists=0; float **Fid=NULL, **M=NULL; MRI_IMAGE *im = NULL; float *far=NULL; int AfniHex=0, freesm; int suc, idISi=0; char stmp[256], *s=NULL, *ooo=NULL, *sdset_prefix; SUMA_PARSED_NAME *sname=NULL; NI_group *ngr=NULL; SUMA_Boolean brk, SkipLast, PosMap, Usage1, Usage2, Usage3, Usage4, flipud, fscolut, LocalHead = NOPE; SUMA_COLOR_MAP *SM=NULL; SUMA_DSET_FORMAT iform; SUMA_DSET *sdset=NULL; SUMA_STANDALONE_INIT; SUMA_mainENTRY; if (argc < 2) { SUMA_MakeColorMap_usage(); exit (0); } kar = 1; freesm = 1; fscolutname = NULL; fsbl0 = -1; fsbl1 = -1; brk = NOPE; SkipLast = NOPE; AfniHex = 0; PosMap = NOPE; Usage1 = NOPE; Usage2 = NOPE; Usage3 = NOPE; Usage4 = NOPE; flipud = NOPE; fscolut = NOPE; showfscolut = 0; MapSpecified = NOPE; idISi=0; iform = SUMA_NO_DSET_FORMAT; sdset_prefix=NULL; while (kar < argc) { /* loop accross command ine options */ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { SUMA_MakeColorMap_usage(); exit (0); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); if (!brk && (strcmp(argv[kar], "-v") == 0)) { LocalHead = NOPE; brk = YUP; } if (!brk && (strcmp(argv[kar], "-flipud") == 0)) { flipud = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-f") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -f "); exit (1); } FidName = argv[kar]; Usage1 = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-fscolutfile") == 0)) { Usage4=YUP; kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -fscolutfile "); exit (1); } fscolutname = argv[kar]; if (fsbl0 < 0) { fsbl0 = 0; fsbl1 = 255; } brk = YUP; } if (!brk && (strcmp(argv[kar], "-usercolutfile") == 0)) { Usage4=YUP; kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -fscolutfile "); exit (1); } fscolutname = argv[kar]; if (fsbl0 < 0) { fsbl0 = 0; fsbl1 = -1; } idISi=1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-fscolut") == 0)) { fscolut = YUP; Usage4=YUP; kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 arguments after -fscolut "); exit (1); } fsbl0 = atoi(argv[kar]); ++kar; fsbl1 = atoi(argv[kar]); if (fsbl0 > fsbl1 || fsbl0 < -1 || fsbl1 > 10000) { SUMA_S_Errv("-fscolut values of %d and %d either\n" "do not make sense or exceed range 0 to 10000\n", fsbl0, fsbl1); exit(1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-show_fscolut") == 0)) { showfscolut = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-fn") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -fn "); exit (1); } FidName = argv[kar]; Usage2 = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-nc") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -nc "); exit (1); } Ncols = atoi(argv[kar]); Usage1 = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-ah") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -ah "); exit (1); } Prfx = argv[kar]; AfniHex = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-ahc") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -ahc "); exit (1); } Prfx = argv[kar]; AfniHex = 2; brk = YUP; } if (!brk && (strcmp(argv[kar], "-suma_cmap") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -suma_cmap"); exit (1); } Prfx = argv[kar]; AfniHex = 3; brk = YUP; } if (!brk && (strcmp(argv[kar], "-std") == 0)) { kar ++; if (MapSpecified) { SUMA_S_Err( "Color map already specified.\n" "-cmap and -std are mutually exclusive\n"); exit (1); } if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -std "); exit (1); } MapSpecified = YUP; StdType = argv[kar]; Usage3 = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-cmapdb") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -cmapdb "); exit (1); } SUMAg_CF->isGraphical = YUP; /* WILL NEED X DISPLAY TO RESOLVE COLOR NAMES */ dbfile = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-cmap") ==0)) { if (MapSpecified) { SUMA_S_Err( "Color map already specified.\n" "-cmap and -std are mutually exclusive\n"); exit (1); } MapSpecified = YUP; kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 arguments after -cmap "); exit (1); } Usage3 = YUP; MapName = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-sl") == 0)) { SkipLast = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-pos") == 0)) { /* obsolete */ PosMap = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-sdset") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need surface dataset after -sdset \n"); exit (1); } iform = SUMA_NO_DSET_FORMAT; if (!(sdset = SUMA_LoadDset_s (argv[kar], &iform, 0))) { SUMA_S_Err("Failed to load surface dset"); exit(1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-sdset_prefix") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need prefix dataset after -sdset_prefix \n"); exit (1); } sdset_prefix = argv[kar]; brk = YUP; } if (!brk) { SUMA_S_Errv("Option %s not understood. Try -help for usage\n", argv[kar]); suggest_best_prog_option(argv[0], argv[kar]); exit (1); } else { brk = NOPE; kar ++; } }/* loop accross command ine options */ /* check input */ if ( (Usage1 && (Usage2 || Usage3 || Usage4)) || (Usage2 && (Usage1 || Usage3 || Usage4)) || (Usage3 && (Usage1 || Usage2 || Usage4)) || (Usage4 && (Usage1 || Usage2 || Usage3)) ) { SUMA_S_Err("Mixing options from multiple usage modes.\n"); exit(1); } if (!Usage1 && !Usage2 && !Usage3 && !Usage4) { SUMA_S_Err("One of these options must be used:\n" "-f, -fn, -std, or -fscolut.\n"); exit(1); } /* are there database files to read */ if (dbfile) { SUMA_LH("Now trying to read db file"); 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); } } if (SUMA_AFNI_Extract_Colors ( dbfile, SUMAg_CF->scm ) < 0) { SUMA_S_Errv("Failed to read %s colormap file.\n", dbfile); exit(1); } } if (Usage1 || Usage2) { if (!SUMA_filexists (FidName)) { SUMA_S_Errv("File %s could not be found.\n", FidName); exit(1); } /* read the fiducials file */ im = mri_read_1D (FidName); if (!im) { SUMA_S_Err("Failed to read file"); exit(1); } far = MRI_FLOAT_PTR(im); N_Fid = im->nx * im->ny; } if (PosMap) { fprintf (SUMA_STDERR,"\nWarning %s: -pos option is obsolete.\n", FuncName); } /* allocate for fiducials */ if (Usage1) { if (N_Fid % 3) { fprintf (SUMA_STDERR, "Error %s: Not all rows in %s appear to have RGB triplets.\n", FuncName, FidName); exit (1); } Fid = (float **) SUMA_allocate2D (N_Fid / 3, 3, sizeof(float)); if (Fid == NULL) { fprintf (SUMA_STDERR, "Error %s: Could not allocate for Fid.\n", FuncName); exit(1); } for (i=0; i < im->nx; ++i) { Fid[i][0] = far[i]; Fid[i][1] = far[i+im->nx]; Fid[i][2] = far[i+2*im->nx]; } mri_free(im); im = NULL; /* now create the color map */ SM = SUMA_MakeColorMap (Fid, N_Fid/3, 0, Ncols, SkipLast, FuncName); if (SM == NULL) { fprintf (SUMA_STDERR, "Error %s: Error in SUMA_MakeColorMap.\n", FuncName); exit(1); } } if (Usage2) { /* second usage */ if (N_Fid % 4) { fprintf (SUMA_STDERR, "Error %s: Not all rows in %s appear to have " "RGB N quadruplets.\n", FuncName, FidName); exit (1); } Fid = (float **) SUMA_allocate2D (N_Fid / 4, 3, sizeof(float)); Nind = (int *) SUMA_calloc (N_Fid/4, sizeof(int)); if (Fid == NULL || !Nind) { fprintf (SUMA_STDERR, "Error %s: Could not allocate for Fid or Nind.\n", FuncName); exit(1); } for (i=0; i < im->nx; ++i) { Fid[i][0] = far[i]; Fid[i][1] = far[i+im->nx]; Fid[i][2] = far[i+2*im->nx]; Nind[i] = (int)far[i+3*im->nx]; } mri_free(im); im = NULL; /* now create the color map */ SM = SUMA_MakeColorMap_v2 (Fid, N_Fid/4, 0, Nind, SkipLast, FuncName); if (SM == NULL) { fprintf (SUMA_STDERR, "Error %s: Error in SUMA_MakeColorMap.\n", FuncName); exit(1); } Ncols = SM->N_M[0]; } if (Usage3) { /* third usage */ if (!MapName) { SM = SUMA_FindNamedColMap (StdType); freesm = 0; if (SM == NULL) { fprintf (SUMA_STDERR, "Error %s: Error in SUMA_MakeColorMap.\n", FuncName); exit(1); } Ncols = SM->N_M[0]; } else { imap = SUMA_Find_ColorMap ( MapName, SUMAg_CF->scm->CMv, SUMAg_CF->scm->N_maps, -2); if (imap < 0) { fprintf (SUMA_STDERR, "Error %s: Could not find colormap %s.\n", FuncName, MapName); exit (1); } SM = SUMAg_CF->scm->CMv[imap]; Ncols = SM->N_M[0]; } } if (Usage4) { /* 4th usage */ if (!(SM = SUMA_FScolutToColorMap(fscolutname, fsbl0, fsbl1, showfscolut, idISi))) { SUMA_S_Err("Failed to get FreeSurfer colormap."); exit(1); } Ncols = SM->N_M[0]; } if (flipud) { SUMA_Flip_Color_Map (SM); } M = SM->M; if (AfniHex && Ncols > 20) { if (!Usage4) { SUMA_S_Note("Writing colormap in colorscale format.\n"); } } if (!AfniHex) { SUMA_disp_mat (M, Ncols, 3, 1); /*SUMA_Show_ColorMapVec (&SM, 1, NULL, 2);*/ } else { if (Usage4 || Ncols > 20) { if (AfniHex == 1) { fprintf (stdout, "%s \n", Prfx); for (i=0; i < Ncols; ++i) { /* Now create the hex form */ r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][0]*255)), 1, 0); fprintf (stdout, "#%s", h); r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][1]*255)), 1, 0); fprintf (stdout, "%s", h); r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][2]*255)), 1, 0); fprintf (stdout, "%s \n", h); } fprintf (stdout, "\n") ; } else if (AfniHex == 2){ /* to go in the C code (see pbardef.h and pbar.c)*/ char *p2 = SUMA_copy_string(Prfx); SUMA_TO_UPPER(p2); fprintf (stdout, "static char %s[] = {\n \"%s \"\n \"", p2, Prfx); SUMA_free(p2); p2 = NULL; for (i=0; i < Ncols; ++i) { if (i) { if (!(i % 4)) { fprintf (stdout, " \"\n \""); } else { fprintf (stdout, " "); } } /* Now create the hex form */ r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][0]*255)), 1, 0); fprintf (stdout, "#%s", h); r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][1]*255)), 1, 0); fprintf (stdout, "%s", h); r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][2]*255)), 1, 0); fprintf (stdout, "%s", h); } fprintf (stdout, " \"\n};\n") ; } else if (AfniHex == 3){ SUMA_LHv("Now turn %s to niml\n", SM->Name); sname = SUMA_ParseFname(Prfx, NULL); snprintf(stmp, 128*sizeof(char), "file:%s.niml.cmap", sname->FileName_NoExt); if (SM->Name) SUMA_free(SM->Name); SM->Name = SUMA_copy_string(sname->FileName_NoExt); ngr = SUMA_CmapToNICmap(SM); NEL_WRITE_TX(ngr, stmp, suc); if (!suc) { SUMA_S_Errv("Failed to write %s\n", stmp); } SUMA_Free_Parsed_Name(sname); sname = NULL; } else { SUMA_S_Err("AfniHex should be 0, 1, or 2\n"); exit(1); } } else { fprintf (stdout, "\n***COLORS\n"); for (i=0; i < Ncols; ++i) { /* Now create the hex form */ r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][0]*255)), 1, 0); if (i<10) fprintf (stdout, "%s_0%d = #%s", Prfx, i, h); else fprintf (stdout, "%s_%d = #%s", Prfx, i, h); r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][1]*255)), 1, 0); fprintf (stdout, "%s", h); r_sprintf_long_to_hex (h, (unsigned long)rint((M[i][2]*255)), 1, 0); fprintf (stdout, "%s\n", h); } /* color map */ fprintf (stdout, "\n***PALETTES %s [%d]\n//1 to -1 range\n", Prfx, Ncols); ifact = 2; for (i=0; i < Ncols; ++i) { fprintf (stdout, "%f -> ", 1.0 - (float)(ifact*i)/Ncols); if (i<10) fprintf (stdout, "%s_0%d\n", Prfx, i); else fprintf (stdout, "%s_%d\n", Prfx, i); } fprintf (stdout, "\n***PALETTES %s [%d+]\n//1 to 0 range\n", Prfx, Ncols); ifact = 1; for (i=0; i < Ncols; ++i) { fprintf (stdout, "%f -> ", 1.0 - (float)(ifact*i)/Ncols); if (i<10) fprintf (stdout, "%s_0%d\n", Prfx, i); else fprintf (stdout, "%s_%d\n", Prfx, i); } } } /* free allocated space */ if (Usage1) { if (Fid) SUMA_free2D((char **)Fid, N_Fid / 3); } else { if (Fid) SUMA_free2D((char **)Fid, N_Fid / 4); if (Nind) SUMA_free(Nind); } /* add colormap to a surface dset ? */ if (sdset) { SUMA_DSET *idset; if (!SUMA_is_AllConsistentCastType_dset(sdset, SUMA_int)) { idset = SUMA_CoercedCopyofDset(sdset, SUMA_int, NULL); } else { idset = sdset; } if (!(SUMA_dset_to_Label_dset_cmap(idset, SM))) { SUMA_S_Err("Failed to make change"); exit(1); } s = SUMA_OutputDsetFileStatus( sdset_prefix?sdset_prefix:SDSET_FILENAME(sdset), NULL, &iform, NULL, ".lbl", &exists); SUMA_AddNgrHist(sdset->ngr, FuncName, argc, argv); ooo = SUMA_WriteDset_s(s, idset, iform, THD_ok_overwrite(), 0); SUMA_free(ooo); ooo=NULL; SUMA_free(s); s = NULL; if (idset != sdset) SUMA_FreeDset(idset); SUMA_FreeDset(sdset); sdset=NULL; } if (SM && !MapName && freesm) SUMA_Free_ColorMap(SM); if (!SUMA_Free_CommonFields(SUMAg_CF)) { SUMA_SL_Err("Failed to free commonfields."); } SUMA_RETURN (0); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"ConvertSurface"}; int kar, volexists, i, j, Doinv, randseed, Domergesurfs=0, pciref; float DoR2S, fv[3], *pcxyzref; double xcen[3], sc[3]; double xform[4][4]; char *if_name = NULL, *of_name = NULL, *if_name2 = NULL, *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL, *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL, *acpc_name=NULL, *xmat_name = NULL, *ifpar_name = NULL, *ifpar_name2 = NULL; SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, iparType = SUMA_FT_NOT_SPECIFIED, oType = SUMA_FT_NOT_SPECIFIED; SUMA_SO_File_Format iForm = SUMA_FF_NOT_SPECIFIED, iparForm = SUMA_FF_NOT_SPECIFIED, oFormat = SUMA_FF_NOT_SPECIFIED; SUMA_SurfaceObject *SO = NULL, *SOpar = NULL, *SOsurf = NULL; SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL; SUMA_SFname *SF_name = NULL; void *SO_name = NULL; char orsurf[6], orcode[6], *PCprojpref=NULL, *NodeDepthpref=NULL; THD_warp *warp=NULL ; THD_3dim_dataset *aset=NULL; SUMA_Boolean brk, Do_tlrc, Do_mni_RAI, Do_mni_LPI, Do_acpc, Docen, Do_flip; SUMA_Boolean Doxmat, Do_wind, Do_p2s, onemore, Do_native, Do_PolDec; int Do_PCproj, Do_PCrot, Do_NodeDepth; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean exists; 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, "-o;-i;-sv;-ipar;"); kar = 1; xmat_name = NULL; xcen[0] = 0.0; xcen[1] = 0.0; xcen[2] = 0.0; brk = NOPE; orcode[0] = '\0'; randseed = 1234; sprintf(orsurf,"RAI"); Docen = NOPE; Doxmat = NOPE; Do_tlrc = NOPE; Do_mni_RAI = NOPE; Do_mni_LPI = NOPE; Do_acpc = NOPE; Do_wind = NOPE; Do_flip = NOPE; Do_p2s = NOPE; Do_native = NOPE; DoR2S = 0.0; Do_PolDec = NOPE; Do_PCproj = NO_PRJ; Do_PCrot = NO_ROT; pciref = -1; pcxyzref = NULL; PCprojpref = NULL; NodeDepthpref = NULL; Do_NodeDepth = 0; Doinv = 0; Domergesurfs = 0; onemore = 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) { usage_SUMA_ConvertSurface(ps, strlen(argv[kar]) > 3 ? 2:1); exit (0); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); SUMA_TO_LOWER(argv[kar]); if (!brk && (strcmp(argv[kar], "-seed") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 integer after -seed\n"); exit (1); } randseed = atoi(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-xyzscale") == 0)) { kar ++; if (kar+2 >= argc) { fprintf (SUMA_STDERR, "need 3 values after -XYZscale\n"); exit (1); } sc[0] = strtod(argv[kar], NULL); kar ++; sc[1] = strtod(argv[kar], NULL); kar ++; sc[2] = strtod(argv[kar], NULL); xmat_name = "Scale"; Doxmat = YUP; Doinv = 0; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-xmat_1d") == 0) || (strcmp(argv[kar], "-xmat_1D") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -xmat_1D\n"); exit (1); } xmat_name = argv[kar]; Doxmat = YUP; Doinv = 0; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-ixmat_1d") == 0) || (strcmp(argv[kar], "-ixmat_1D") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -ixmat_1D\n"); exit (1); } xmat_name = argv[kar]; Doxmat = YUP; Doinv = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-polar_decomp") == 0)) { Do_PolDec = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-merge_surfs") == 0)) { Domergesurfs = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-pc_proj") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 argument after -pc_proj\n"); exit (1); } if (!strcmp(argv[kar],"PC0_plane")) Do_PCproj = E1_PLN_PRJ; else if (!strcmp(argv[kar],"PC1_plane")) Do_PCproj = E2_PLN_PRJ; else if (!strcmp(argv[kar],"PC2_plane")) Do_PCproj = E3_PLN_PRJ; else if (!strcmp(argv[kar],"PCZ_plane")) Do_PCproj = EZ_PLN_PRJ; else if (!strcmp(argv[kar],"PCY_plane")) Do_PCproj = EY_PLN_PRJ; else if (!strcmp(argv[kar],"PCX_plane")) Do_PCproj = EX_PLN_PRJ; else if (!strcmp(argv[kar],"PC0_dir")) Do_PCproj = E1_DIR_PRJ; else if (!strcmp(argv[kar],"PC1_dir")) Do_PCproj = E2_DIR_PRJ; else if (!strcmp(argv[kar],"PC2_dir")) Do_PCproj = E3_DIR_PRJ; else if (!strcmp(argv[kar],"PCZ_dir")) Do_PCproj = EZ_DIR_PRJ; else if (!strcmp(argv[kar],"PCY_dir")) Do_PCproj = EY_DIR_PRJ; else if (!strcmp(argv[kar],"PCX_dir")) Do_PCproj = EX_DIR_PRJ; else { SUMA_S_Err("Bad value of %s for -pca_proj", argv[kar]); exit(1); } ++kar; if (argv[kar][0] == '-') { SUMA_S_Err("Prefix for -pc_proj should not start with '-'.\n" "Could it be that %s is another option and \n" "the prefix was forgtotten?", argv[kar]); exit(1); } PCprojpref = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-node_depth") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need a prefix argument after -node_depth\n"); exit (1); } Do_NodeDepth = 1; if (argv[kar][0] == '-') { SUMA_S_Err("Prefix for -node_depth should not start with '-'.\n" "Could it be that %s is another option and \n" "the prefix was forgtotten?", argv[kar]); exit(1); } NodeDepthpref = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-make_consistent") == 0)) { Do_wind = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-flip_orient") == 0)) { Do_flip = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xcenter") == 0)) { kar ++; if (kar+2>= argc) { fprintf (SUMA_STDERR, "need 3 arguments after -xcenter\n"); exit (1); } xcen[0] = atof(argv[kar]); ++kar; xcen[1] = atof(argv[kar]); ++kar; xcen[2] = atof(argv[kar]); Docen = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-native") == 0)) { Do_native = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-orient_out") == 0)) { kar ++; if (kar>= argc) { fprintf (SUMA_STDERR, "need 1 argument after -orient_out\n"); exit (1); } snprintf(orcode, 4*sizeof(char), "%s", argv[kar]); if (!SUMA_ok_orstring(orcode)) { fprintf (SUMA_STDERR, "%s is a bad orientation string\n", orcode); exit (1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-radial_to_sphere") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -radial_to_sphere\n"); exit (1); } DoR2S = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-patch2surf") == 0)) { Do_p2s = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_ascii") == 0)) { oFormat = SUMA_XML_ASCII_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_b64") == 0)) { oFormat = SUMA_XML_B64_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_b64gz") == 0)) { oFormat = SUMA_XML_B64GZ_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) { Do_tlrc = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-acpc") == 0)) { Do_acpc = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-mni_rai") == 0)) { Do_mni_RAI = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-mni_lpi") == 0)) { Do_mni_LPI = YUP; brk = YUP; } if (!brk && !ps->arg_checked[kar]) { 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 ++; } } if (argc < 3) { SUMA_S_Err("Too few options"); usage_SUMA_ConvertSurface (ps, 0); exit (1); } /* transfer info from ps structure (backward compat) */ if (ps->o_N_surfnames) { of_name = ps->o_surfnames[0]; of_name2 = ps->o_surftopo[0]; oType = ps->o_FT[0]; if (oFormat == SUMA_FF_NOT_SPECIFIED) { oFormat = ps->o_FF[0]; } } if (ps->i_N_surfnames) { if_name = ps->i_surfnames[0]; if_name2 = ps->i_surftopo[0]; iType = ps->i_FT[0]; iForm = ps->i_FF[0]; } if (ps->ipar_N_surfnames) { ifpar_name = ps->ipar_surfnames[0]; ifpar_name2 = ps->ipar_surftopo[0]; iparType = ps->ipar_FT[0]; iparForm = ps->ipar_FF[0]; } if (ps->N_sv) sv_name = ps->sv[0]; if (ps->N_vp) vp_name = ps->vp[0]; /* sanity checks */ if (Do_native && orcode[0] != '\0') { SUMA_S_Err("Options -native and -orient_out are mutually exclusive"); exit(1); } if (Do_mni_LPI && Do_mni_RAI) { SUMA_S_Err("\nCombining -MNI_lpi and -MNI_rai options.\nNot good."); exit(1); } if (!if_name) { SUMA_S_Err("input surface not specified.\n"); exit(1); } if (!of_name && (Do_PCproj < 0 && !Do_NodeDepth) ) { SUMA_S_Err("output surface or projection PREFIX not specified.\n"); exit(1); } if (iType == SUMA_FT_NOT_SPECIFIED) { SUMA_S_Err("input type not recognized.\n"); exit(1); } if (oType == SUMA_FT_NOT_SPECIFIED && (Do_PCproj < 0 && !Do_NodeDepth) ) { SUMA_S_Err("output type not recognized.\n"); exit(1); } if ( oType != SUMA_GIFTI && oFormat >= SUMA_XML_SURF && oFormat <= SUMA_XML_B64GZ_SURF && (Do_PCproj < 0 && !Do_NodeDepth) ){ SUMA_S_Err("XML output options only valid with -o_gii\n"); exit(1); } if (iType == SUMA_SUREFIT) { if (!if_name2) { SUMA_S_Err("input SureFit surface incorrectly specified.\n"); exit(1); } if (sv_name && !vp_name) { SUMA_S_Err("VolParent needs the -sv option for SureFit surfaces."); exit(1); } } if (iType == SUMA_VEC) { if (!if_name2) { SUMA_S_Err("Input vec surface incorrectly specified.\n"); exit(1); } } if (( Do_mni_RAI || Do_mni_LPI) && !Do_tlrc) { SUMA_SL_Warn ( "I hope you know what you're doing.\n" "The MNI transform should only be applied to a\n" "Surface in the AFNI tlrc coordinate space.\n"); } if (Do_acpc && Do_tlrc) { SUMA_S_Err("You can't do -tlrc and -acpc simultaneously."); exit(1); } if ((Doxmat || Docen) && (Do_acpc || Do_tlrc)) { SUMA_S_Err("You can't do -tlrc or -acpc with -xmat_1D and -xcenter.\n"); exit(1); } if ((!Doxmat && Docen)) { SUMA_S_Err("You can't use -xcenter without -xmat_1D.\n"); exit(1); } if (oType == SUMA_SUREFIT) { if (!of_name2) { SUMA_S_Err("output SureFit surface incorrectly specified. \n"); exit(1); } } if (oType == SUMA_VEC) { if (!of_name2) { SUMA_S_Err("output vec surface incorrectly specified. \n"); exit(1); } } if ( ps->i_N_surfnames > 1 && !Domergesurfs) { SUMA_S_Err("Multiple surfaces specified without -merge_surfs option\n" "Nothing to do for such an input\n"); exit(1); } /* test for existence of input files */ if (!SUMA_is_predefined_SO_name(if_name, NULL, NULL, NULL, NULL) && !SUMA_filexists(if_name)) { SUMA_S_Errv("if_name %s not found.\n", if_name); exit(1); } if (if_name2) { if (!SUMA_filexists(if_name2)) { SUMA_S_Errv("if_name2 %s not found.\n", if_name2); exit(1); } } if (ifpar_name2) { if (!SUMA_filexists(ifpar_name2)) { SUMA_S_Errv("ifpar_name2 %s not found.\n", ifpar_name2); exit(1); } } if (ifpar_name) { if (!SUMA_filexists(ifpar_name)) { SUMA_S_Errv("ifpar_name %s not found.\n", ifpar_name); exit(1); } } if (xmat_name) { if (!strstr(special_xmats,xmat_name) && !SUMA_filexists(xmat_name)) { SUMA_S_Errv("xmat file %s not found.\n", xmat_name); exit(1); } } else { if (Do_PolDec) { SUMA_S_Err("-polar_decomp is useless without -xmat_1D"); exit(1); } } if (sv_name) { char *head = NULL, view[10]; head = SUMA_AfniPrefix(sv_name, view, NULL, &volexists); if (!SUMA_AfniExistsView(volexists, view) && !SUMA_filexists(sv_name)) { fprintf (SUMA_STDERR, "Error %s: volume %s not found.\n", FuncName, head); exit(1); } if (head) SUMA_free(head); head = NULL; } if ((Do_tlrc || Do_acpc) && (!sv_name)) { fprintf (SUMA_STDERR, "Error %s: -tlrc must be used with -sv option.\n", FuncName); exit(1); } if (vp_name) { if (!SUMA_filexists(vp_name)) { fprintf (SUMA_STDERR, "Error %s: %s not found.\n", FuncName, vp_name); exit(1); } } /* check for existence of output files */ if ((Do_PCproj < 0 && !Do_NodeDepth) ) { if (of_name2) { SUMA_SFname *SFname; SO_name = SUMA_2Prefix2SurfaceName (of_name, of_name2, NULL, vp_name, oType, &exists); SFname = (SUMA_SFname *)SO_name; OF_name2 = SUMA_copy_string(SFname->name_topo); OF_name = SUMA_copy_string(SFname->name_coord); } else { SO_name = SUMA_Prefix2SurfaceName (of_name, NULL, vp_name, oType, &exists); OF_name = SUMA_copy_string((char *) SO_name); } if (exists && !THD_ok_overwrite()) { if (OF_name2) fprintf (SUMA_STDERR, "Error %s: output file(s) %s and/or %s exist already.\n", FuncName, OF_name, OF_name2); else fprintf ( SUMA_STDERR, "Error %s: output file %s exists already.\n", FuncName, OF_name); exit(1); } } /* now for the real work */ if (Doxmat) { MRI_IMAGE *im = NULL; double *far=NULL; int nrow, ncol; if (!strcmp(xmat_name,"RandRigid")) { SUMA_FillRandXform(xform, randseed, 2); } else if (!strcmp(xmat_name,"RandAffine")) { SUMA_FillRandXform(xform, randseed, 3); } else if (!strcmp(xmat_name,"RandShift")) { SUMA_FillRandXform(xform, randseed, 1); } else if (!strcmp(xmat_name,"Scale")) { SUMA_FillScaleXform(xform, sc); } else if (!strcmp(xmat_name,"NegXY")) { SUMA_FillXYnegXform(xform); } else { im = mri_read_double_1D (xmat_name); if (!im) { SUMA_SLP_Err("Failed to read 1D file"); exit(1); } far = MRI_DOUBLE_PTR(im); nrow = im->nx; ncol = im->ny; if (nrow == 1) { if (ncol != 12) { SUMA_SL_Err("Mat file must have\n" "one row of 12 columns."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } i = 0; while (i < 12) { xform[i/4][0] = far[i]; ++i; xform[i/4][1] = far[i]; ++i; xform[i/4][2] = far[i]; ++i; xform[i/4][3] = far[i]; ++i; } xform[3][0] = 0.0; xform[3][1] = 0.0; xform[3][2] = 0.0; xform[3][3] = 1.0; } else { if (ncol < 4 ) { SUMA_SL_Err("Mat file must have\n" "at least 4 columns."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } if (nrow < 3 ) { SUMA_SL_Err("Mat file must have\n" "at least 3 rows."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } if (ncol > 4) { SUMA_SL_Warn( "Ignoring entries beyond 4th \n" "column in transform file."); } if (nrow > 3) { SUMA_SL_Warn( "Ignoring entries beyond 3rd\n" "row in transform file.\n"); } for (i=0; i < 3; ++i) { xform[i][0] = far[i]; xform[i][1] = far[i+nrow]; xform[i][2] = far[i+2*nrow]; xform[i][3] = far[i+3*nrow]; } xform[3][0] = 0.0; xform[3][1] = 0.0; xform[3][2] = 0.0; xform[3][3] = 1.0; } } if (LocalHead) { fprintf(SUMA_STDERR,"\n++ ConvertSurface xform:\n"); for (i=0; i < 4; ++i) { fprintf(SUMA_STDERR," %+.5f\t%+.5f\t%+.5f\t%+.5f\n", xform[i][0], xform[i][1], xform[i][2], xform[i][3]); } fprintf(SUMA_STDERR,"\n"); } mri_free(im); im = NULL; if (Doinv) { mat44 A, A0; LOAD_MAT44( A0, \ xform[0][0], xform[0][1], xform[0][2], xform[0][3], \ xform[1][0], xform[1][1], xform[1][2], xform[1][3], \ xform[2][0], xform[2][1], xform[2][2], xform[2][3] ); A = nifti_mat44_inverse(A0); UNLOAD_MAT44(A, \ xform[0][0], xform[0][1], xform[0][2], xform[0][3], \ xform[1][0], xform[1][1], xform[1][2], xform[1][3], \ xform[2][0], xform[2][1], xform[2][2], xform[2][3] ); } if (Do_PolDec) { #ifdef USE_DECOMPOSE_SHOEMAKE /* a little something to do a polar decomposition on M into M = Q*S*/ { float det, m[4][4], q[4][4], s[4][4]; char *stmp = SUMA_append_string("QS_",xmat_name); FILE *fout = fopen(stmp,"w"); SUMA_free(stmp); stmp = NULL; SUMA_S_Note("FixMe! #include above and if(1) here ..."); det = polar_decomp(M, q,s); fprintf(fout,"#[M][D]: (D is the shift)\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", M[i][0], M[i][1], M[i][2], M[i][3]); fprintf(fout,"#Q:\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], q[i][3]); fprintf(fout,"#S:\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", s[i][0], s[i][1], s[i][2], s[i][3]); fprintf(fout,"#det: %f\n", det); fprintf(fout, "#[Q][D]: A close xform to [M][D], " "without scaling.\n#M = Q*S\n"); for (i=0;i<3; ++i) fprintf(fout, "%.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], M[i][3]); fclose(fout); SUMA_free(stmp); stmp = NULL; } /* replace user's xform with orthogonal one: */ fprintf(SUMA_STDOUT,"Replacing matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", M[i][0], M[i][1], M[i][2], M[i][3]); fprintf(SUMA_STDOUT," with matrix:\n"); for (i=0;i<3; ++i) fprintf(SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], M[i][3]); for (i=0;i<3; ++i) { M[i][0] = q[i][0]; M[i][1] = q[i][1]; M[i][2] = q[i][2]; } #else {/* use the NIFTI polar decomposition function (same results as above)*/ mat33 Q, A; for (i=0;i<3;++i) { A.m[i][0] = xform[i][0]; A.m[i][1] = xform[i][1]; A.m[i][2] = xform[i][2]; } Q = nifti_mat33_polar( A ); /* replace user's xform with orthogonal one: */ fprintf(SUMA_STDOUT,"Replacing matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", xform[i][0], xform[i][1], xform[i][2], xform[i][3]); fprintf(SUMA_STDOUT," with matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", Q.m[i][0], Q.m[i][1], Q.m[i][2], xform[i][3]); for (i=0;i<3; ++i) { xform[i][0] = Q.m[i][0]; xform[i][1] = Q.m[i][1]; xform[i][2] = Q.m[i][2]; } } #endif } } if ( ps->i_N_surfnames == 1) { /* load that one surface */ SO = SUMA_Load_Surface_Object_Wrapper ( if_name, if_name2, vp_name, iType, iForm, sv_name, 1); if (!SO) { SUMA_S_Err("Failed to read input surface.\n"); exit (1); } } else if ( ps->i_N_surfnames > 1 && Domergesurfs) { SUMA_SurfaceObject **SOar=NULL; int ii; SUMA_S_Notev("Merging %d surfaces into 1\n", ps->i_N_surfnames); SOar = (SUMA_SurfaceObject **) SUMA_calloc(ps->i_N_surfnames, sizeof(SUMA_SurfaceObject *)); if (ps->N_sv > 1 || ps->N_vp > 1) { SUMA_S_Errv("Cannot handle multiple (%d) -sv or multiple (%d) -vp\n", ps->N_sv, ps->N_vp); exit(1); } for (ii = 0; ii<ps->i_N_surfnames; ++ii) { SOar[ii] = SUMA_Load_Surface_Object_Wrapper(ps->i_surfnames[ii], ps->i_surftopo[ii], vp_name, ps->i_FT[0], ps->i_FF[0], sv_name, 1); } if (!(SO = SUMA_MergeSurfs(SOar, ps->i_N_surfnames))) { SUMA_S_Err("Failed to merge"); exit(1); } for (ii = 0; ii<ps->i_N_surfnames; ++ii) { SUMA_Free_Surface_Object(SOar[ii]); SOar[ii]=NULL; } SUMA_free(SOar); SOar=NULL; } if (DoR2S > 0.0000001) { if (!SUMA_ProjectSurfaceToSphere(SO, NULL , DoR2S , NULL)) { SUMA_S_Err("Failed to project to surface"); exit(1); } } if (ifpar_name) { SOpar = SUMA_Load_Surface_Object_Wrapper ( ifpar_name, ifpar_name2, vp_name, iparType, iparForm, sv_name, 1); if (!SOpar) { SUMA_S_Err("Failed to read input parent surface.\n"); exit (1); } /* need edge list */ if (!SUMA_SurfaceMetrics_eng (SOpar,"EdgeList", NULL, 0, SUMAg_CF->DsetList)) { SUMA_SL_Err("Failed to create edgelist for parent"); exit(1); } } /* if Do_wind */ if (Do_wind) { fprintf (SUMA_STDOUT, "Checking and repairing mesh's winding consistency...\n"); /* check the winding, but that won't fix the normals, you'll have to recalculate those things, if need be ... */ if (!SUMA_SurfaceMetrics_eng (SO, "CheckWind", NULL, 0, SUMAg_CF->DsetList)) { SUMA_S_Err("Failed in SUMA_SurfaceMetrics.\n"); exit(1); } } if (Do_flip) { fprintf (SUMA_STDOUT, "Flipping triangle winding...\n"); SUMA_FlipSOTriangles(SO); } if (Do_tlrc) { fprintf (SUMA_STDOUT,"Performing talairach transform...\n"); /* form the tlrc version of the surface volume */ tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+ strlen(SO->VolPar->prefix)+60, sizeof(char)); sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix); if (!SUMA_filexists(tlrc_name)) { fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name); exit(1); } /* read the tlrc header */ aset = THD_open_dataset(tlrc_name) ; if( !ISVALID_DSET(aset) ){ SUMA_S_Err("%s is not a valid data set.\n", tlrc_name) ; exit(1); } if( aset->warp == NULL ){ SUMA_S_Err("tlrc_name does not contain a talairach transform.\n"); exit(1); } warp = aset->warp ; /* now warp the coordinates, one node at a time */ if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) { SUMA_S_Err("Failed in SUMA_AFNI_forward_warp_xyz.\n"); exit(1); } } if (Do_acpc) { fprintf (SUMA_STDOUT,"Performing acpc transform...\n"); /* form the acpc version of the surface volume */ acpc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+ strlen(SO->VolPar->prefix)+60, sizeof(char)); sprintf (acpc_name, "%s%s+acpc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix); if (!SUMA_filexists(acpc_name)) { fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, acpc_name); exit(1); } /* read the acpc header */ aset = THD_open_dataset(acpc_name) ; if( !ISVALID_DSET(aset) ){ fprintf (SUMA_STDERR, "Error %s: %s is not a valid data set.\n", FuncName, acpc_name) ; exit(1); } if( aset->warp == NULL ){ fprintf (SUMA_STDERR, "Error %s: acpc_name does not contain an acpc transform.\n", FuncName); exit(1); } warp = aset->warp ; /* now warp the coordinates, one node at a time */ if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName); exit(1); } } if (Do_mni_RAI) { fprintf (SUMA_STDOUT,"Performing MNI_RAI transform...\n"); /* apply the mni warp */ if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "RAI")) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName); exit(1); } sprintf(orsurf,"RAI"); } if (Do_mni_LPI) { fprintf (SUMA_STDOUT,"Performing MNI_LPI transform...\n"); /* apply the mni warp */ if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "LPI")) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName); exit(1); } sprintf(orsurf,"LPI"); } if (Doxmat) { fprintf (SUMA_STDOUT,"Performing affine transform...\n"); if (LocalHead) { for (i=0; i<3 ; ++i) { fprintf (SUMA_STDERR, "M[%d][:] = %f %f %f %f\n", i, xform[i][0], xform[i][1], xform[i][2], xform[i][3]); } fprintf (SUMA_STDERR,"Cen[:] %f %f %f\n", xcen[0], xcen[1], xcen[2]); } if (Docen) { if (!SUMA_Apply_Coord_xform( SO->NodeList, SO->N_Node, SO->NodeDim, xform, 0, xcen)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); } } else { if (!SUMA_Apply_Coord_xform( SO->NodeList, SO->N_Node, SO->NodeDim, xform, 0, NULL)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); } } SUMA_Blank_AfniSO_Coord_System(SO->aSO); } if (orcode[0] != '\0') { SUMA_LHv("Changing coordinates from %s to %s\n", orsurf, orcode); if (!SUMA_CoordChange(orsurf, orcode, SO->NodeList, SO->N_Node)) { SUMA_S_Err("Failed to change coords."); exit(1); } SUMA_Blank_AfniSO_Coord_System(SO->aSO); } if (Do_p2s) { SUMA_SurfaceObject *SOold = SO; SUMA_LH("Changing patch to surface..."); SO = SUMA_Patch2Surf(SOold->NodeList, SOold->N_Node, SO->FaceSetList, SO->N_FaceSet, 3); if (!SO) { SUMA_S_Err("Failed to change patch to surface."); exit(1); } /* get rid of old surface object */ SUMA_Free_Surface_Object(SOold); } if (Do_native) { if (!SUMA_Delign_to_VolPar (SO, NULL)) { SUMA_S_Err("Failed to transform coordinates to native space"); exit(1); } } if (Do_NodeDepth) { float *dpth=NULL, mx=0.0; SUMA_PC_XYZ_PROJ *pcp=NULL; if (SUMA_NodeDepth(SO->NodeList, SO->N_Node, E1_DIR_PRJ, &dpth, 0.0, NULL, &mx, &pcp) < 0) { SUMA_S_Err("Failed to compute node depth"); exit(1); } else { if (!SUMA_WriteNodeDepth(NodeDepthpref,pcp,dpth, mx)) { SUMA_S_Err("Failed to write node depth"); exit(1); } } SUMA_ifree(dpth); pcp = SUMA_Free_PC_XYZ_Proj(pcp); } if (Do_PCproj > NO_PRJ) { SUMA_PC_XYZ_PROJ *pcp=NULL; pciref = 0; pcxyzref = NULL; if (!(pcp = SUMA_Project_Coords_PCA(SO->NodeList, SO->N_Node, pciref, pcxyzref, Do_PCproj, Do_PCrot, 1))) { SUMA_S_Err("Failed to project"); exit(1); } else { if (!SUMA_Write_PC_XYZ_Proj(pcp, PCprojpref)) { SUMA_S_Err("Failed to write out projections"); exit(1); } else { pcp = SUMA_Free_PC_XYZ_Proj(pcp); } exit(0); } } /* write the surface object */ if (SO_name) { if (LocalHead) SUMA_Print_Surface_Object (SO, stderr); fprintf (SUMA_STDOUT,"Writing surface...\n"); if (!(SUMA_Save_Surface_Object ( SO_name, SO, oType, oFormat, SOpar))) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } } if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip); if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip); if (OF_name) SUMA_free(OF_name); if (OF_name2) SUMA_free(OF_name2); if (SF_name) SUMA_free(SF_name); if (SO_name) SUMA_free(SO_name); if (SO) SUMA_Free_Surface_Object(SO); if (SOpar) SUMA_Free_Surface_Object(SOpar); if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; return (0); }