From 34361b542f0351a060afbbd349e300b5927018fe Mon Sep 17 00:00:00 2001 From: Saad Jbabdi <saad@fmrib.ox.ac.uk> Date: Tue, 22 Aug 2006 14:55:35 +0000 Subject: [PATCH] reordering dyads - first sketch --- reorder_dyadic_vectors.cc | 316 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 reorder_dyadic_vectors.cc diff --git a/reorder_dyadic_vectors.cc b/reorder_dyadic_vectors.cc new file mode 100644 index 0000000..bb43399 --- /dev/null +++ b/reorder_dyadic_vectors.cc @@ -0,0 +1,316 @@ +/* reorder_dyadic_vectors.cc + + Saad Jbabdi, FMRIB Image Analysis Group + + Copyright (C) 2006 University of Oxford */ + +/* CCOPYRIGHT */ + +#include "utils/options.h" +#include "heap.h" +#include "newimage/newimageall.h" +#include "miscmaths/miscprob.h" +#include "stdlib.h" + +#define AP 2 +#define NB 1 +#define FA 0 + + +using namespace Utilities; +using namespace std; +using namespace NEWIMAGE; +using namespace MISCMATHS; + + +string title="reorder_dyadic_vectors (Version 1.0)\nReordering of the dyadic vectors with direction preservation"; +string examples="reorder_dyadic_vectors -b <dirname> [-m mask]\n<dirname> is supposed to contain mean_fisamples and dyadsi for i=1:n"; + +Option<bool> verbose(string("-v,--verbose"),false, + string("switch on diagnostic messages"), + false,no_argument); +Option<bool> help(string("-h,--help"),false, + string("display this message"), + false,no_argument); +Option<string> basename(string("-b,--basename"),string(""), + string("output basename"), + true,requires_argument); +Option<string> mask(string("-m,--mask"),string(""), + string("filename of brain mask"), + false,requires_argument); +//////////////////////////////////////////////////////// + +class FM{ + private: + volume<float> mask,tmap,state; + vector< volume4D<float> > dyads; + vector< volume<float> > meanf; + int nx,ny,nz; + Matrix P; + Matrix neighbours; + + Option<string>& obasename; + Option<string>& omask; + + public: + FM(Option<string>& optbasename,Option<string>& optmask):obasename(optbasename),omask(optmask){ + + int fib=1; + bool fib_existed=true; + while(fib_existed){ + if(fsl_imageexists(obasename.value()+"mean_f"+num2str(fib)+"samples")){ + volume4D<float> *tmpdptr=new volume4D<float>; + volume<float> *tmpfptr=new volume<float>; + read_volume4D(*tmpdptr,obasename.value()+"dyads"+num2str(fib)); + dyads.push_back(*tmpdptr); + read_volume(*tmpfptr,obasename.value()+"mean_f"+num2str(fib)+"samples"); + meanf.push_back(*tmpfptr); + fib++; + } + else + fib_existed=false; + } + + // read input volumes + nx=dyads[0].xsize(); + ny=dyads[0].ysize(); + nz=dyads[0].zsize(); + // create other volumes + if(omask.set()){ + volume<float> mask; + read_volume(mask,omask.value()); + } + else{ + volume<float> maskvol(nx,ny,nz); + copybasicproperties(dyads[0],mask); + mask=1; + } + + state.reinitialize(nx,ny,nz); + tmap.reinitialize(nx,ny,nz); + + P=MISCMATHS::perms(dyads.size()); + + neighbours.ReSize(3,26); + neighbours << 1 << 0 << 0 << -1 << 0 << 0 << 1 << 1 <<-1 <<-1 << 1 <<-1 << 1 <<-1 << 0 << 0 << 0 << 0 << 1 <<-1 << 1 << 1 <<-1 <<-1 << 1 <<-1 + << 0 << 1 << 0 << 0 <<-1 << 0 << 1 <<-1 << 1 <<-1 << 0 << 0 << 0 << 0 << 1 <<-1 << 1 <<-1 << 1 << 1 <<-1 << 1 <<-1 << 1 <<-1 <<-1 + << 0 << 0 << 1 << 0 << 0 <<-1 << 0 << 0 << 0 << 0 << 1 << 1 <<-1 <<-1 << 1 << 1 <<-1 <<-1 << 1 << 1 << 1 <<-1 << 1 <<-1 <<-1 <<-1; + } + + ////////////////////// functions + void do_fast_marching(){ + int i0,j0,k0; /* current point coords */ + float tval; + + /********************************/ + /*** performing fmt algorithm ***/ + /********************************/ + + /*** initialization ***/ + + /* look for bigger f1+f2 point as a seed */ + float maxf=0,curf; + for(int z=0;z<nz;z++) + for(int y=0;y<ny;y++) + for(int x=0;x<nx;x++){ + curf=0; + for(unsigned int f=0;f<meanf.size();f++) + curf += meanf[f](x,y,z); + if(curf>maxf){ + i0=x;j0=y;k0=z; + maxf=curf; + } + state(x,y,z)=FA; + tmap(x,y,z)=1; + } + state(i0,j0,k0)=AP; + tmap(i0,j0,k0)=0; + + /* create heap sort structure */ + Heap h(nx,ny,nz); + + /* and all points of the ROIs as Alive Points */ + updateNBvalue(i0,j0,k0,h); + /*--------------------------------------------------------*/ + /*** big loop ***/ + int STOP = 0; + int counter = 0; + while(STOP==0){ + /*break;*/ + counter++; + + /*** uses the heap sort structure to find the NB point with the smallest T-value ***/ + h.heapRemove(tval,i0,j0,k0); + + /*** add this point to the set of alive points ***/ + state(i0,j0,k0)=AP; + + if(h.get_N()==0) + break; + + /*** update narrow band's T-value ***/ + updateNBvalue(i0,j0,k0,h); + + } + + } + int isInside(int i,int j,int k){ + return((i>=0) && (i<nx) + && (j>=0) && (j<ny) + && (k>=0) && (k<nz) + && (mask(i,j,k)!=0)); + } + void computeT(int x,int y,int z){ + Matrix V(P.Ncols(),3); + Matrix nV(P.Ncols(),3); + ColumnVector mF(P.Ncols()); + + V=get_vector(x,y,z); + mF=get_f(x,y,z); + + int nbx,nby,nbz; + int opt_perm=1; + float opt_sperm=0; + for(int per=1;per<P.Nrows();per++){ + + float opt_nb=0;int nnb=0; + for(int nb=1;nb<=neighbours.Ncols();nb++){ + nbx=x+neighbours(1,nb);nby=y+neighbours(2,nb);nbz=z+neighbours(3,nb); + if(!isInside(nbx,nby,nbz)) + continue; + if(state(nbx,nby,nbz)==AP){ + nV=get_vector(nbx,nby,nbz); + + float opt_s=0,s; + for(int f=1;f<=V.Nrows();f++){ + s=dot(nV.Row(f).t(),V.Row(P(per,f)).t()); + if(s>opt_s){ + opt_s=s; + } + }//f + opt_nb+=opt_s; + nnb++; + }//nb + opt_nb/=nnb; + + if(opt_nb>opt_sperm){ + opt_sperm=opt_nb; + opt_perm=per; + } + + }//endif + }//perm + tmap(x,y,z)=1-opt_sperm; // store optimal mean scalar product + + // reorder dyads + for(unsigned int f=0;f<dyads.size();f++){ + dyads[f](x,y,z,0)=V(P(opt_perm,f+1),1); + dyads[f](x,y,z,1)=V(P(opt_perm,f+1),2); + dyads[f](x,y,z,2)=V(P(opt_perm,f+1),3); + + meanf[f](x,y,z)=mF(P(opt_perm,f+1)); + } + } + + ReturnMatrix get_vector(int x,int y,int z){ + Matrix V(P.Ncols(),3); + for(unsigned int f=0;f<dyads.size();f++) + for(int i=1;i<=3;i++) + V(f+1,i)=dyads[f](x,y,z,i-1); + + V.Release(); + return V; + } + + ReturnMatrix get_f(int x,int y,int z){ + ColumnVector V(P.Ncols()); + for(unsigned int f=0;f<dyads.size();f++) + V(f+1)=meanf[f](x,y,z); + + V.Release(); + return V; + } + + void updateNBvalue(int i,int j,int k,Heap& h){ + int ni,nj,nk; + int pos; + double val; + + for(int nb=1;nb<neighbours.Ncols();nb++){ + ni=i+neighbours(1,nb);nj=j+neighbours(2,nb);nk=k+neighbours(3,nb); + if(isInside(ni,nj,nk)){ + if(state(ni,nj,nk)==AP)continue; + computeT(ni,nj,nk); + val=tmap(ni,nj,nk); + /* update value if in NB */ + if(state(ni,nj,nk)==NB){ + pos=h.get_bpr(ni,nj,nk); + h.set_val(pos,MIN(h.get_val(pos),val)); + h.heapUp(pos); + } + /* insert value if in FA */ + else{ + state(ni,nj,nk)=NB; + h.heapInsert(val,ni,nj,nk); + } + } + + } + } + + void save_results(){ + int fib=1; + for(unsigned int f=0;f<dyads.size();f++){ + save_volume4D(dyads[f],obasename.value()+"reordered_dyads"+num2str(fib)); + save_volume(meanf[f],obasename.value()+"reordered_meanf"+num2str(fib)+"samples"); + fib++; + } + } + +}; + + + + +int main(int argc,char *argv[]){ + + Tracer tr("main"); + OptionParser options(title,examples); + + try{ + options.add(verbose); + options.add(help); + options.add(basename); + options.add(mask); + + options.parse_command_line(argc,argv); + + + if ( (help.value()) || (!options.check_compulsory_arguments(true)) ){ + options.usage(); + exit(EXIT_FAILURE); + } + + + FM fm(basename,mask); + + fm.do_fast_marching(); + + fm.save_results(); + + + + } + catch(X_OptionError& e) { + options.usage(); + cerr << endl << e.what() << endl; + exit(EXIT_FAILURE); + } + catch(std::exception &e) { + cerr << e.what() << endl; + } + + return 0; + + +} -- GitLab