SUMA_DSET *calcWithOffsets(SUMA_SurfaceObject *SO, SUMA_KUBATEST_OPTIONS* Opt) { static char FuncName[]={"calcWithOffsets"}; /* initialize OffS */ SUMA_GET_OFFSET_STRUCT *OffS = SUMA_Initialize_getoffsets (SO->N_Node); struct timeval start_time, start_time_all; float etime_GetOffset, etime_GetOffset_all; float *gD=NULL, *pD=NULL, *rD=NULL; int *Pr=NULL, *Nd=NULL, *Lj=NULL; float pathD = 0;/*shortest distance along surface to node ii*/ float geomD = 0;/*geometric distance to node ii*/ float ratio = 1; int i = 0, j = 0, ii = 0, lj =0; float x1, x2 , y1, y2, z1, z2, dx, dy, dz, d1, d2, r; FILE* outFile = NULL, *segDO=NULL; SUMA_DSET *dset=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_ENTRY; if (Opt->outfile) { if (!(outFile = fopen(Opt->outfile, "w"))) { SUMA_S_Errv("Failed to open %s for writing.\n", Opt->outfile); SUMA_RETURN(NULL); } fprintf(outFile, "#Col. 0 Node index\n" "#Col. 1 Node for which the ratio in 4 is the largest. " " (Companion of Node in Col.0)\n" "#Col. 2 distance in 3D\n" "#Col. 3 shortest surface path\n" "#Col. 4 Ratio of path/distance\n" "#Col. 5 Neighborhood layer of node in Col.1, " " i.e. Neighborhood layer of the companion of node in Col.0"); if (Opt->histnote) { fprintf(outFile, "#History:%s\n", Opt->histnote); } } if (Opt->segdo) { if (!(segDO = fopen(Opt->segdo, "w"))) { SUMA_S_Errv("Failed to open %s for writing.\n", Opt->segdo); SUMA_RETURN(NULL); } fprintf(segDO, "#node-based_segments\n"); if (Opt->histnote) { fprintf(segDO, "#History:%s\n", Opt->histnote); } } Nd=(int *)SUMA_calloc(SO->N_Node, sizeof(int)); Pr=(int *)SUMA_calloc(SO->N_Node, sizeof(int)); Lj=(int *)SUMA_calloc(SO->N_Node, sizeof(int)); gD=(float *)SUMA_calloc(SO->N_Node, sizeof(float)); pD=(float *)SUMA_calloc(SO->N_Node, sizeof(float)); rD=(float *)SUMA_calloc(SO->N_Node, sizeof(float)); if (!Pr || !gD || !pD || !rD) { SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NOPE); } SUMA_etime(&start_time_all,0); for (i=0; i < SO->N_Node; ++i) { pathD = 0;/*shortest distance along surface to node ii*/ geomD = 0;/*geometric distance to node ii*/ ratio = 1; j = 0; ii = 0; lj = -1; /* show me the offset from node 0 */ SUMA_LHv("Calculating offsets from node %d\n", i); if (i == 0) { SUMA_etime(&start_time,0); } SUMA_getoffsets2 (i, SO, Opt->plimit, OffS, NULL, 0); if (i == 99) { etime_GetOffset = SUMA_etime(&start_time,1); SUMA_LHv("Search to %f mm took %f seconds for %d nodes.\n" "Projected completion time: %f minutes\n", Opt->plimit, etime_GetOffset, i+1, etime_GetOffset * SO->N_Node / 60.0 / (i+1)); } /*find smallest ratio*/ for (j=0; j < OffS->N_Nodes; j++) { if( i!=j && OffS->LayerVect[j] >= 0) { x1 = SO->NodeList[i*3+0]; x2 = SO->NodeList[j*3+0]; y1 = SO->NodeList[i*3+1]; y2 = SO->NodeList[j*3+1]; z1 = SO->NodeList[i*3+2]; z2 = SO->NodeList[j*3+2]; dx = x1 - x2; dy = y1 - y2; dz = z1 - z2; d1 = OffS->OffVect[j]; d2 = sqrt(dx*dx + dy*dy + dz*dz); r = d1 / d2; if ( d2 < Opt->dlimit && d1 < Opt->plimit && r > ratio ) { if (r > 1000) { SUMA_S_Notev("Extreme Ratio:\n" "node=%d (%f %f %f), paired with node %d (%f %f %f)\n" " geo_dist=%f Euc_dist=%f r=%f layer=%d\n", i, x1, y1, z1, j, x2, y2, z2, d1, d2, r, OffS->LayerVect[j]); } ratio = r; ii = j; lj = OffS->LayerVect[j]; pathD = d1; geomD = d2; } } } Nd[i] = i; Pr[i] = ii; Lj[i] = lj; gD[i] = geomD; pD[i] = pathD; rD[i] = ratio; if (outFile) fprintf(outFile, "%i\t%i\t%f\t%f\t%f\t%d\n", i, ii, geomD, pathD, ratio, lj); if (segDO) { float r,g,b,a; SUMA_RAND_COL(i?-1:0,r,g,b,a); fprintf(segDO, "%i\t%i\t%f %f %f %f\n", i, ii, r,g,b,1.0); } if (LocalHead) fprintf(SUMA_STDERR,"%s: Recycling OffS\n", FuncName); SUMA_Recycle_getoffsets (OffS); if (LocalHead) fprintf(SUMA_STDERR,"%s: Done.\n", FuncName); } if (outFile) fclose(outFile); if (segDO) fclose(segDO); dset = SUMA_CreateDsetPointer(Opt->prefix, SUMA_NODE_BUCKET, NULL, SO->idcode_str, SO->N_Node); if (!SUMA_AddDsetNelCol(dset, "node index", SUMA_NODE_INDEX, Nd, NULL, 1)) { SUMA_S_Err("Failed to add new data"); SUMA_FreeDset(dset); SUMA_RETURN(NULL); } if (!SUMA_AddDsetNelCol(dset, "PairingNode", SUMA_NODE_INT, Pr, NULL, 1)) { SUMA_S_Err("Failed to add new data"); SUMA_FreeDset(dset); SUMA_RETURN(NULL); } if (!SUMA_AddDsetNelCol(dset, "LayerOfPairNode", SUMA_NODE_INT, Lj, NULL, 1)){ SUMA_S_Err("Failed to add new data"); SUMA_FreeDset(dset); SUMA_RETURN(NULL); } if (!SUMA_AddDsetNelCol(dset, "Eucl.Dist", SUMA_NODE_FLOAT, gD, NULL, 1)) { SUMA_S_Err("Failed to add new data"); SUMA_FreeDset(dset); SUMA_RETURN(NULL); } if (!SUMA_AddDsetNelCol(dset, "Geo.Dist",SUMA_NODE_FLOAT, pD, NULL, 1)) { SUMA_S_Err("Failed to add new data"); SUMA_FreeDset(dset); SUMA_RETURN(NULL); } if (!SUMA_AddDsetNelCol(dset, "G/E.Dist",SUMA_NODE_FLOAT, rD, NULL, 1)) { SUMA_S_Err("Failed to add new data"); SUMA_FreeDset(dset); SUMA_RETURN(NULL); } etime_GetOffset_all = SUMA_etime(&start_time_all,1); SUMA_S_Notev("Done.\nSearch to %f mm took %f minutes for %d nodes.\n" , Opt->plimit, etime_GetOffset_all / 60.0 , SO->N_Node); SUMA_Free_getoffsets(OffS); SUMA_free(Nd); Nd = NULL; SUMA_free(Pr); Pr = NULL; SUMA_free(Lj); Lj = NULL; SUMA_free(gD); gD = NULL; SUMA_free(pD); pD = NULL; SUMA_free(rD); rD = NULL; SUMA_RETURN(dset); }
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); }
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[]={"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 main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SurfToSurf"}; SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_SurfaceObject *SO1=NULL, *SO2 = NULL; SUMA_SurfSpecFile *Spec = NULL; SUMA_M2M_STRUCT *M2M = NULL; int N_Spec=0, *nodeind = NULL, N_nodeind, icol, i, j; MRI_IMAGE *im = NULL, *im_data=NULL; int nvec=0, ncol=0, nvec_data=0, ncol_data=0, Nchar=0; float *far = NULL, *far_data=NULL, *dt = NULL, *projdir=NULL; char *outname = NULL, *s=NULL, sbuf[100]; void *SO_name = NULL; FILE *outptr=NULL; SUMA_Boolean exists = NOPE; SUMA_INDEXING_ORDER d_order = SUMA_NO_ORDER; SUMA_STRING *SS=NULL; 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;-t;-spec;-s;-sv;-o;"); Opt = SUMA_SurfToSurf_ParseInput (argv, argc, ps); if (argc < 2) { SUMA_S_Err("Too few options"); usage_SurfToSurf(ps, 0); exit (1); } /* if output surface requested, check on pre-existing file */ if (ps->o_N_surfnames) { SO_name = SUMA_Prefix2SurfaceName(ps->o_surfnames[0], NULL, NULL, ps->o_FT[0], &exists); if (exists) { fprintf(SUMA_STDERR, "Error %s:\nOutput file(s) %s* on disk.\n" "Will not overwrite.\n", FuncName, ps->o_surfnames[0]); exit(1); } } if (Opt->debug > 2) LocalHead = YUP; outname = SUMA_append_extension(Opt->out_prefix,".1D"); if (SUMA_filexists(outname) && !THD_ok_overwrite()) { fprintf(SUMA_STDERR,"Output file %s exists.\n", outname); exit(1); } /* Load the surfaces from command line*/ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec != 1) { SUMA_S_Err( "Multiple spec at input.\n" "Do not mix surface input types together\n"); exit(1); } if (Spec->N_Surfs != 2) { SUMA_S_Err("2 surfaces expected."); exit(1); } SO1 = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0); if (!SO1) { fprintf (SUMA_STDERR,"Error %s:\n" "Failed to find surface\n" "in spec file. \n", FuncName ); exit(1); } if (!SUMA_SurfaceMetrics(SO1, "EdgeList|MemberFace", NULL)) { SUMA_SL_Err("Failed to create edge list for SO1"); exit(1); } if (Opt->fix_winding) { int orient, trouble; if (LocalHead) fprintf(SUMA_STDERR, "%s: Making sure S1 is consistently orientated\n", FuncName); if (!SUMA_MakeConsistent (SO1->FaceSetList, SO1->N_FaceSet, SO1->EL, Opt->debug, &trouble)) { SUMA_SL_Err("Failed in SUMA_MakeConsistent"); } if (trouble && LocalHead) { fprintf(SUMA_STDERR, "%s: trouble value of %d from SUMA_MakeConsistent.\n" "Inconsistencies were found and corrected unless \n" "stderr output messages from SUMA_MakeConsistent\n" "indicate otherwise.\n", FuncName, trouble); } if (LocalHead) fprintf(SUMA_STDERR,"%s: Checking orientation.\n", FuncName); orient = SUMA_OrientTriangles (SO1->NodeList, SO1->N_Node, SO1->FaceSetList, SO1->N_FaceSet, 1, 0, NULL, NULL); if (orient < 0) { /* flipping was done, dump the edge list since it is not automatically updated (should do that in function, just like in SUMA_MakeConsistent, shame on you) If you revisit this section, use the newer: SUMA_OrientSOTriangles */ if (SO1->EL) SUMA_free_Edge_List(SO1->EL); SO1->EL = NULL; if (!SUMA_SurfaceMetrics(SO1, "EdgeList", NULL)) { SUMA_SL_Err("Failed to create edge list for SO1"); exit(1); } /* free normals, new ones needed (Normals should be flipped inside of SUMA_OrientTriangles! (just like in SUMA_MakeConsistent) ) */ if (SO1->NodeNormList) SUMA_free(SO1->NodeNormList); SO1->NodeNormList = NULL; if (SO1->FaceNormList) SUMA_free(SO1->FaceNormList); SO1->FaceNormList = NULL; } if (!orient) { fprintf(SUMA_STDERR, "Error %s:\nFailed in SUMA_OrientTriangles\n", FuncName); } if (LocalHead) { if (orient < 0) { SUMA_SL_Note("S1 was reoriented"); } else { SUMA_SL_Note("S1 was properly oriented"); } } } if (!SO1->NodeNormList || !SO1->FaceNormList) { SUMA_LH("Node Normals"); SUMA_RECOMPUTE_NORMALS(SO1); } if (Opt->NodeDbg >= SO1->N_Node) { SUMA_SL_Warn( "node_debug index is larger than number " "of nodes in surface, ignoring -node_debug."); Opt->NodeDbg = -1; } SO2 = SUMA_Load_Spec_Surf(Spec, 1, ps->sv[1], 0); if (!SO2) { fprintf (SUMA_STDERR,"Error %s:\n" "Failed to find surface\n" "in spec file. \n", FuncName ); exit(1); } if (!SUMA_SurfaceMetrics(SO2, "EdgeList|MemberFace", NULL)) { SUMA_SL_Err("Failed to create edge list for SO2"); exit(1); } if (!SO2->NodeNormList || !SO2->FaceNormList) { SUMA_LH("Node Normals"); SUMA_RECOMPUTE_NORMALS(SO2); } if (LocalHead) { SUMA_LH("Surf1"); SUMA_Print_Surface_Object(SO1, NULL); SUMA_LH("Surf2"); SUMA_Print_Surface_Object(SO2, NULL); } /* a select list of nodes? */ nodeind = NULL; N_nodeind = 0; if (Opt->in_nodeindices) { im = mri_read_1D(Opt->in_nodeindices); if (!im) { SUMA_SL_Err("Failed to read 1D file of node indices"); exit(1);} far = MRI_FLOAT_PTR(im); N_nodeind = nvec = im->nx; ncol = im->ny; if (ncol != 1) { SUMA_SL_Err("More than one column in node index input file."); exit(1); } nodeind = (int *)SUMA_calloc(nvec, sizeof(int)); if (!nodeind) { SUMA_SL_Crit("Failed to allocate"); exit(1); } for (i=0;i<nvec;++i) { nodeind[i] = (int)far[i]; if (nodeind[i] < 0 || nodeind[i] >= SO1->N_Node) { fprintf(SUMA_STDERR, "Error %s:\n" "A node index of %d was found in input file %s, entry %d.\n" "Acceptable indices are positive and less than %d\n", FuncName, nodeind[i], Opt->in_nodeindices, i, SO1->N_Node); exit(1); } } mri_free(im); im = NULL; /* done with that baby */ } /* a preset directions vector ?*/ projdir = NULL; if (Opt->in_1D) { im = mri_read_1D(Opt->in_1D); if (!im) { SUMA_SL_Err("Failed to read 1D file of projection directions"); exit(1); } far = MRI_FLOAT_PTR(im); if (im->ny != 3) { SUMA_SL_Err("Need three columns in projection directions file."); exit(1); } if (im->nx != SO1->N_Node) { fprintf(SUMA_STDERR, "Error %s: You must have a direction for each node in SO1.\n" "%d directions found but SO1 has %d nodes.\n", FuncName, im->nx, SO1->N_Node); exit(1); } /* change to row major major and make it match nodeind */ projdir = (float *)SUMA_calloc(SO1->N_Node*3, sizeof(float)); if (!projdir) { SUMA_SL_Crit("Failed to allocate"); exit(1); } for (i=0; i<SO1->N_Node; ++i) { projdir[3*i ] = far[i ]; projdir[3*i+1] = far[i+ SO1->N_Node]; projdir[3*i+2] = far[i+2*SO1->N_Node]; } mri_free(im); im = NULL; /* done with that baby */ } if (SO_name) { /* user is interpolating surface coords, check on other input insanity */ if (nodeind) { fprintf( SUMA_STDERR, "Error %s: You cannot combine " "option -o_TYPE with -node_indices", FuncName); exit(1); } if (Opt->in_name) { fprintf(SUMA_STDERR, "Error %s: You cannot combine option -o_TYPE with -data", FuncName); exit(1); } } /* a 1D file containing data, or Data parameter (for XYZ)? */ if (Opt->Data > 0) { if (Opt->in_name) { /* When you are ready to work with dsets, you should checkout the function morphDsetToStd. It uses M2M */ im_data = mri_read_1D(Opt->in_name); if (!im_data) { SUMA_SL_Err("Failed to read 1D file of data"); exit(1);} far_data = MRI_FLOAT_PTR(im_data); nvec_data = im_data->nx; ncol_data = im_data->ny; if (nvec_data != SO2->N_Node) { SUMA_SL_Err("Your data file must have one row " "for each node in surface 2.\n"); exit(1); } d_order = SUMA_COLUMN_MAJOR; } else { im_data = NULL; far_data = SO2->NodeList; nvec_data = SO2->N_Node; ncol_data = 3; d_order = SUMA_ROW_MAJOR; } } else { /* just -dset */ } if (!Opt->s) { SUMA_LH("Going for the mapping of SO1 --> SO2"); M2M = SUMA_GetM2M_NN( SO1, SO2, nodeind, N_nodeind, projdir, 0, Opt->NodeDbg, Opt->iopt); SUMA_S_Notev("Saving M2M into %s\n\n", Opt->out_prefix); if (!(SUMA_Save_M2M(Opt->out_prefix, M2M))) { SUMA_S_Err("Failed to save M2M"); exit(1); } } else { SUMA_S_Notev("Reusing mapping of SO1 --> SO2 from %s\n\n", Opt->s); if (!(M2M = SUMA_Load_M2M(Opt->s))) { SUMA_S_Errv("Failed to load %s\n", Opt->s); exit(1); } } /* Now show the mapping results for a debug node ? */ if (Opt->NodeDbg >= 0) { char *s = NULL; s = SUMA_M2M_node_Info(M2M, Opt->NodeDbg); fprintf(SUMA_STDERR,"%s: Debug for node %d ([%f, %f, %f])of SO1:\n%s\n\n", FuncName, Opt->NodeDbg, SO1->NodeList[3*Opt->NodeDbg], SO1->NodeList[3*Opt->NodeDbg+1], SO1->NodeList[3*Opt->NodeDbg+2], s); SUMA_free(s); s = NULL; } /* Now please do the interpolation */ if (Opt->Data > 0) { if (Opt->NearestNode > 1) dt = SUMA_M2M_interpolate( M2M, far_data, ncol_data, nvec_data, d_order, 0 ); else if (Opt->NearestNode == 1) dt = SUMA_M2M_interpolate( M2M, far_data, ncol_data, nvec_data, d_order, 1 ); if (!dt) { SUMA_SL_Err("Failed to interpolate"); exit(1); } } else if (Opt->Data < 0) { SUMA_DSET *dset=NULL, *dseto=NULL; char *oname=NULL, *uname=NULL, *s1=NULL, *s2=NULL; int iform=SUMA_NO_DSET_FORMAT; if (Opt->NodeDbg>= 0) { SUMA_S_Notev("Processing dset %s\n", Opt->in_name); } iform = SUMA_NO_DSET_FORMAT; if (!(dset = SUMA_LoadDset_s (Opt->in_name, &iform, 0))) { SUMA_S_Errv("Failed to load %s\n", Opt->in_name); exit(1); } if (!(dseto = SUMA_morphDsetToStd ( dset, M2M, Opt->NearestNode == 1 ? 1:0))) { SUMA_S_Errv("Failed to map %s\n", Opt->in_name); exit(1); } s1 = SUMA_append_string( SUMA_FnameGet(Opt->in_name,"pa", SUMAg_CF->cwd), Opt->out_prefix); s2 = SUMA_RemoveDsetExtension_s( SUMA_FnameGet(Opt->in_name,"l",SUMAg_CF->cwd), SUMA_NO_DSET_FORMAT); uname = SUMA_append_extension(s1,s2); SUMA_free(s1); SUMA_free(s2); oname = SUMA_WriteDset_s (uname, dseto, Opt->oform, 1, 1); if (Opt->NodeDbg>= 0) SUMA_S_Notev("Wrote %s\n", oname); if (oname) SUMA_free(oname); oname=NULL; if (uname) SUMA_free(uname); oname=NULL; if (dseto) SUMA_FreeDset(dseto); dseto = NULL; if (dset) SUMA_FreeDset(dset); dset = NULL; } SUMA_LH("Forming the remaining output"); outptr = fopen(outname,"w"); if (!outptr) { SUMA_SL_Err("Failed to open file for output.\n"); exit(1); } /* first create the header of the output */ SS = SUMA_StringAppend(NULL, NULL); SS = SUMA_StringAppend_va(SS, "#Mapping from nodes on surf 1 (S1) to nodes on surf 2 (S2)\n" "# Surf 1 is labeled %s, idcode:%s\n" "# Surf 2 is labeled %s, idcode:%s\n", SO1->Label, SO1->idcode_str, SO2->Label, SO2->idcode_str); icol = 0; SS = SUMA_StringAppend_va(SS, "#Col. %d:\n" "# S1n (or nj): Index of node on S1\n" , icol); ++icol; if (Opt->NearestNode > 1) { SS = SUMA_StringAppend_va(SS, "#Col. %d..%d:\n" "# S2ne_S1n: Indices of %d nodes on S2 \n" "# that are closest neighbors of nj.\n" "# The first index is that of the node on S2 that is closest \n" "# to nj. If -1 then these values should be ignored because\n" "# in such cases, nj's projection failed.\n" , icol, icol+Opt->NearestNode-1, Opt->NearestNode); icol += Opt->NearestNode; SS = SUMA_StringAppend_va(SS, "#Col. %d..%d:\n" "# S2we_S1n: Weights assigned to nodes on surf 2 (S2) \n" "# that are closest neighbors of nj.\n" , icol, icol+Opt->NearestNode-1, Opt->NearestNode); icol += Opt->NearestNode; } else if (Opt->NearestNode == 1) { SS = SUMA_StringAppend_va(SS, "#Col. %d:\n" "# S2ne_S1n: Index of the node on S2 (label:%s idcode:%s)\n" "# that is the closest neighbor of nj.\n" "# If -1 then this value should be ignored because\n" "# nj's projection failed.\n" , icol, SO2->Label, SO2->idcode_str); ++icol; } if (Opt->NearestTriangle) { SS = SUMA_StringAppend_va(SS, "#Col. %d:\n" "# S2t_S1n: Index of the S2 triangle that hosts node nj on S1.\n" "# In other words, nj's closest projection onto S2 falls on \n" "# triangle S2t_S1n\n" "# If -1 then this value should be ignored because \n" "# nj's projection failed.\n" , icol); ++icol; } if (Opt->ProjectionOnMesh) { SS = SUMA_StringAppend_va(SS, "#Col. %d..%d:\n" "# S2p_S1n: Coordinates of projection of nj onto S2\n" , icol, icol+2); icol += 3; } if (Opt->DistanceToMesh) { SS = SUMA_StringAppend_va(SS, "#Col. %d:\n" "# Closest distance from nj to S2\n" , icol); ++icol; } if (Opt->NearestNodeCoords) { SS = SUMA_StringAppend_va(SS, "#Col. %d .. %d:\n" "# X Y Z coords of nearest node\n" , icol, icol+2); icol += 3; } if (Opt->Data > 0) { if (!Opt->in_name) { SS = SUMA_StringAppend_va(SS, "#Col. %d..%d:\n" "# Interpolation using XYZ coordinates of S2 nodes that neighbor nj\n" "# (same as coordinates of node's projection onto triangle in S2, \n" "# if using barycentric interpolation)\n" , icol, icol+2); icol += 3; } else { SS = SUMA_StringAppend_va(SS, "#Col. %d..%d:\n" "# Interpolation of data at nodes on S2 that neighbor nj\n" "# Data obtained from %s\n" , icol, icol+ncol_data-1, Opt->in_name); icol += ncol_data; } } s = SUMA_HistString("SurfToSurf", argc, argv, NULL); SS = SUMA_StringAppend_va(SS, "#History:\n" "#%s\n", s); SUMA_free(s); s = NULL; SUMA_SS2S(SS,s); fprintf(outptr,"%s\n",s); SUMA_free(s); s = NULL; /* put headers atop columns */ Nchar = 6; /* if you change this number you'll need to fix formats below */ for (i=0; i<icol; ++i) { sprintf(sbuf,"#%s", MV_format_fval2(i, Nchar -1)); fprintf(outptr,"%6s ", sbuf); } fprintf(outptr,"\n"); /* Now put in the values, make sure you parallel columns above! */ for (i=0; i<M2M->M1Nn; ++i) { fprintf(outptr,"%6s ", MV_format_fval2(M2M->M1n[i], Nchar)); if (Opt->NearestNode > 0) { for (j=0; j<Opt->NearestNode; ++j) { if (j < M2M->M2Nne_M1n[i]) fprintf(outptr,"%6s ", MV_format_fval2(M2M->M2ne_M1n[i][j], Nchar)); else fprintf(outptr,"%6s ", "-1"); } /* Neighboring nodes */ } if (Opt->NearestNode > 1) { /* add the weights */ for (j=0; j<Opt->NearestNode; ++j) { if (j < M2M->M2Nne_M1n[i]) fprintf(outptr,"%6s ", MV_format_fval2(M2M->M2we_M1n[i][j], Nchar)); else fprintf(outptr,"%6s ", "0.0"); } } if (Opt->NearestTriangle) { fprintf(outptr,"%6s ", MV_format_fval2(M2M->M2t_M1n[i], Nchar)); } if (Opt->ProjectionOnMesh) { fprintf(outptr,"%6s ", MV_format_fval2(M2M->M2p_M1n[3*i], Nchar)); fprintf(outptr,"%6s ", MV_format_fval2(M2M->M2p_M1n[3*i+1], Nchar)); fprintf(outptr,"%6s ", MV_format_fval2(M2M->M2p_M1n[3*i+2], Nchar)); } if (Opt->DistanceToMesh) { fprintf(outptr,"%6s ", MV_format_fval2(M2M->PD[i], Nchar)); } if (Opt->NearestNodeCoords) { float x=0.0,y=0.0,z=0.0; int n = M2M->M2ne_M1n[i][0]; if (n>0) { n = n * SO2->NodeDim; x = SO2->NodeList[n]; y = SO2->NodeList[n+1]; z = SO2->NodeList[n+2]; } fprintf(outptr,"%6s ", MV_format_fval2(x, Nchar)); fprintf(outptr,"%6s ", MV_format_fval2(y, Nchar)); fprintf(outptr,"%6s ", MV_format_fval2(z, Nchar)); } if (dt && Opt->Data > 0) { if (!Opt->in_name) { fprintf(outptr,"%6s ", MV_format_fval2(dt[3*i], Nchar)); fprintf(outptr,"%6s ", MV_format_fval2(dt[3*i+1], Nchar)); fprintf(outptr,"%6s ", MV_format_fval2(dt[3*i+2], Nchar)); } else { /* Column major business */ for (j=0; j<ncol_data; ++j) { fprintf(outptr,"%6s ", MV_format_fval2(dt[i+j*M2M->M1Nn], Nchar)); } } } fprintf(outptr,"\n"); } /* do they want an output surface ? */ if (SO_name) { float *tmpfv = NULL; SUMA_LH("Writing surface"); tmpfv = SO1->NodeList; SO1->NodeList = dt; if (!SUMA_Save_Surface_Object (SO_name, SO1, ps->o_FT[0], ps->o_FF[0], NULL)) { SUMA_S_Err("Failed to write surface object.\n"); exit (1); } SO1->NodeList = tmpfv; tmpfv = NULL; } 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 (projdir) SUMA_free(projdir); projdir = NULL; if (SO_name) SUMA_free(SO_name); SO_name = NULL; if (outptr) fclose(outptr); outptr = NULL; if (dt) SUMA_free(dt); dt = NULL; if (s) SUMA_free(s); s = NULL; if (im_data) mri_free(im_data); im_data = NULL; /* done with the data */ if (nodeind) SUMA_free(nodeind); nodeind = NULL; if (M2M) M2M = SUMA_FreeM2M(M2M); if (SO1) SUMA_Free_Surface_Object(SO1); SO1 = NULL; if (SO2) SUMA_Free_Surface_Object(SO2); SO2 = NULL; if (Spec) SUMA_free(Spec); Spec = 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); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SurfClust"}; int kar, SO_read, *ni=NULL, N_ni, cnt, i, *nip=NULL, N_Spec = 0; float *data_old = NULL, *far = NULL, *nv=NULL, *nt = NULL; void *SO_name = NULL; SUMA_SurfaceObject *SO = NULL, *SOnew = NULL; MRI_IMAGE *im = NULL; SUMA_DSET_FORMAT iform; SUMA_SURFCLUST_OPTIONS *Opt; SUMA_SurfSpecFile *Spec=NULL; DList *list = NULL; SUMA_DSET *dset = NULL; float *NodeArea = NULL; FILE *clustout=NULL; char *ClustOutName = NULL, *params=NULL, stmp[200]; char sapa[32]={""}, sapd[32]={""}, sapn[32]={""}, sap[100]={""}; SUMA_GENERIC_ARGV_PARSE *ps=NULL; 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, "-spec;-i;-t;-sv;-s;"); Opt = SUMA_SurfClust_ParseInput (argv, argc, ps); if (argc < 6) { SUMA_S_Err("Too few options"); usage_SUMA_SurfClust(0); exit (1); } if (Opt->DistLim >= 0.0) { sprintf(sapd, "_r%.1f", Opt->DistLim); } else { sprintf(sapd, "_e%d", -(int)Opt->DistLim); } if (Opt->AreaLim < 0) { sapa[0]='\0'; } else { sprintf(sapa, "_a%.1f", Opt->AreaLim); } if (Opt->NodeLim < 0) { sapn[0]='\0'; } else { sprintf(sapn, "_n%d", Opt->NodeLim); } sprintf(sap, "%s%s%s", sapd, sapa, sapn); if (Opt->WriteFile) { sprintf(stmp,"_ClstTable%s.1D", sap); ClustOutName = SUMA_append_string(Opt->out_prefix, stmp); if (SUMA_filexists(ClustOutName) && !THD_ok_overwrite()) { fprintf (SUMA_STDERR, "Error %s:\n" "Output file %s exists, will not overwrite.\n", FuncName, ClustOutName); 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); } if (Spec->N_Surfs != 1) { SUMA_S_Err("1 and only 1 surface expected at input"); exit(1); } SUMA_LH("Loading surface..."); SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0); if (!SO) { fprintf (SUMA_STDERR,"Error %s:\n" "Failed to find surface\n" "in spec file. \n", FuncName ); exit(1); } if (!SUMA_SurfaceMetrics(SO, "EdgeList", NULL)) { SUMA_S_Err("Failed to compute edgelist"); exit(1); } NodeArea = SUMA_CalculateNodeAreas(SO, NULL); if (!NodeArea) { SUMA_S_Err("Failed to calculate Node Areas.\n"); exit(1); } /* load the data */ iform = SUMA_NO_DSET_FORMAT; dset = SUMA_LoadDset_s (Opt->in_name, &iform, 0); if (LocalHead) SUMA_ShowDset(dset, 0, NULL); if (!dset) { SUMA_S_Err( "Failed to load dataset.\n" "Make sure file exists\n" "and is of the specified\n" "format."); exit(1); } if (!SUMA_OKassign(dset, SO)) { SUMA_SL_Err("Failed to assign data set to surface."); exit(1); } /* get the node index column */ nip = SUMA_GetNodeDef(dset); N_ni = SDSET_VECLEN(dset); if (!nip) { SUMA_S_Err("Failed to find node index column"); exit(1); } /* copy nip's contents because you will be modifying in the thresholding below */ ni = (int *)SUMA_malloc(N_ni*sizeof(int)); memcpy (ni, nip, N_ni*sizeof(int)); nv = SUMA_DsetCol2Float(dset, Opt->labelcol, 0); if (!nv) { SUMA_S_Err("Failed to find node value column"); exit(1); } /* any thresholding ? */ if (Opt->DoThreshold > SUMA_NO_THRESH) { nt = SUMA_DsetCol2Float(dset, Opt->tind, 0); if (!nt) { SUMA_S_Err("Failed to find threshold column"); exit(1); } cnt = 0; if (Opt->DoThreshold == SUMA_LESS_THAN) { if (Opt->update) fprintf( SUMA_STDERR, "%s: Thresholding at %f...\n", FuncName, Opt->ThreshR[0]); for (i=0;i<N_ni; ++i) { if (nt[i] >= Opt->ThreshR[0]) { ni[cnt] = ni[i]; nv[cnt] = nv[i]; ++cnt; } } } else if (Opt->DoThreshold == SUMA_ABS_LESS_THAN) { SUMA_LH("ABS Thresholding at %f...", Opt->ThreshR[0]); for (i=0;i<N_ni; ++i) { if (fabs(nt[i]) >= Opt->ThreshR[0]) { ni[cnt] = ni[i]; nv[cnt] = nv[i]; ++cnt; } } } else if (Opt->DoThreshold == SUMA_THRESH_INSIDE_RANGE) { SUMA_LH("Range Thresholding at %f %f...", Opt->ThreshR[0], Opt->ThreshR[1]); for (i=0;i<N_ni; ++i) { if (nt[i] >= Opt->ThreshR[0] && nt[i] <= Opt->ThreshR[1]) { ni[cnt] = ni[i]; nv[cnt] = nv[i]; ++cnt; } } } else if (Opt->DoThreshold == SUMA_THRESH_OUTSIDE_RANGE) { SUMA_LH("Ex Range Thresholding at %f %f...", Opt->ThreshR[0], Opt->ThreshR[1]); for (i=0;i<N_ni; ++i) { if (nt[i] < Opt->ThreshR[0] || nt[i] > Opt->ThreshR[1]) { ni[cnt] = ni[i]; nv[cnt] = nv[i]; ++cnt; } } } else { SUMA_S_Err("Not ready for threshold mode of %d", Opt->DoThreshold); } N_ni = cnt; } if (Opt->update) { Opt->update = -(N_ni * Opt->update / 100); /* make it negative before you begin a clustering operation */ if (LocalHead) { fprintf( SUMA_STDERR, "Update parameter, once every %d nodes\n" "%d nodes to work with.\n", -(int)Opt->update, N_ni); } } /* make the call */ list = SUMA_FindClusters (SO, ni, nv, N_ni, -1, Opt, NodeArea); if (!list) { SUMA_S_Err("Failed in SUMA_FindClusters"); exit(1); } if (list->size) { /* sort the list */ if (!SUMA_Sort_ClustersList (list, Opt->SortMode)) { SUMA_S_Err("Failed to sort cluster list"); exit(1); } } /* Show the results */ params = SUMA_HistString(FuncName, argc, argv, NULL); if (Opt->WriteFile) { if (0) { /* You can also write a NIML formatted cluster table with */ NI_element *nel=NULL; int suc; char sbuf[512]={""}; nel = SUMA_SurfClust_list_2_nel(list, 0, params, NULL); snprintf(sbuf, 510, "file:%s%s.niml.clstbl", Opt->out_prefix, sap); NEL_WRITE_TXH(nel, sbuf, suc); NI_free_element(nel); nel=NULL; } clustout = fopen(ClustOutName, "w"); if (!clustout) { fprintf (SUMA_STDERR, "Error %s:\n" "Failed to open %s for writing.\n" "Check permissions.\n", FuncName, ClustOutName); exit(1); } SUMA_Show_SurfClust_list(list, clustout, 0, params, NULL); fclose(clustout);clustout = NULL; } else SUMA_Show_SurfClust_list(list, NULL, 0, params, NULL); if (!list->size) { /* nothing left to do, quit */ exit(0); } if (Opt->OutROI) { SUMA_DSET *dset_roi = NULL; char *ROIprefix = NULL; char *NameOut = NULL; sprintf(stmp,"_ClstMsk%s", sap); ROIprefix = SUMA_append_string(Opt->out_prefix, stmp); /* Call this function, write out the resultant dset to disk then cleanup */ dset_roi = SUMA_SurfClust_list_2_DsetMask(SO, list, Opt->FullROIList, ROIprefix); if (!dset_roi) { SUMA_S_Err("NULL dset_roi"); exit(1); } if (Opt->prepend_node_index) {/* prepend node index? */ if (!SUMA_InsertDsetNelCol ( dset_roi, "Node Index Copy", SUMA_NODE_INT, (void *)(dset_roi->inel->vec[0]), NULL ,1, 0)) { SUMA_S_Err("Failed to insert column"); } if (LocalHead) SUMA_ShowDset(dset_roi,0, NULL); } NameOut = SUMA_WriteDset_s ( ROIprefix, dset_roi, Opt->oform, THD_ok_overwrite(), 0); if (!NameOut) { SUMA_SL_Err("Failed to write dataset."); exit(1); } SUMA_FreeDset((void *)dset_roi); dset_roi = NULL; if (NameOut) SUMA_free(NameOut); NameOut = NULL; if (ROIprefix) SUMA_free(ROIprefix); ROIprefix = NULL; } if (Opt->OutClustDset) { SUMA_DSET *dset_clust = NULL; char *Clustprefix = NULL; char *NameOut = NULL; sprintf(stmp,"_Clustered%s", sap); Clustprefix = SUMA_append_string(Opt->out_prefix, stmp); /* Call this function, write out the resultant dset to disk then cleanup */ dset_clust = SUMA_MaskDsetByClustList( dset, SO, list, Opt->FullROIList, Clustprefix); if (!dset_clust) { SUMA_S_Err("NULL dset_clust"); exit(1); } NameOut = SUMA_WriteDset_s ( Clustprefix, dset_clust, Opt->oform, THD_ok_overwrite(), 0); if (!NameOut) { SUMA_SL_Err("Failed to write dataset."); exit(1); } SUMA_FreeDset((void *)dset_clust); dset_clust = NULL; if (NameOut) SUMA_free(NameOut); NameOut = NULL; if (Clustprefix) SUMA_free(Clustprefix); Clustprefix = NULL; } if (ClustOutName) SUMA_free(ClustOutName); ClustOutName = NULL; if (list) dlist_destroy(list); SUMA_free(list); list = NULL; if (ni) SUMA_free(ni); ni = NULL; if (nv) SUMA_free(nv); nv = NULL; if (nt) SUMA_free(nt); nt = NULL; if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt) SUMA_free_SurfClust_Opt(Opt); if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (dset) SUMA_FreeDset((void *)dset); dset = NULL; if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } exit(0); }
int main(int argc, char *argv[]) { int i,j,k,m,n,mm; int iarg; THD_3dim_dataset *insetTIME = NULL; THD_3dim_dataset *MASK=NULL; THD_3dim_dataset *ROIS=NULL; char *prefix="NETCORR" ; char in_name[300]; char in_mask[300]; char in_rois[300]; char OUT_grid[300]; char OUT_indiv[300]; char OUT_indiv0[300]; // int *SELROI=NULL; // if selecting subset of ROIs // int HAVE_SELROI=0; int NIFTI_OUT = 0; byte ***mskd=NULL; // define mask of where time series are nonzero byte *mskd2=NULL; // not great, but another format of mask int HAVE_MASK=0; int HAVE_ROIS=0; int FISH_OUT=0; int PART_CORR=0; int TS_OUT=0; int TS_LABEL=0; int TS_INDIV=0; int TS_WBCORR_r=0; int TS_WBCORR_Z=0; int *NROI_REF=NULL,*INVROI_REF=NULL; int **ROI_LABELS_REF=NULL, **INV_LABELS_REF=NULL,**ROI_COUNT=NULL; int ***ROI_LISTS=NULL; double ***ROI_AVE_TS=NULL; // double because of GSL float ***Corr_Matr=NULL; float ***PCorr_Matr=NULL, ***PBCorr_Matr=NULL; int Nvox=-1; // tot number vox int *Dim=NULL; int *Nlist=NULL; Dtable *roi_dtable=NULL; char *LabTabStr=NULL; char ***ROI_STR_LABELS=NULL; // for niml.dset -> graph viewing in SUMA char ***gdset_roi_names=NULL; SUMA_DSET *gset=NULL; float ***flat_matr=NULL; float *xyz=NULL; char OUT_gdset[300]; NI_group *GDSET_netngrlink=NULL; char *NAME_gdset=NULL; int Noutmat = 1; // num of matr to output: start with CC for sure char **ParLab=NULL; int FM_ctr = 0; // for counting through flatmatr entries int OLD_LABEL=0; // ooollld style format of regions: Nnumber:Rnumber int IGNORE_LT=0; // ignore label table int idx = 0; int Nmask = 0; FILE *fout1,*fin,*fout2; AFNI_SETUP_OMP(0) ; /* 24 Jun 2013 */ mainENTRY("3dNetCorr"); machdep(); // **************************************************************** // **************************************************************** // load AFNI stuff // **************************************************************** // **************************************************************** // INFO_message("version: BETA"); /** scan args **/ if (argc == 1) { usage_NetCorr(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_NetCorr(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-prefix") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-prefix'"); prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '-prefix'"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-inset") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-input'"); sprintf(in_name,"%s", argv[iarg]); insetTIME = THD_open_dataset(in_name) ; if( (insetTIME == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_name); // just 0th time point for output... Dim = (int *)calloc(4,sizeof(int)); DSET_load(insetTIME); CHECK_LOAD_ERROR(insetTIME); Nvox = DSET_NVOX(insetTIME) ; Dim[0] = DSET_NX(insetTIME); Dim[1] = DSET_NY(insetTIME); Dim[2] = DSET_NZ(insetTIME); Dim[3]= DSET_NVALS(insetTIME); iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); HAVE_MASK= 1; sprintf(in_mask,"%s", argv[iarg]); MASK = THD_open_dataset(in_mask) ; if( (MASK == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_mask); DSET_load(MASK); CHECK_LOAD_ERROR(MASK); iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_rois") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-in_rois'"); sprintf(in_rois,"%s", argv[iarg]); ROIS = THD_open_dataset(in_rois) ; if( (ROIS == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_rois); DSET_load(ROIS); CHECK_LOAD_ERROR(ROIS); HAVE_ROIS=DSET_NVALS(ROIS); //number of subbricks iarg++ ; continue ; } if( strcmp(argv[iarg],"-fish_z") == 0) { FISH_OUT=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-nifti") == 0) { NIFTI_OUT=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-part_corr") == 0) { PART_CORR=2; // because we calculate two matrices here iarg++ ; continue ; } if( strcmp(argv[iarg],"-ts_out") == 0) { TS_OUT=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-ts_label") == 0) { TS_LABEL=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-ts_indiv") == 0) { TS_INDIV=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-ts_wb_corr") == 0) { TS_WBCORR_r=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-ts_wb_Z") == 0) { TS_WBCORR_Z=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-old_labels") == 0) { OLD_LABEL=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-ignore_LT") == 0) { IGNORE_LT=1; iarg++ ; continue ; } /* if( strcmp(argv[iarg],"-sel_roi") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-in_rois'"); SELROI = (int *)calloc(MAX_SELROI,sizeof(int)); if( (fin = fopen(argv[iarg], "r")) == NULL) { fprintf(stderr, "Error opening file %s.",argv[iarg]); exit(1); } idx=0; while( !feof(fin) && (idx<MAX_SELROI-1) ){ fscanf(fin, "%d",&SELROI[idx]); fscanf(fin," "); idx++; } HAVE_SELROI=idx; printf("HAVE_SELROI=%d\n",HAVE_SELROI); if(HAVE_SELROI<=0) { ERROR_message("Error reading in `-sel_roi'-- appears to have no ROIs listed.\n"); exit(1); } iarg++ ; continue ; }*/ ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } INFO_message("Reading in."); if( !TS_OUT && TS_LABEL) { ERROR_message("with '-ts_label', you also need '-ts_out'.\n"); exit(1); } if (iarg < 3) { ERROR_message("Too few options. Try -help for details.\n"); exit(1); } if(!HAVE_ROIS) { ERROR_message("Need to load ROIs with >=1 subbrick...\n"); exit(1); } if(Nvox != DSET_NVOX(ROIS)) { ERROR_message("Data sets of `-inset' and `in_rois' have " "different numbers of voxels per brik!\n"); exit(1); } if( (HAVE_MASK>0) && (Nvox != DSET_NVOX(MASK)) ) { ERROR_message("Data sets of `-inset' and `mask' have " "different numbers of voxels per brik!\n"); exit(1); } // **************************************************************** // **************************************************************** // make storage // **************************************************************** // **************************************************************** Nlist = (int *)calloc(1,sizeof(int)); mskd2 = (byte *)calloc(Nvox,sizeof(byte)); mskd = (byte ***) calloc( Dim[0], sizeof(byte **) ); for ( i = 0 ; i < Dim[0] ; i++ ) mskd[i] = (byte **) calloc( Dim[1], sizeof(byte *) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) mskd[i][j] = (byte *) calloc( Dim[2], sizeof(byte) ); if( (mskd == NULL) || (Nlist == NULL) || (mskd2 == NULL)) { fprintf(stderr, "\n\n MemAlloc failure (masks).\n\n"); exit(122); } // ************************************************************* // ************************************************************* // Beginning of main loops // ************************************************************* // ************************************************************* INFO_message("Allocating..."); // go through once: define data vox, and calc rank for each for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { if( HAVE_MASK ) { if( THD_get_voxel(MASK,idx,0)>0 ) { mskd[i][j][k] = 1; mskd2[idx] = 1; Nmask++; } } else // simple automask attempt if( fabs(THD_get_voxel(insetTIME,idx,0))+ fabs(THD_get_voxel(insetTIME,idx,1))+ fabs(THD_get_voxel(insetTIME,idx,2))+ fabs(THD_get_voxel(insetTIME,idx,3))+ fabs(THD_get_voxel(insetTIME,idx,4)) > EPS_V) { mskd[i][j][k] = 1; mskd2[idx] = 1; Nmask++; } idx+= 1; // skip, and mskd and KW are both still 0 from calloc } if (HAVE_MASK) { DSET_delete(MASK); free(MASK); } // obviously, this should always be TRUE at this point... if(HAVE_ROIS>0) { NROI_REF = (int *)calloc(HAVE_ROIS, sizeof(int)); INVROI_REF = (int *)calloc(HAVE_ROIS, sizeof(int)); if( (NROI_REF == NULL) || (INVROI_REF == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(122); } for( i=0 ; i<HAVE_ROIS ; i++) INVROI_REF[i] = (int) THD_subbrick_max(ROIS, i, 1); ROI_LABELS_REF = calloc( HAVE_ROIS,sizeof(ROI_LABELS_REF)); for(i=0 ; i<HAVE_ROIS ; i++) ROI_LABELS_REF[i] = calloc(INVROI_REF[i]+1,sizeof(int)); INV_LABELS_REF = calloc( HAVE_ROIS,sizeof(INV_LABELS_REF)); for(i=0 ; i<HAVE_ROIS ; i++) INV_LABELS_REF[i] = calloc(INVROI_REF[i]+1,sizeof(int)); if( (ROI_LABELS_REF == NULL) || (INV_LABELS_REF == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } INFO_message("Labelling regions internally."); // Step 3A-2: find out the labels in the ref, organize them // both backwards and forwards. i = ViveLeRoi(ROIS, ROI_LABELS_REF, // ordered list of ROILABEL ints, [1..M]; // maxval is N. INV_LABELS_REF, // ith values at the actual input locs; // maxval is M. NROI_REF, // M: # of ROIs per brik INVROI_REF); // N: max ROI label per brik if( i != 1) ERROR_exit("Problem loading/assigning ROI labels"); ROI_STR_LABELS = (char ***) calloc( HAVE_ROIS, sizeof(char **) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) ROI_STR_LABELS[i] = (char **) calloc( NROI_REF[i]+1, sizeof(char *) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i]+1 ; j++ ) ROI_STR_LABELS[i][j] = (char *) calloc( 100 , sizeof(char) ); if( (ROI_STR_LABELS == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } // Sept 2014: Labeltable stuff if( IGNORE_LT ) { INFO_message("Ignoring any '-in_rois' label table (if there is one)."); } else{ if ((ROIS->Label_Dtable = DSET_Label_Dtable(ROIS))) { if ((LabTabStr = Dtable_to_nimlstring( DSET_Label_Dtable(ROIS), "VALUE_LABEL_DTABLE"))) { //fprintf(stdout,"%s", LabTabStr); if (!(roi_dtable = Dtable_from_nimlstring(LabTabStr))) { ERROR_exit("Could not parse labeltable."); } } else { INFO_message("No label table from '-in_rois'."); } } } i = Make_ROI_Output_Labels( ROI_STR_LABELS, ROI_LABELS_REF, HAVE_ROIS, NROI_REF, roi_dtable, 1 );//!!!opts.DUMP_with_LABELS ROI_COUNT = calloc( HAVE_ROIS,sizeof(ROI_COUNT)); for(i=0 ; i<HAVE_ROIS ; i++) ROI_COUNT[i] = calloc(NROI_REF[i],sizeof(int)); if( (ROI_COUNT == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } // find num of vox per ROI for( m=0 ; m<HAVE_ROIS ; m++ ) { idx=0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { if( (THD_get_voxel(ROIS,idx,m) > 0 ) && mskd[i][j][k] ) { ROI_COUNT[m][INV_LABELS_REF[m][(int) THD_get_voxel(ROIS,idx,m)]-1]++; } idx++; } } // make list of vox per ROI ROI_LISTS = (int ***) calloc( HAVE_ROIS, sizeof(int **) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) ROI_LISTS[i] = (int **) calloc( NROI_REF[i], sizeof(int *) ); for ( i=0 ; i <HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i] ; j++ ) ROI_LISTS[i][j] = (int *) calloc( ROI_COUNT[i][j], sizeof(int) ); // make average time series per voxel ROI_AVE_TS = (double ***) calloc( HAVE_ROIS, sizeof(double **) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) ROI_AVE_TS[i] = (double **) calloc( NROI_REF[i], sizeof(double *) ); for ( i=0 ; i <HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i] ; j++ ) ROI_AVE_TS[i][j] = (double *) calloc( Dim[3], sizeof(double) ); // store corr coefs Corr_Matr = (float ***) calloc( HAVE_ROIS, sizeof(float **) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) Corr_Matr[i] = (float **) calloc( NROI_REF[i], sizeof(float *) ); for ( i=0 ; i <HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i] ; j++ ) Corr_Matr[i][j] = (float *) calloc( NROI_REF[i], sizeof(float) ); if( (ROI_LISTS == NULL) || (ROI_AVE_TS == NULL) || (Corr_Matr == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } if(PART_CORR) { PCorr_Matr = (float ***) calloc( HAVE_ROIS, sizeof(float **) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) PCorr_Matr[i] = (float **) calloc( NROI_REF[i], sizeof(float *) ); for ( i=0 ; i <HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i] ; j++ ) PCorr_Matr[i][j] = (float *) calloc( NROI_REF[i], sizeof(float)); PBCorr_Matr = (float ***) calloc( HAVE_ROIS, sizeof(float **) ); for ( i=0 ; i<HAVE_ROIS ; i++ ) PBCorr_Matr[i] = (float **) calloc( NROI_REF[i], sizeof(float *) ); for ( i=0 ; i <HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i] ; j++ ) PBCorr_Matr[i][j] = (float *) calloc( NROI_REF[i], sizeof(float)); if( (PCorr_Matr == NULL) || (PBCorr_Matr == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } } // reuse this to help place list indices for( i=0 ; i<HAVE_ROIS ; i++ ) for( j=0 ; j<NROI_REF[i] ; j++ ) ROI_COUNT[i][j] = 0; INFO_message("Getting volumes."); for( m=0 ; m<HAVE_ROIS ; m++ ) { idx=0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { if( (THD_get_voxel(ROIS,idx,m) > 0) && mskd[i][j][k] ) { mm = INV_LABELS_REF[m][(int) THD_get_voxel(ROIS,idx,m)]-1; ROI_LISTS[m][mm][ROI_COUNT[m][mm]] = idx; ROI_COUNT[m][mm]++; } idx++; } } } // bit of freeing for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) { free(mskd[i][j]); } for( i=0 ; i<Dim[0] ; i++) { free(mskd[i]); } free(mskd); INFO_message("Calculating average time series."); // ROI values for(i=0 ; i<HAVE_ROIS ; i++) for( j=0 ; j<NROI_REF[i] ; j++ ) { Nlist[0]=ROI_COUNT[i][j]; k = CalcAveRTS(ROI_LISTS[i][j], ROI_AVE_TS[i][j], insetTIME, Dim, Nlist); } INFO_message("Calculating correlation matrix."); if(PART_CORR) INFO_message("... and calculating partial correlation matrix."); for(i=0 ; i<HAVE_ROIS ; i++) { for( j=0 ; j<NROI_REF[i] ; j++ ) for( k=j ; k<NROI_REF[i] ; k++ ) { Corr_Matr[i][j][k] = Corr_Matr[i][k][j] = (float) CORR_FUN(ROI_AVE_TS[i][j], ROI_AVE_TS[i][k], Dim[3]); } if(PART_CORR) mm = CalcPartCorrMatr(PCorr_Matr[i], PBCorr_Matr[i], Corr_Matr[i], NROI_REF[i]); } // ************************************************************** // ************************************************************** // Store and output // ************************************************************** // ************************************************************** INFO_message("Writing output: %s ...", prefix); // - - - - - - - - NIML prep - - - - - - - - - - - - - - if(FISH_OUT) Noutmat++; if(PART_CORR) Noutmat+=2; ParLab = (char **)calloc(Noutmat, sizeof(char *)); for (j=0; j<Noutmat; ++j) ParLab[j] = (char *)calloc(32, sizeof(char)); if( (ParLab == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(121); } // NIML output flat_matr = (float ***) calloc( HAVE_ROIS, sizeof(float **) ); for ( i = 0 ; i < HAVE_ROIS ; i++ ) flat_matr[i] = (float **) calloc( Noutmat, sizeof(float *) ); for ( i = 0 ; i < HAVE_ROIS ; i++ ) for ( j = 0 ; j < Noutmat ; j++ ) flat_matr[i][j] = (float *) calloc( NROI_REF[i]*NROI_REF[i], sizeof(float)); gdset_roi_names = (char ***)calloc(HAVE_ROIS, sizeof(char **)); for (i=0; i< HAVE_ROIS ; i++ ) { gdset_roi_names[i] = (char **)calloc(NROI_REF[i], sizeof(char *)); for (j=0; j<NROI_REF[i]; ++j) { gdset_roi_names[i][j] = (char *)calloc(32, sizeof(char)); if( OLD_LABEL ) snprintf(gdset_roi_names[i][j],31,"N%03d:R%d", i, ROI_LABELS_REF[i][j]); else{ snprintf(gdset_roi_names[i][j],31,"%s", ROI_STR_LABELS[i][j+1]); //fprintf(stderr," %s ", // ROI_STR_LABELS[i][j+1]); } } } if( (flat_matr == NULL) || ( gdset_roi_names == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(14); } for( k=0 ; k<HAVE_ROIS ; k++) { // each netw gets own file sprintf(OUT_grid,"%s_%03d.netcc",prefix,k); // zero counting now if( (fout1 = fopen(OUT_grid, "w")) == NULL) { fprintf(stderr, "Error opening file %s.",OUT_grid); exit(19); } // same format as .grid files now fprintf(fout1,"# %d # Number of network ROIs\n",NROI_REF[k]); // NROIs fprintf(fout1,"# %d # Number of netcc matrices\n", FISH_OUT+PART_CORR+1); // Num of params // Sept 2014: label_table stuff // don't need labeltable to make them, can do anyways fprintf(fout1, "# WITH_ROI_LABELS\n"); for( i=1 ; i<NROI_REF[k] ; i++ ) fprintf(fout1," %10s \t",ROI_STR_LABELS[k][i]); fprintf(fout1," %10s\n",ROI_STR_LABELS[k][i]); // THIS IS FOR KNOWING WHICH MATR WE'RE AT // it's always zero for CC; they match one-to-one with later vars FM_ctr = 0; ParLab[FM_ctr] = strdup("CC"); for( i=1 ; i<NROI_REF[k] ; i++ ) // labels of ROIs fprintf(fout1," %10d \t",ROI_LABELS_REF[k][i]);// at =NROI, have '\n' fprintf(fout1," %10d\n# %s\n",ROI_LABELS_REF[k][i],"CC"); for( i=0 ; i<NROI_REF[k] ; i++ ) { for( j=0 ; j<NROI_REF[k]-1 ; j++ ) {// b/c we put '\n' after last one. fprintf(fout1,"%12.4f\t",Corr_Matr[k][i][j]); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = Corr_Matr[k][i][j]; } fprintf(fout1,"%12.4f\n",Corr_Matr[k][i][j]); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = Corr_Matr[k][i][j]; } if(FISH_OUT) { FM_ctr++; ParLab[FM_ctr] = strdup("FZ"); fprintf(fout1,"# %s\n", "FZ"); for( i=0 ; i<NROI_REF[k] ; i++ ) { for( j=0 ; j<NROI_REF[k]-1 ; j++ ) {// b/c we put '\n' after last fprintf(fout1,"%12.4f\t",BOBatanhf(Corr_Matr[k][i][j])); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = BOBatanhf(Corr_Matr[k][i][j]); /* fprintf(fout1,"%12.4f\t",FisherZ(Corr_Matr[k][i][j])); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = FisherZ(Corr_Matr[k][i][j]);*/ } fprintf(fout1,"%12.4f\n",BOBatanhf(Corr_Matr[k][i][j])); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = BOBatanhf(Corr_Matr[k][i][j]); /*fprintf(fout1,"%12.4f\n",FisherZ(Corr_Matr[k][i][j])); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = FisherZ(Corr_Matr[k][i][j]);*/ } } if(PART_CORR) { FM_ctr++; ParLab[FM_ctr] = strdup("PC"); fprintf(fout1,"# %s\n", "PC"); for( i=0 ; i<NROI_REF[k] ; i++ ) { for( j=0 ; j<NROI_REF[k]-1 ; j++ ) {// b/c we put '\n' after last fprintf(fout1,"%12.4f\t",PCorr_Matr[k][i][j]); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = PCorr_Matr[k][i][j]; } fprintf(fout1,"%12.4f\n",PCorr_Matr[k][i][j]); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = PCorr_Matr[k][i][j]; } FM_ctr++; ParLab[FM_ctr] = strdup("PCB"); fprintf(fout1,"# %s\n", "PCB"); for( i=0 ; i<NROI_REF[k] ; i++ ) { for( j=0 ; j<NROI_REF[k]-1 ; j++ ) {// b/c we put '\n' after last fprintf(fout1,"%12.4f\t",PBCorr_Matr[k][i][j]); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = PBCorr_Matr[k][i][j]; } fprintf(fout1,"%12.4f\n",PBCorr_Matr[k][i][j]); flat_matr[k][FM_ctr][i*NROI_REF[k]+j] = PBCorr_Matr[k][i][j]; } } fclose(fout1); // more nimling gset = SUMA_FloatVec_to_GDSET(flat_matr[k], Noutmat, NROI_REF[k]*NROI_REF[k], "full", ParLab, NULL, NULL, NULL); if( xyz = THD_roi_cmass(ROIS, k, ROI_LABELS_REF[k]+1, NROI_REF[k]) ) { if (!(SUMA_AddGDsetNodeListElement(gset, NULL, xyz, NULL, NULL, gdset_roi_names[k], NULL, NULL, NROI_REF[k]))) { ERROR_message("Failed to add node list"); exit(1); } free(xyz); } else { ERROR_message("Failed in THD_roi_cmass"); exit(1); } sprintf(OUT_gdset,"%s_%03d",prefix,k); GDSET_netngrlink = Network_link(SUMA_FnameGet( OUT_gdset, "f",NULL)); NI_add_to_group(gset->ngr, GDSET_netngrlink); NAME_gdset = SUMA_WriteDset_ns( OUT_gdset, gset, SUMA_ASCII_NIML, 1, 0); if (!NAME_gdset && !SUMA_IS_DSET_STDXXX_FORMAT(SUMA_ASCII_NIML)) { ERROR_message("Failed to write dataset."); exit(1); } else { if (NAME_gdset) SUMA_free(NAME_gdset); NAME_gdset = NULL; } SUMA_FreeDset(gset); gset=NULL; } if(TS_OUT) { for( k=0 ; k<HAVE_ROIS ; k++) { // each netw gets own file sprintf(OUT_grid,"%s_%03d.netts",prefix,k); if( (fout1 = fopen(OUT_grid, "w")) == NULL) { fprintf(stderr, "Error opening file %s.",OUT_grid); exit(19); } for( i=0 ; i<NROI_REF[k] ; i++ ) { if(TS_LABEL) fprintf(fout1,"%d\t",ROI_LABELS_REF[k][i+1]); // labels go 1...M for( j=0 ; j<Dim[3]-1 ; j++ ) // b/c we put '\n' after last one. fprintf(fout1,"%.3e\t",ROI_AVE_TS[k][i][j]); fprintf(fout1,"%.3e\n",ROI_AVE_TS[k][i][j]); } fclose(fout1); } } if( TS_INDIV ) { for( k=0 ; k<HAVE_ROIS ; k++) { // each netw gets own file sprintf(OUT_indiv0,"%s_%03d_INDIV", prefix, k); mkdir(OUT_indiv0, 0777); for( i=0 ; i<NROI_REF[k] ; i++ ) { sprintf(OUT_indiv,"%s/ROI_%03d.netts", OUT_indiv0,ROI_LABELS_REF[k][i+1]); if( (fout2 = fopen(OUT_indiv, "w")) == NULL) { fprintf(stderr, "\nError opening file '%s'.\n",OUT_indiv); exit(19); } for( j=0 ; j<Dim[3]-1 ; j++ ) // b/c we put '\n' after last one. fprintf(fout2,"%.3e\t",ROI_AVE_TS[k][i][j]); fprintf(fout2,"%.3e\n",ROI_AVE_TS[k][i][j]); fclose(fout2); } } } if( TS_WBCORR_r || TS_WBCORR_Z ) { INFO_message("Starting whole brain correlations."); i = WB_netw_corr( TS_WBCORR_r, TS_WBCORR_Z, HAVE_ROIS, prefix, NIFTI_OUT, NROI_REF, Dim, ROI_AVE_TS, ROI_LABELS_REF, insetTIME, mskd2, Nmask, argc, argv); } // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ DSET_delete(ROIS); free(ROIS); for ( i = 0 ; i < HAVE_ROIS ; i++ ) { for (j = 0; j < NROI_REF[i]; ++j) free(gdset_roi_names[i][j]); free(gdset_roi_names[i]); } free(gdset_roi_names); for ( i = 0 ; i < HAVE_ROIS ; i++ ) for ( j = 0 ; j < Noutmat ; j++ ) free(flat_matr[i][j]); for ( i = 0 ; i < HAVE_ROIS ; i++ ) free(flat_matr[i]); free(flat_matr); for( i=0 ; i<Noutmat ; i++) free(ParLab[i]); free(ParLab); if(LabTabStr) free(LabTabStr); if(roi_dtable) free(roi_dtable); for ( i=0 ; i<HAVE_ROIS ; i++ ) for ( j=0 ; j<NROI_REF[i]+1 ; j++ ) free(ROI_STR_LABELS[i][j]); for ( i=0 ; i<HAVE_ROIS ; i++ ) free(ROI_STR_LABELS[i]); free(ROI_STR_LABELS); DSET_delete(insetTIME); free(insetTIME); free(mskd2); free(Nlist); free(Dim); // need to free last because it's used for other arrays... free(prefix); // if(HAVE_SELROI) // free(SELROI); if(HAVE_ROIS >0) { for( i=0 ; i<HAVE_ROIS ; i++) { for( j=0 ; j<NROI_REF[i] ; j++) { free(ROI_LISTS[i][j]); free(ROI_AVE_TS[i][j]); free(Corr_Matr[i][j]); if(PART_CORR) { free(PCorr_Matr[i][j]); free(PBCorr_Matr[i][j]); } } free(ROI_LISTS[i]); free(ROI_AVE_TS[i]); free(Corr_Matr[i]); if(PART_CORR){ free(PCorr_Matr[i]); free(PBCorr_Matr[i]); } free(ROI_LABELS_REF[i]); free(INV_LABELS_REF[i]); free(ROI_COUNT[i]); } free(ROI_LISTS); free(ROI_AVE_TS); free(Corr_Matr); if(PART_CORR) { free(PCorr_Matr); free(PBCorr_Matr); } free(ROI_LABELS_REF); free(INV_LABELS_REF); free(ROI_COUNT); free(NROI_REF); free(INVROI_REF); } return 0; }
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); }