int GenFeatureDist(SEG_OPTS *Opt) { ENTRY("GenFeatureDist"); /* get the probability maps */ if (!Opt->pset && Opt->DO_p) { if (!(Opt->pset = p_C_GIV_A(Opt))) { ERROR_message("Failed miserably"); RETURN(0); } } /* Get the classes */ if (!Opt->cset && Opt->crefix && Opt->DO_c) { if (!(SUMA_assign_classes_eng(Opt->pset, Opt->clss->str, Opt->clss->num, Opt->keys, Opt->cmask, &Opt->cset))) { ERROR_message("Failed aimlessly"); RETURN(0); } EDIT_dset_items(Opt->cset, ADN_prefix, Opt->crefix, ADN_none); if( !THD_ok_overwrite() && THD_is_file( DSET_HEADNAME(Opt->cset) ) ){ ERROR_exit("Output file %s already exists -- cannot continue!\n", DSET_HEADNAME(Opt->cset) ) ; } } /* group classes ? */ if (Opt->group_classes) { THD_3dim_dataset *gcset=NULL; THD_3dim_dataset *gpset=NULL; if (!SUMA_Regroup_classes (Opt, Opt->clss->str, Opt->clss->num, Opt->keys, Opt->group_classes->str, Opt->group_classes->num, Opt->group_keys, Opt->cmask, Opt->pset, Opt->cset, &gpset, &gcset) ) { ERROR_message("Failed to regroup"); RETURN(0); } DSET_write(gpset); DSET_write(gcset); } RETURN(1); }
static FILE * fopen_maybe( char *fname ) /* 05 Feb 2008 */ { FILE *imfile ; char *tname = NULL; int tlen; if( fname == NULL || *fname == '\0' ) return NULL ; /* bad input */ /* special case -- be sure not to fclose() stdout! */ /* ------------------------------------------------------------- */ /* test file streams with tname, where any .1D has been stripped */ /* note: the .1D suffix might come from EDIT_dset_items() */ /* problem noted by I Schwabacher 13 Nov 2012 [rickr] */ tlen = strlen(fname); if( tlen > 3 && !strcmp(fname+tlen-3, ".1D") ) { tname = strdup(fname); tname[tlen-3] = '\0'; } else tname = fname; if( strcmp(tname,"-") == 0 || strcmp(tname,"stdout") == 0 || strcmp(tname,"stdout:") == 0 ) return stdout ; if( strcmp(tname,"stderr" ) == 0 || strcmp(tname,"stderr:") == 0 ) return stderr ; if( tname != fname ) free(tname); /* done with tname */ /* ------------------------------------------------------------- */ if( THD_is_ondisk(fname) ){ /* check for existing file */ if( !THD_ok_overwrite() ){ /* if not allowed to overwrite */ ERROR_message("(FAILED) attempt to over-write file %s",fname) ; return NULL ; } else { WARNING_message("over-writing file %s",fname) ; /* tell the user */ } } imfile = fopen(fname,"w") ; if( imfile == NULL ) ERROR_message("Can't open for output: %s",fname) ; return imfile ; }
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[]) { int i,j,k,m,n,aa,ii,jj,kk,mm,rr; int iarg; int nmask1=0; int nmask2=0; THD_3dim_dataset *insetFA = NULL, *insetV1 = NULL, *insetMD = NULL, *insetL1 = NULL; THD_3dim_dataset *insetEXTRA=NULL; THD_3dim_dataset *mset2=NULL; THD_3dim_dataset *mset1=NULL; THD_3dim_dataset *outsetMAP=NULL, *outsetMASK=NULL; char *prefix="tracky"; int LOG_TYPE=0; char in_FA[300]; char in_V1[300]; char in_MD[300]; char in_L1[300]; int EXTRAFILE=0; // switch for whether other file is input as WM map char OUT_bin[300]; char OUT_tracstat[300]; char prefix_mask[300]; char prefix_map[300]; // FACT algopts FILE *fout0; float MinFA=0.2,MaxAngDeg=45,MinL=20.0; float MaxAng; int SeedPerV[3]={2,2,2}; int ArrMax=0; float tempvmagn; int Nvox=-1; // tot number vox int Dim[3]={0,0,0}; // dim in each dir int Nseed=0,M=30,bval=1000; int DimSeed[3]; // number of seeds there will be float Ledge[3]; // voxel edge lengths int *ROI1, *ROI2; short int *temp_arr; char *temp_byte; int **Tforw, **Tback; int **Ttot; float **flTforw, **flTback; float ****coorded; int ****INDEX; int len_forw, len_back; // int count of num of squares through float phys_forw[1], phys_back[1]; int idx; float ave_tract_len, ave_tract_len_phys; int inroi1, inroi2, KEEPIT; // switches for detecting int in[3]; // to pass to trackit float physin[3]; // also for trackit, physical loc, int totlen; float totlen_phys; int Numtract; int READS_in; float READS_fl; int end[2][3]; int test_ind[2][3]; int roi3_ct=0, id=0; float roi3_mu_MD = 0.,roi3_mu_RD = 0.,roi3_mu_L1 = 0.,roi3_mu_FA = 0.; float roi3_sd_MD = 0.,roi3_sd_RD = 0.,roi3_sd_L1 = 0.,roi3_sd_FA = 0.; float tempMD,tempFA,tempRD,tempL1; char dset_or[4] = "RAI"; THD_3dim_dataset *dsetn; int TV_switch[3] = {0,0,0}; TAYLOR_BUNDLE *tb=NULL; TAYLOR_TRACT *tt=NULL; char *mode = "NI_fast_binary"; NI_element *nel=NULL; int dump_opts=0; tv_io_header header1 = {.id_string = "TRACK\0", .origin = {0,0,0}, .n_scalars = 3, .scal_n[0] = "FA", .scal_n[1] = "MD", .scal_n[2] = "L1", .n_properties = 0, .vox_to_ras = {{0.,0.,0.,0.},{0.,0.,0.,0.}, {0.,0.,0.,0.},{0.,0.,0.,0.}}, // reset this later based on actual data set .voxel_order = "RAI\0", .invert_x = 0, .invert_y = 0, .invert_z = 0, .swap_xy = 0, .swap_yz = 0, .swap_zx = 0, .n_count = 0, .version = 2, .hdr_size = 1000}; // for testing names... char *postfix[4]={"+orig.HEAD\0",".nii.gz\0",".nii\0","+tlrc.HEAD\0"}; int FOUND =-1; int RECORD_ORIG = 0; float Orig[3] = {0.0,0.0,0.0}; mainENTRY("3dTrackID"); machdep(); // **************************************************************** // **************************************************************** // load AFNI stuff // **************************************************************** // **************************************************************** INFO_message("version: MU"); /** scan args **/ if (argc == 1) { usage_TrackID(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_TrackID(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-verb") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-verb'") ; set_tract_verb(atoi(argv[iarg])); iarg++ ; continue ; } if( strcmp(argv[iarg],"-write_opts") == 0) { dump_opts=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-rec_orig") == 0) { RECORD_ORIG=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-tract_out_mode") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-tract_out_mode'") ; if (strcmp(argv[iarg], "NI_fast_binary") && strcmp(argv[iarg], "NI_fast_text") && strcmp(argv[iarg], "NI_slow_binary") && strcmp(argv[iarg], "NI_slow_text") ) { ERROR_message("Bad value (%s) for -tract_out_mode",argv[iarg]); exit(1); } mode = argv[iarg]; iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask1") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask1'") ; mset1 = THD_open_dataset( argv[iarg] ) ; if( mset1 == NULL ) ERROR_exit("Can't open mask1 dataset '%s'", argv[iarg]) ; DSET_load(mset1) ; CHECK_LOAD_ERROR(mset1) ; nmask1 = DSET_NVOX(mset1) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask2") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask2'") ; mset2 = THD_open_dataset( argv[iarg] ) ; if( mset2 == NULL ) ERROR_exit("Can't open mask2 dataset '%s'", argv[iarg]) ; DSET_load(mset2) ; CHECK_LOAD_ERROR(mset2) ; nmask2 = DSET_NVOX(mset2) ; iarg++ ; continue ; } 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],"-input") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-input'"); for( i=0 ; i<4 ; i++) { sprintf(in_FA,"%s_FA%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_FA)) { FOUND = i; break; } } insetFA = THD_open_dataset(in_FA) ; if( (insetFA == NULL ) || (FOUND==-1)) ERROR_exit("Can't open dataset '%s': for FA.",in_FA); DSET_load(insetFA) ; CHECK_LOAD_ERROR(insetFA) ; Nvox = DSET_NVOX(insetFA) ; Dim[0] = DSET_NX(insetFA); Dim[1] = DSET_NY(insetFA); Dim[2] = DSET_NZ(insetFA); Ledge[0] = fabs(DSET_DX(insetFA)); Ledge[1] = fabs(DSET_DY(insetFA)); Ledge[2] = fabs(DSET_DZ(insetFA)); Orig[0] = DSET_XORG(insetFA); Orig[1] = DSET_YORG(insetFA); Orig[2] = DSET_ZORG(insetFA); // check tot num vox match (as proxy for dims...) if( (Nvox != nmask1) || (Nvox != nmask2) ) ERROR_exit("Input dataset does not match both mask volumes!"); // this stores the original data file orientation for later use, // as well since we convert everything to RAI temporarily, as // described below header1.voxel_order[0]=ORIENT_typestr[insetFA->daxes->xxorient][0]; header1.voxel_order[1]=ORIENT_typestr[insetFA->daxes->yyorient][0]; header1.voxel_order[2]=ORIENT_typestr[insetFA->daxes->zzorient][0]; for( i=0 ; i<3 ; i++) { header1.dim[i] = Dim[i]; header1.voxel_size[i] = Ledge[i]; // will want this when outputting file later for TrackVis. TV_switch[i] = !(dset_or[i]==header1.voxel_order[i]); } dset_or[3]='\0'; FOUND = -1; for( i=0 ; i<4 ; i++) { sprintf(in_V1,"%s_V1%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_V1)) { FOUND = i; break; } } insetV1 = THD_open_dataset(in_V1); if( insetV1 == NULL ) ERROR_exit("Can't open dataset '%s':V1",in_V1); DSET_load(insetV1) ; CHECK_LOAD_ERROR(insetV1) ; FOUND = -1; for( i=0 ; i<4 ; i++) { sprintf(in_L1,"%s_L1%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_L1)) { FOUND = i; break; } } insetL1 = THD_open_dataset(in_L1); if( insetL1 == NULL ) ERROR_exit("Can't open dataset '%s':L1",in_L1); DSET_load(insetL1) ; CHECK_LOAD_ERROR(insetL1) ; FOUND = -1; for( i=0 ; i<4 ; i++) { sprintf(in_MD,"%s_MD%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_MD)) { FOUND = i; break; } } insetMD = THD_open_dataset(in_MD); if( insetMD == NULL ) ERROR_exit("Can't open dataset '%s':MD",in_MD); DSET_load(insetMD) ; CHECK_LOAD_ERROR(insetMD) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-algopt") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-algopt'"); if (!(nel = ReadTractAlgOpts(argv[iarg]))) { ERROR_message("Failed to read options in %s\n", argv[iarg]); exit(19); } if (NI_getTractAlgOpts(nel, &MinFA, &MaxAngDeg, &MinL, SeedPerV, &M, &bval)) { ERROR_message("Failed to get options"); exit(1); } NI_free_element(nel); nel=NULL; iarg++ ; continue ; } if( strcmp(argv[iarg],"-logic") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-logic'"); INFO_message("ROI logic type is: %s",argv[iarg]); if( strcmp(argv[iarg],"AND") == 0 ) LOG_TYPE = 1; else if( strcmp(argv[iarg],"OR") == 0 ) LOG_TYPE = 0; else if( strcmp(argv[iarg],"ALL") == 0 ) LOG_TYPE = -1; else ERROR_exit("Illegal after '-logic': need 'OR' or 'AND'"); iarg++ ; continue ; } //@@ if( strcmp(argv[iarg],"-extra_set") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-extra_set'"); EXTRAFILE = 1; // switch on insetEXTRA = THD_open_dataset(argv[iarg]); if( (insetEXTRA == NULL ) ) ERROR_exit("Can't open dataset '%s': for extra set.",argv[iarg]); DSET_load(insetEXTRA) ; CHECK_LOAD_ERROR(insetEXTRA) ; if( !((Dim[0] == DSET_NX(insetEXTRA)) && (Dim[1] == DSET_NY(insetEXTRA)) && (Dim[2] == DSET_NZ(insetEXTRA)))) ERROR_exit("Dimensions of extra set '%s' don't match those of the DTI prop ones ('%s', etc.).",argv[iarg], in_FA); iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } if (iarg < 4) { ERROR_message("Too few options. Try -help for details.\n"); exit(1); } if (dump_opts) { nel = NI_setTractAlgOpts(NULL, &MinFA, &MaxAngDeg, &MinL, SeedPerV, &M, &bval); WriteTractAlgOpts(prefix, nel); NI_free_element(nel); nel=NULL; } // Process the options a little for( i=0 ; i<3 ; i++) DimSeed[i] = Dim[i]*SeedPerV[i]; Nseed = Nvox*SeedPerV[0]*SeedPerV[1]*SeedPerV[2]; // convert to cos of rad value for comparisons, instead of using acos() MaxAng = cos(CONV*MaxAngDeg); // switch to add header-- option for now, added Sept. 2012 // for use with map_TrackID to map tracks to different space if(RECORD_ORIG) { for( i=0 ; i<3 ; i++) header1.origin[i] = Orig[i]; } // at some point, we will have to convert indices into // pseudo-locations; being forced into this choice means that // different data set orientations would be represented differently // and incorrectly in some instances... so, for now, we'll resample // everything to RAI, and then resample back later. guess this will // just slow things down slightly. // have all be RAI for processing here if(TV_switch[0] || TV_switch[1] || TV_switch[2]) { dsetn = r_new_resam_dset(insetFA, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetFA); insetFA=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(insetMD, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetMD); insetMD=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(insetV1, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetV1); insetV1=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(insetL1, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetL1); insetL1=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(mset1, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(mset1); mset1=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(mset2, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(mset2); mset2=dsetn; dsetn=NULL; if(EXTRAFILE) { dsetn = r_new_resam_dset(insetEXTRA, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetEXTRA); insetEXTRA=dsetn; dsetn=NULL; } } // **************************************************************** // **************************************************************** // make arrays for tracking // **************************************************************** // **************************************************************** // for temp storage array, just a multiple of longest dimension! if(Dim[0] > Dim[1]) ArrMax = Dim[0] * 4; else ArrMax = Dim[1] * 4; if(4*Dim[2] > ArrMax) ArrMax = Dim[2] * 4; ROI1 = (int *)calloc(Nvox, sizeof(int)); ROI2 = (int *)calloc(Nvox, sizeof(int)); temp_arr = (short int *)calloc(Nvox, sizeof(short int)); temp_byte = (char *)calloc(Nvox, sizeof(char)); // temp storage whilst tracking Tforw = calloc(ArrMax, sizeof(Tforw)); for(i=0 ; i<ArrMax ; i++) Tforw[i] = calloc(3, sizeof(int)); Ttot = calloc(2*ArrMax , sizeof(Ttot)); for(i=0 ; i<2*ArrMax ; i++) Ttot[i] = calloc(3, sizeof(int)); Tback = calloc(ArrMax, sizeof(Tback)); for(i=0 ; i<ArrMax ; i++) Tback[i] = calloc(3, sizeof(int)); // temp storage whilst tracking, physical loc flTforw = calloc(ArrMax, sizeof(flTforw)); for(i=0 ; i<ArrMax ; i++) flTforw[i] = calloc(3, sizeof(int)); flTback = calloc(ArrMax,sizeof(flTback)); for(i=0 ; i<ArrMax ; i++) flTback[i] = calloc(3, sizeof(int)); if( (ROI1 == NULL) || (ROI2 == NULL) || (temp_arr == NULL) || (Tforw == NULL) || (Tback == NULL) || (flTforw == NULL) || (flTback == NULL) || (Ttot == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(12); } coorded = (float ****) calloc( Dim[0], sizeof(float ***) ); for ( i = 0 ; i < Dim[0] ; i++ ) coorded[i] = (float ***) calloc( Dim[1], sizeof(float **) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) coorded[i][j] = (float **) calloc( Dim[2], sizeof(float *) ); for ( i=0 ; i<Dim[0] ; i++ ) for ( j=0 ; j<Dim[1] ; j++ ) for ( k= 0 ; k<Dim[2] ; k++ ) //3 comp of V1 and FA coorded[i][j][k] = (float *) calloc( 4, sizeof(float) ); INDEX = (int ****) calloc( Dim[0], sizeof(int ***) ); for ( i = 0 ; i < Dim[0] ; i++ ) INDEX[i] = (int ***) calloc( Dim[1], sizeof(int **) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) INDEX[i][j] = (int **) calloc( Dim[2], sizeof(int *) ); for ( i=0 ; i<Dim[0] ; i++ ) for ( j=0 ; j<Dim[1] ; j++ ) for ( k= 0 ; k<Dim[2] ; k++ ) INDEX[i][j][k] = (int *) calloc( 4, sizeof(int) ); // this statement will never be executed if allocation fails above if( (INDEX == NULL) || (coorded == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(122); } for(i=0 ; i<Nvox ; i++) { if(THD_get_voxel( mset1, i, 0) >0.5){ ROI1[i] = 1; } if(THD_get_voxel( mset2, i, 0) >0.5) ROI2[i] = 1; } // set up eigvecs in 3D coord sys, // mark off where ROIs are and keep index handy idx=0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { for( m=0 ; m<3 ; m++ ) coorded[i][j][k][m] = THD_get_voxel(insetV1, idx, m); if(EXTRAFILE) coorded[i][j][k][3] = THD_get_voxel(insetEXTRA, idx, 0); else coorded[i][j][k][3] = THD_get_voxel(insetFA, idx, 0); // make sure that |V1| == 1 for all eigenvects, otherwise it's /// a problem in the tractography; currently, some from // 3dDWItoDT do not have this property... tempvmagn = sqrt(coorded[i][j][k][0]*coorded[i][j][k][0]+ coorded[i][j][k][1]*coorded[i][j][k][1]+ coorded[i][j][k][2]*coorded[i][j][k][2]); if( tempvmagn<0.99 ) for( m=0 ; m<3 ; m++ ) coorded[i][j][k][m]/= tempvmagn; INDEX[i][j][k][0] =idx; // first value is the index itself if( ROI1[idx]==1 ) INDEX[i][j][k][1]=1; // second value identifies ROI1 mask else INDEX[i][j][k][1]=0; if( ROI2[idx]==1 ) INDEX[i][j][k][2]=1; // third value identifies ROI2 mask else INDEX[i][j][k][2]=0; // fourth value will be counter for number of kept tracks // passing through INDEX[i][j][k][3] = 0; idx+= 1; } // ************************************************************* // ************************************************************* // Beginning of main loop // ************************************************************* // ************************************************************* Numtract = 0; ave_tract_len = 0.; ave_tract_len_phys = 0.; sprintf(OUT_bin,"%s.trk",prefix); if( (fout0 = fopen(OUT_bin, "w")) == NULL) { fprintf(stderr, "Error opening file %s.",OUT_bin); exit(16); } fwrite(&header1,sizeof(tv_io_header),1,fout0); if (get_tract_verb()) { INFO_message("Begin tracking..."); } tb = AppCreateBundle(NULL, 0, NULL, insetFA); // start bundle id = 0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) if(coorded[i][j][k][3] >= MinFA) { for( ii=0 ; ii<SeedPerV[0] ; ii++ ) for( jj=0 ; jj<SeedPerV[1] ; jj++ ) for( kk=0 ; kk<SeedPerV[2] ; kk++ ) { in[0] = i; in[1] = j; in[2] = k; physin[0] = ((float) in[0] + (0.5 + (float) ii)/SeedPerV[0])*Ledge[0]; physin[1] = ((float) in[1] + (0.5 + (float) jj)/SeedPerV[1])*Ledge[1]; physin[2] = ((float) in[2] + (0.5 + (float) kk)/SeedPerV[2])*Ledge[2]; len_forw = TrackIt(coorded, in, physin, Ledge, Dim, MinFA, MaxAng, ArrMax, Tforw, flTforw, 1, phys_forw); // reset, because it's changed in TrackIt func in[0] = i; in[1] = j; in[2] = k; physin[0] = ((float) in[0] + (0.5 + (float) ii)/SeedPerV[0])*Ledge[0]; physin[1] = ((float) in[1] + (0.5 + (float) jj)/SeedPerV[1])*Ledge[1]; physin[2] = ((float) in[2] + (0.5 + (float) kk)/SeedPerV[2])*Ledge[2]; len_back = TrackIt(coorded, in, physin, Ledge, Dim, MinFA, MaxAng, ArrMax, Tback, flTback, -1, phys_back); KEEPIT = 0; // a simple switch totlen = len_forw+len_back-1; // NB: overlap of starts totlen_phys = phys_forw[0] + phys_back[0]; if( totlen_phys >= MinL ) { // glue together for simpler notation later for( n=0 ; n<len_back ; n++) { // all of this rr = len_back-n-1; // read in backward for(m=0;m<3;m++) Ttot[rr][m] = Tback[n][m]; } for( n=1 ; n<len_forw ; n++){// skip first->overlap rr = n+len_back-1; // put after for(m=0;m<3;m++) Ttot[rr][m] = Tforw[n][m]; } // <<So close and orthogonal condition>>: // test projecting ends, to see if they abut ROI. for(m=0;m<3;m++) { //actual projected ends end[1][m] = 2*Ttot[totlen-1][m]-Ttot[totlen-2][m]; end[0][m] = 2*Ttot[0][m]-Ttot[1][m]; // default choice, just retest known ends // as default test_ind[1][m] = test_ind[0][m] = Ttot[0][m]; } tt = Create_Tract(len_back, flTback, len_forw, flTforw, id, insetFA); ++id; if (LOG_TYPE == -1) { KEEPIT = 1; } else { inroi1 = 0; // check forw for( n=0 ; n<len_forw ; n++) { if(INDEX[Tforw[n][0]][Tforw[n][1]][Tforw[n][2]][1]==1){ inroi1 = 1; break; } else continue; } if( inroi1==0 ){// after 1st half, check 2nd half for( m=0 ; m<len_back ; m++) { if(INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][1]==1){ inroi1 = 1; break; } else continue; } } // after 1st&2nd halves, check bound/neigh if( inroi1==0 ) { if(INDEX[test_ind[1][0]][test_ind[1][1]][test_ind[1][2]][1]==1) inroi1 = 1; if(INDEX[test_ind[0][0]][test_ind[0][1]][test_ind[0][2]][1]==1) inroi1 = 1; } if( ((LOG_TYPE ==0) && (inroi1 ==0)) || ((LOG_TYPE ==1) && (inroi1 ==1))) { // have to check in ROI2 inroi2 = 0; // check forw for( n=0 ; n<len_forw ; n++) { if(INDEX[Tforw[n][0]][Tforw[n][1]][Tforw[n][2]][2]==1){ inroi2 = 1; break; } else continue; } //after 1st half, check 2nd half if( inroi2==0 ) { for( m=0 ; m<len_back ; m++) { if(INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][2]==1){ inroi2 = 1; break; } else continue; } } // after 1st&2nd halves, check bound/neigh if( inroi2==0 ) { if(INDEX[test_ind[1][0]][test_ind[1][1]][test_ind[1][2]][2]==1) inroi2 = 1; if(INDEX[test_ind[0][0]][test_ind[0][1]][test_ind[0][2]][2]==1) inroi2 = 1; } // for both cases, need to see it here to keep if( inroi2 ==1 ) KEEPIT = 1; // otherwise, it's gone } else if((LOG_TYPE ==0) && (inroi1 ==1)) KEEPIT = 1; } } // by now, we *know* if we're keeping this or not. if( KEEPIT == 1 ) { tb = AppCreateBundle(tb, 1, tt, NULL); tt = Free_Tracts(tt, 1); READS_in = totlen; fwrite(&READS_in,sizeof(READS_in),1,fout0); for( n=0 ; n<len_back ; n++) { //put this one in backwords, to make it connect m = len_back - 1 - n; for(aa=0 ; aa<3 ; aa++) { // recenter phys loc for trackvis, if nec... // just works this way (where they define // origin) READS_fl = flTback[m][aa]; if(!TV_switch[aa]) READS_fl = Ledge[aa]*Dim[aa]-READS_fl; fwrite(&READS_fl,sizeof(READS_fl),1,fout0); } mm = INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][0]; READS_fl =THD_get_voxel(insetFA, mm, 0); // FA fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetMD, mm, 0); // MD fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetL1, mm, 0); // L1 fwrite(&READS_fl,sizeof(READS_fl),1,fout0); // count this voxel for having a tract INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][3]+= 1; } for( m=1 ; m<len_forw ; m++) { for(aa=0 ; aa<3 ; aa++) { // recenter phys loc for trackvis, if nec... READS_fl = flTforw[m][aa]; if(!TV_switch[aa]) READS_fl = Ledge[aa]*Dim[aa]-READS_fl; fwrite(&READS_fl,sizeof(READS_fl),1,fout0); } mm = INDEX[Tforw[m][0]][Tforw[m][1]][Tforw[m][2]][0]; READS_fl =THD_get_voxel(insetFA, mm, 0); // FA fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetMD, mm, 0); // MD fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetL1, mm, 0); // L1 fwrite(&READS_fl,sizeof(READS_fl),1,fout0); // count this voxel for having a tract INDEX[Tforw[m][0]][Tforw[m][1]][Tforw[m][2]][3]+= 1; } ave_tract_len+= totlen; ave_tract_len_phys+= totlen_phys; Numtract+=1; } } } fclose(fout0); if (get_tract_verb()) { INFO_message("Done tracking, have %d tracks.", tb->N_tracts); Show_Taylor_Bundle(tb, NULL, 3); } if (!Write_Bundle(tb,prefix,mode)) { ERROR_message("Failed to write the bundle"); } // ************************************************************** // ************************************************************** // Some simple stats on ROIs and outputs // ************************************************************** // ************************************************************** for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { if( INDEX[i][j][k][3]>=1 ) { tempMD = THD_get_voxel(insetMD,INDEX[i][j][k][0],0); tempFA = THD_get_voxel(insetFA,INDEX[i][j][k][0],0); tempL1 = THD_get_voxel(insetL1,INDEX[i][j][k][0],0); tempRD = 0.5*(3*tempMD-tempL1); roi3_mu_MD+= tempMD; roi3_mu_FA+= tempFA; roi3_mu_L1+= tempL1; roi3_mu_RD+= tempRD; roi3_sd_MD+= tempMD*tempMD; roi3_sd_FA+= tempFA*tempFA; roi3_sd_L1+= tempL1*tempL1; roi3_sd_RD+= tempRD*tempRD; roi3_ct+= 1; } } if(roi3_ct > 0 ) { // !!!! make into afni file roi3_mu_MD/= (float) roi3_ct; roi3_mu_FA/= (float) roi3_ct; roi3_mu_L1/= (float) roi3_ct; roi3_mu_RD/= (float) roi3_ct; roi3_sd_MD-= roi3_ct*roi3_mu_MD*roi3_mu_MD; roi3_sd_FA-= roi3_ct*roi3_mu_FA*roi3_mu_FA; roi3_sd_L1-= roi3_ct*roi3_mu_L1*roi3_mu_L1; roi3_sd_RD-= roi3_ct*roi3_mu_RD*roi3_mu_RD; roi3_sd_MD/= (float) roi3_ct-1; roi3_sd_FA/= (float) roi3_ct-1; roi3_sd_L1/= (float) roi3_ct-1; roi3_sd_RD/= (float) roi3_ct-1; roi3_sd_MD = sqrt(roi3_sd_MD); roi3_sd_FA = sqrt(roi3_sd_FA); roi3_sd_L1 = sqrt(roi3_sd_L1); roi3_sd_RD = sqrt(roi3_sd_RD); sprintf(OUT_tracstat,"%s.stats",prefix); if( (fout0 = fopen(OUT_tracstat, "w")) == NULL) { fprintf(stderr, "Error opening file %s.",OUT_tracstat); exit(19); } fprintf(fout0,"%d\t%d\n",Numtract,roi3_ct); fprintf(fout0,"%.3f\t%.3f\n",ave_tract_len/Numtract, ave_tract_len_phys/Numtract); // as usual, these next values would have to be divided by the // bval to get their actual value in standard phys units fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_FA,roi3_sd_FA); fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_MD,roi3_sd_MD); fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_RD,roi3_sd_RD); fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_L1,roi3_sd_L1); fclose(fout0); sprintf(prefix_map,"%s_MAP",prefix); sprintf(prefix_mask,"%s_MASK",prefix); outsetMAP = EDIT_empty_copy( mset1 ) ; EDIT_dset_items( outsetMAP , ADN_datum_all , MRI_short , ADN_prefix , prefix_map , ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMAP)); outsetMASK = EDIT_empty_copy( mset1 ) ; EDIT_dset_items( outsetMASK , ADN_datum_all , MRI_byte , ADN_prefix , prefix_mask , ADN_none ) ; if(!THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMASK)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMASK)); m=0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { temp_arr[m]=INDEX[i][j][k][3]; if(temp_arr[m]>0.5) temp_byte[m]=1; else temp_byte[m]=0; m++; } // re-orient the data as original inputs // (this function copies the pointer) EDIT_substitute_brick(outsetMAP, 0, MRI_short, temp_arr); temp_arr=NULL; if(TV_switch[0] || TV_switch[1] || TV_switch[2]) { dsetn = r_new_resam_dset(outsetMAP, NULL, 0.0, 0.0, 0.0, header1.voxel_order, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(outsetMAP); outsetMAP=dsetn; dsetn=NULL; } EDIT_dset_items( outsetMAP , ADN_prefix , prefix_map , ADN_none ) ; THD_load_statistics(outsetMAP ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMAP)); tross_Make_History( "3dTrackID" , argc , argv , outsetMAP) ; THD_write_3dim_dataset(NULL, NULL, outsetMAP, True); // re-orient the data as original inputs EDIT_substitute_brick(outsetMASK, 0, MRI_byte, temp_byte); temp_byte=NULL; if(TV_switch[0] || TV_switch[1] || TV_switch[2]) { dsetn = r_new_resam_dset(outsetMASK, NULL, 0.0, 0.0, 0.0, header1.voxel_order, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(outsetMASK); outsetMASK=dsetn; dsetn=NULL; } EDIT_dset_items( outsetMASK , ADN_prefix , prefix_mask , ADN_none ) ; THD_load_statistics(outsetMASK); if(!THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMASK)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMASK)); tross_Make_History( "3dTrackID" , argc , argv , outsetMASK) ; THD_write_3dim_dataset(NULL, NULL, outsetMASK, True); INFO_message("Number of tracts found = %d",Numtract) ; } else INFO_message("\n No Tracts Found!!!\n"); // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ // !!! need to free afni-sets? DSET_delete(insetFA); DSET_delete(insetMD); DSET_delete(insetL1); DSET_delete(insetV1); DSET_delete(insetEXTRA); //DSET_delete(outsetMAP); //DSET_delete(outsetMASK); DSET_delete(mset2); DSET_delete(mset1); free(prefix); free(insetV1); free(insetFA); free(mset1); free(mset2); free(insetEXTRA); free(ROI1); free(ROI2); free(temp_byte); for( i=0 ; i<ArrMax ; i++) { free(Tforw[i]); free(Tback[i]); free(flTforw[i]); free(flTback[i]); } free(Tforw); free(Tback); free(flTforw); free(flTback); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) for( k=0 ; k<Dim[2] ; k++) free(coorded[i][j][k]); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) free(coorded[i][j]); for( i=0 ; i<Dim[0] ; i++) free(coorded[i]); free(coorded); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) for( k=0 ; k<Dim[2] ; k++) free(INDEX[i][j][k]); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) free(INDEX[i][j]); for( i=0 ; i<Dim[0] ; i++) free(INDEX[i]); free(INDEX); free(temp_arr); // need to free for( i=0 ; i<2*ArrMax ; i++) free(Ttot[i]); free(Ttot); //free(mode); return 0; }
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[]) {/* Main */ static char FuncName[]={"ConvertSurface"}; int kar, volexists, i, j, Doinv, randseed, Domergesurfs=0, pciref; float DoR2S, fv[3], *pcxyzref; double xcen[3], sc[3]; double xform[4][4]; char *if_name = NULL, *of_name = NULL, *if_name2 = NULL, *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL, *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL, *acpc_name=NULL, *xmat_name = NULL, *ifpar_name = NULL, *ifpar_name2 = NULL; SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, iparType = SUMA_FT_NOT_SPECIFIED, oType = SUMA_FT_NOT_SPECIFIED; SUMA_SO_File_Format iForm = SUMA_FF_NOT_SPECIFIED, iparForm = SUMA_FF_NOT_SPECIFIED, oFormat = SUMA_FF_NOT_SPECIFIED; SUMA_SurfaceObject *SO = NULL, *SOpar = NULL, *SOsurf = NULL; SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL; SUMA_SFname *SF_name = NULL; void *SO_name = NULL; char orsurf[6], orcode[6], *PCprojpref=NULL, *NodeDepthpref=NULL; THD_warp *warp=NULL ; THD_3dim_dataset *aset=NULL; SUMA_Boolean brk, Do_tlrc, Do_mni_RAI, Do_mni_LPI, Do_acpc, Docen, Do_flip; SUMA_Boolean Doxmat, Do_wind, Do_p2s, onemore, Do_native, Do_PolDec; int Do_PCproj, Do_PCrot, Do_NodeDepth; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean exists; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;-ipar;"); kar = 1; xmat_name = NULL; xcen[0] = 0.0; xcen[1] = 0.0; xcen[2] = 0.0; brk = NOPE; orcode[0] = '\0'; randseed = 1234; sprintf(orsurf,"RAI"); Docen = NOPE; Doxmat = NOPE; Do_tlrc = NOPE; Do_mni_RAI = NOPE; Do_mni_LPI = NOPE; Do_acpc = NOPE; Do_wind = NOPE; Do_flip = NOPE; Do_p2s = NOPE; Do_native = NOPE; DoR2S = 0.0; Do_PolDec = NOPE; Do_PCproj = NO_PRJ; Do_PCrot = NO_ROT; pciref = -1; pcxyzref = NULL; PCprojpref = NULL; NodeDepthpref = NULL; Do_NodeDepth = 0; Doinv = 0; Domergesurfs = 0; onemore = NOPE; while (kar < argc) { /* loop accross command ine options */ /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { usage_SUMA_ConvertSurface(ps, strlen(argv[kar]) > 3 ? 2:1); exit (0); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); SUMA_TO_LOWER(argv[kar]); if (!brk && (strcmp(argv[kar], "-seed") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 integer after -seed\n"); exit (1); } randseed = atoi(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-xyzscale") == 0)) { kar ++; if (kar+2 >= argc) { fprintf (SUMA_STDERR, "need 3 values after -XYZscale\n"); exit (1); } sc[0] = strtod(argv[kar], NULL); kar ++; sc[1] = strtod(argv[kar], NULL); kar ++; sc[2] = strtod(argv[kar], NULL); xmat_name = "Scale"; Doxmat = YUP; Doinv = 0; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-xmat_1d") == 0) || (strcmp(argv[kar], "-xmat_1D") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -xmat_1D\n"); exit (1); } xmat_name = argv[kar]; Doxmat = YUP; Doinv = 0; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-ixmat_1d") == 0) || (strcmp(argv[kar], "-ixmat_1D") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -ixmat_1D\n"); exit (1); } xmat_name = argv[kar]; Doxmat = YUP; Doinv = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-polar_decomp") == 0)) { Do_PolDec = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-merge_surfs") == 0)) { Domergesurfs = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-pc_proj") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 argument after -pc_proj\n"); exit (1); } if (!strcmp(argv[kar],"PC0_plane")) Do_PCproj = E1_PLN_PRJ; else if (!strcmp(argv[kar],"PC1_plane")) Do_PCproj = E2_PLN_PRJ; else if (!strcmp(argv[kar],"PC2_plane")) Do_PCproj = E3_PLN_PRJ; else if (!strcmp(argv[kar],"PCZ_plane")) Do_PCproj = EZ_PLN_PRJ; else if (!strcmp(argv[kar],"PCY_plane")) Do_PCproj = EY_PLN_PRJ; else if (!strcmp(argv[kar],"PCX_plane")) Do_PCproj = EX_PLN_PRJ; else if (!strcmp(argv[kar],"PC0_dir")) Do_PCproj = E1_DIR_PRJ; else if (!strcmp(argv[kar],"PC1_dir")) Do_PCproj = E2_DIR_PRJ; else if (!strcmp(argv[kar],"PC2_dir")) Do_PCproj = E3_DIR_PRJ; else if (!strcmp(argv[kar],"PCZ_dir")) Do_PCproj = EZ_DIR_PRJ; else if (!strcmp(argv[kar],"PCY_dir")) Do_PCproj = EY_DIR_PRJ; else if (!strcmp(argv[kar],"PCX_dir")) Do_PCproj = EX_DIR_PRJ; else { SUMA_S_Err("Bad value of %s for -pca_proj", argv[kar]); exit(1); } ++kar; if (argv[kar][0] == '-') { SUMA_S_Err("Prefix for -pc_proj should not start with '-'.\n" "Could it be that %s is another option and \n" "the prefix was forgtotten?", argv[kar]); exit(1); } PCprojpref = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-node_depth") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need a prefix argument after -node_depth\n"); exit (1); } Do_NodeDepth = 1; if (argv[kar][0] == '-') { SUMA_S_Err("Prefix for -node_depth should not start with '-'.\n" "Could it be that %s is another option and \n" "the prefix was forgtotten?", argv[kar]); exit(1); } NodeDepthpref = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-make_consistent") == 0)) { Do_wind = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-flip_orient") == 0)) { Do_flip = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xcenter") == 0)) { kar ++; if (kar+2>= argc) { fprintf (SUMA_STDERR, "need 3 arguments after -xcenter\n"); exit (1); } xcen[0] = atof(argv[kar]); ++kar; xcen[1] = atof(argv[kar]); ++kar; xcen[2] = atof(argv[kar]); Docen = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-native") == 0)) { Do_native = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-orient_out") == 0)) { kar ++; if (kar>= argc) { fprintf (SUMA_STDERR, "need 1 argument after -orient_out\n"); exit (1); } snprintf(orcode, 4*sizeof(char), "%s", argv[kar]); if (!SUMA_ok_orstring(orcode)) { fprintf (SUMA_STDERR, "%s is a bad orientation string\n", orcode); exit (1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-radial_to_sphere") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -radial_to_sphere\n"); exit (1); } DoR2S = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-patch2surf") == 0)) { Do_p2s = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_ascii") == 0)) { oFormat = SUMA_XML_ASCII_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_b64") == 0)) { oFormat = SUMA_XML_B64_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_b64gz") == 0)) { oFormat = SUMA_XML_B64GZ_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) { Do_tlrc = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-acpc") == 0)) { Do_acpc = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-mni_rai") == 0)) { Do_mni_RAI = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-mni_lpi") == 0)) { Do_mni_LPI = YUP; brk = YUP; } if (!brk && !ps->arg_checked[kar]) { fprintf (SUMA_STDERR, "Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]); suggest_best_prog_option(argv[0], argv[kar]); exit (1); } else { brk = NOPE; kar ++; } } if (argc < 3) { SUMA_S_Err("Too few options"); usage_SUMA_ConvertSurface (ps, 0); exit (1); } /* transfer info from ps structure (backward compat) */ if (ps->o_N_surfnames) { of_name = ps->o_surfnames[0]; of_name2 = ps->o_surftopo[0]; oType = ps->o_FT[0]; if (oFormat == SUMA_FF_NOT_SPECIFIED) { oFormat = ps->o_FF[0]; } } if (ps->i_N_surfnames) { if_name = ps->i_surfnames[0]; if_name2 = ps->i_surftopo[0]; iType = ps->i_FT[0]; iForm = ps->i_FF[0]; } if (ps->ipar_N_surfnames) { ifpar_name = ps->ipar_surfnames[0]; ifpar_name2 = ps->ipar_surftopo[0]; iparType = ps->ipar_FT[0]; iparForm = ps->ipar_FF[0]; } if (ps->N_sv) sv_name = ps->sv[0]; if (ps->N_vp) vp_name = ps->vp[0]; /* sanity checks */ if (Do_native && orcode[0] != '\0') { SUMA_S_Err("Options -native and -orient_out are mutually exclusive"); exit(1); } if (Do_mni_LPI && Do_mni_RAI) { SUMA_S_Err("\nCombining -MNI_lpi and -MNI_rai options.\nNot good."); exit(1); } if (!if_name) { SUMA_S_Err("input surface not specified.\n"); exit(1); } if (!of_name && (Do_PCproj < 0 && !Do_NodeDepth) ) { SUMA_S_Err("output surface or projection PREFIX not specified.\n"); exit(1); } if (iType == SUMA_FT_NOT_SPECIFIED) { SUMA_S_Err("input type not recognized.\n"); exit(1); } if (oType == SUMA_FT_NOT_SPECIFIED && (Do_PCproj < 0 && !Do_NodeDepth) ) { SUMA_S_Err("output type not recognized.\n"); exit(1); } if ( oType != SUMA_GIFTI && oFormat >= SUMA_XML_SURF && oFormat <= SUMA_XML_B64GZ_SURF && (Do_PCproj < 0 && !Do_NodeDepth) ){ SUMA_S_Err("XML output options only valid with -o_gii\n"); exit(1); } if (iType == SUMA_SUREFIT) { if (!if_name2) { SUMA_S_Err("input SureFit surface incorrectly specified.\n"); exit(1); } if (sv_name && !vp_name) { SUMA_S_Err("VolParent needs the -sv option for SureFit surfaces."); exit(1); } } if (iType == SUMA_VEC) { if (!if_name2) { SUMA_S_Err("Input vec surface incorrectly specified.\n"); exit(1); } } if (( Do_mni_RAI || Do_mni_LPI) && !Do_tlrc) { SUMA_SL_Warn ( "I hope you know what you're doing.\n" "The MNI transform should only be applied to a\n" "Surface in the AFNI tlrc coordinate space.\n"); } if (Do_acpc && Do_tlrc) { SUMA_S_Err("You can't do -tlrc and -acpc simultaneously."); exit(1); } if ((Doxmat || Docen) && (Do_acpc || Do_tlrc)) { SUMA_S_Err("You can't do -tlrc or -acpc with -xmat_1D and -xcenter.\n"); exit(1); } if ((!Doxmat && Docen)) { SUMA_S_Err("You can't use -xcenter without -xmat_1D.\n"); exit(1); } if (oType == SUMA_SUREFIT) { if (!of_name2) { SUMA_S_Err("output SureFit surface incorrectly specified. \n"); exit(1); } } if (oType == SUMA_VEC) { if (!of_name2) { SUMA_S_Err("output vec surface incorrectly specified. \n"); exit(1); } } if ( ps->i_N_surfnames > 1 && !Domergesurfs) { SUMA_S_Err("Multiple surfaces specified without -merge_surfs option\n" "Nothing to do for such an input\n"); exit(1); } /* test for existence of input files */ if (!SUMA_is_predefined_SO_name(if_name, NULL, NULL, NULL, NULL) && !SUMA_filexists(if_name)) { SUMA_S_Errv("if_name %s not found.\n", if_name); exit(1); } if (if_name2) { if (!SUMA_filexists(if_name2)) { SUMA_S_Errv("if_name2 %s not found.\n", if_name2); exit(1); } } if (ifpar_name2) { if (!SUMA_filexists(ifpar_name2)) { SUMA_S_Errv("ifpar_name2 %s not found.\n", ifpar_name2); exit(1); } } if (ifpar_name) { if (!SUMA_filexists(ifpar_name)) { SUMA_S_Errv("ifpar_name %s not found.\n", ifpar_name); exit(1); } } if (xmat_name) { if (!strstr(special_xmats,xmat_name) && !SUMA_filexists(xmat_name)) { SUMA_S_Errv("xmat file %s not found.\n", xmat_name); exit(1); } } else { if (Do_PolDec) { SUMA_S_Err("-polar_decomp is useless without -xmat_1D"); exit(1); } } if (sv_name) { char *head = NULL, view[10]; head = SUMA_AfniPrefix(sv_name, view, NULL, &volexists); if (!SUMA_AfniExistsView(volexists, view) && !SUMA_filexists(sv_name)) { fprintf (SUMA_STDERR, "Error %s: volume %s not found.\n", FuncName, head); exit(1); } if (head) SUMA_free(head); head = NULL; } if ((Do_tlrc || Do_acpc) && (!sv_name)) { fprintf (SUMA_STDERR, "Error %s: -tlrc must be used with -sv option.\n", FuncName); exit(1); } if (vp_name) { if (!SUMA_filexists(vp_name)) { fprintf (SUMA_STDERR, "Error %s: %s not found.\n", FuncName, vp_name); exit(1); } } /* check for existence of output files */ if ((Do_PCproj < 0 && !Do_NodeDepth) ) { if (of_name2) { SUMA_SFname *SFname; SO_name = SUMA_2Prefix2SurfaceName (of_name, of_name2, NULL, vp_name, oType, &exists); SFname = (SUMA_SFname *)SO_name; OF_name2 = SUMA_copy_string(SFname->name_topo); OF_name = SUMA_copy_string(SFname->name_coord); } else { SO_name = SUMA_Prefix2SurfaceName (of_name, NULL, vp_name, oType, &exists); OF_name = SUMA_copy_string((char *) SO_name); } if (exists && !THD_ok_overwrite()) { if (OF_name2) fprintf (SUMA_STDERR, "Error %s: output file(s) %s and/or %s exist already.\n", FuncName, OF_name, OF_name2); else fprintf ( SUMA_STDERR, "Error %s: output file %s exists already.\n", FuncName, OF_name); exit(1); } } /* now for the real work */ if (Doxmat) { MRI_IMAGE *im = NULL; double *far=NULL; int nrow, ncol; if (!strcmp(xmat_name,"RandRigid")) { SUMA_FillRandXform(xform, randseed, 2); } else if (!strcmp(xmat_name,"RandAffine")) { SUMA_FillRandXform(xform, randseed, 3); } else if (!strcmp(xmat_name,"RandShift")) { SUMA_FillRandXform(xform, randseed, 1); } else if (!strcmp(xmat_name,"Scale")) { SUMA_FillScaleXform(xform, sc); } else if (!strcmp(xmat_name,"NegXY")) { SUMA_FillXYnegXform(xform); } else { im = mri_read_double_1D (xmat_name); if (!im) { SUMA_SLP_Err("Failed to read 1D file"); exit(1); } far = MRI_DOUBLE_PTR(im); nrow = im->nx; ncol = im->ny; if (nrow == 1) { if (ncol != 12) { SUMA_SL_Err("Mat file must have\n" "one row of 12 columns."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } i = 0; while (i < 12) { xform[i/4][0] = far[i]; ++i; xform[i/4][1] = far[i]; ++i; xform[i/4][2] = far[i]; ++i; xform[i/4][3] = far[i]; ++i; } xform[3][0] = 0.0; xform[3][1] = 0.0; xform[3][2] = 0.0; xform[3][3] = 1.0; } else { if (ncol < 4 ) { SUMA_SL_Err("Mat file must have\n" "at least 4 columns."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } if (nrow < 3 ) { SUMA_SL_Err("Mat file must have\n" "at least 3 rows."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } if (ncol > 4) { SUMA_SL_Warn( "Ignoring entries beyond 4th \n" "column in transform file."); } if (nrow > 3) { SUMA_SL_Warn( "Ignoring entries beyond 3rd\n" "row in transform file.\n"); } for (i=0; i < 3; ++i) { xform[i][0] = far[i]; xform[i][1] = far[i+nrow]; xform[i][2] = far[i+2*nrow]; xform[i][3] = far[i+3*nrow]; } xform[3][0] = 0.0; xform[3][1] = 0.0; xform[3][2] = 0.0; xform[3][3] = 1.0; } } if (LocalHead) { fprintf(SUMA_STDERR,"\n++ ConvertSurface xform:\n"); for (i=0; i < 4; ++i) { fprintf(SUMA_STDERR," %+.5f\t%+.5f\t%+.5f\t%+.5f\n", xform[i][0], xform[i][1], xform[i][2], xform[i][3]); } fprintf(SUMA_STDERR,"\n"); } mri_free(im); im = NULL; if (Doinv) { mat44 A, A0; LOAD_MAT44( A0, \ xform[0][0], xform[0][1], xform[0][2], xform[0][3], \ xform[1][0], xform[1][1], xform[1][2], xform[1][3], \ xform[2][0], xform[2][1], xform[2][2], xform[2][3] ); A = nifti_mat44_inverse(A0); UNLOAD_MAT44(A, \ xform[0][0], xform[0][1], xform[0][2], xform[0][3], \ xform[1][0], xform[1][1], xform[1][2], xform[1][3], \ xform[2][0], xform[2][1], xform[2][2], xform[2][3] ); } if (Do_PolDec) { #ifdef USE_DECOMPOSE_SHOEMAKE /* a little something to do a polar decomposition on M into M = Q*S*/ { float det, m[4][4], q[4][4], s[4][4]; char *stmp = SUMA_append_string("QS_",xmat_name); FILE *fout = fopen(stmp,"w"); SUMA_free(stmp); stmp = NULL; SUMA_S_Note("FixMe! #include above and if(1) here ..."); det = polar_decomp(M, q,s); fprintf(fout,"#[M][D]: (D is the shift)\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", M[i][0], M[i][1], M[i][2], M[i][3]); fprintf(fout,"#Q:\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], q[i][3]); fprintf(fout,"#S:\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", s[i][0], s[i][1], s[i][2], s[i][3]); fprintf(fout,"#det: %f\n", det); fprintf(fout, "#[Q][D]: A close xform to [M][D], " "without scaling.\n#M = Q*S\n"); for (i=0;i<3; ++i) fprintf(fout, "%.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], M[i][3]); fclose(fout); SUMA_free(stmp); stmp = NULL; } /* replace user's xform with orthogonal one: */ fprintf(SUMA_STDOUT,"Replacing matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", M[i][0], M[i][1], M[i][2], M[i][3]); fprintf(SUMA_STDOUT," with matrix:\n"); for (i=0;i<3; ++i) fprintf(SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], M[i][3]); for (i=0;i<3; ++i) { M[i][0] = q[i][0]; M[i][1] = q[i][1]; M[i][2] = q[i][2]; } #else {/* use the NIFTI polar decomposition function (same results as above)*/ mat33 Q, A; for (i=0;i<3;++i) { A.m[i][0] = xform[i][0]; A.m[i][1] = xform[i][1]; A.m[i][2] = xform[i][2]; } Q = nifti_mat33_polar( A ); /* replace user's xform with orthogonal one: */ fprintf(SUMA_STDOUT,"Replacing matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", xform[i][0], xform[i][1], xform[i][2], xform[i][3]); fprintf(SUMA_STDOUT," with matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", Q.m[i][0], Q.m[i][1], Q.m[i][2], xform[i][3]); for (i=0;i<3; ++i) { xform[i][0] = Q.m[i][0]; xform[i][1] = Q.m[i][1]; xform[i][2] = Q.m[i][2]; } } #endif } } if ( ps->i_N_surfnames == 1) { /* load that one surface */ SO = SUMA_Load_Surface_Object_Wrapper ( if_name, if_name2, vp_name, iType, iForm, sv_name, 1); if (!SO) { SUMA_S_Err("Failed to read input surface.\n"); exit (1); } } else if ( ps->i_N_surfnames > 1 && Domergesurfs) { SUMA_SurfaceObject **SOar=NULL; int ii; SUMA_S_Notev("Merging %d surfaces into 1\n", ps->i_N_surfnames); SOar = (SUMA_SurfaceObject **) SUMA_calloc(ps->i_N_surfnames, sizeof(SUMA_SurfaceObject *)); if (ps->N_sv > 1 || ps->N_vp > 1) { SUMA_S_Errv("Cannot handle multiple (%d) -sv or multiple (%d) -vp\n", ps->N_sv, ps->N_vp); exit(1); } for (ii = 0; ii<ps->i_N_surfnames; ++ii) { SOar[ii] = SUMA_Load_Surface_Object_Wrapper(ps->i_surfnames[ii], ps->i_surftopo[ii], vp_name, ps->i_FT[0], ps->i_FF[0], sv_name, 1); } if (!(SO = SUMA_MergeSurfs(SOar, ps->i_N_surfnames))) { SUMA_S_Err("Failed to merge"); exit(1); } for (ii = 0; ii<ps->i_N_surfnames; ++ii) { SUMA_Free_Surface_Object(SOar[ii]); SOar[ii]=NULL; } SUMA_free(SOar); SOar=NULL; } if (DoR2S > 0.0000001) { if (!SUMA_ProjectSurfaceToSphere(SO, NULL , DoR2S , NULL)) { SUMA_S_Err("Failed to project to surface"); exit(1); } } if (ifpar_name) { SOpar = SUMA_Load_Surface_Object_Wrapper ( ifpar_name, ifpar_name2, vp_name, iparType, iparForm, sv_name, 1); if (!SOpar) { SUMA_S_Err("Failed to read input parent surface.\n"); exit (1); } /* need edge list */ if (!SUMA_SurfaceMetrics_eng (SOpar,"EdgeList", NULL, 0, SUMAg_CF->DsetList)) { SUMA_SL_Err("Failed to create edgelist for parent"); exit(1); } } /* if Do_wind */ if (Do_wind) { fprintf (SUMA_STDOUT, "Checking and repairing mesh's winding consistency...\n"); /* check the winding, but that won't fix the normals, you'll have to recalculate those things, if need be ... */ if (!SUMA_SurfaceMetrics_eng (SO, "CheckWind", NULL, 0, SUMAg_CF->DsetList)) { SUMA_S_Err("Failed in SUMA_SurfaceMetrics.\n"); exit(1); } } if (Do_flip) { fprintf (SUMA_STDOUT, "Flipping triangle winding...\n"); SUMA_FlipSOTriangles(SO); } if (Do_tlrc) { fprintf (SUMA_STDOUT,"Performing talairach transform...\n"); /* form the tlrc version of the surface volume */ tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+ strlen(SO->VolPar->prefix)+60, sizeof(char)); sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix); if (!SUMA_filexists(tlrc_name)) { fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name); exit(1); } /* read the tlrc header */ aset = THD_open_dataset(tlrc_name) ; if( !ISVALID_DSET(aset) ){ SUMA_S_Err("%s is not a valid data set.\n", tlrc_name) ; exit(1); } if( aset->warp == NULL ){ SUMA_S_Err("tlrc_name does not contain a talairach transform.\n"); exit(1); } warp = aset->warp ; /* now warp the coordinates, one node at a time */ if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) { SUMA_S_Err("Failed in SUMA_AFNI_forward_warp_xyz.\n"); exit(1); } } if (Do_acpc) { fprintf (SUMA_STDOUT,"Performing acpc transform...\n"); /* form the acpc version of the surface volume */ acpc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+ strlen(SO->VolPar->prefix)+60, sizeof(char)); sprintf (acpc_name, "%s%s+acpc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix); if (!SUMA_filexists(acpc_name)) { fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, acpc_name); exit(1); } /* read the acpc header */ aset = THD_open_dataset(acpc_name) ; if( !ISVALID_DSET(aset) ){ fprintf (SUMA_STDERR, "Error %s: %s is not a valid data set.\n", FuncName, acpc_name) ; exit(1); } if( aset->warp == NULL ){ fprintf (SUMA_STDERR, "Error %s: acpc_name does not contain an acpc transform.\n", FuncName); exit(1); } warp = aset->warp ; /* now warp the coordinates, one node at a time */ if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName); exit(1); } } if (Do_mni_RAI) { fprintf (SUMA_STDOUT,"Performing MNI_RAI transform...\n"); /* apply the mni warp */ if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "RAI")) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName); exit(1); } sprintf(orsurf,"RAI"); } if (Do_mni_LPI) { fprintf (SUMA_STDOUT,"Performing MNI_LPI transform...\n"); /* apply the mni warp */ if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "LPI")) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName); exit(1); } sprintf(orsurf,"LPI"); } if (Doxmat) { fprintf (SUMA_STDOUT,"Performing affine transform...\n"); if (LocalHead) { for (i=0; i<3 ; ++i) { fprintf (SUMA_STDERR, "M[%d][:] = %f %f %f %f\n", i, xform[i][0], xform[i][1], xform[i][2], xform[i][3]); } fprintf (SUMA_STDERR,"Cen[:] %f %f %f\n", xcen[0], xcen[1], xcen[2]); } if (Docen) { if (!SUMA_Apply_Coord_xform( SO->NodeList, SO->N_Node, SO->NodeDim, xform, 0, xcen)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); } } else { if (!SUMA_Apply_Coord_xform( SO->NodeList, SO->N_Node, SO->NodeDim, xform, 0, NULL)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); } } SUMA_Blank_AfniSO_Coord_System(SO->aSO); } if (orcode[0] != '\0') { SUMA_LHv("Changing coordinates from %s to %s\n", orsurf, orcode); if (!SUMA_CoordChange(orsurf, orcode, SO->NodeList, SO->N_Node)) { SUMA_S_Err("Failed to change coords."); exit(1); } SUMA_Blank_AfniSO_Coord_System(SO->aSO); } if (Do_p2s) { SUMA_SurfaceObject *SOold = SO; SUMA_LH("Changing patch to surface..."); SO = SUMA_Patch2Surf(SOold->NodeList, SOold->N_Node, SO->FaceSetList, SO->N_FaceSet, 3); if (!SO) { SUMA_S_Err("Failed to change patch to surface."); exit(1); } /* get rid of old surface object */ SUMA_Free_Surface_Object(SOold); } if (Do_native) { if (!SUMA_Delign_to_VolPar (SO, NULL)) { SUMA_S_Err("Failed to transform coordinates to native space"); exit(1); } } if (Do_NodeDepth) { float *dpth=NULL, mx=0.0; SUMA_PC_XYZ_PROJ *pcp=NULL; if (SUMA_NodeDepth(SO->NodeList, SO->N_Node, E1_DIR_PRJ, &dpth, 0.0, NULL, &mx, &pcp) < 0) { SUMA_S_Err("Failed to compute node depth"); exit(1); } else { if (!SUMA_WriteNodeDepth(NodeDepthpref,pcp,dpth, mx)) { SUMA_S_Err("Failed to write node depth"); exit(1); } } SUMA_ifree(dpth); pcp = SUMA_Free_PC_XYZ_Proj(pcp); } if (Do_PCproj > NO_PRJ) { SUMA_PC_XYZ_PROJ *pcp=NULL; pciref = 0; pcxyzref = NULL; if (!(pcp = SUMA_Project_Coords_PCA(SO->NodeList, SO->N_Node, pciref, pcxyzref, Do_PCproj, Do_PCrot, 1))) { SUMA_S_Err("Failed to project"); exit(1); } else { if (!SUMA_Write_PC_XYZ_Proj(pcp, PCprojpref)) { SUMA_S_Err("Failed to write out projections"); exit(1); } else { pcp = SUMA_Free_PC_XYZ_Proj(pcp); } exit(0); } } /* write the surface object */ if (SO_name) { if (LocalHead) SUMA_Print_Surface_Object (SO, stderr); fprintf (SUMA_STDOUT,"Writing surface...\n"); if (!(SUMA_Save_Surface_Object ( SO_name, SO, oType, oFormat, SOpar))) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } } if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip); if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip); if (OF_name) SUMA_free(OF_name); if (OF_name2) SUMA_free(OF_name2); if (SF_name) SUMA_free(SF_name); if (SO_name) SUMA_free(SO_name); if (SO) SUMA_Free_Surface_Object(SO); if (SOpar) SUMA_Free_Surface_Object(SOpar); if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; return (0); }
int main( int argc , char * argv[] ) { int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ; float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ; MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ; THD_3dim_dataset **ortset=NULL ; int nortset=0 ; THD_3dim_dataset *inset=NULL , *outset=NULL; char *prefix="RSFC" ; byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , nx,ny,nz,nvox , nfft=0 , kk ; float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime ; MRI_vectim *mrv ; float pvrad=0.0f ; int nosat=0 ; int do_despike=0 ; // @@ non-BP variables float fbotALL=0.0f, ftopALL=999999.9f; // do full range version int NumDen = 0; // switch for doing numerator or denom THD_3dim_dataset *outsetALL=NULL ; int m, mm; float delf; // harmonics int ind_low,ind_high,N_ny, ctr; float sqnt,nt_fac; gsl_fft_real_wavetable *real1, *real2; // GSL stuff gsl_fft_real_workspace *work; double *series1, *series2; double *xx1,*xx2; float numer,denom,val; float *alff=NULL,*malff=NULL,*falff=NULL, *rsfa=NULL,*mrsfa=NULL,*frsfa=NULL; // values float meanALFF=0.0f,meanRSFA=0.0f; // will be for mean in brain region THD_3dim_dataset *outsetALFF=NULL; THD_3dim_dataset *outsetmALFF=NULL; THD_3dim_dataset *outsetfALFF=NULL; THD_3dim_dataset *outsetRSFA=NULL; THD_3dim_dataset *outsetmRSFA=NULL; THD_3dim_dataset *outsetfRSFA=NULL; char out_lff[300]; char out_alff[300]; char out_malff[300]; char out_falff[300]; char out_rsfa[300]; char out_mrsfa[300]; char out_frsfa[300]; char out_unBP[300]; int SERIES_OUT = 1; int UNBP_OUT = 0; int DO_RSFA = 1; int BP_LAST = 0; // option for only doing filter to LFFs at very end of proc float de_rsfa=0.0f,nu_rsfa=0.0f; double pow1=0.0,pow2=0.0; /*-- help? --*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "\n Program to calculate common resting state functional connectivity (RSFC)\n" " parameters (ALFF, mALFF, fALFF, RSFA, etc.) for resting state time\n" " series. This program is **heavily** based on the existing\n" " 3dBandPass by RW Cox, with the amendments to calculate RSFC\n" " parameters written by PA Taylor (July, 2012).\n" " This program is part of FATCAT (Taylor & Saad, 2013) in AFNI. Importantly,\n" " its functionality can be included in the `afni_proc.py' processing-script \n" " generator; see that program's help file for an example including RSFC\n" " and spectral parameter calculation via the `-regress_RSFC' option.\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "\n" " All options of 3dBandPass may be used here (with a couple other\n" " parameter options, as well): essentially, the motivation of this\n" " program is to produce ALFF, etc. values of the actual RSFC time\n" " series that you calculate. Therefore, all the 3dBandPass processing\n" " you normally do en route to making your final `resting state time\n" " series' is done here to generate your LFFs, from which the\n" " amplitudes in the LFF band are calculated at the end. In order to\n" " calculate fALFF, the same initial time series are put through the\n" " same processing steps which you have chosen but *without* the\n" " bandpass part; the spectrum of this second time series is used to\n" " calculate the fALFF denominator.\n" " \n" " For more information about each RSFC parameter, see, e.g.: \n" " ALFF/mALFF -- Zang et al. (2007),\n" " fALFF -- Zou et al. (2008),\n" " RSFA -- Kannurpatti & Biswal (2008).\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "\n" " + USAGE: 3dRSFC [options] fbot ftop dataset\n" "\n" "* One function of this program is to prepare datasets for input\n" " to 3dSetupGroupInCorr. Other uses are left to your imagination.\n" "\n" "* 'dataset' is a 3D+time sequence of volumes\n" " ++ This must be a single imaging run -- that is, no discontinuities\n" " in time from 3dTcat-ing multiple datasets together.\n" "\n" "* fbot = lowest frequency in the passband, in Hz\n" " ++ fbot can be 0 if you want to do a lowpass filter only;\n" " HOWEVER, the mean and Nyquist freq are always removed.\n" "\n" "* ftop = highest frequency in the passband (must be > fbot)\n" " ++ if ftop > Nyquist freq, then it's a highpass filter only.\n" "\n" "* Set fbot=0 and ftop=99999 to do an 'allpass' filter.\n" " ++ Except for removal of the 0 and Nyquist frequencies, that is.\n" "\n" "* You cannot construct a 'notch' filter with this program!\n" " ++ You could use 3dRSFC followed by 3dcalc to get the same effect.\n" " ++ If you are understand what you are doing, that is.\n" " ++ Of course, that is the AFNI way -- if you don't want to\n" " understand what you are doing, use Some other PrograM, and\n" " you can still get Fine StatisticaL maps.\n" "\n" "* 3dRSFC will fail if fbot and ftop are too close for comfort.\n" " ++ Which means closer than one frequency grid step df,\n" " where df = 1 / (nfft * dt) [of course]\n" "\n" "* The actual FFT length used will be printed, and may be larger\n" " than the input time series length for the sake of efficiency.\n" " ++ The program will use a power-of-2, possibly multiplied by\n" " a power of 3 and/or 5 (up to and including the 3rd power of\n" " each of these: 3, 9, 27, and 5, 25, 125).\n" "\n" "* Note that the results of combining 3dDetrend and 3dRSFC will\n" " depend on the order in which you run these programs. That's why\n" " 3dRSFC has the '-ort' and '-dsort' options, so that the\n" " time series filtering can be done properly, in one place.\n" "\n" "* The output dataset is stored in float format.\n" "\n" "* The order of processing steps is the following (most are optional), and\n" " for the LFFs, the bandpass is done between the specified fbot and ftop,\n" " while for the `whole spectrum' (i.e., fALFF denominator) the bandpass is:\n" " done only to exclude the time series mean and the Nyquist frequency:\n" " (0) Check time series for initial transients [does not alter data]\n" " (1) Despiking of each time series\n" " (2) Removal of a constant+linear+quadratic trend in each time series\n" " (3) Bandpass of data time series\n" " (4) Bandpass of -ort time series, then detrending of data\n" " with respect to the -ort time series\n" " (5) Bandpass and de-orting of the -dsort dataset,\n" " then detrending of the data with respect to -dsort\n" " (6) Blurring inside the mask [might be slow]\n" " (7) Local PV calculation [WILL be slow!]\n" " (8) L2 normalization [will be fast.]\n" " (9) Calculate spectrum and amplitudes, for RSFC parameters.\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "--------\n" "OPTIONS:\n" "--------\n" " -despike = Despike each time series before other processing.\n" " ++ Hopefully, you don't actually need to do this,\n" " which is why it is optional.\n" " -ort f.1D = Also orthogonalize input to columns in f.1D\n" " ++ Multiple '-ort' options are allowed.\n" " -dsort fset = Orthogonalize each voxel to the corresponding\n" " voxel time series in dataset 'fset', which must\n" " have the same spatial and temporal grid structure\n" " as the main input dataset.\n" " ++ At present, only one '-dsort' option is allowed.\n" " -nodetrend = Skip the quadratic detrending of the input that\n" " occurs before the FFT-based bandpassing.\n" " ++ You would only want to do this if the dataset\n" " had been detrended already in some other program.\n" " -dt dd = set time step to 'dd' sec [default=from dataset header]\n" " -nfft N = set the FFT length to 'N' [must be a legal value]\n" " -norm = Make all output time series have L2 norm = 1\n" " ++ i.e., sum of squares = 1\n" " -mask mset = Mask dataset\n" " -automask = Create a mask from the input dataset\n" " -blur fff = Blur (inside the mask only) with a filter\n" " width (FWHM) of 'fff' millimeters.\n" " -localPV rrr = Replace each vector by the local Principal Vector\n" " (AKA first singular vector) from a neighborhood\n" " of radius 'rrr' millimiters.\n" " ++ Note that the PV time series is L2 normalized.\n" " ++ This option is mostly for Bob Cox to have fun with.\n" "\n" " -input dataset = Alternative way to specify input dataset.\n" " -band fbot ftop = Alternative way to specify passband frequencies.\n" "\n" " -prefix ppp = Set prefix name of output dataset. Name of filtered time\n" " series would be, e.g., ppp_LFF+orig.*, and the parameter\n" " outputs are named with obvious suffices.\n" " -quiet = Turn off the fun and informative messages. (Why?)\n" " -no_rs_out = Don't output processed time series-- just output\n" " parameters (not recommended, since the point of\n" " calculating RSFC params here is to have them be quite\n" " related to the time series themselves which are used for\n" " further analysis)." " -un_bp_out = Output the un-bandpassed series as well (default is not \n" " to). Name would be, e.g., ppp_unBP+orig.* .\n" " with suffix `_unBP'.\n" " -no_rsfa = If you don't want RSFA output (default is to do so).\n" " -bp_at_end = A (probably unnecessary) switch to have bandpassing be \n" " the very last processing step that is done in the\n" " sequence of steps listed above; at Step 3 above, only \n" " the time series mean and nyquist are BP'ed out, and then\n" " the LFF series is created only after Step 9. NB: this \n" " probably makes only very small changes for most\n" " processing sequences (but maybe not, depending usage).\n" "\n" " -notrans = Don't check for initial positive transients in the data:\n" " *OR* ++ The test is a little slow, so skipping it is OK,\n" " -nosat if you KNOW the data time series are transient-free.\n" " ++ Or set AFNI_SKIP_SATCHECK to YES.\n" " ++ Initial transients won't be handled well by the\n" " bandpassing algorithm, and in addition may seriously\n" " contaminate any further processing, such as inter-\n" " voxel correlations via InstaCorr.\n" " ++ No other tests are made [yet] for non-stationary \n" " behavior in the time series data.\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "\n" " If you use this program, please reference the introductory/description\n" " paper for the FATCAT toolbox:\n" " Taylor PA, Saad ZS (2013). FATCAT: (An Efficient) Functional\n" " And Tractographic Connectivity Analysis Toolbox. Brain \n" " Connectivity 3(5):523-535.\n" "____________________________________________________________________________\n" ); PRINT_AFNI_OMP_USAGE( " 3dRSFC" , " * At present, the only part of 3dRSFC that is parallelized is the\n" " '-blur' option, which processes each sub-brick independently.\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } /*-- startup --*/ mainENTRY("3dRSFC"); machdep(); AFNI_logger("3dRSFC",argc,argv); PRINT_VERSION("3dRSFC (from 3dBandpass by RW Cox): version THETA"); AUTHOR("PA Taylor"); nosat = AFNI_yesenv("AFNI_SKIP_SATCHECK") ; nopt = 1 ; while( nopt < argc && argv[nopt][0] == '-' ){ if( strcmp(argv[nopt],"-despike") == 0 ){ /* 08 Oct 2010 */ do_despike++ ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-nfft") == 0 ){ int nnup ; if( ++nopt >= argc ) ERROR_exit("need an argument after -nfft!") ; nfft = (int)strtod(argv[nopt],NULL) ; nnup = csfft_nextup_even(nfft) ; if( nfft < 16 || nfft != nnup ) ERROR_exit("value %d after -nfft is illegal! Next legal value = %d",nfft,nnup) ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-blur") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -blur!") ; blur = strtod(argv[nopt],NULL) ; if( blur <= 0.0f ) WARNING_message("non-positive blur?!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-localPV") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -localpv!") ; pvrad = strtod(argv[nopt],NULL) ; if( pvrad <= 0.0f ) WARNING_message("non-positive -localpv?!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-prefix") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -prefix!") ; prefix = strdup(argv[nopt]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("bad -prefix option!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-automask") == 0 ){ if( mask != NULL ) ERROR_exit("Can't use -mask AND -automask!") ; do_automask = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-mask") == 0 ){ THD_3dim_dataset *mset ; if( ++nopt >= argc ) ERROR_exit("Need argument after '-mask'") ; if( mask != NULL || do_automask ) ERROR_exit("Can't have two mask inputs") ; mset = THD_open_dataset( argv[nopt] ) ; CHECK_OPEN_ERROR(mset,argv[nopt]) ; DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset); mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ; if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[nopt]) ; nmask = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ; if( verb ) INFO_message("Number of voxels in mask = %d",nmask) ; if( nmask < 1 ) ERROR_exit("Mask is too small to process") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-norm") == 0 ){ do_norm = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-quiet") == 0 ){ verb = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-no_rs_out") == 0 ){ // @@ SERIES_OUT = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-un_bp_out") == 0 ){ // @@ UNBP_OUT = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-no_rsfa") == 0 ){ // @@ DO_RSFA = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-bp_at_end") == 0 ){ // @@ BP_LAST = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-notrans") == 0 || strcmp(argv[nopt],"-nosat") == 0 ){ nosat = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-ort") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -ort!") ; if( ortar == NULL ) INIT_IMARR(ortar) ; ortim = mri_read_1D( argv[nopt] ) ; if( ortim == NULL ) ERROR_exit("can't read from -ort '%s'",argv[nopt]) ; mri_add_name(argv[nopt],ortim) ; ADDTO_IMARR(ortar,ortim) ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-dsort") == 0 ){ THD_3dim_dataset *qset ; if( ++nopt >= argc ) ERROR_exit("need an argument after -dsort!") ; if( nortset > 0 ) ERROR_exit("only 1 -dsort option is allowed!") ; qset = THD_open_dataset(argv[nopt]) ; CHECK_OPEN_ERROR(qset,argv[nopt]) ; ortset = (THD_3dim_dataset **)realloc(ortset, sizeof(THD_3dim_dataset *)*(nortset+1)) ; ortset[nortset++] = qset ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-nodetrend",6) == 0 ){ qdet = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-dt") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -dt!") ; dt = (float)strtod(argv[nopt],NULL) ; if( dt <= 0.0f ) WARNING_message("value after -dt illegal!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-input") == 0 ){ if( inset != NULL ) ERROR_exit("Can't have 2 -input options!") ; if( ++nopt >= argc ) ERROR_exit("need an argument after -input!") ; inset = THD_open_dataset(argv[nopt]) ; CHECK_OPEN_ERROR(inset,argv[nopt]) ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-band",5) == 0 ){ if( ++nopt >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ; if( have_freq ) WARNING_message("second -band option replaces first one!") ; fbot = strtod(argv[nopt++],NULL) ; ftop = strtod(argv[nopt++],NULL) ; have_freq = 1 ; continue ; } ERROR_exit("Unknown option: '%s'",argv[nopt]) ; } /** check inputs for reasonablositiness **/ if( !have_freq ){ if( nopt+1 >= argc ) ERROR_exit("Need frequencies on command line after options!") ; fbot = (float)strtod(argv[nopt++],NULL) ; ftop = (float)strtod(argv[nopt++],NULL) ; } if( inset == NULL ){ if( nopt >= argc ) ERROR_exit("Need input dataset name on command line after options!") ; inset = THD_open_dataset(argv[nopt]) ; CHECK_OPEN_ERROR(inset,argv[nopt]) ; nopt++ ; } DSET_UNMSEC(inset) ; if( fbot < 0.0f ) ERROR_exit("fbot value can't be negative!") ; if( ftop <= fbot ) ERROR_exit("ftop value %g must be greater than fbot value %g!",ftop,fbot) ; ntime = DSET_NVALS(inset) ; if( ntime < 9 ) ERROR_exit("Input dataset is too short!") ; if( nfft <= 0 ){ nfft = csfft_nextup_even(ntime) ; if( verb ) INFO_message("Data length = %d FFT length = %d",ntime,nfft) ; (void)THD_bandpass_set_nfft(nfft) ; } else if( nfft < ntime ){ ERROR_exit("-nfft %d is less than data length = %d",nfft,ntime) ; } else { kk = THD_bandpass_set_nfft(nfft) ; if( kk != nfft && verb ) INFO_message("Data length = %d FFT length = %d",ntime,kk) ; } if( dt <= 0.0f ){ dt = DSET_TR(inset) ; if( dt <= 0.0f ){ WARNING_message("Setting dt=1.0 since input dataset lacks a time axis!") ; dt = 1.0f ; } } ftopALL = 1./dt ;// Aug,2016: should solve problem of a too-large // value for THD_bandpass_vectors(), while still // being >f_{Nyquist} if( !THD_bandpass_OK(ntime,dt,fbot,ftop,1) ) ERROR_exit("Can't continue!") ; nx = DSET_NX(inset); ny = DSET_NY(inset); nz = DSET_NZ(inset); nvox = nx*ny*nz; /* check mask, or create it */ if( verb ) INFO_message("Loading input dataset time series" ) ; DSET_load(inset) ; if( mask != NULL ){ if( mask_nx != nx || mask_ny != ny || mask_nz != nz ) ERROR_exit("-mask dataset grid doesn't match input dataset") ; } else if( do_automask ){ mask = THD_automask( inset ) ; if( mask == NULL ) ERROR_message("Can't create -automask from input dataset?") ; nmask = THD_countmask( DSET_NVOX(inset) , mask ) ; if( verb ) INFO_message("Number of voxels in automask = %d",nmask); if( nmask < 1 ) ERROR_exit("Automask is too small to process") ; } else { mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ; memset(mask,1,sizeof(byte)*nvox) ; // if( verb ) // @@ alert if aaaalllllll vox are going to be analyzed! INFO_message("No mask ==> processing all %d voxels",nvox); } /* A simple check of dataset quality [08 Feb 2010] */ if( !nosat ){ float val ; INFO_message( "Checking dataset for initial transients [use '-notrans' to skip this test]") ; val = THD_saturation_check(inset,mask,0,0) ; kk = (int)(val+0.54321f) ; if( kk > 0 ) ININFO_message( "Looks like there %s %d non-steady-state initial time point%s :-(" , ((kk==1) ? "is" : "are") , kk , ((kk==1) ? " " : "s") ) ; else if( val > 0.3210f ) /* don't ask where this threshold comes from! */ ININFO_message( "MAYBE there's an initial positive transient of 1 point, but it's hard to tell\n") ; else ININFO_message("No widespread initial positive transient detected :-)") ; } /* check -dsort inputs for match to inset */ for( kk=0 ; kk < nortset ; kk++ ){ if( DSET_NX(ortset[kk]) != nx || DSET_NY(ortset[kk]) != ny || DSET_NZ(ortset[kk]) != nz || DSET_NVALS(ortset[kk]) != ntime ) ERROR_exit("-dsort %s doesn't match input dataset grid" , DSET_BRIKNAME(ortset[kk]) ) ; } /* convert input dataset to a vectim, which is more fun */ // @@ convert BP'ing ftop/bot into indices for the DFT (below) delf = 1.0/(ntime*dt); ind_low = (int) rint(fbot/delf); ind_high = (int) rint(ftop/delf); if( ntime % 2 ) // nyquist number N_ny = (ntime-1)/2; else N_ny = ntime/2; sqnt = sqrt(ntime); nt_fac = sqrt(ntime*(ntime-1)); // @@ if BP_LAST==0: // now we go through twice, doing LFF bandpass for NumDen==0 and // `full spectrum' processing for NumDen==1. // if BP_LAST==1: // now we go through once, doing only `full spectrum' processing for( NumDen=0 ; NumDen<2 ; NumDen++) { //if( NumDen==1 ){ // full spectrum // fbot = fbotALL; // ftop = ftopALL; //} // essentially, just doesn't BP here, and the perfect filtering at end // is used for both still; this makes the final output spectrum // contain only frequencies in range of 0.01-0.08 if( BP_LAST==1 ) INFO_message("Only doing filtering to LFFs at end!"); mrv = THD_dset_to_vectim( inset , mask , 0 ) ; if( mrv == NULL ) ERROR_exit("Can't load time series data!?") ; if( NumDen==1 ) DSET_unload(inset) ; // @@ only unload on 2nd pass /* similarly for the ort vectors */ if( ortar != NULL ){ for( kk=0 ; kk < IMARR_COUNT(ortar) ; kk++ ){ ortim = IMARR_SUBIM(ortar,kk) ; if( ortim->nx < ntime ) ERROR_exit("-ort file %s is shorter than input dataset time series", ortim->name ) ; ort = (float **)realloc( ort , sizeof(float *)*(nort+ortim->ny) ) ; for( vv=0 ; vv < ortim->ny ; vv++ ) ort[nort++] = MRI_FLOAT_PTR(ortim) + ortim->nx * vv ; } } /* all the real work now */ if( do_despike ){ int_pair nsp ; if( verb ) INFO_message("Testing data time series for spikes") ; nsp = THD_vectim_despike9( mrv ) ; if( verb ) ININFO_message(" -- Squashed %d spikes from %d voxels",nsp.j,nsp.i) ; } if( verb ) INFO_message("Bandpassing data time series") ; if( (BP_LAST==0) && (NumDen==0) ) (void)THD_bandpass_vectim( mrv , dt,fbot,ftop , qdet , nort,ort ) ; else (void)THD_bandpass_vectim( mrv , dt,fbotALL,ftopALL, qdet,nort,ort ) ; /* OK, maybe a little more work */ if( nortset == 1 ){ MRI_vectim *orv ; orv = THD_dset_to_vectim( ortset[0] , mask , 0 ) ; if( orv == NULL ){ ERROR_message("Can't load -dsort %s",DSET_BRIKNAME(ortset[0])) ; } else { float *dp , *mvv , *ovv , ff ; if( verb ) INFO_message("Orthogonalizing to bandpassed -dsort") ; //(void)THD_bandpass_vectim( orv , dt,fbot,ftop , qdet , nort,ort ) ; //@@ if( (BP_LAST==0) && (NumDen==0) ) (void)THD_bandpass_vectim(orv,dt,fbot,ftop,qdet,nort,ort); else (void)THD_bandpass_vectim(orv,dt,fbotALL,ftopALL,qdet,nort,ort); THD_vectim_normalize( orv ) ; dp = malloc(sizeof(float)*mrv->nvec) ; THD_vectim_vectim_dot( mrv , orv , dp ) ; for( vv=0 ; vv < mrv->nvec ; vv++ ){ ff = dp[vv] ; if( ff != 0.0f ){ mvv = VECTIM_PTR(mrv,vv) ; ovv = VECTIM_PTR(orv,vv) ; for( kk=0 ; kk < ntime ; kk++ ) mvv[kk] -= ff*ovv[kk] ; } } VECTIM_destroy(orv) ; free(dp) ; } } if( blur > 0.0f ){ if( verb ) INFO_message("Blurring time series data spatially; FWHM=%.2f",blur) ; mri_blur3D_vectim( mrv , blur ) ; } if( pvrad > 0.0f ){ if( verb ) INFO_message("Local PV-ing time series data spatially; radius=%.2f",pvrad) ; THD_vectim_normalize( mrv ) ; THD_vectim_localpv( mrv , pvrad ) ; } if( do_norm && pvrad <= 0.0f ){ if( verb ) INFO_message("L2 normalizing time series data") ; THD_vectim_normalize( mrv ) ; } /* create output dataset, populate it, write it, then quit */ if( (NumDen==0) ) { // @@ BP'ed version; will do filt if BP_LAST if(BP_LAST) // do bandpass here for BP_LAST (void)THD_bandpass_vectim(mrv,dt,fbot,ftop,qdet,0,NULL); if( verb ) INFO_message("Creating output dataset in memory, then writing it") ; outset = EDIT_empty_copy(inset) ; if(SERIES_OUT){ sprintf(out_lff,"%s_LFF",prefix); EDIT_dset_items( outset , ADN_prefix,out_lff , ADN_none ) ; tross_Copy_History( inset , outset ) ; tross_Make_History( "3dBandpass" , argc,argv , outset ) ; } for( vv=0 ; vv < ntime ; vv++ ) EDIT_substitute_brick( outset , vv , MRI_float , NULL ) ; #if 1 THD_vectim_to_dset( mrv , outset ) ; #else AFNI_OMP_START ; #pragma omp parallel { float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ; #pragma omp for for( vv=0 ; vv < ntime ; vv++ ){ far = DSET_BRICK_ARRAY(outset,vv) ; var = mrv->fvec + vv ; for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ; } } AFNI_OMP_END ; #endif VECTIM_destroy(mrv) ; if(SERIES_OUT){ // @@ DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ; } } else{ // @@ non-BP'ed version if( verb ) INFO_message("Creating output dataset 2 in memory") ; // do this here because LFF version was also BP'ed at end. if(BP_LAST) // do bandpass here for BP_LAST (void)THD_bandpass_vectim(mrv,dt,fbotALL,ftopALL,qdet,0,NULL); outsetALL = EDIT_empty_copy(inset) ; if(UNBP_OUT){ sprintf(out_unBP,"%s_unBP",prefix); EDIT_dset_items( outsetALL, ADN_prefix, out_unBP, ADN_none ); tross_Copy_History( inset , outsetALL ) ; tross_Make_History( "3dRSFC" , argc,argv , outsetALL ) ; } for( vv=0 ; vv < ntime ; vv++ ) EDIT_substitute_brick( outsetALL , vv , MRI_float , NULL ) ; #if 1 THD_vectim_to_dset( mrv , outsetALL ) ; #else AFNI_OMP_START ; #pragma omp parallel { float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ; #pragma omp for for( vv=0 ; vv < ntime ; vv++ ){ far = DSET_BRICK_ARRAY(outsetALL,vv) ; var = mrv->fvec + vv ; for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ; } } AFNI_OMP_END ; #endif VECTIM_destroy(mrv) ; if(UNBP_OUT){ DSET_write(outsetALL) ; if( verb ) WROTE_DSET(outsetALL) ; } } }// end of NumDen loop // @@ INFO_message("Starting the (f)ALaFFel calcs") ; // allocations series1 = (double *)calloc(ntime,sizeof(double)); series2 = (double *)calloc(ntime,sizeof(double)); xx1 = (double *)calloc(2*ntime,sizeof(double)); xx2 = (double *)calloc(2*ntime,sizeof(double)); alff = (float *)calloc(nvox,sizeof(float)); malff = (float *)calloc(nvox,sizeof(float)); falff = (float *)calloc(nvox,sizeof(float)); if( (series1 == NULL) || (series2 == NULL) || (xx1 == NULL) || (xx2 == NULL) || (alff == NULL) || (malff == NULL) || (falff == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(122); } if(DO_RSFA) { rsfa = (float *)calloc(nvox,sizeof(float)); mrsfa = (float *)calloc(nvox,sizeof(float)); frsfa = (float *)calloc(nvox,sizeof(float)); if( (rsfa == NULL) || (mrsfa == NULL) || (frsfa == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } } work = gsl_fft_real_workspace_alloc (ntime); real1 = gsl_fft_real_wavetable_alloc (ntime); real2 = gsl_fft_real_wavetable_alloc (ntime); gsl_complex_packed_array compl_freqs1 = xx1; gsl_complex_packed_array compl_freqs2 = xx2; // ********************************************************************* // ********************************************************************* // ************** Falafelling = ALFF/fALFF calcs ***************** // ********************************************************************* // ********************************************************************* // Be now have the BP'ed data set (outset) and the non-BP'ed one // (outsetALL). now we'll FFT both, get amplitudes in appropriate // ranges, and calculate: ALFF, mALFF, fALFF, ctr = 0; for( kk=0; kk<nvox ; kk++) { if(mask[kk]) { // BP one, and unBP one, either for BP_LAST or !BP_LAST for( m=0 ; m<ntime ; m++ ) { series1[m] = THD_get_voxel(outset,kk,m); series2[m] = THD_get_voxel(outsetALL,kk,m); } mm = gsl_fft_real_transform(series1, 1, ntime, real1, work); mm = gsl_fft_halfcomplex_unpack(series1, compl_freqs1, 1, ntime); mm = gsl_fft_real_transform(series2, 1, ntime, real2, work); mm = gsl_fft_halfcomplex_unpack(series2, compl_freqs2, 1, ntime); numer = 0.0f; denom = 0.0f; de_rsfa = 0.0f; nu_rsfa = 0.0f; for( m=1 ; m<N_ny ; m++ ) { mm = 2*m; pow2 = compl_freqs2[mm]*compl_freqs2[mm] + compl_freqs2[mm+1]*compl_freqs2[mm+1]; // power //pow2*=2;// factor of 2 since ampls are even funcs denom+= (float) sqrt(pow2); // amplitude de_rsfa+= (float) pow2; if( ( m>=ind_low ) && ( m<=ind_high ) ){ pow1 = compl_freqs1[mm]*compl_freqs1[mm]+ compl_freqs1[mm+1]*compl_freqs1[mm+1]; //pow1*=2; numer+= (float) sqrt(pow1); nu_rsfa+= (float) pow1; } } if( denom>0.000001 ) falff[kk] = numer/denom; else falff[kk] = 0.; alff[kk] = 2*numer/sqnt;// factor of 2 since ampl is even funct meanALFF+= alff[kk]; if(DO_RSFA){ nu_rsfa = sqrt(2*nu_rsfa); // factor of 2 since ampls de_rsfa = sqrt(2*de_rsfa); // are even funcs if( de_rsfa>0.000001 ) frsfa[kk] = nu_rsfa/de_rsfa; else frsfa[kk]=0.; rsfa[kk] = nu_rsfa/nt_fac; meanRSFA+= rsfa[kk]; } ctr+=1; } } meanALFF/= ctr; meanRSFA/= ctr; gsl_fft_real_wavetable_free(real1); gsl_fft_real_wavetable_free(real2); gsl_fft_real_workspace_free(work); // ALFFs divided by mean of brain value for( kk=0 ; kk<nvox ; kk++ ) if(mask[kk]){ malff[kk] = alff[kk]/meanALFF; if(DO_RSFA) mrsfa[kk] = rsfa[kk]/meanRSFA; } // ************************************************************** // ************************************************************** // Store and output // ************************************************************** // ************************************************************** outsetALFF = EDIT_empty_copy( inset ) ; sprintf(out_alff,"%s_ALFF",prefix); EDIT_dset_items( outsetALFF, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_alff, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetALFF)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetALFF)); EDIT_substitute_brick(outsetALFF, 0, MRI_float, alff); alff=NULL; THD_load_statistics(outsetALFF); tross_Make_History("3dRSFC", argc, argv, outsetALFF); THD_write_3dim_dataset(NULL, NULL, outsetALFF, True); outsetfALFF = EDIT_empty_copy( inset ) ; sprintf(out_falff,"%s_fALFF",prefix); EDIT_dset_items( outsetfALFF, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_falff, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfALFF)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetfALFF)); EDIT_substitute_brick(outsetfALFF, 0, MRI_float, falff); falff=NULL; THD_load_statistics(outsetfALFF); tross_Make_History("3dRSFC", argc, argv, outsetfALFF); THD_write_3dim_dataset(NULL, NULL, outsetfALFF, True); outsetmALFF = EDIT_empty_copy( inset ) ; sprintf(out_malff,"%s_mALFF",prefix); EDIT_dset_items( outsetmALFF, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_malff, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmALFF)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetmALFF)); EDIT_substitute_brick(outsetmALFF, 0, MRI_float, malff); malff=NULL; THD_load_statistics(outsetmALFF); tross_Make_History("3dRSFC", argc, argv, outsetmALFF); THD_write_3dim_dataset(NULL, NULL, outsetmALFF, True); if(DO_RSFA){ outsetRSFA = EDIT_empty_copy( inset ) ; sprintf(out_rsfa,"%s_RSFA",prefix); EDIT_dset_items( outsetRSFA, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_rsfa, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetRSFA)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetRSFA)); EDIT_substitute_brick(outsetRSFA, 0, MRI_float, rsfa); rsfa=NULL; THD_load_statistics(outsetRSFA); tross_Make_History("3dRSFC", argc, argv, outsetRSFA); THD_write_3dim_dataset(NULL, NULL, outsetRSFA, True); outsetfRSFA = EDIT_empty_copy( inset ) ; sprintf(out_frsfa,"%s_fRSFA",prefix); EDIT_dset_items( outsetfRSFA, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_frsfa, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfRSFA)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetfRSFA)); EDIT_substitute_brick(outsetfRSFA, 0, MRI_float, frsfa); frsfa=NULL; THD_load_statistics(outsetfRSFA); tross_Make_History("3dRSFC", argc, argv, outsetfRSFA); THD_write_3dim_dataset(NULL, NULL, outsetfRSFA, True); outsetmRSFA = EDIT_empty_copy( inset ) ; sprintf(out_mrsfa,"%s_mRSFA",prefix); EDIT_dset_items( outsetmRSFA, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_mrsfa, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmRSFA)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetmRSFA)); EDIT_substitute_brick(outsetmRSFA, 0, MRI_float, mrsfa); mrsfa=NULL; THD_load_statistics(outsetmRSFA); tross_Make_History("3dRSFC", argc, argv, outsetmRSFA); THD_write_3dim_dataset(NULL, NULL, outsetmRSFA, True); } // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ DSET_delete(inset); DSET_delete(outsetALL); DSET_delete(outset); DSET_delete(outsetALFF); DSET_delete(outsetmALFF); DSET_delete(outsetfALFF); DSET_delete(outsetRSFA); DSET_delete(outsetmRSFA); DSET_delete(outsetfRSFA); free(inset); free(outsetALL); free(outset); free(outsetALFF); free(outsetmALFF); free(outsetfALFF); free(outsetRSFA); free(outsetmRSFA); free(outsetfRSFA); free(rsfa); free(mrsfa); free(frsfa); free(alff); free(malff); free(falff); free(mask); free(series1); free(series2); free(xx1); free(xx2); exit(0) ; }
int main( int argc , char * argv[] ) { THD_3dim_dataset *mask_dset=NULL, *iset=NULL, *sset=NULL, *xset=NULL, *vset=NULL; char *prefix="toy"; int iarg=1 , mcount, udatum = MRI_float; byte *maskvox=NULL; mainENTRY("3dToyProg main"); machdep(); AFNI_logger("3dToyProg",argc,argv); #ifdef USING_MCW_MALLOC enable_mcw_malloc() ; #endif /*-- options --*/ set_obliquity_report(0); /* silence obliquity */ while( iarg < argc && argv[iarg][0] == '-' ){ CHECK_HELP(argv[iarg], help_3dToyProg); if( strncmp(argv[iarg],"-mask",5) == 0 ){ if (iarg >= argc) ERROR_exit("Need dset after -mask"); mask_dset = THD_open_dataset( argv[++iarg] ) ; if( mask_dset == NULL ) ERROR_exit("Cannot open mask dataset!\n") ; if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex ) ERROR_exit("Cannot deal with complex-valued mask dataset!\n"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-input") == 0) { if (iarg >= argc) ERROR_exit("Need dset after -mask"); if (!(iset = THD_open_dataset( argv[++iarg]))) { ERROR_exit("Cannot open input dataset %s!\n", argv[iarg]) ; } DSET_mallocize(iset); DSET_load(iset); /* load data part of dataset */ iarg++ ; continue ; } if( strncmp(argv[iarg],"-prefix",6) == 0) { if (iarg >= argc) ERROR_exit("Need name after -prefix"); prefix = argv[++iarg]; iarg++ ; continue ; continue ; } if( strcmp(argv[iarg],"-datum") == 0) { if (iarg >= argc) ERROR_exit("Need datum type after -datum"); ++iarg; if (!strcmp(argv[iarg],"float")) udatum = MRI_float; else if (!strcmp(argv[iarg],"short")) udatum = MRI_short; else { ERROR_exit( "For the purpose of this demo, only float and short are allowed"); } iarg++ ; continue ; continue ; } ERROR_message("ILLEGAL option: %s\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } if( argc < 2 ){ help_3dToyProg(TXT, 0); PRINT_COMPILE_DATE ; exit(0) ; } if( !iset ) ERROR_exit("No dataset on command line!?") ; if (mask_dset) { if (THD_dataset_mismatch(mask_dset, iset)) ERROR_exit("grid mismatch between input dset and mask dset"); maskvox = THD_makemask( mask_dset , 0 , 1.0, -1.0 ) ; mcount = THD_countmask( DSET_NVOX(mask_dset) , maskvox ) ; if( mcount <= 0 ) ERROR_exit("No voxels in the mask!\n") ; INFO_message("%d voxels in the mask dset %s\n", mcount, DSET_PREFIX(mask_dset)) ; DSET_delete(mask_dset) ; mask_dset=NULL; /* Done with the mask dset */ } /* An illustration of how volume navigation works */ Dataset_Navigation(iset); /* Let us create a dataset from scratch */ sset = New_Dataset_From_Scratch(prefix); /* Now for the output, add history, check for overwrite and write away */ tross_Copy_History( iset , sset );/* Copy the old history (not mandatory). */ tross_Make_History("3dToyProg", argc, argv ,sset) ; /* add the new */ if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(sset)) ) { ERROR_message( "Output %s already exists, use -overwrite to do you know what", DSET_HEADNAME(sset)); } else DSET_write(sset); /* Now we'll do some voxelwise computations */ xset = Voxelwise_Operations(sset, maskvox, prefix); tross_Copy_History( iset , xset ) ; /* Copy the old */ tross_Make_History("3dToyProg", argc, argv ,xset) ; /* add the new */ if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(xset)) ) { ERROR_message( "Output %s already exists, use -overwrite to do you know what", DSET_HEADNAME(xset)); } else DSET_write(xset); /* Or some volumewise operations */ vset = Volumewise_Operations(sset, prefix, udatum); tross_Copy_History( iset , vset ) ; /* Copy the old */ tross_Make_History("3dToyProg", argc, argv ,vset) ; /* add the new */ if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(vset)) ) { ERROR_message( "Output %s already exists, use -overwrite to do you know what", DSET_HEADNAME(vset)); } else DSET_write(vset); /* cleanup */ DSET_delete(xset); xset = NULL; DSET_delete(vset); vset = NULL; DSET_delete(sset); sset = NULL; exit(0) ; }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SurfPatch"}; SUMA_GETPATCH_OPTIONS *Opt; char *ppref=NULL, ext[5]; float *far=NULL; MRI_IMAGE *im = NULL; int SO_read = -1; int *NodePatch=NULL, N_NodePatch=-1, *FaceSetList=NULL , N_FaceSet = -1, N_Node = -1, N_Spec=0; int i, inodeoff=-1, ilabeloff=-1, nvec, ncol, cnt; SUMA_SurfaceObject *SO = NULL; SUMA_PATCH *ptch = NULL; SUMA_SurfSpecFile *Spec; SUMA_INDEXING_ORDER d_order; void *SO_name = NULL; SUMA_Boolean exists = NOPE; SUMA_SO_File_Type typetmp; SUMA_SurfaceObject *SOnew = NULL; float *NodeList = NULL; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;"); /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = SUMA_GetPatch_ParseInput (argv, argc, ps); if (argc < 2) { SUMA_S_Err("Too few options"); usage_SUMA_getPatch(ps, 0); exit (1); } /* read all surfaces */ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec > 1 ) { SUMA_S_Err( "Mike, you cannot mix -spec with -i or -t options " "for specifying surfaces."); exit(1); } if (Spec->N_Surfs < 1) { SUMA_S_Err("No surfaces"); exit(1); } if (Opt->DoVol && Spec->N_Surfs != 2) { SUMA_S_Errv("Must specify 2 and only 2 surfaces with -vol options\n" "Have %d from the command line\n",Spec->N_Surfs); exit(1); } if (Opt->oType != SUMA_FT_NOT_SPECIFIED && !Opt->VolOnly) { for (i=0; i < Spec->N_Surfs; ++i) { if (Spec->N_Surfs > 1) { sprintf(ext, "_%c", 65+i); ppref = SUMA_append_string(Opt->out_prefix, ext); } else { ppref = SUMA_copy_string(Opt->out_prefix); } SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, Opt->oType, &exists); if (exists && !THD_ok_overwrite()) { fprintf(SUMA_STDERR, "Error %s:\nOutput file(s) %s* on disk.\n" "Will not overwrite.\n", FuncName, ppref); exit(1); } if (ppref) SUMA_free(ppref); ppref = NULL; if (SO_name) SUMA_free(SO_name); SO_name = NULL; } } /* read in the file containing the node information */ im = mri_read_1D (Opt->in_name); if (!im) { SUMA_S_Errv("Failed to read 1D file '%s'\n", Opt->in_name); exit(1); } far = MRI_FLOAT_PTR(im); nvec = im->nx; ncol = im->ny; if (Opt->nodecol >= ncol || Opt->labelcol >= ncol) { fprintf(SUMA_STDERR, "\n" "Error %s: Input file has a total of %d columns.\n" "One or both user-specified node (%d) and \n" "label (%d) columns are too high. Maximum usable\n" "column index is %d.\n" , FuncName, ncol, Opt->nodecol, Opt->labelcol, ncol -1 ); exit(1); } d_order = SUMA_COLUMN_MAJOR; if (!nvec) { SUMA_SL_Err("Empty file"); exit(1); } /* form the node vector */ NodePatch = (int *)SUMA_malloc(sizeof(int)*nvec); if (!NodePatch) { SUMA_SL_Crit("Failed to allocate."); exit(1); } inodeoff = Opt->nodecol*nvec; if (Opt->labelcol < 0) { /* all listed nodes */ for (i=0; i<nvec; ++i) { NodePatch[i] = far[i+inodeoff]; } N_NodePatch = nvec; } else { ilabeloff = Opt->labelcol*nvec; if (Opt->thislabel < 0) { /* all nodes with non zero labels */ cnt = 0; for (i=0; i<nvec; ++i) { if (far[i+ilabeloff]) { NodePatch[cnt] = far[i+inodeoff]; ++cnt; } } N_NodePatch = cnt; } else { /* select labels */ cnt = 0; for (i=0; i<nvec; ++i) { if (far[i+ilabeloff] == Opt->thislabel) { NodePatch[cnt] = far[i+inodeoff]; ++cnt; } } N_NodePatch = cnt; } NodePatch = (int *) SUMA_realloc(NodePatch , sizeof(int)*N_NodePatch); } /* done with im, free it */ mri_free(im); im = NULL; if (Opt->DoVol) { SUMA_SurfaceObject *SO1 = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], 0); SUMA_SurfaceObject *SO2 = SUMA_Load_Spec_Surf_with_Metrics(Spec, 1, ps->sv[0], 0); double Vol = 0.0; SUMA_SurfaceObject *SOp = SUMA_Alloc_SurfObject_Struct(1); byte *adj_N=NULL; if (Opt->adjust_contour) adj_N = SUMA_calloc(SO1->N_Node, sizeof(byte)); if (!SO1 || !SO2) { SUMA_SL_Err("Failed to load surfaces."); exit(1); } /* a chunk used to test SUMA_Pattie_Volume */ Vol = SUMA_Pattie_Volume(SO1, SO2, NodePatch, N_NodePatch, SOp, Opt->minhits, Opt->FixBowTie, Opt->adjust_contour, adj_N, Opt->verb); fprintf (SUMA_STDOUT,"Volume = %f\n", fabs(Vol)); if (Opt->out_volprefix) { if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SOp->FileType = Opt->oType; if (Opt->flip) { if (Opt->verb > 1) SUMA_S_Note("Flipping stitched surf's triangles\n"); SUMA_FlipSOTriangles (SOp); } if (!(SUMA_Save_Surface_Object_Wrap ( Opt->out_volprefix, NULL, SOp, SUMA_PLY, SUMA_ASCII, NULL))) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); } if (Opt->adjust_contour && adj_N) { Opt->out_volprefix = SUMA_append_replace_string(Opt->out_volprefix, ".adjneighb","",1); ppref = SUMA_Extension(Opt->out_volprefix, ".1D.dset", NOPE); SUMA_WRITE_IND_ARRAY_1D(adj_N, NULL, SO1->N_Node, 1, ppref); SUMA_free(ppref); ppref=NULL; } } if (SOp) SUMA_Free_Surface_Object(SOp); SOp = NULL; } if (!Opt->VolOnly) { FaceSetList = NULL; N_FaceSet = -1; for (i=0; i < Spec->N_Surfs; ++i) {/* loop to read in surfaces */ /* now identify surface needed */ if (!(SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, i, ps->sv[0], 0))) { SUMA_S_Err("Failed to load surface .\n"); exit(1); } if (SO->aSO) { /* otherwise, when you reset the number of FaceSets for example, and you still write in GIFTI, the old contents of aSO will prevail */ SO->aSO = SUMA_FreeAfniSurfaceObject(SO->aSO); } /* extract the patch */ ptch = SUMA_getPatch (NodePatch, N_NodePatch, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->MF, Opt->minhits, Opt->FixBowTie, (!i && !Opt->DoVol)); /* verbose only for first patch, and if no volume computation was required This is to keep the warnings to a minimum*/ if (!ptch) { SUMA_SL_Err("Failed to form patch."); exit(1); } if (LocalHead) SUMA_ShowPatch(ptch, NULL); /* Now create a surface with that patch */ if (Spec->N_Surfs > 1) { sprintf(ext, "_%c", 65+i); ppref = SUMA_append_string(Opt->out_prefix, ext); } else { ppref = SUMA_copy_string(Opt->out_prefix); } /* save the original type */ typetmp = SO->FileType; if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SO->FileType = Opt->oType; SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, SO->FileType, &exists); if (ppref) SUMA_free(ppref); ppref = NULL; /* save the original pointers to the facesets and their number */ FaceSetList = SO->FaceSetList; N_FaceSet = SO->N_FaceSet; NodeList = SO->NodeList; N_Node = SO->N_Node; /* replace with Patch */ SO->FaceSetList = ptch->FaceSetList; SO->N_FaceSet = ptch->N_FaceSet; if (Opt->Do_p2s) { if (LocalHead) fprintf (SUMA_STDERR, "%s: Changing patch to surface...\n", FuncName); SOnew = SUMA_Patch2Surf(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, 3); if (!SOnew) { SUMA_S_Err("Failed to change patch to surface."); exit(1); } SO->FaceSetList = SOnew->FaceSetList; SO->N_FaceSet = SOnew->N_FaceSet; SO->N_Node = SOnew->N_Node; SO->NodeList = SOnew->NodeList; } if (SO->N_FaceSet <= 0) { SUMA_S_Warn("The patch is empty.\n" " Non existing surface not written to disk.\n"); } else { /* Is the gain wanted? */ if (Opt->coordgain) { SUMA_SL_Note("Applying coord gain to surface nodes!"); for (cnt=0; cnt < SO->NodeDim*SO->N_Node; ++cnt) SO->NodeList[cnt] *= Opt->coordgain; } if (Opt->flip) { if (Opt->verb > 1) SUMA_S_Note("Flipping triangles\n"); SUMA_FlipTriangles (SO->FaceSetList, SO->N_FaceSet); SUMA_RECOMPUTE_NORMALS(SO); } if (!SUMA_Save_Surface_Object (SO_name, SO, SO->FileType, SUMA_ASCII, NULL)) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } } /* bring SO back to shape */ SO->FileType = typetmp; SO->FaceSetList = FaceSetList; FaceSetList = NULL; SO->N_FaceSet = N_FaceSet; N_FaceSet = -1; SO->NodeList = NodeList; NodeList = NULL; SO->N_Node = N_Node; N_Node = -1; if (SO_name) SUMA_free(SO_name); SO_name = NULL; if (ptch) SUMA_freePatch(ptch); ptch = NULL; if (SOnew) SUMA_Free_Surface_Object(SOnew); SOnew = NULL; /* get rid of old surface object */ } } SUMA_LH("clean up"); if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free spec fields"); } SUMA_free(Spec); Spec = NULL; if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt->out_volprefix) SUMA_free(Opt->out_volprefix); Opt->out_volprefix = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (!SUMA_Free_CommonFields(SUMAg_CF)) { SUMA_SL_Err("SUMAg_CF Cleanup Failed!"); } SUMA_RETURN(0); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"quickspec"}; int detail, kar, i, j, N_surf, N_name, idefstate; FILE *fid = NULL; char *spec_name, stmp[500], *Unique_st; SUMA_SO_File_Type TypeC[SUMA_MAX_N_SURFACE_SPEC]; static char *State[SUMA_MAX_N_SURFACE_SPEC], *Name_coord[SUMA_MAX_N_SURFACE_SPEC], *Name_topo[SUMA_MAX_N_SURFACE_SPEC], Anat[SUMA_MAX_N_SURFACE_SPEC], *LDP[SUMA_MAX_N_SURFACE_SPEC], *MARK[SUMA_MAX_N_SURFACE_SPEC], *LABEL[SUMA_MAX_N_SURFACE_SPEC]; SUMA_GENERIC_ARGV_PARSE *ps; SUMA_Boolean brk; SUMA_mainENTRY; /* allocate space for CommonFields structure */ SUMAg_CF = SUMA_Create_CommonFields (); if (SUMAg_CF == NULL) { fprintf( SUMA_STDERR, "Error %s: Failed in SUMA_Create_CommonFields\n", FuncName); exit(1); } ps = SUMA_Parse_IO_Args(argc, argv, "-t;"); if (argc < 3) { usage_SUMA_quickspec (ps); exit (1); } kar = 1; brk = NOPE; detail = 1; N_surf = 0; N_name = 0; spec_name = NULL; 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_quickspec(ps); exit (1); } if (!brk && (strcmp(argv[kar], "-spec") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -spec \n"); exit (1); } spec_name = argv[kar]; if (!THD_ok_overwrite() && SUMA_filexists(spec_name)) { fprintf (SUMA_STDERR, "File %s exists, choose another one.\n", spec_name); exit(1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-tn") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Type argument must follow -tn \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if (TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file type.\n", argv[kar]); exit(1); } /* get the name */ if (TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } State[N_surf] = NULL; Anat[N_surf] = 'Y'; LDP[N_surf] = NULL; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsn") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsn \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsn \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } Anat[N_surf] = 'Y'; LDP[N_surf] = NULL; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsnad") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsnad \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } /* get the anatomical flag */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Anatomical flag must follow NAME with -tsnad \n"); exit (1); } Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]); if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') { SUMA_S_Err("Anatomical flag must be either 'y' or 'n'"); exit (1); } /* get the LDP */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LDP[N_surf] = argv[kar]; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsnadm") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsnad \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } /* get the anatomical flag */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Anatomical flag must follow NAME with -tsnad \n"); exit (1); } Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]); if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') { SUMA_S_Err("Anatomical flag must be either 'y' or 'n'"); exit (1); } /* get the LDP */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LDP[N_surf] = argv[kar]; /* get the nodeMarker */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } MARK[N_surf] = argv[kar]; ++N_surf; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tsnadl") == 0)) { if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_SL_Err("Exceeding maximum number of allowed surfaces..."); exit(1); } /* get the type */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n"); exit (1); } TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]); if ( TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) { fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]); exit(1); } /* get the state */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsnad \n"); exit (1); } State[N_surf] = argv[kar]; /* get the name */ if ( TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2; else N_name = 1; if (kar+N_name >= argc) { fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name); exit (1); } kar ++; Name_coord[N_surf] = argv[kar]; if (N_name == 2) { kar ++; Name_topo[N_surf] = argv[kar]; } else { Name_topo[N_surf] = NULL; } /* get the anatomical flag */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "Anatomical flag must follow NAME with -tsnad \n"); exit (1); } Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]); if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') { SUMA_S_Err("Anatomical flag must be either 'y' or 'n'"); exit (1); } /* get the LDP */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LDP[N_surf] = argv[kar]; /* get the nodeMarker */ kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "LocalDomainParent must follow Anatomical flag with -tsnad \n"); exit (1); } LABEL[N_surf] = argv[kar]; ++N_surf; brk = YUP; } if (!brk) { fprintf (SUMA_STDERR, "Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]); exit (1); } else { brk = NOPE; kar ++; } } /* write out the comments */ if (!spec_name) { fid = fopen("quick.spec", "w"); } else { fid = fopen(spec_name,"w"); } if (!fid){ SUMA_SL_Err("Failed to open file for output"); exit(1); } fprintf(fid,"# define the group\n"); fprintf(fid,"\tGroup = QuickSpec\n"); /* now create a list of unique states */ idefstate = 0; if (!State[0]) { Unique_st = SUMA_copy_string ("\tStateDef = S_1\n"); idefstate = 1; } else { sprintf(stmp, "\tStateDef = %s\n", State[0]); Unique_st = SUMA_copy_string (stmp); } for (i=1; i < N_surf; ++i) { if (!State[i]) { ++idefstate; sprintf(stmp,"\tStateDef = S_%d\n", idefstate); Unique_st = SUMA_append_replace_string (Unique_st, stmp, "", 1); } else { if (SUMA_iswordin(Unique_st, State[i]) != 1) { sprintf(stmp, "\tStateDef = %s\n", State[i]); Unique_st = SUMA_append_replace_string(Unique_st, stmp, "", 1); } } } fprintf (fid, "# define the various States\n"); fprintf (fid, "%s\n", Unique_st); /* check on LDP correctness */ for (i=0; i < N_surf; ++i) { if (LDP[i]) { if (!strcmp(LDP[i],"same") || !strcmp(LDP[i],"Same")) SUMA_TO_UPPER(LDP[i]); if (strcmp(LDP[i],"SAME")) { j= 0; while (j<N_surf && strcmp(LDP[i], Name_coord[j])) ++j; if (j == N_surf) { SUMA_S_Errv("Could not find a surface named %s\n" "to be the local domain parent of %s\n", LDP[i], Name_coord[i]); exit(1); } if (!strcmp(LDP[i], Name_coord[i])) {/* reset to SAME*/ LDP[i] = NULL; /* this results is SAME below */ } } } } /* now loop accross surfaces and write out the results */ idefstate = 0; for (i=0; i < N_surf; ++i) { fprintf(fid, "\nNewSurface\n"); fprintf(fid, "\tSurfaceType = %s\n", SUMA_SurfaceTypeString(TypeC[i])); if (!State[i]) { ++idefstate; fprintf(fid, "\tSurfaceState = S_%d\n", idefstate); } else fprintf(fid, "\tSurfaceState = %s\n", State[i]); if (Name_topo[i]) { fprintf(fid, "\tCoordFile = %s\n", Name_coord[i]); fprintf(fid, "\tTopoFile = %s\n", Name_topo[i]); } else { fprintf(fid, "\tSurfaceName = %s\n", Name_coord[i]); } /* add LocalDomainParent */ if (LDP[i]) fprintf(fid, "\tLocalDomainParent = %s\n", LDP[i]); else fprintf(fid, "\tLocalDomainParent = SAME\n"); /* add Anatomical */ if (Anat[i]) fprintf(fid, "\tAnatomical = %c\n", Anat[i]); else fprintf(fid, "\tAnatomical = Y\n"); /* add nodeMarker */ if (MARK[i]) fprintf(fid, "\tNodeMarker = %s\n", MARK[i]); if (LABEL[i]) fprintf(fid, "\tLabelDset = %s\n", LABEL[i]); /* binary ? */ switch (TypeC[i]) { case SUMA_FREE_SURFER: if (!SUMA_isExtension(Name_coord[i], ".asc")) { fprintf(fid, "\tSurfaceFormat = BINARY\n"); } break; default: break; } } fclose(fid); fid = NULL; if (Unique_st) SUMA_free(Unique_st); Unique_st = NULL; if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (!SUMA_Free_CommonFields(SUMAg_CF)) { fprintf(SUMA_STDERR,"Error %s: SUMAg_CF Cleanup Failed!\n", FuncName); exit(1); } SUMA_RETURN(0); }/* main quickspec */
int main( int argc , char * argv[] ) { THD_dfvec3 *xx , *yy , dv ; int nvec=0 , ii,jj, iarg ; THD_dvecmat rt , rtinv ; THD_dmat33 pp,ppt , rr ; THD_dfvec3 tt ; THD_3dim_dataset *mset=NULL , *dset=NULL ; double *ww=NULL ; int nww=0 ; int keeptags=1 , wtval=0 , verb=0 , dummy=0 ; char * prefix = "tagalign" , *mfile=NULL ; float *fvol , cbot,ctop , dsum ; int nval , nvox , clipit , ival, RMETH=MRI_CUBIC; float matar[12] ; int use_3dWarp=1 , matrix_type=ROTATION ; mainENTRY("3dTagalign main"); /*--- help? ---*/ /*- scan args -*/ iarg = 1 ; RMETH=MRI_CUBIC; while( iarg < argc && argv[iarg][0] == '-' ){ /*-----*/ if( strcmp(argv[iarg],"-h") == 0 || strcmp(argv[iarg],"-help") == 0){ /* 22 Apr 2003 */ usage_3dTagalign(strlen(argv[iarg]) > 3 ? 2:1); exit(0); } /*-----*/ if( strcmp(argv[iarg],"-NN") == 0 ){ RMETH = MRI_NN ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-linear") == 0 ){ RMETH = MRI_LINEAR ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-cubic") == 0 ){ RMETH = MRI_CUBIC ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-quintic") == 0 ){ RMETH = MRI_QUINTIC ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-rotate") == 0 ){ /* 22 Apr 2003 */ matrix_type = ROTATION ; use_3dWarp = 1 ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-affine") == 0 ){ /* 21 Apr 2003 */ matrix_type = AFFINE ; use_3dWarp = 1 ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-rotscl") == 0 ){ /* 22 Apr 2003 */ matrix_type = ROTSCL ; use_3dWarp = 1 ; iarg++ ; continue ; } #if 0 /*-----*/ if( strcmp(argv[iarg],"-3dWarp") == 0 ){ /* 21 Apr 2003 */ use_3dWarp = 1 ; iarg++ ; continue ; } #endif /*-----*/ if( strcmp(argv[iarg],"-master") == 0 ){ if( mset != NULL ) ERREX("Can only have one -master option") ; if( ++iarg >= argc ) ERREX("Need an argument after -master") ; mset = THD_open_dataset( argv[iarg] ) ; if( mset == NULL ) ERREX("Can't open -master dataset") ; if( mset->tagset == NULL ) ERREX("No tags in -master dataset") ; if( TAGLIST_COUNT(mset->tagset) < 3 ) ERREX("Not enough tags in -master dataset") ; for( nvec=ii=0 ; ii < TAGLIST_COUNT(mset->tagset) ; ii++ ) if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) ) nvec++ ; if( nvec < 3 ) ERREX("Not enough tags set in -master dataset") ; if( nvec < TAGLIST_COUNT(mset->tagset) ) fprintf(stderr,"++ WARNING: not all tags are set in -master dataset\n") ; if( verb ) fprintf(stderr,"++ Found %d tags in -master dataset\n",nvec) ; iarg++ ; continue ; } #if 0 /*-----*/ if( strcmp(argv[iarg],"-wtval") == 0 ){ if( ww != NULL ) ERREX("Can't have -wtval after -wt1D") ; wtval++ ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-wt1D") == 0 ){ MRI_IMAGE * wtim ; float * wtar ; if( wtval ) ERREX("Can't have -wt1D after -wtval") ; if( ww != NULL ) ERREX("Can't have two -wt1D options!") ; if( ++iarg >= argc ) ERREX("Need an argument after -wt1D") ; wtim = mri_read_1D( argv[iarg] ) ; if( wtim == NULL ) ERREX("Can't read -wtim file") ; if( wtim->ny > 1 ) ERREX("-wtim file has more than one columm") ; wtar = MRI_FLOAT_PTR(wtim) ; ww = (double *) malloc(sizeof(double)*wtim->nx) ; nww = wtim->nx ; for( ii=0 ; ii < nww ; ii++ ){ ww[ii] = (double) wtar[ii] ; if( ww[ii] < 0.0 ) ERREX("Negative value found in -wt1D file") ; } mri_free(wtim) ; iarg++ ; continue ; } #endif /*-----*/ if( strcmp(argv[iarg],"-nokeeptags") == 0 ){ keeptags = 0 ; iarg++ ; continue ; } /*-----*/ if( strncmp(argv[iarg],"-verb",5) == 0 ){ verb++ ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-dummy") == 0 ){ dummy++ ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-prefix") == 0 ){ if( ++iarg >= argc ) ERREX("Need an argument after -prefix") ; prefix = argv[iarg] ; if( !THD_filename_ok(prefix) ) ERREX("-prefix string is illegal") ; iarg++ ; continue ; } /*-----*/ if( strcmp(argv[iarg],"-matvec") == 0 ){ if( ++iarg >= argc ) ERREX("Need an argument after -matvec") ; mfile = argv[iarg] ; if( !THD_filename_ok(mfile) ) ERREX("-matvec string is illegal") ; iarg++ ; continue ; } /*-----*/ fprintf(stderr,"** Unknown option: %s\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1) ; } /* end of scanning command line for options */ if( argc < 2 ){ ERROR_message("Too few options"); usage_3dTagalign(0); exit(1) ; } if( mset == NULL ) ERREX("No -master option found on command line") ; #if 0 if( ww != NULL && nww < nvec ) ERREX("Not enough weights found in -wt1D file") ; /*-- if -wtval, setup weights from master tag values --*/ if( wtval ){ ww = (double *) malloc(sizeof(double)*nvec) ; nww = nvec ; for( ii=jj=0 ; ii < TAGLIST_COUNT(mset->tagset) ; ii++ ){ if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) ){ ww[jj] = (double) TAG_VAL(TAGLIST_SUBTAG(mset->tagset,ii)) ; if( ww[jj] < 0.0 ) ERREX("Negative value found in -master tag values") ; jj++ ; } } } #endif /*-- read input dataset (to match to master dataset) --*/ if( iarg >= argc ) ERREX("No input dataset?") ; dset = THD_open_dataset( argv[iarg] ) ; if( dset == NULL ) ERREX("Can't open input dataset") ; if( dset->tagset == NULL ) ERREX("No tags in input dataset") ; if( TAGLIST_COUNT(dset->tagset) != TAGLIST_COUNT(mset->tagset) ) ERREX("Tag counts don't match in -master and input") ; /* check if set tags match exactly */ for( ii=0 ; ii < TAGLIST_COUNT(mset->tagset) ; ii++ ){ if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) != TAG_SET(TAGLIST_SUBTAG(dset->tagset,ii)) ) ERREX("Set tags don't match in -master and input") ; } /*-- load vector lists: xx=master, yy=input --*/ xx = (THD_dfvec3 *) malloc( sizeof(THD_dfvec3) * nvec ) ; yy = (THD_dfvec3 *) malloc( sizeof(THD_dfvec3) * nvec ) ; dsum = 0.0 ; for( ii=jj=0 ; ii < nvec ; ii++ ){ if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) ){ LOAD_DFVEC3( xx[jj] , /* N.B.: */ TAG_X( TAGLIST_SUBTAG(mset->tagset,ii) ) , /* these are */ TAG_Y( TAGLIST_SUBTAG(mset->tagset,ii) ) , /* in Dicom */ TAG_Z( TAGLIST_SUBTAG(mset->tagset,ii) ) ) ; /* order now */ LOAD_DFVEC3( yy[jj] , TAG_X( TAGLIST_SUBTAG(dset->tagset,ii) ) , TAG_Y( TAGLIST_SUBTAG(dset->tagset,ii) ) , TAG_Z( TAGLIST_SUBTAG(dset->tagset,ii) ) ) ; dv = SUB_DFVEC3( xx[jj] , yy[jj] ) ; dsum += dv.xyz[0]*dv.xyz[0] + dv.xyz[1]*dv.xyz[1] + dv.xyz[2]*dv.xyz[2] ; jj++ ; } } dsum = sqrt(dsum/nvec) ; fprintf(stderr,"++ RMS distance between tags before = %.2f mm\n" , dsum ) ; /*-- compute best transformation from mset to dset coords --*/ switch( matrix_type ){ default: case ROTATION: rt = DLSQ_rot_trans( nvec , yy , xx , ww ) ; /* in thd_rot3d.c */ break ; case AFFINE: rt = DLSQ_affine ( nvec , yy , xx ) ; /* 21 Apr 2003 */ break ; case ROTSCL: rt = DLSQ_rotscl ( nvec , yy , xx , (DSET_NZ(dset)==1) ? 2 : 3 ) ; break ; } rtinv = INV_DVECMAT(rt) ; /*-- check for floating point legality --*/ nval = 0 ; for( ii=0 ; ii < 3 ; ii++ ){ dsum = rt.vv.xyz[ii] ; nval += thd_floatscan(1,&dsum) ; for( jj=0 ; jj < 3 ; jj++ ){ dsum = rt.mm.mat[ii][jj] ; nval += thd_floatscan(1,&dsum) ; } } if( nval > 0 ){ fprintf(stderr,"** Floating point errors during calculation\n" "** of transform matrix and translation vector\n" ) ; exit(1) ; } /*-- check for rotation matrix legality --*/ dsum = DMAT_DET(rt.mm) ; if( dsum == 0.0 || (matrix_type == ROTATION && fabs(dsum-1.0) > 0.01) ){ fprintf(stderr,"** Invalid transform matrix computed: tags dependent?\n" "** computed [matrix] and [vector] follow:\n" ) ; for( ii=0 ; ii < 3 ; ii++ ) fprintf(stderr," [ %10.5f %10.5f %10.5f ] [ %10.5f ] \n", rt.mm.mat[ii][0],rt.mm.mat[ii][1],rt.mm.mat[ii][2],rt.vv.xyz[ii] ); exit(1) ; } /*-- print summary --*/ if( verb ){ fprintf(stderr,"++ Matrix & Vector [Dicom: x=R-L; y=A-P; z=I-S]\n") ; for( ii=0 ; ii < 3 ; ii++ ) fprintf(stderr," %10.5f %10.5f %10.5f %10.5f\n", rt.mm.mat[ii][0],rt.mm.mat[ii][1],rt.mm.mat[ii][2],rt.vv.xyz[ii] ); } if( matrix_type == ROTATION || matrix_type == ROTSCL ){ double theta, costheta , dist , fac=1.0 ; if( matrix_type == ROTSCL ){ fac = DMAT_DET(rt.mm); fac = fabs(fac); if( DSET_NZ(dset) == 1 ) fac = sqrt(fac) ; else fac = cbrt(fac) ; } costheta = 0.5 * sqrt(1.0 + DMAT_TRACE(rt.mm)/fac ) ; theta = 2.0 * acos(costheta) * 180/3.14159265 ; dist = SIZE_DFVEC3(rt.vv) ; fprintf(stderr,"++ Total rotation=%.2f degrees; translation=%.2f mm; scaling=%.2f\n", theta,dist,fac) ; } if( mfile ){ FILE * mp ; if( THD_is_file(mfile) ) fprintf(stderr,"++ Warning: -matvec will overwrite file %s\n",mfile) ; mp = fopen(mfile,"w") ; if( mp == NULL ){ fprintf(stderr,"** Can't write to -matvec %s\n",mfile) ; } else { for( ii=0 ; ii < 3 ; ii++ ) fprintf(mp," %10.5f %10.5f %10.5f %10.5f\n", rt.mm.mat[ii][0],rt.mm.mat[ii][1],rt.mm.mat[ii][2],rt.vv.xyz[ii] ); fclose(mp) ; if( verb ) fprintf(stderr,"++ Wrote matrix+vector to %s\n",mfile) ; } } if( dummy ){ fprintf(stderr,"++ This was a -dummy run: no output dataset\n") ; exit(0) ; } /*-- 21 Apr 2003: transformation can be done the old way (a la 3drotate), or the new way (a la 3dWarp). --*/ #if 0 if( !use_3dWarp ){ /**** the old way ****/ /*-- now must scramble the rotation matrix and translation vector from Dicom coordinate order to dataset brick order --*/ pp = DBLE_mat_to_dicomm( dset ) ; ppt = TRANSPOSE_DMAT(pp) ; rr = DMAT_MUL(ppt,rt.mm) ; rr = DMAT_MUL(rr,pp) ; tt = DMATVEC(ppt,rt.vv) ; /*-- now create the output dataset by screwing with the input dataset (this code is adapted from 3drotate.c) --*/ DSET_mallocize(dset) ; DSET_load( dset ) ; CHECK_LOAD_ERROR(dset) ; dset->idcode = MCW_new_idcode() ; dset->dblk->diskptr->storage_mode = STORAGE_BY_BRICK ; /* 14 Jan 2004 */ EDIT_dset_items( dset , ADN_prefix , prefix , ADN_label1 , prefix , ADN_none ) ; if( !THD_ok_overwrite() && (THD_deathcon() && THD_is_file(dset->dblk->diskptr->header_name) )){ fprintf(stderr, "** Output file %s already exists -- cannot continue!\n", dset->dblk->diskptr->header_name ) ; exit(1) ; } tross_Make_History( "3dTagalign" , argc,argv , dset ) ; /*-- if desired, keep old tagset --*/ if( keeptags ){ THD_dfvec3 rv ; dsum = 0.0 ; for( jj=ii=0 ; ii < TAGLIST_COUNT(dset->tagset) ; ii++ ){ if( TAG_SET(TAGLIST_SUBTAG(dset->tagset,ii)) ){ rv = DMATVEC( rt.mm , yy[jj] ) ; /* operating on */ rv = ADD_DFVEC3( rt.vv , rv ) ; /* Dicom order */ dv = SUB_DFVEC3( xx[jj] , rv ) ; dsum += dv.xyz[0]*dv.xyz[0] + dv.xyz[1]*dv.xyz[1] + dv.xyz[2]*dv.xyz[2] ; UNLOAD_DFVEC3( rv , TAG_X( TAGLIST_SUBTAG(dset->tagset,ii) ) , TAG_Y( TAGLIST_SUBTAG(dset->tagset,ii) ) , TAG_Z( TAGLIST_SUBTAG(dset->tagset,ii) ) ) ; jj++ ; } } dsum = sqrt(dsum/nvec) ; fprintf(stderr,"++ RMS distance between tags after = %.2f mm\n" , dsum ) ; } else { myXtFree(dset->tagset) ; /* send it to the dustbin */ } /*-- rotate sub-bricks --*/ if( verb ) fprintf(stderr,"++ computing output BRIK") ; nvox = DSET_NVOX(dset) ; nval = DSET_NVALS(dset) ; fvol = (float *) malloc( sizeof(float) * nvox ) ; THD_rota_method( MRI_HEPTIC ) ; clipit = 1 ; for( ival=0 ; ival < nval ; ival++ ){ /*- get sub-brick out of dataset -*/ EDIT_coerce_type( nvox , DSET_BRICK_TYPE(dset,ival),DSET_ARRAY(dset,ival) , MRI_float,fvol ) ; if( clipit ){ register int ii ; register float bb,tt ; bb = tt = fvol[0] ; for( ii=1 ; ii < nvox ; ii++ ){ if( fvol[ii] < bb ) bb = fvol[ii] ; else if( fvol[ii] > tt ) tt = fvol[ii] ; } cbot = bb ; ctop = tt ; } if( verb && nval < 5 ) fprintf(stderr,".") ; /*- rotate it -*/ THD_rota_vol_matvec( DSET_NX(dset) , DSET_NY(dset) , DSET_NZ(dset) , fabs(DSET_DX(dset)) , fabs(DSET_DY(dset)) , fabs(DSET_DZ(dset)) , fvol , rr , tt ) ; if( verb ) fprintf(stderr,".") ; if( clipit ){ register int ii ; register float bb,tt ; bb = cbot ; tt = ctop ; for( ii=0 ; ii < nvox ; ii++ ){ if( fvol[ii] < bb ) fvol[ii] = bb ; else if( fvol[ii] > tt ) fvol[ii] = tt ; } } if( verb && nval < 5 ) fprintf(stderr,".") ; /*- put it back into dataset -*/ EDIT_coerce_type( nvox, MRI_float,fvol , DSET_BRICK_TYPE(dset,ival),DSET_ARRAY(dset,ival) ); } /* end of loop over sub-brick index */ if( verb ) fprintf(stderr,":") ; /* save matrix+vector into dataset, too */ UNLOAD_DMAT(rt.mm,matar[0],matar[1],matar[2], matar[4],matar[5],matar[6], matar[8],matar[9],matar[10] ) ; UNLOAD_DFVEC3(rt.vv,matar[3],matar[7],matar[11]) ; THD_set_atr( dset->dblk, "TAGALIGN_MATVEC", ATR_FLOAT_TYPE, 12, matar ) ; /* write dataset to disk */ dset->dblk->master_nvals = 0 ; /* in case this was a mastered dataset */ DSET_write(dset) ; if( verb ) fprintf(stderr,"\n") ; } else #endif { /**** the new way: use 3dWarp type transformation ****/ THD_3dim_dataset *oset ; THD_vecmat tran ; #if 0 DFVEC3_TO_FVEC3( rt.vv , tran.vv ) ; DMAT_TO_MAT ( rt.mm , tran.mm ) ; #else DFVEC3_TO_FVEC3( rtinv.vv , tran.vv ) ; DMAT_TO_MAT ( rtinv.mm , tran.mm ) ; #endif mri_warp3D_method( RMETH ) ; oset = THD_warp3D_affine( dset, tran, mset, prefix, 0, WARP3D_NEWDSET ) ; if( oset == NULL ){ fprintf(stderr,"** ERROR: THD_warp3D() fails!\n"); exit(1); } tross_Copy_History( dset , oset ) ; tross_Make_History( "3dTagalign" , argc,argv , oset ) ; UNLOAD_DMAT(rt.mm,matar[0],matar[1],matar[2], matar[4],matar[5],matar[6], matar[8],matar[9],matar[10] ) ; UNLOAD_DFVEC3(rt.vv,matar[3],matar[7],matar[11]) ; THD_set_atr( oset->dblk, "TAGALIGN_MATVEC", ATR_FLOAT_TYPE, 12, matar ) ; /*-- if desired, keep old tagset --*/ if( keeptags ){ THD_dfvec3 rv ; oset->tagset = myXtNew(THD_usertaglist) ; *(oset->tagset) = *(dset->tagset) ; dsum = 0.0 ; for( jj=ii=0 ; ii < TAGLIST_COUNT(oset->tagset) ; ii++ ){ if( TAG_SET(TAGLIST_SUBTAG(oset->tagset,ii)) ){ rv = DMATVEC( rt.mm , yy[jj] ) ; rv = ADD_DFVEC3( rt.vv , rv ) ; dv = SUB_DFVEC3( xx[jj] , rv ) ; dsum += dv.xyz[0]*dv.xyz[0] + dv.xyz[1]*dv.xyz[1] + dv.xyz[2]*dv.xyz[2] ; UNLOAD_DFVEC3( rv , TAG_X( TAGLIST_SUBTAG(oset->tagset,ii) ) , TAG_Y( TAGLIST_SUBTAG(oset->tagset,ii) ) , TAG_Z( TAGLIST_SUBTAG(oset->tagset,ii) ) ) ; jj++ ; } } dsum = sqrt(dsum/nvec) ; fprintf(stderr,"++ RMS distance between tags after = %.2f mm\n" , dsum ) ; } DSET_write(oset) ; } /* end of 3dWarp-like work */ exit(0) ; }
int main(int argc, char *argv[]) { int CHECK = 0; int iarg; char *Fname_input = NULL; char *Fname_output = NULL; char *Fname_outputBV = NULL; char *Fname_bval = NULL; int opt; FILE *fin=NULL, *fout=NULL, *finbv=NULL, *foutBV=NULL; int i,j,k; int BZER=0,idx=0,idx2=0; MRI_IMAGE *flim=NULL; MRI_IMAGE *preREADIN=NULL; MRI_IMAGE *preREADBVAL=NULL; float *READIN=NULL; float *READBVAL=NULL; float OUT_MATR[MAXGRADS][7]; // b- or g-matrix float OUT_GRAD[MAXGRADS][4]; // b- or g-matrix int INV[3] = {1,1,1}; // if needing to switch int FLAG[MAXGRADS]; float temp; int YES_B = 0; int EXTRA_ZEROS=0; int HAVE_BVAL = 0; int BVAL_OUT = 0; int BVAL_OUT_SEP = 0; float BMAX_REF = 1; // i.e., essentially zero int IN_FORM = 0; // 0 for row, 1 for col int OUT_FORM = 1; // 1 for col, 2 for bmatr int HAVE_BMAX_REF=0 ; // referring to user input value int count_in=0, count_out=0; THD_3dim_dataset *dwset=NULL, *dwout=NULL; int Nbrik = 0; char *prefix=NULL ; float **temp_arr=NULL, **temp_grad=NULL; int Ndwi = 0, dwi=0, Ndwout = 0, Ndwi_final = 0, Ndwout_final = 0; int Nvox = 0; int DWI_COMP_FAC = 0; int ct_dwi = 0; float MaxDP = 0; mainENTRY("1dDW_Grad_o_Mat"); machdep(); if (argc == 1) { usage_1dDW_Grad_o_Mat(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_1dDW_Grad_o_Mat(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-flip_x") == 0) { INV[0] = -1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-flip_y") == 0) { INV[1] = -1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-flip_z") == 0) { INV[2] = -1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-keep_b0s") == 0) { YES_B = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-put_zeros_top") == 0) { EXTRA_ZEROS = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_grad_rows") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_grad_rows'\n") ; Fname_input = argv[iarg]; count_in++; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_grad_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_grad_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_gmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matT_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 2; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_gmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matA_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 3; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_bmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matT_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 4; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_bmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matA_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 5; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_grad_rows") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_grad_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 0; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_grad_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_grad_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_gmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_gmatT_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 2; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_gmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_gmatA_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 3; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_bmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_bmatT_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 4; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_bmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_bmatA_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 5; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_bvals") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_bvals'\n") ; Fname_bval = argv[iarg]; HAVE_BVAL = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-bmax_ref") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-bmax_ref'\n"); BMAX_REF = atof(argv[iarg]); HAVE_BMAX_REF = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_bval_col") == 0) { BVAL_OUT = 1; iarg++ ; continue ; } // May,2015 if( strcmp(argv[iarg],"-out_bval_row_sep") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_bval_row_sep'\n") ; Fname_outputBV = argv[iarg]; BVAL_OUT_SEP = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-proc_dset") == 0 ){ // in DWIs if( ++iarg >= argc ) ERROR_exit("Need argument after '-proc_dset'") ; dwset = THD_open_dataset( argv[iarg] ) ; if( dwset == NULL ) ERROR_exit("Can't open DWI dataset '%s'", argv[iarg]) ; DSET_load(dwset) ; CHECK_LOAD_ERROR(dwset) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-pref_dset") == 0 ){ // will be output iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-pref_dset'"); prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '-pref_dset'"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-dwi_comp_fac") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-dwi_comp_fac'\n"); DWI_COMP_FAC = atoi(argv[iarg]); if (DWI_COMP_FAC <=1) ERROR_exit("The compression factor after '-dwi_comp_fac'" "must be >1!"); iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * if( (Fname_input == NULL) ) { fprintf(stderr, "\n\tBad Command-lining! Option '-in_*' requires argument.\n"); exit(1); } if( (Fname_output == NULL) ) { fprintf(stderr, "\n\tBad Command-lining! Option '-out_*' requires arg.\n"); exit(2); } if( count_in > 1 ) { fprintf(stderr, "\n\tBad Command-lining! Can't have >1 vec file input.\n"); exit(3); } if( count_out > 1 ) { fprintf(stderr, "\n\tBad Command-lining! Can't have >1 output file opt.\n"); exit(4); } if(YES_B && dwset) { fprintf(stderr, "\n** Bad Command-lining! " "Can't have '-keep_b0s' and '-proc_dset' together.\n"); exit(5); } if( !prefix && dwset) { fprintf(stderr, "\n** Bad Command-lining! " "Need an output '-pref_dset' when using '-proc_dset'.\n"); exit(6); } if(YES_B && DWI_COMP_FAC) { fprintf(stderr, "\n** Bad Command-lining! " "Can't have '-keep_b0s' and '-dwi_comp_fac' together.\n"); exit(7); } if(!HAVE_BVAL && (BVAL_OUT || BVAL_OUT_SEP)) { fprintf(stderr, "\n** Bad Command-lining! " "Can't have ask for outputting bvals with no '-in_bvals FILE'.\n"); exit(8); } // ******************************************************************** // ************************* start reading **************************** // ******************************************************************** flim = mri_read_1D (Fname_input); if (flim == NULL) { ERROR_exit("Error reading gradient vector file"); } if( IN_FORM ) preREADIN = mri_transpose(flim); // effectively *undoes* autotranspose else preREADIN = mri_copy(flim); mri_free(flim); idx = preREADIN->ny; if( HAVE_BVAL ) { flim = mri_read_1D (Fname_bval); if (flim == NULL) { ERROR_exit("Error reading b-value file"); } if( flim->ny == 1) preREADBVAL = mri_transpose(flim); // effectively *undoes* autotransp else preREADBVAL = mri_copy(flim); mri_free(flim); idx2 = preREADBVAL->ny; } if(idx>= MAXGRADS ) { printf("Error, too many input grads.\n"); mri_free (preREADIN); if( HAVE_BVAL ) mri_free (preREADBVAL); exit(4); } if( ( (preREADIN->nx != 3 ) && (preREADIN->ny != 3 )) && (preREADIN->nx != 6 ) ) printf("Probably an error, " "because there aren't 3 or 6 numbers in columns!\n"); if( HAVE_BVAL && ( idx != idx2 ) ) { printf("Error, because the number of bvecs (%d)\n" "and bvals (%d) don't appear to match!\n", idx, idx2); mri_free (preREADIN); mri_free (preREADBVAL); exit(3); } if(dwset) { Nbrik = DSET_NVALS(dwset); if( idx != Nbrik ) { fprintf(stderr, "\n** ERROR: the number of bvecs (%d) does not match the " "number of briks in '-proc_dset' (%d).\n", idx, Nbrik); exit(4); } } READIN = MRI_FLOAT_PTR( preREADIN ); if( HAVE_BVAL ) READBVAL = MRI_FLOAT_PTR( preREADBVAL ); // 0 is grad row; // 1 is grad col; // 2 is gmatrRow col T; // 3 is gmatrDiag col A; // 4 is bmatrRow col T; // 5 is bmatrDiag col A; //if( IN_FORM == 0 ) // grad rows, no binfo // for( i=0; i<idx ; i++ ) // for ( j=0; j<3 ; j++ ) // OUT_GRAD[i][j+1] = *(READIN +j*idx +i) ; //else if ( IN_FORM <= 1 ) // grad cols, no binfo for( i=0; i<idx ; i++ ) for ( j=0; j<3 ; j++ ) OUT_GRAD[i][j+1] = *(READIN + 3*i+j); // A/row/3dDWItoDT: Bxx, Byy, Bzz, Bxy, Bxz, Byz // T/diag/TORTOISE: b_xx 2b_xy 2b_xz b_yy 2b_yz b_zz else if ( (IN_FORM == 3) || (IN_FORM ==5 ) ) { // diag matr for( i=0; i<idx ; i++ ) { for( j=0; j<3 ; j++ ) { OUT_MATR[i][j+1] = *(READIN+6*i+j); OUT_MATR[i][3+j+1] = *(READIN+6*i+3+j); } for( j=0; j<3 ; j++ ) if(OUT_MATR[i][j] < 0 ) CHECK++; } if(CHECK > 0) INFO_message("Warning: you *said* you input a mat'T'," " but the matr diagonals don't appear to be uniformly" " positive. If input cols 0, 3 and 5 are positive," " then you might have meant mat'A'?"); } else if ( (IN_FORM ==2 ) || (IN_FORM ==4 ) ) { // row matr CHECK = 0; for( i=0; i<idx ; i++ ) { OUT_MATR[i][1] = *(READIN +6*i); OUT_MATR[i][2] = *(READIN +6*i+3); OUT_MATR[i][3] = *(READIN +6*i+5); OUT_MATR[i][4] = *(READIN +6*i+1)/2.; OUT_MATR[i][5] = *(READIN +6*i+2)/2.; OUT_MATR[i][6] = *(READIN +6*i+4)/2.; } for( i=0; i<idx ; i++ ) for( j=0; j<3 ; j++ ) if(OUT_MATR[i][j] < 0 ) CHECK++; if(CHECK > 0) INFO_message("Warning: you *said* you input a mat'A'," " but the matr diagonals don't appear to be uniformly" " positive. If input cols 0, 1 and 2 are positive," " then you might have meant mat'T'?"); } else{ fprintf(stderr, "Coding error with format number (%d), not allowed.\n", IN_FORM); exit(2); } // get bval info if( ( (IN_FORM ==4 ) || (IN_FORM ==5 ) ) ) { //bval for( i=0; i<idx ; i++ ) { OUT_MATR[i][0] = OUT_GRAD[i][0] = OUT_MATR[i][1] + OUT_MATR[i][2] + OUT_MATR[i][3]; if( OUT_MATR[i][0] > 0.000001) for( j=1 ; j<7 ; j++ ) OUT_MATR[i][j]/= OUT_MATR[i][0]; } } else if ( HAVE_BVAL ) for( i=0; i<idx ; i++ ) { OUT_MATR[i][0] = OUT_GRAD[i][0] = *(READBVAL + i); } else if ( OUT_FORM > 3 || BVAL_OUT || BVAL_OUT_SEP || HAVE_BMAX_REF ) { fprintf(stderr, "ERROR: you asked for b-value dependent output, " "but gave me no bvals to work with.\n"); exit(2); } // * * * ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * * // at this point, all IN_FORM >1 cases which need bval have led to: // + grad[0] has bval // + matr[0] has bval // + matr file normalized and in diagonal form // * * * ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * * for( i=0; i<idx ; i++ ) if( IN_FORM > 1) j = GradConv_Gsign_from_BmatA( OUT_GRAD[i]+1, OUT_MATR[i]+1); else j = GradConv_BmatA_from_Gsign( OUT_MATR[i]+1, OUT_GRAD[i]+1); // flip if necessary for( i=0 ; i<idx ; i++) { for( j=0 ; j<3 ; j++) OUT_GRAD[i][j+1]*= INV[j]; OUT_MATR[i][4]*= INV[0]*INV[1]; OUT_MATR[i][5]*= INV[0]*INV[2]; OUT_MATR[i][6]*= INV[1]*INV[2]; } BZER=0; for( i=0 ; i<idx ; i++) { if( HAVE_BVAL || (IN_FORM ==4) || (IN_FORM ==5) ) if( OUT_GRAD[i][0] >= BMAX_REF ) FLAG[i] = 1; else{ if( YES_B ) FLAG[i] = 1; BZER++; } else { temp = 0.; for( j=1 ; j<4 ; j++) temp+= pow(OUT_GRAD[i][j],2); if( temp > 0.1 ) FLAG[i] = 1; else{ if( YES_B ) FLAG[i] = 1; BZER++; } } } if(YES_B) { printf("\tChose to *keep* %d b0s,\tas well as \t%d grads\n", BZER,idx-BZER); BZER=0; } else { printf("\tGetting rid of %d b0s,\tleaving the %d grads\n", BZER,idx-BZER); Ndwi = idx-BZER; } Ndwi_final = idx-BZER; // default: all DWIs if( DWI_COMP_FAC ) { if( Ndwi % DWI_COMP_FAC != 0 ) { fprintf(stderr, "\n** ERROR can't compress: " "Ndwi=%d, and %d/%d has a nonzero remainder (=%d).\n", Ndwi,Ndwi,DWI_COMP_FAC, Ndwi % DWI_COMP_FAC ); exit(1); } else { Ndwi_final = Ndwi/DWI_COMP_FAC; INFO_message("You have chosen a compression factor of %d, " "with %d DWIs,\n" "\tso that afterward there will be %d DWIs.", DWI_COMP_FAC, Ndwi, Ndwi_final); } } if(BVAL_OUT_SEP) if( (foutBV = fopen(Fname_outputBV, "w")) == NULL) { fprintf(stderr, "\n\nError opening file %s.\n",Fname_outputBV); exit(1); } if( (fout = fopen(Fname_output, "w")) == NULL) { fprintf(stderr, "\n\nError opening file %s.\n",Fname_output); exit(1); } // 0 is grad row; // 1 is grad col; // 2 is gmatrRow col T; // 3 is gmatrDiag col A; // 4 is bmatrRow col T; // 5 is bmatrDiag col A; if( OUT_FORM>0) { if( EXTRA_ZEROS ) { if( BVAL_OUT ) fprintf(fout,"%8d ", 0); if( BVAL_OUT_SEP ) fprintf(foutBV,"%8d ", 0); if( OUT_FORM == 1 ) for( k=1 ; k<4 ; k++ ) fprintf(fout,"%11.5f ", 0.0); else if ( OUT_FORM > 1 ) // bit superfluous at this point for( k=1 ; k<7 ; k++ ) fprintf(fout,"%11.5f ", 0.0); fprintf(fout,"\n"); } ct_dwi = 0; for(i=0 ; i<idx ; i++){ if(FLAG[i]) { if( BVAL_OUT ) fprintf(fout,"%8d ", (int) OUT_GRAD[i][0]); if( BVAL_OUT_SEP ) fprintf(foutBV,"%8d ", (int) OUT_GRAD[i][0]); if( (OUT_FORM == 4) || (OUT_FORM ==5) ) for( k=1 ; k<7 ; k++ ) OUT_MATR[i][k]*= OUT_MATR[i][0]; if( OUT_FORM == 1 ) // grad col for( k=1 ; k<4 ; k++ ) fprintf(fout,"%11.5f ", OUT_GRAD[i][k]); else if( (OUT_FORM == 3) || (OUT_FORM == 5) ) { // gmat for( k=1 ; k<6 ; k++ ) fprintf(fout,"%11.5f ", OUT_MATR[i][k]); fprintf(fout,"%11.5f", OUT_MATR[i][k]); } else if ( (OUT_FORM == 2 ) || (OUT_FORM ==4)) { // bmat fprintf(fout,"%11.5f ", OUT_MATR[i][1]); fprintf(fout,"%11.5f ", 2*OUT_MATR[i][4]); fprintf(fout,"%11.5f ", 2*OUT_MATR[i][5]); fprintf(fout,"%11.5f ", OUT_MATR[i][2]); fprintf(fout,"%11.5f ", 2*OUT_MATR[i][6]); fprintf(fout,"%11.5f", OUT_MATR[i][3]); } fprintf(fout,"\n"); ct_dwi++; } if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) { INFO_message("Reached compression level: DWI number %d", Ndwi_final); break; } } } else if(OUT_FORM ==0) { if(BVAL_OUT) WARNING_message("Ignoring '-out_bval_col' option, since " " you are outputting in rows."); for( k=1 ; k<4 ; k++ ) { if(EXTRA_ZEROS){ fprintf(fout,"% -11.5f ", 0.0); if( (k==1) && BVAL_OUT_SEP ) // only output 1 zeroin bval file fprintf(foutBV,"%8d ", 0); } ct_dwi = 0; for(i=0 ; i<idx ; i++) { if(FLAG[i]) { fprintf(fout,"% -11.5f ", OUT_GRAD[i][k]); if( (k==1) && BVAL_OUT_SEP )// only output 1 zeroin bval file fprintf(foutBV,"%8d ", (int) OUT_GRAD[i][0]); ct_dwi++; } if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) { INFO_message("Reached compression level: DWI number %d", Ndwi_final); break; } } fprintf(fout,"\n"); } } fclose(fout); if( BVAL_OUT_SEP ) { fprintf(foutBV,"\n"); fclose(foutBV); } if(dwset) { INFO_message("Processing the B0+DWI file now."); if(!BZER) { fprintf(stderr, "\n** Error in processing data set: " "no b=0 values from bvecs/bval info!\n"); exit(5); } // FLAG marks where DWIs are if not using '-keep_b0s'! Nvox = DSET_NVOX(dwset); Ndwout = Ndwi+1; temp_arr = calloc( Ndwout,sizeof(temp_arr)); for( i=0 ; i<Ndwout ; i++) temp_arr[i] = calloc( Nvox,sizeof(float)); temp_grad = calloc( Ndwi,sizeof(temp_grad)); for( i=0 ; i<Ndwi ; i++) temp_grad[i] = calloc( 3,sizeof(float)); if( (temp_arr == NULL) || (temp_grad == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } dwi = 0; // keep track of DWI contraction for( i=0 ; i<Nbrik ; i++) if( !FLAG[i] ) // b=0 for( j=0 ; j<Nvox ; j++) temp_arr[0][j]+= THD_get_voxel(dwset,j,i); else { for( j=0 ; j<3 ; j++) temp_grad[dwi][j]= OUT_GRAD[i][j+1]; dwi++; for( j=0 ; j<Nvox ; j++) temp_arr[dwi][j]+= THD_get_voxel(dwset,j,i); } if( dwi != Ndwi ) { fprintf(stderr, "\n** Mismatch in internal DWI counting!\n"); exit(6); } // average the values for( j=0 ; j<Nvox ; j++) temp_arr[0][j]/= BZER; // can't be zero here. if( DWI_COMP_FAC ) { INFO_message("Compressing DWI file"); for( k=1 ; k<DWI_COMP_FAC ; k++) for( i=0 ; i<Ndwi_final ; i++) for( j=0 ; j<Nvox ; j++) temp_arr[1+i][j]+= temp_arr[1+k*Ndwi_final+i][j]; for( i=0 ; i<Ndwi_final ; i++) for( j=0 ; j<Nvox ; j++) temp_arr[1+i][j]/= DWI_COMP_FAC; INFO_message("Checking closeness of compressed gradient values"); MaxDP = GradCloseness(temp_grad, Ndwi, DWI_COMP_FAC); INFO_message("The max angular difference between matched/compressed\n" "\tgradients is: %f", MaxDP); if( MaxDP > 2) WARNING_message("The max angular difference seem kinda big-- you\n" " sure about the compression factor?"); } Ndwout_final = Ndwi_final + 1; INFO_message("Writing the processed data set."); dwout = EDIT_empty_copy( dwset ); EDIT_dset_items(dwout, ADN_nvals, Ndwout_final, ADN_ntt, 0, ADN_datum_all, MRI_float , ADN_prefix, prefix, ADN_none ); for( i=0; i<Ndwout_final ; i++) { EDIT_substitute_brick(dwout, i, MRI_float, temp_arr[i]); temp_arr[i]=NULL; } // if necessary for( i=Ndwout_final ; i<Ndwout ; i++) temp_arr[i]=NULL; THD_load_statistics( dwout ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(dwout)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(dwout)); tross_Make_History("1dDW_Grad_o_Mat", argc, argv, dwout); THD_write_3dim_dataset(NULL, NULL, dwout, True); DSET_delete(dwout); free(dwout); DSET_delete(dwset); free(dwset); for( i=0 ; i<Ndwout_final ; i++) free(temp_arr[i]); free(temp_arr); } mri_free(preREADIN); if( HAVE_BVAL ) mri_free(preREADBVAL); if(prefix) free(prefix); printf("\n\tDone. Check output file '%s' for results",Fname_output); if(dwset) { printf("\n\t-> as well as the data_set '%s'",DSET_FILECODE(dwout)); } if(BVAL_OUT_SEP) printf("\n\t-> and even the b-value rows '%s'",Fname_outputBV); printf("\n\n"); exit(0); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"ConvexHull"}; int i, i3, nspec = 0; void *SO_name=NULL; SUMA_SurfaceObject *SO = NULL; SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt; char stmp[200]; SUMA_Boolean exists = NOPE; SUMA_Boolean LocalHead = NOPE; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;"); if (argc < 2) { usage_SUMA_ConvexHull(ps); exit (1); } Opt = SUMA_ConvexHull_ParseInput (argv, argc, ps); SO_name = SUMA_Prefix2SurfaceName(Opt->out_prefix, NULL, NULL, Opt->SurfFileType, &exists); if (exists && !THD_ok_overwrite()) { SUMA_S_Err("Output file(s) %s* on disk.\nWill not overwrite.\n", Opt->out_prefix); exit(1); } if (Opt->obj_type < 0) { if (Opt->in_name) { if (Opt->debug) { SUMA_S_Note("Creating mask..."); } if (!SUMA_Get_isosurface_datasets (Opt)) { SUMA_SL_Err("Failed to get data."); exit(1); } if (Opt->debug > 1) { if (Opt->debug == 2) { FILE *fout=fopen("inmaskvec.1D","w"); SUMA_S_Note("Writing masked values...\n"); if (!fout) { SUMA_SL_Err("Failed to write maskvec"); exit(1); } fprintf(fout, "#Col. 0 Voxel Index\n" "#Col. 1 Is a mask (all values here should be 1)\n" ); for (i=0; i<Opt->nvox; ++i) { if (Opt->mcdatav[i]) { fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]); } } fclose(fout); fout = NULL; } else { FILE *fout=fopen("maskvec.1D","w"); SUMA_S_Note("Writing all mask values...\n"); if (!fout) { SUMA_S_Err("Failed to write maskvec"); exit(1); } fprintf(fout, "#Col. 0 Voxel Index\n" "#Col. 1 Is in mask ?\n" ); for (i=0; i<Opt->nvox; ++i) { fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]); } fclose(fout); fout = NULL; } } } else if (Opt->in_1D) { MRI_IMAGE *im = NULL; float *far=NULL; int nx2; /* load the 1D file */ im = mri_read_1D (Opt->in_1D); if (!im) { SUMA_S_Err("Failed to read file"); exit(1); } far = MRI_FLOAT_PTR(im); if (im->nx == 0) { fprintf(SUMA_STDERR,"Error %s:\n Empty file %s.\n", FuncName, Opt->in_1D); exit(1); } if (im->ny != 3) { fprintf(SUMA_STDERR,"Error %s:\n Found %d columns in %s. Expecting 3\n", FuncName, im->ny, Opt->in_1D); exit(1); } /* copy the columns */ Opt->N_XYZ = im->nx; Opt->XYZ = (float *)SUMA_malloc(im->nx*im->ny*sizeof(float)); if (!Opt->XYZ) { SUMA_S_Crit("Failed to allocate."); exit(1); } nx2 = 2*im->nx; for (i=0;i<Opt->N_XYZ; ++i) { i3 = 3*i; Opt->XYZ[i3 ] = far[i]; Opt->XYZ[i3+1] = far[i+im->nx]; Opt->XYZ[i3+2] = far[i+nx2]; } /* done, clean up and out you go */ if (im) mri_free(im); im = NULL; } else if (ps->i_N_surfnames) { SUMA_SurfSpecFile *Spec=NULL; SUMA_SurfaceObject *SO=NULL; if (ps->i_N_surfnames > 1) { SUMA_S_Err("Only 1 input surface allowed!"); exit(1); } Spec = SUMA_IO_args_2_spec(ps, &nspec); if (!Spec) { SUMA_S_Err("Failed to create spec!"); exit(1); } if (nspec != 1) { SUMA_S_Warn("Expected one spec and nothing else"); } /* load the surface object */ SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0); if (!SO) { SUMA_S_Err("Failed to read surface."); exit(1); } /* transfer coords */ if(SO->NodeDim != 3) { SUMA_S_Err("bad node coords."); exit(1); } Opt->N_XYZ = SO->N_Node; Opt->XYZ = (float *)SUMA_malloc(SO->N_Node * SO->NodeDim * sizeof(float)); if (!Opt->XYZ) { SUMA_S_Crit("Failed to allocate."); exit(1); } for (i=0;i<SO->NodeDim*SO->N_Node; ++i) Opt->XYZ[i] = SO->NodeList[i]; if (nspec) { int k=0; for (k=0; k<nspec; ++k) { if (!SUMA_FreeSpecFields(&(Spec[k]))) { SUMA_S_Err("Failed to free spec fields"); } } SUMA_free(Spec); Spec = NULL; nspec = 0; } if (SO) SUMA_Free_Surface_Object(SO); SO = NULL; } else { SUMA_S_Err("No input!"); exit(1); } } else { SUMA_S_Err("Bad input!"); exit(1); } /* Now call Marching Cube functions */ if (!(SO = SUMA_ConvexHullSurface(Opt))) { SUMA_S_Err("Failed to create surface.\n"); exit(1); } /* write the surface to disk */ if (!SUMA_Save_Surface_Object (SO_name, SO, Opt->SurfFileType, Opt->SurfFileFormat, NULL)) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (Opt->fvec) SUMA_free(Opt->fvec); Opt->fvec = NULL; if (Opt->mcdatav) {SUMA_free(Opt->mcdatav); Opt->mcdatav = NULL;} if (Opt->in_vol) { DSET_delete( Opt->in_vol); Opt->in_vol = NULL;} if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt->XYZ) SUMA_free(Opt->XYZ); Opt->XYZ = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (SO_name) SUMA_free(SO_name); SO_name = NULL; if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); exit(0); }
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); }
/*! \brief parse the arguments for SurfSmooth program \param argv (char *) \param argc (int) \return Opt (SUMA_GETPATCH_OPTIONS *) options structure. To free it, use SUMA_free(Opt->outfile); SUMA_free(Opt->histnote); SUMA_free(Opt); */ SUMA_KUBATEST_OPTIONS *SUMA_SampBias_ParseInput( char *argv[], int argc, SUMA_KUBATEST_OPTIONS* Opt, SUMA_GENERIC_ARGV_PARSE *ps) { static char FuncName[]={"SUMA_SampBias_ParseInput"}; int kar, i, ind; char *outprefix; SUMA_Boolean brk = NOPE; SUMA_Boolean LocalHead = NOPE; SUMA_ENTRY; kar = 1; brk = NOPE; Opt->debug = 0; Opt->plimit = 50; Opt->dlimit = 1000; Opt->outfile = NULL; Opt->prefix = NULL; Opt->segdo = NULL; Opt->ps=ps; 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) { ps->hverb = strlen(argv[kar])>3?2:1; usage_SUMA_SampBias(ps); exit (0); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); if (!brk && (strcmp(argv[kar], "-plimit") == 0)) { kar++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -plimit \n"); exit (1); } Opt->plimit = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-dlimit") == 0)) { kar++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -dlimit \n"); exit (1); } Opt->dlimit = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-out") == 0)) { kar++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -out \n"); exit (1); } Opt->outfile = SUMA_copy_string(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-segdo") == 0)) { kar++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -segdo \n"); exit (1); } Opt->segdo = SUMA_Extension(argv[kar], ".1D.do", NOPE); brk = YUP; } if (!brk && (strcmp(argv[kar], "-prefix") == 0)) { kar++; if (kar >= argc) { fprintf (SUMA_STDERR, "need argument after -prefix \n"); exit (1); } Opt->prefix = SUMA_copy_string(argv[kar]); brk = YUP; } if (!brk && !ps->arg_checked[kar]) { 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 ++; } } /* sanity checks */ if (Opt->outfile == NULL && Opt->prefix == NULL) { SUMA_SL_Err("No outfile, or prefix specified."); exit(1); } if (Opt->outfile) { if (!THD_ok_overwrite() && SUMA_filexists(Opt->outfile)) { SUMA_S_Errv("Outfile %s already exists\n", Opt->outfile); exit(1); } } if (Opt->prefix) { SUMA_DSET_NAME_CHECK(Opt->prefix); } Opt->histnote = SUMA_HistString (NULL, argc, argv, NULL); SUMA_RETURN (Opt); }
int main(int argc, char *argv[]) { int i, k, ii; int iarg; char *prefix=NULL; char *maskname=NULL; char *gradsname=NULL; char *dtsname=NULL; THD_3dim_dataset *MASK=NULL; THD_3dim_dataset *DTS=NULL; MRI_IMAGE *GRADS=NULL, *GRADS_IN=NULL; int Ngrads=0, Nfull=0; int Nvox=-1; // tot number vox int Dim[3]={0,0,0}; // dim in each dir float NOISESCALE_DWI = -1.; float NOISESCALE_B0 = -1; float S0 = 1000.; float bval = 1.; int NOISE_IN_S0 = 0; byte *mskd2=NULL; // not great, but another format of mask float **dwi=NULL; THD_3dim_dataset *DWI_OUT=NULL; const gsl_rng_type * T; gsl_rng *r; long seed; srand(time(0)); seed = time(NULL) ; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); gsl_rng_set (r, seed); // ################################################################### // ######################### load ################################## // ################################################################### mainENTRY("3dDTtoNoisyDWI"); machdep(); if (argc == 1) { usage_DTtoNoisyDWI(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_DTtoNoisyDWI(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-dt_in") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-eig_vecs'"); dtsname = strdup(argv[iarg]) ; iarg++ ; continue ; } 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],"-mask") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); maskname = strdup(argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-grads") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); gradsname = strdup(argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-noise_DWI") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-noise_DWI'"); NOISESCALE_DWI = atof(argv[iarg]); iarg++ ; continue ; } if( strcmp(argv[iarg],"-noise_B0") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-noise_B0'"); NOISESCALE_B0 = atof(argv[iarg]); iarg++ ; continue ; } if( strcmp(argv[iarg],"-S0") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-S0'"); S0 = atof(argv[iarg]); if(S0 <= 0 ) ERROR_exit("The '-S0' value must be >0."); iarg++ ; continue ; } if( strcmp(argv[iarg],"-bval") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-bval'"); bval = atof(argv[iarg]); if(bval <= 0 ) ERROR_exit("The '-bval' value must be >0."); iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } // ################################################################### // #################### some checks ############################### // ################################################################### if(!prefix) ERROR_exit("Need to give a '-prefix'."); if(!dtsname) ERROR_exit("Need to input diffusion tensor file after '-dt_in'."); if(!gradsname) ERROR_exit("Need to input gradient file after '-grads'."); if( NOISESCALE_DWI<0 ) ERROR_exit("Fractional noise value after '-snr0' needs to be >0. " "It sets the noise scale of ref signal S0."); if(NOISESCALE_DWI > 0) INFO_message("You have chosen an SNR0 of approximately %.2f for DWIs", 1./NOISESCALE_DWI); else INFO_message("You have noiseless (i.e., infinite SNR) set of DWIs"); if( NOISESCALE_B0 < 0 ) NOISESCALE_B0 = NOISESCALE_DWI; if(NOISESCALE_B0 > 0) INFO_message("You have chosen an SNR0 of approximately %.2f for the B0", 1./NOISESCALE_B0); else INFO_message("You have noiseless (i.e., infinite SNR) reference B0."); // ################################################################### if(dtsname) { DTS = THD_open_dataset(dtsname); DSET_load(DTS); CHECK_LOAD_ERROR(DTS); if( 6 != DSET_NVALS(DTS) ) ERROR_exit("DT file '%s' must have 6 bricks-- " "it has %d bricks!", dtsname, DSET_NVALS(DTS)); } Nvox = DSET_NVOX(DTS); Dim[0] = DSET_NX(DTS); Dim[1] = DSET_NY(DTS); Dim[2] = DSET_NZ(DTS); if(Nvox<0) ERROR_exit("Error reading Nvox from eigenvalue file."); mskd2 = (byte *)calloc(Nvox,sizeof(byte)); if( (mskd2 == NULL)) { fprintf(stderr, "\n\n MemAlloc failure (masks).\n\n"); exit(122); } if(maskname) { MASK = THD_open_dataset(maskname); DSET_load(MASK); CHECK_LOAD_ERROR(MASK); if( 1 != DSET_NVALS(MASK) ) ERROR_exit("Mask file '%s' is not scalar-- " "it has %d bricks!", maskname, DSET_NVALS(MASK)); for( k=0 ; k<Nvox ; k++ ) if (THD_get_voxel(MASK, k, 0) > 0 ) mskd2[k] = 1; DSET_delete(MASK); free(MASK); free(maskname); } else { for( k=0 ; k<Nvox ; k++ ) if( fabs(THD_get_voxel(DTS,k,0) > EPS_V) ) mskd2[k] = 1; } GRADS_IN = mri_read_1D (gradsname); GRADS = mri_transpose(GRADS_IN); // get rid of autotranspose... if (GRADS == NULL) ERROR_exit("Error reading gradient vector file"); mri_free(GRADS_IN); Ngrads = GRADS->ny; if(Ngrads < 6) ERROR_exit("Too few grads (there appear to be only %d).",Ngrads); if(GRADS->nx !=3 ) ERROR_exit("Wrong number of columns in the grad file: " " am reading %d instead of 3.",GRADS->nx); Nfull = Ngrads+1; INFO_message("Have surmised there are %d total grads; " "output file will have %d bricks", Ngrads,Nfull); dwi = calloc(Nfull,sizeof(dwi)); for(i=0 ; i<Nfull ; i++) dwi[i] = calloc( Nvox,sizeof(float)); INFO_message("Calculating the DWIs."); i = RicianNoiseDWIs( dwi, Nvox, Ngrads, DTS, NOISESCALE_DWI, NOISESCALE_B0, GRADS, mskd2, S0, bval, r); INFO_message("Writing the DWIs."); DWI_OUT = EDIT_empty_copy( DTS ); EDIT_dset_items(DWI_OUT, ADN_nvals, Nfull, ADN_datum_all, MRI_float , ADN_prefix, prefix, ADN_none ); for( i=0; i<Nfull ; i++) { EDIT_substitute_brick(DWI_OUT, i, MRI_float, dwi[i]); dwi[i]=NULL; } THD_load_statistics( DWI_OUT ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(DWI_OUT)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(DWI_OUT)); tross_Make_History("3dDTtoNoisyDWI", argc, argv, DWI_OUT); THD_write_3dim_dataset(NULL, NULL, DWI_OUT, True); DSET_delete(DWI_OUT); free(DWI_OUT); // ################################################################# // ########################## free ############################### // ################################################################# DSET_delete(DTS); free(DTS); for( i=0 ; i<Nfull ; i++) free(dwi[i]); free(dwi); free(prefix); free(gradsname); free(dtsname); mri_free(GRADS); return 0; }
int WB_netw_corr(int Do_r, int Do_Z, int HAVE_ROIS, char *prefix, int NIFTI_OUT, int *NROI_REF, int *Dim, double ***ROI_AVE_TS, int **ROI_LABELS_REF, THD_3dim_dataset *insetTIME, byte *mskd2, int Nmask, int argc, char *argv[]) { int i,j,k; float **AVE_TS_fl=NULL; // not great, but another format of TS char OUT_indiv0[300]; char OUT_indiv[300]; char OUT_indivZ[300]; MRI_IMAGE *mri=NULL; THD_3dim_dataset *OUT_CORR_MAP=NULL; THD_3dim_dataset *OUT_Z_MAP=NULL; float *zscores=NULL; int Nvox; Nvox = Dim[0]*Dim[1]*Dim[2]; // make average time series per voxel AVE_TS_fl = calloc( 1,sizeof(AVE_TS_fl)); for(i=0 ; i<1 ; i++) AVE_TS_fl[i] = calloc(Dim[3],sizeof(float)); if( (AVE_TS_fl == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure (time series out).\n\n"); exit(123); } fprintf(stderr,"\nHAVE_ROIS=%d",HAVE_ROIS); 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++ ) { fprintf(stderr,"\nNROI_REF[%d]= %d",k,NROI_REF[k]); for( j=0 ; j<Dim[3] ; j++) AVE_TS_fl[0][j] = (float) ROI_AVE_TS[k][i][j]; if( NIFTI_OUT ) sprintf(OUT_indiv,"%s/WB_CORR_ROI_%03d.nii.gz", OUT_indiv0,ROI_LABELS_REF[k][i+1]); else sprintf(OUT_indiv,"%s/WB_CORR_ROI_%03d", OUT_indiv0,ROI_LABELS_REF[k][i+1]); mri = mri_float_arrays_to_image(AVE_TS_fl,Dim[3],1); OUT_CORR_MAP = THD_Tcorr1D(insetTIME, mskd2, Nmask, mri, "pearson", OUT_indiv); if(Do_r){ THD_load_statistics(OUT_CORR_MAP); tross_Copy_History( insetTIME , OUT_CORR_MAP ) ; tross_Make_History( "3dNetcorr", argc, argv, OUT_CORR_MAP ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(OUT_CORR_MAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(OUT_CORR_MAP)); THD_write_3dim_dataset(NULL, NULL, OUT_CORR_MAP, True); INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(OUT_CORR_MAP)); } if(Do_Z){ if( NIFTI_OUT ) sprintf(OUT_indivZ,"%s/WB_Z_ROI_%03d.nii.gz", OUT_indiv0,ROI_LABELS_REF[k][i+1]); else sprintf(OUT_indivZ,"%s/WB_Z_ROI_%03d", OUT_indiv0,ROI_LABELS_REF[k][i+1]); OUT_Z_MAP = EDIT_empty_copy(OUT_CORR_MAP); EDIT_dset_items( OUT_Z_MAP, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , OUT_indivZ, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(OUT_Z_MAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(OUT_Z_MAP)); zscores = (float *)calloc(Nvox,sizeof(float)); if( (zscores == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure (zscores).\n\n"); exit(123); } for( j=0 ; j<Nvox ; j++ ) if( mskd2[j] ) // control for r ==1 BOBatanhf( THD_get_voxel(OUT_CORR_MAP, j, 0) ); /* if( THD_get_voxel(OUT_CORR_MAP, j, 0) > MAX_R ) zscores[j] = (float) atanh(MAX_R); else if ( THD_get_voxel(OUT_CORR_MAP, j, 0) < -MAX_R ) zscores[j] = (float) atanh(-MAX_R); else zscores[j] = (float) atanh(THD_get_voxel(OUT_CORR_MAP, j, 0));*/ EDIT_substitute_brick(OUT_Z_MAP, 0, MRI_float, zscores); zscores=NULL; THD_load_statistics(OUT_Z_MAP); tross_Copy_History(insetTIME, OUT_Z_MAP); tross_Make_History("3dNetcorr", argc, argv, OUT_Z_MAP); THD_write_3dim_dataset(NULL, NULL, OUT_Z_MAP, True); INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(OUT_Z_MAP)); DSET_delete(OUT_Z_MAP); free(OUT_Z_MAP); OUT_Z_MAP=NULL; } DSET_delete(OUT_CORR_MAP); free(OUT_CORR_MAP); OUT_CORR_MAP=NULL; } } free(zscores); mri_free(mri); for( i=0 ; i<1 ; i++) free(AVE_TS_fl[i]); free(AVE_TS_fl); RETURN(1); }
int main(int argc, char *argv[]) { int i,j,k,l,m,n,mm,ii; int idx; int iarg; THD_3dim_dataset *insetTIME = NULL; // THD_3dim_dataset *inset0 = NULL; THD_3dim_dataset *MASK=NULL; char *prefix="REHO" ; char in_name[300]; char in_mask[300]; THD_3dim_dataset *outset=NULL; char outname[300]; int NIFTI_OUT=0; int DTYPE=0; int HAVE_MASK = 0; int ***mskd; // define mask of where time series are nonzero double temp_sum; // FILE *fout0, *fout1; int Nvox=-1; // tot number vox int Dim[4]={0,0,0,0}; float fbot = -1., ftop = -1; float delF = -1; float *allF=NULL; float **allPar=NULL; int Npar=NRSFC; // currently... see list below char *namePar[NRSFC]={"ALFF", "MALFF", "FALFF", "RSFA", "MRSFA", "FRSFA"}; int MIN_full=0, MAX_full=-1; // indices of full spect int MIN_bp=0, MAX_bp = -1; // indices of lff/bp region mainENTRY("3dAmpToRSFC"); machdep(); // **************************************************************** // **************************************************************** // load AFNI stuff // **************************************************************** // **************************************************************** // INFO_message("version: NU"); /** scan args **/ if (argc == 1) { usage_AmpToRSFC(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_AmpToRSFC(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strncmp(argv[iarg],"-band",5) == 0 ){ if( ++iarg >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ; fbot = strtod(argv[iarg++],NULL) ; ftop = strtod(argv[iarg++],NULL) ; 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],"-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],"-in_amp") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-in_amp'"); sprintf(in_name,"%s", argv[iarg]); DTYPE = 1; // for amps iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_pow") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-in_pow'"); sprintf(in_name,"%s", argv[iarg]); DTYPE = 2; // for pow 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],"-nifti") == 0) { NIFTI_OUT=1; iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } // --------------------------------------------------------------- // TEST BASIC INPUT PROPERTIES if (iarg < 3) { ERROR_message("Too few options. Try -help for details.\n"); exit(1); } if( !DTYPE ) { ERROR_message("Think somebody forgot to specify an input file" " using '-in_amp ...' or '-in_pow ...'."); exit(12); } else{ insetTIME = THD_open_dataset(in_name) ; if( (insetTIME == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_name); 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); delF = DSET_TR(insetTIME); } if( (fbot<0) || (ftop<0) ) { ERROR_message("Think somebody forgot to specify upper and lower" " frequency bounds using '-band ... ...'."); exit(11); } if( fbot > ftop ) ERROR_exit("Can't have ftop < fbot! Try entering frequency" "band limits again"); if( MASK ) if ( Dim[0] != DSET_NX(MASK) || Dim[1] != DSET_NY(MASK) || Dim[2] != DSET_NZ(MASK) ) { ERROR_message("Mask and inset don't appear to have the same " "dimensions.\n"); exit(1); } // **************************************************************** // **************************************************************** // pre-stuff, make storage // **************************************************************** // **************************************************************** // array of freqs-- starts at delta F, not zero, as the current // input data sets must! allF = (float *)calloc(Dim[3], sizeof(float)); // will be the output allPar = calloc(Npar,sizeof(allPar)); for(i=0 ; i<Npar ; i++) allPar[i] = calloc(Nvox,sizeof(float)); // MASK mskd = (int ***) calloc( Dim[0], sizeof(int **) ); for ( i = 0 ; i < Dim[0] ; i++ ) mskd[i] = (int **) calloc( Dim[1], sizeof(int *) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) mskd[i][j] = (int *) calloc( Dim[2], sizeof(int) ); if( (mskd == NULL) || (allF == NULL) || (allPar == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure (mask).\n\n"); exit(33); } // ************************************************************* // ************************************************************* // Beginning of main loops // ************************************************************* // ************************************************************* // Populate freq bands. For now, delF is constant. Later.... who // knows, so make flexible allF[0] = DSET_TIMEORIGIN(insetTIME); if( allF[0] < EPS_V ) ERROR_exit("The t-axis (here, frequency) origin is 0!" "\n\t-> but you shouldn't have a baseline 0-frequency!"); for( i=1 ; i<Dim[3] ; i++ ) allF[i] = allF[i-1] + delF; // fill in rest of freq ranges; MIN_full=0 already MAX_full = Dim[3]-1; // these should be in order, so we can pass through like this. for( i=0 ; i<Dim[3] ; i++ ) { ii = Dim[3] - 1 - i; if( allF[ii] >= fbot ) MIN_bp = ii; if( allF[i] <= ftop ) MAX_bp = i; } if(MAX_bp < MIN_bp) // shouldn't happen... ERROR_exit("Something went horribly wrong with reading in the " "bandpass limits! bot:%f, top:%f",MIN_bp, MAX_bp); INFO_message("Actual BP range: indices [%d, %d] -> " "freqs [%.4f, %.4f]", MIN_bp, MAX_bp, allF[MIN_bp], allF[MAX_bp]); INFO_message("Full freq range: indices [%d, %d] -> " "freqs [%.4f, %.4f]", MIN_full, MAX_full, allF[MIN_full], allF[MAX_full]); // go through once: define data vox idx = 0; 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; } else { temp_sum = 0.; for ( l=0 ; l<Dim[3] ; l++ ) temp_sum+= abs(THD_get_voxel(insetTIME,idx,l)); if ( temp_sum > EPS_V ) mskd[i][j][k] = 1; } idx++; } INFO_message("Done masking."); Spect_to_RSFC( insetTIME, DTYPE, Dim, mskd, MIN_bp, MAX_bp, MIN_full, MAX_full, allPar, Npar ); INFO_message("Done calculating parameters."); // ************************************************************** // ************************************************************** // Store and output // ************************************************************** // ************************************************************** for( m=0; m<Npar ; m++) { outset = EDIT_empty_copy(insetTIME) ; if(NIFTI_OUT) sprintf(outname,"%s_%s.nii.gz",prefix, namePar[m]); else sprintf(outname,"%s_%s",prefix, namePar[m]); INFO_message(" writing: %s %s", prefix, outname); EDIT_dset_items( outset, ADN_nvals , 1 , ADN_datum_all , MRI_float , ADN_prefix , outname , ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outset)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outset)); EDIT_substitute_brick(outset, 0, MRI_float, allPar[m]); allPar[m]=NULL; THD_load_statistics(outset); tross_Make_History("3dAmpToRSFC", argc, argv, outset); THD_write_3dim_dataset(NULL, NULL, outset, True); if(outset) { DSET_delete(outset); free(outset); } } // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ if(allF) free(allF); if(MASK) { DSET_delete(MASK); free(MASK); } if(insetTIME) { DSET_delete(insetTIME); free(insetTIME); } if(mskd) { 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); } if(allPar) { // have freed other parts of this above free(allPar); } return 0; }