From 83e34a10ab40c5681b0ccd48dfc21a115296d6e5 Mon Sep 17 00:00:00 2001 From: Tim Behrens <behrens@fmrib.ox.ac.uk> Date: Thu, 14 Jul 2005 09:31:35 +0000 Subject: [PATCH] *** empty log message *** --- fibre.h | 19 +- probtrackx.cc | 81 +++++++ probtrackx.h | 10 + ptx_seedmask.cc | 45 ++++ ptx_seedmask.h | 16 ++ ptx_simple.cc | 51 +++++ ptx_simple.h | 15 ++ ptx_twomasks.cc | 61 ++++++ ptx_twomasks.h | 13 ++ streamlines.cc | 572 ++++++++++++++++++++++++++++++++++++++++++++++++ streamlines.h | 201 +++++++++++++++++ 11 files changed, 1074 insertions(+), 10 deletions(-) create mode 100644 probtrackx.cc create mode 100644 probtrackx.h create mode 100644 ptx_seedmask.cc create mode 100644 ptx_seedmask.h create mode 100644 ptx_simple.cc create mode 100644 ptx_simple.h create mode 100644 ptx_twomasks.cc create mode 100644 ptx_twomasks.h create mode 100644 streamlines.cc create mode 100644 streamlines.h diff --git a/fibre.h b/fibre.h index 6109d12..87c98a6 100644 --- a/fibre.h +++ b/fibre.h @@ -108,7 +108,6 @@ namespace FIBRE{ m_th(th), m_ph(ph), m_f(f), m_lam(lam),m_lam_jump(lam_jump), m_d(d), m_alpha(alpha), m_beta(beta), m_bvals(bvals) { - m_th_old=m_th; m_ph_old=m_ph; m_f_old=m_f; @@ -117,7 +116,7 @@ namespace FIBRE{ m_ph_prop=0.2; m_f_prop=0.2; m_lam_prop=1; - + m_th_prior=0; compute_th_prior(); @@ -313,12 +312,12 @@ namespace FIBRE{ inline bool propose_lam(){ if(m_lam_jump){ - m_lam_old=m_lam; - m_lam+=normrnd().AsScalar()*m_lam_prop; - bool rejflag=compute_lam_prior(); - compute_f_prior(); - compute_prior(); - return rejflag; + m_lam_old=m_lam; + m_lam+=normrnd().AsScalar()*m_lam_prop; + bool rejflag=compute_lam_prior(); + compute_f_prior(); + compute_prior(); + return rejflag; } else {return true;} }; @@ -339,7 +338,7 @@ namespace FIBRE{ m_th=rhs.m_th; m_ph=rhs.m_ph; m_f=rhs.m_f; - m_lam=rhs. m_lam; + m_lam=rhs.m_lam; m_th_prop=rhs. m_th_prop; m_ph_prop=rhs.m_ph_prop; m_f_prop=rhs.m_f_prop; @@ -693,7 +692,7 @@ namespace FIBRE{ m_fibres[f].reject_f(); } - + if(!m_fibres[f].propose_lam()){ compute_prior(); compute_energy(); diff --git a/probtrackx.cc b/probtrackx.cc new file mode 100644 index 0000000..dfffb8c --- /dev/null +++ b/probtrackx.cc @@ -0,0 +1,81 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include <iostream> +#include <fstream> +#include "newimage/newimageall.h" +#include "utils/log.h" +#include "meshclass/meshclass.h" +#include "probtrackx.h" + + +using namespace std; +using namespace NEWIMAGE; +using namespace TRACT; +using namespace Utilities; +using namespace PARTICLE; +using namespace TRACTVOLS; +using namespace mesh; +//using namespace NEWMAT; +////////////////////////// +///////////////////////// + + + +int main ( int argc, char **argv ){ + probtrackOptions& opts =probtrackOptions::getInstance(); + Log& logger = LogSingleton::getInstance(); + opts.parse_command_line(argc,argv,logger); + srand(opts.rseed.value()); + + + if(opts.verbose.value()>0){ + opts.status(); + } + if(opts.mode.value()=="simple") + track(); + else if(fsl_imageexists(opts.mask2.value())){ twomasks();} + else if(fsl_imageexists(opts.seedfile.value())){ seedmask();} + + // else if(opts.mode.value()=="seeds_to_targets") + // seeds_to_targets(); + // else if(opts.mode.value()=="seedmask") + // alltracts(); + // else if(opts.mode.value()=="twomasks_symm") + // twomasks_symm(); + // else if(opts.mode.value()=="waypoints") + // waypoints(); + // else if(opts.mode.value()=="matrix1") + // matrix1(); + // else if(opts.mode.value()=="matrix2"){ + // if(opts.meshfile.value()=="") + // matrix2(); + // else + // mesh_matrix2(); + // } + // else if(opts.mode.value()=="maskmatrix") + // maskmatrix(); + // else if(opts.mode.value()=="meshlengths") + // mesh_lengths(); + else{ + cout <<"Invalid setting for option mode -- try setting mode=help"<<endl; + } + + return 0; +} + + + + + + + + + + + + + + + diff --git a/probtrackx.h b/probtrackx.h new file mode 100644 index 0000000..856a6d0 --- /dev/null +++ b/probtrackx.h @@ -0,0 +1,10 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include "probtrackOptions.h" +#include "particle.h" +#include "tractvols.h" +#include "ptx_simple.h" +#include "ptx_seedmask.h" +#include "ptx_twomasks.h" diff --git a/ptx_seedmask.cc b/ptx_seedmask.cc new file mode 100644 index 0000000..e755cf6 --- /dev/null +++ b/ptx_seedmask.cc @@ -0,0 +1,45 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include "ptx_seedmask.h" +#include "streamlines.h" + +using namespace std; +using namespace NEWIMAGE; +using namespace TRACT; +using namespace Utilities; +using namespace PARTICLE; +using namespace TRACTVOLS; +using namespace mesh; + + + +void seedmask() +{ + probtrackOptions& opts =probtrackOptions::getInstance(); + + //////////////////////////////// + // Log& logger = LogSingleton::getInstance(); + volume<int> seeds; + read_volume(seeds,opts.seedfile.value()); + Streamliner stline; + Counter counter(seeds,stline); + counter.initialise(); + Seedmanager seedmanager(counter); + + for(int z=0;z<seeds.zsize();z++){ + for(int y=0;y<seeds.ysize();y++){ + for(int x=0;x<seeds.xsize();x++){ + if(seeds(x,y,z)>0){ + seedmanager.run(x,y,z); + } + } + } + } + + counter.save(); + +} + + diff --git a/ptx_seedmask.h b/ptx_seedmask.h new file mode 100644 index 0000000..9fc135a --- /dev/null +++ b/ptx_seedmask.h @@ -0,0 +1,16 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include <fstream> +#include "newimage/newimageall.h" +#include "utils/log.h" +#include "meshclass/meshclass.h" +#include "probtrackOptions.h" +#include "particle.h" +#include "tractvols.h" + + + + +void seedmask(); diff --git a/ptx_simple.cc b/ptx_simple.cc new file mode 100644 index 0000000..3425efb --- /dev/null +++ b/ptx_simple.cc @@ -0,0 +1,51 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include "ptx_simple.h" +#include "streamlines.h" + +using namespace std; +using namespace NEWIMAGE; +using namespace TRACT; +using namespace Utilities; +using namespace PARTICLE; +using namespace TRACTVOLS; +using namespace mesh; + + +void track(){ + probtrackOptions& opts =probtrackOptions::getInstance(); + + //////////////////////////// + Log& logger = LogSingleton::getInstance(); + if(opts.verbose.value()>1){ + logger.makeDir("particles","particle0",true,false); + } + + volume<int> seedref; + if(opts.seedref.value()!=""){ + read_volume(seedref,opts.seedref.value()); + } + else{ + read_volume(seedref,opts.maskfile.value()); + } + + Streamliner stline; + Counter counter(seedref,stline); + counter.initialise(); + Seedmanager seedmanager(counter); + + + Matrix Seeds = read_ascii_matrix(opts.seedfile.value()); + for(int SN=1; SN<=Seeds.Nrows();SN++){ + float xst=Seeds(SN,1); + float yst=Seeds(SN,2); + float zst=Seeds(SN,3); + seedmanager.run(xst,yst,zst); + string add=num2str(Seeds(SN,1))+(string)"_"+num2str(Seeds(SN,2))+(string)"_"+num2str(Seeds(SN,3)); + + counter.save_pathdist(add); + counter.reset_prob(); + } //Close Seed number Loop +} diff --git a/ptx_simple.h b/ptx_simple.h new file mode 100644 index 0000000..3f8590e --- /dev/null +++ b/ptx_simple.h @@ -0,0 +1,15 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include <fstream> +#include "newimage/newimageall.h" +#include "utils/log.h" +#include "meshclass/meshclass.h" +#include "probtrackOptions.h" +#include "particle.h" +#include "tractvols.h" + + + +void track(); diff --git a/ptx_twomasks.cc b/ptx_twomasks.cc new file mode 100644 index 0000000..1abcde0 --- /dev/null +++ b/ptx_twomasks.cc @@ -0,0 +1,61 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include "ptx_twomasks.h" +#include "streamlines.h" + +using namespace std; +using namespace NEWIMAGE; +using namespace TRACT; +using namespace Utilities; +using namespace PARTICLE; +using namespace TRACTVOLS; +using namespace mesh; + + + +void twomasks() +{ + probtrackOptions& opts =probtrackOptions::getInstance(); + + //////////////////////////////// + // Log& logger = LogSingleton::getInstance(); + volume<int> seeds,seeds2; + read_volume(seeds,opts.seedfile.value()); + read_volume(seeds2,opts.mask2.value()); + Streamliner stline; + Counter counter(seeds,stline); + counter.initialise(); + Seedmanager seedmanager(counter); + + stline.add_waymask(seeds2); + for(int z=0;z<seeds.zsize();z++){ + for(int y=0;y<seeds.ysize();y++){ + for(int x=0;x<seeds.xsize();x++){ + if(seeds(x,y,z)>0){ + seedmanager.run(x,y,z); + } + } + } + } + stline.pop_waymasks(); + + + stline.add_waymask(seeds); + for(int z=0;z<seeds2.zsize();z++){ + for(int y=0;y<seeds2.ysize();y++){ + for(int x=0;x<seeds2.xsize();x++){ + if(seeds2(x,y,z)>0){ + seedmanager.run(x,y,z); + } + } + } + } + + + counter.save(); + +} + + diff --git a/ptx_twomasks.h b/ptx_twomasks.h new file mode 100644 index 0000000..626d000 --- /dev/null +++ b/ptx_twomasks.h @@ -0,0 +1,13 @@ +/* Copyright (C) 2004 University of Oxford */ + +/* CCOPYRIGHT */ + +#include <fstream> +#include "newimage/newimageall.h" +#include "utils/log.h" +#include "meshclass/meshclass.h" +#include "probtrackOptions.h" +#include "particle.h" +#include "tractvols.h" + +void twomasks(); diff --git a/streamlines.cc b/streamlines.cc new file mode 100644 index 0000000..c32eab2 --- /dev/null +++ b/streamlines.cc @@ -0,0 +1,572 @@ +#include "streamlines.h" + + + +namespace TRACT{ + + + + void read_masks(vector<string>& masks, const string& filename){ + ifstream fs(filename.c_str()); + string tmp; + if(fs){ + fs>>tmp; + while(!fs.eof()){ + masks.push_back(tmp); + fs>>tmp; + } + } + else{ + cerr<<filename<<" does not exist"<<endl; + exit(0); + } + } + + + Streamliner::Streamliner():opts(probtrackOptions::getInstance()),logger(LogSingleton::getInstance()), + vols(opts.usef.value()){ + + read_volume(m_mask,opts.maskfile.value()); + m_part.initialise(0,0,0,0,0,0,opts.steplength.value(),m_mask.xdim(),m_mask.ydim(),m_mask.zdim(),false); + if(opts.skipmask.value()!="") read_volume(m_skipmask,opts.skipmask.value()); + m_lcrat=5; + if(opts.loopcheck.value()){ + m_loopcheck.reinitialize(int(ceil(m_mask.xsize()/m_lcrat)+1),int(ceil(m_mask.ysize()/m_lcrat)+1),int(ceil(m_mask.zsize()/m_lcrat)+1),3); + m_loopcheck=0; + } + if(opts.rubbishfile.value()!=""){ + read_volume(m_rubbish,opts.rubbishfile.value()); + } + + vector<string> masknames; + if(opts.waypoints.value()!=""){ + if(fsl_imageexists(opts.waypoints.value())){ + masknames.push_back( opts.waypoints.value() ); + } + else{ + read_masks(masknames,opts.waypoints.value()); + } + + for( unsigned int m = 0; m < masknames.size(); m++ ){ + volume<int>* tmpptr =new volume<int>; + if(opts.verbose.value()>0) + cout<<masknames[m]<<endl; + read_volume(*tmpptr,masknames[m]); + m_waymasks.push_back(tmpptr); + m_passed_flags.push_back(false); + m_own_waymasks.push_back(true); + } + } + if(opts.seeds_to_dti.value()!=""){ + read_ascii_matrix(m_Seeds_to_DTI,opts.seeds_to_dti.value()); + } + else{ + m_Seeds_to_DTI=Identity(4); + } + vols.initialise(opts.basename.value()); + m_path.reserve(opts.nparticles.value()); + m_x_s_init=0; + m_y_s_init=0; + m_z_s_init=0; + } + + + bool Streamliner::streamline(const float& x_init,const float& y_init,const float& z_init, const ColumnVector& dim_seeds,const int& fibst){ + + //fibst tells tractvols which fibre to start with if there are more than one.. + //x_init etc. are in seed space... + vols.reset(fibst); + m_x_s_init=x_init; //seed x position in voxels + m_y_s_init=y_init; // and y + m_z_s_init=z_init; // and z + ColumnVector xyz_seeds(3); + xyz_seeds<<x_init<<y_init<<z_init; + ColumnVector xyz_dti; + ColumnVector th_ph_f; + float xst,yst,zst,x,y,z,tmp2; + xyz_dti=vox_to_vox(xyz_seeds,dim_seeds,vols.dimensions(),m_Seeds_to_DTI); + xst=xyz_dti(1);yst=xyz_dti(2);zst=xyz_dti(3); + m_path.clear(); + x=xst;y=yst;z=zst; + m_part.change_xyz(x,y,z); + int partlength=0; + //NB - this only goes in one direction!! + for(unsigned int pf=0;pf<m_passed_flags.size();pf++) { + m_passed_flags[pf]=false; /// only keep it if this streamline went through all the masks + } + + for( int it = 1 ; it <= opts.nsteps.value()/2; it++){ + if( (m_mask( round(m_part.x()), round(m_part.y()), round(m_part.z())) > 0) ){ + + /////////////////////////////////// + //loopchecking + /////////////////////////////////// + if(opts.loopcheck.value()){ + float oldrx=m_loopcheck((int)round(m_part.x()/m_lcrat),(int)round(m_part.y()/m_lcrat),(int)round(m_part.z()/m_lcrat),0); + float oldry=m_loopcheck((int)round(m_part.x()/m_lcrat),(int)round(m_part.y()/m_lcrat),(int)round(m_part.z()/m_lcrat),1); + float oldrz=m_loopcheck((int)round(m_part.x()/m_lcrat),(int)round(m_part.y()/m_lcrat),(int)round(m_part.z()/m_lcrat),2); + if(m_part.rx()*oldrx+m_part.ry()*oldry+m_part.rz()*oldrz<0) + { + break; + } + + m_loopcheck((int)round(m_part.x()/m_lcrat),(int)round(m_part.y()/m_lcrat),(int)round(m_part.z()/m_lcrat),0)=m_part.rx(); + m_loopcheck((int)round(m_part.x()/m_lcrat),(int)round(m_part.y()/m_lcrat),(int)round(m_part.z()/m_lcrat),1)=m_part.ry(); + m_loopcheck((int)round(m_part.x()/m_lcrat),(int)round(m_part.y()/m_lcrat),(int)round(m_part.z()/m_lcrat),2)=m_part.rz(); + + } + + if(opts.verbose.value()>1) + logger<<m_part; + + x=m_part.x();y=m_part.y();z=m_part.z(); + xyz_dti <<x<<y<<z; + xyz_seeds=vox_to_vox(xyz_dti,vols.dimensions(),dim_seeds,m_Seeds_to_DTI.i()); + int x_s =(int)round((float)xyz_seeds(1)); + int y_s =(int)round((float)xyz_seeds(2)); + int z_s =(int)round((float)xyz_seeds(3)); + if(opts.rubbishfile.value()!=""){ + if(m_rubbish(x_s,y_s,z_s)>0) break; + } + + m_path.push_back(xyz_seeds); + // m_path(it,1)=x_s; + // m_path(it,2)=y_s; + // m_path(it,3)=z_s; + partlength++; + + //update every passed_flag + for( unsigned int wm=0;wm<m_waymasks.size();wm++ ){ + if( (*m_waymasks[wm])(x_s,y_s,z_s)>0 ) + m_passed_flags[wm]=true; + } + + + if(opts.skipmask.value() == ""){ + th_ph_f=vols.sample(m_part.x(),m_part.y(),m_part.z(),m_part.rx(),m_part.ry(),m_part.rz()); + } + else{ + if(m_skipmask(x_s,y_s,z_s)==0) + th_ph_f=vols.sample(m_part.x(),m_part.y(),m_part.z(),m_part.rx(),m_part.ry(),m_part.rz()); + } + + + tmp2=rand(); tmp2/=RAND_MAX; + if(th_ph_f(3)>tmp2){ + if(!m_part.check_dir(th_ph_f(1),th_ph_f(2),opts.c_thr.value())){ + break; + } + + if((th_ph_f(1)!=0&&th_ph_f(2)!=0)){ + if( (m_mask( round(m_part.x()), round(m_part.y()), round(m_part.z())) != 0) ){ + if(!opts.modeuler.value()) + m_part.jump(th_ph_f(1),th_ph_f(2)); + else + { + ColumnVector test_th_ph_f; + m_part.testjump(th_ph_f(1),th_ph_f(2)); + test_th_ph_f=vols.sample(m_part.testx(),m_part.testy(),m_part.testz(),m_part.rx(),m_part.ry(),m_part.rz()); + m_part.jump(test_th_ph_f(1),test_th_ph_f(2)); + } + } + + + } + } + + + } + + } // Close Step Number Loop + if(opts.loopcheck.value()){ + m_loopcheck=0; + } + bool accept_path=true; + if(m_passed_flags.size()!=0){ + for(unsigned int i=0; i<m_passed_flags.size();i++) + if(!m_passed_flags[i]) + accept_path=false; + } + return accept_path; + } + + + void Counter::initialise(){ + if(opts.simpleout.value()||opts.matrix1out.value()){ + initialise_path_dist(); + } + if(opts.s2tout.value()){ + initialise_seedcounts(); + } + if(opts.matrix1out.value()){ + initialise_matrix1(); + } + if(opts.matrix2out.value()){ + initialise_matrix2(); + } + if(opts.maskmatrixout.value()){ + initialise_maskmatrix(); + } + } + + void Counter::initialise_seedcounts(){ + + volume<int> tmp; + //vector<int> tmpvec; + read_masks(m_targetmasknames,opts.targetfile.value()); + m_targflags.resize(m_targetmasknames.size(),0); + //m_particle_numbers.resize(m_targetmasknames.size()); + //tmpvec.reserve(opts.nparticles.value()); + cout<<"Number of masks "<<m_targetmasknames.size()<<endl; + //are they initialised to zero? + for(unsigned int m=0;m<m_targetmasknames.size();m++){ + read_volume(tmp,m_targetmasknames[m]); + m_targetmasks.push_back(tmp); + tmp=0; + m_seedcounts.push_back(tmp); + //m_particle_numbers.push_back(tmpvec); + } + } + + + void Counter::initialise_matrix1(){ + m_Conrow=0; + int numseeds=0; + for(int Wz=m_seeds.minz();Wz<=m_seeds.maxz();Wz++) + for(int Wy=m_seeds.miny();Wy<=m_seeds.maxy();Wy++) + for(int Wx=m_seeds.minx();Wx<=m_seeds.maxx();Wx++) + if(m_seeds.value(Wx,Wy,Wz)>0) + numseeds++; + + m_ConMat.reinitialize(numseeds,numseeds,1); + m_CoordMat.reinitialize(numseeds,3,1); + int myrow=0; + + for(int Wz=m_seeds.minz();Wz<=m_seeds.maxz();Wz++){ + for(int Wy=m_seeds.miny();Wy<=m_seeds.maxy();Wy++){ + for(int Wx=m_seeds.minx();Wx<=m_seeds.maxx();Wx++){ + if(m_seeds(Wx,Wy,Wz)>0){ + m_CoordMat(myrow,0,0)=Wx; + m_CoordMat(myrow,1,0)=Wy; + m_CoordMat(myrow,2,0)=Wz; + myrow++; + } + } + } + } + + } + + void Counter::initialise_matrix2(){ + m_Conrow2=0; + read_volume(m_lrmask,opts.lrmask.value()); + m_beenhere2.reinitialize(m_lrmask.xsize(),m_lrmask.ysize(),m_lrmask.zsize()); + m_lrdim.ReSize(3); + m_lrdim<<m_lrmask.xdim()<<m_lrmask.ydim()<<m_lrmask.zdim(); + int numseeds=0,numnz=0; + for(int Wz=m_seeds.minz();Wz<=m_seeds.maxz();Wz++) + for(int Wy=m_seeds.miny();Wy<=m_seeds.maxy();Wy++) + for(int Wx=m_seeds.minx();Wx<=m_seeds.maxx();Wx++) + if(m_seeds.value(Wx,Wy,Wz)>0) + numseeds++; + + for(int Wz=m_lrmask.minz();Wz<=m_lrmask.maxz();Wz++) + for(int Wy=m_lrmask.miny();Wy<=m_lrmask.maxy();Wy++) + for(int Wx=m_lrmask.minx();Wx<=m_lrmask.maxx();Wx++) + if(m_lrmask.value(Wx,Wy,Wz)>0) + numnz++; + + + if(numnz> pow(2,(float)sizeof(short)*8-1)-1){ + cerr<<"Output matrix too big for AVW - stopping."<<endl; + cerr<<" Remember - you can store your tracts in "<<endl; + cerr<<" low res even if you want your seeds in high res"<<endl; + cerr<<" Just subsample the structural space mask"<<endl; + cerr<<" Although, it must stay in line with the seeds"<<endl; + exit(-1); + } + m_ConMat2.reinitialize(numseeds,numnz,1); + m_CoordMat2.reinitialize(numseeds,3,1); + m_CoordMat_tract2.reinitialize(numnz,3,1); + + Matrix tempy(numnz,1); + for(int i=1;i<=numnz;i++){tempy(i,1)=i-1;} + m_lookup2.addvolume(m_lrmask); + m_lookup2.setmatrix(tempy.t(),m_lrmask); + + int mytrow=0; + for(int Wz=m_lrmask.minz();Wz<=m_lrmask.maxz();Wz++) + for(int Wy=m_lrmask.miny();Wy<=m_lrmask.maxy();Wy++) + for(int Wx=m_lrmask.minx();Wx<=m_lrmask.maxx();Wx++) + if(m_lrmask(Wx,Wy,Wz)>0){ + m_CoordMat_tract2(mytrow,0,0)=Wx; + m_CoordMat_tract2(mytrow,1,0)=Wy; + m_CoordMat_tract2(mytrow,2,0)=Wz; + mytrow++; + } + + int myrow=0; + for(int Wz=m_seeds.minz();Wz<=m_seeds.maxz();Wz++) + for(int Wy=m_seeds.miny();Wy<=m_seeds.maxy();Wy++) + for(int Wx=m_seeds.minx();Wx<=m_seeds.maxx();Wx++) + if(m_seeds(Wx,Wy,Wz)>0){ + m_CoordMat2(myrow,0,0)=Wx; + m_CoordMat2(myrow,1,0)=Wy; + m_CoordMat2(myrow,2,0)=Wz; + myrow++; + } + + + } + + void Counter::count_streamline(){ + if(opts.simpleout.value()||opts.matrix1out.value()){ + update_pathdist(); + } + if(opts.s2tout.value()){ + update_seedcounts(); + } + if(opts.matrix2out.value()){ + update_matrix2_row(); + } + if(opts.maskmatrixout.value()){ + update_maskmatrix(); + } + } + + void Counter::count_seed(){ + if(opts.matrix1out.value()){ + update_matrix1(); + } + if(opts.matrix2out.value()){ + next_matrix2_row(); + } + } + + + void Counter::clear_streamline(const bool& forwardflag,const bool& backwardflag){ + if(opts.simpleout.value()||opts.matrix1out.value()){ + reset_beenhere(forwardflag,backwardflag); + } + if(opts.s2tout.value()){ + reset_targetflags(); + } + if(opts.matrix2out.value()){ + reset_beenhere2(forwardflag,backwardflag); + } + if(opts.maskmatrixout.value()){ + //Do whatever it it you have to do!! + } + } + + void Counter::update_pathdist(){ + const vector<ColumnVector>& path=m_stline.get_path_ref(); + for(unsigned int i=0;i<path.size();i++){ + int x_s=int(round(float(path[i](1)))),y_s=int(round(float(path[i](2)))),z_s=int(round(float(path[i](3)))); + if(m_beenhere(x_s,y_s,z_s)==0){ + m_prob(x_s,y_s,z_s)+=1; + m_beenhere(x_s,y_s,z_s)=1; + } + } + + } + + void Counter::reset_beenhere(const bool& forwardflag,const bool& backwardflag){ + if(forwardflag){ + for(unsigned int i=0;i<m_path.size();i++){ + int x_s=int(round(float(m_path[i](1)))),y_s=int(round(float(m_path[i](2)))),z_s=int(round(float(m_path[i](3)))); + m_beenhere(x_s,y_s,z_s)=0; + } + } + if(backwardflag){ + const vector<ColumnVector>& path=m_stline.get_path_ref(); + for(unsigned int i=0;i<path.size();i++){ + int x_s=int(round(float(path[i](1)))),y_s=int(round(float(path[i](2)))),z_s=int(round(float(path[i](3)))); + m_beenhere(x_s,y_s,z_s)=0; + } + } + } + + + void Counter::update_seedcounts(){ + const vector<ColumnVector>& path=m_stline.get_path_ref(); + int xseedvox=int(round(m_stline.get_x_seed())); + int yseedvox=int(round(m_stline.get_y_seed())); + int zseedvox=int(round(m_stline.get_z_seed())); + for(unsigned int i=0;i<path.size();i++){ + int x_s=int(round(float(path[i](1)))),y_s=int(round(float(path[i](2)))),z_s=int(round(float(path[i](3)))); + for(unsigned int m=0;m<m_targetmasknames.size();m++){ + if(m_targetmasks[m](x_s,y_s,z_s)>0 && m_targflags[m]==0){ + m_seedcounts[m](xseedvox,yseedvox,zseedvox)=m_seedcounts[m](xseedvox,yseedvox,zseedvox)+1; + m_targflags[m]=1; + //m_particle_numbers[m].push_back(particle_number); + } + } + } + + } + + + + void Counter::update_matrix1(){ + //after each particle, update_pathdist(), only run this after each voxel + int Concol=0; + for(int Wz=m_prob.minz();Wz<=m_prob.maxz();Wz++){ + for(int Wy=m_prob.miny();Wy<=m_prob.maxy();Wy++){ + for(int Wx=m_prob.minx();Wx<=m_prob.maxx();Wx++){ + if(m_seeds(Wx,Wy,Wz)>0){ + if(m_prob(Wx,Wy,Wz)>0){ + m_ConMat(m_Conrow,Concol,0)=m_prob(Wx,Wy,Wz); + } + Concol++; + } + m_prob(Wx,Wy,Wz)=0; + + } + } + } + + m_Conrow++; + } + + void Counter::update_matrix2_row(){ + //run this one every streamline - not every voxel.. + const vector<ColumnVector>& path=m_stline.get_path_ref(); + for(unsigned int i=0;i<path.size();i++){ + ColumnVector xyz_seeds=path[i]; + ColumnVector xyz_lr=vox_to_vox(xyz_seeds,m_seedsdim,m_lrdim,m_I); + int x_lr=int(round(float(xyz_lr(1)))),y_lr=int(round(float(xyz_lr(2)))),z_lr=int(round(float(xyz_lr(3)))); + int Concol2=m_lookup2(x_lr,y_lr,z_lr,0); + if(Concol2!=0){ + if(m_beenhere2(x_lr,y_lr,z_lr)==0){ + m_ConMat2(m_Conrow2,Concol2,0)+=1; + m_beenhere2(x_lr,y_lr,z_lr)=1; + } + } + + } + + } + + + + void Counter::reset_beenhere2(const bool& forwardflag,const bool& backwardflag){ + if(forwardflag){ + for(unsigned int i=0;i<m_path.size();i++){ + ColumnVector xyz_seeds=m_path[i]; + ColumnVector xyz_lr=vox_to_vox(xyz_seeds,m_seedsdim,m_lrdim,m_I); + int x_lr=int(round(float(xyz_lr(1)))),y_lr=int(round(float(xyz_lr(2)))),z_lr=int(round(float(xyz_lr(3)))); + m_beenhere2(x_lr,y_lr,z_lr)=0; + } + } + if(backwardflag){ + const vector<ColumnVector>& path=m_stline.get_path_ref(); + for(unsigned int i=0;i<path.size();i++){ + ColumnVector xyz_seeds=path[i]; + ColumnVector xyz_lr=vox_to_vox(xyz_seeds,m_seedsdim,m_lrdim,m_I); + int x_lr=int(round(float(xyz_lr(1)))),y_lr=int(round(float(xyz_lr(2)))),z_lr=int(round(float(xyz_lr(3)))); + m_beenhere2(x_lr,y_lr,z_lr)=0; + } + } + + } + + void Counter::save(){ + if(opts.simpleout.value()){ + save_pathdist(); + } + if(opts.s2tout.value()){ + save_seedcounts(); + } + if(opts.matrix1out.value()){ + save_matrix1(); + } + if(opts.matrix2out.value()){ + save_matrix2(); + } + if(opts.maskmatrixout.value()){ + save_maskmatrix(); + } + + } + + void Counter::save_pathdist(){ + save_volume(m_prob,logger.appendDir(opts.outfile.value())); + } + + void Counter::save_pathdist(string add){ //for simple mode + string thisout=opts.outfile.value(); + make_basename(thisout); + thisout+=add; + save_volume(m_prob,thisout); + } + + void Counter::save_seedcounts(){ + for(unsigned int m=0;m<m_targetmasknames.size();m++){ + string tmpname=m_targetmasknames[m]; + + int pos=tmpname.find("/",0); + int lastpos=pos; + + while(pos>=0){ + lastpos=pos; + pos=tmpname.find("/",pos); + // replace / with _ + tmpname[pos]='_'; + } + + //only take things after the last pos + tmpname=tmpname.substr(lastpos+1,tmpname.length()-lastpos-1); + + save_volume(m_seedcounts[m],logger.appendDir("seeds_to_"+tmpname)); + } + } + + void Counter::save_matrix1(){ + save_volume(m_ConMat,logger.appendDir("fdt_matrix1")); + save_volume(m_CoordMat,logger.appendDir("coords_for_fdt_matrix1")); + } + + void Counter::save_matrix2(){ + save_volume(m_ConMat2,logger.appendDir("fdt_matrix2")); + save_volume(m_CoordMat2,logger.appendDir("coords_for_fdt_matrix2")); + save_volume(m_CoordMat_tract2,logger.appendDir("tract_space_coords_for_fdt_matrix2")); + save_volume4D(m_lookup2,logger.appendDir("lookup_tractspace_fdt_matrix2")); + + } + + void Seedmanager::run(const float& x,const float& y,const float& z,bool onewayonly){ + //onewayonly for mesh things.. + int fibst=m_seeds(int(round(x)),int(round(y)),int(round(z)))-1;//fibre to start with is taken from seed volume.. + for(int p=0;p<opts.nparticles.value();p++){ + if(opts.verbose.value()>1) + logger.setLogFile("particle"+num2str(p)); + + m_stline.reset(); + bool forwardflag=false,backwardflag=false; + if(!onewayonly){ + if(m_stline.streamline(x,y,z,m_seeddims,fibst)){ + forwardflag=true; + m_counter.store_path(); + m_counter.count_streamline(); + } + m_stline.reverse(); + } + if(m_stline.streamline(x,y,z,m_seeddims,fibst)){ + backwardflag=true; + m_counter.count_streamline(); + } + + m_counter.clear_streamline(forwardflag,backwardflag); + } + m_counter.count_seed(); + + + } + + + +} + + + diff --git a/streamlines.h b/streamlines.h new file mode 100644 index 0000000..d2869a6 --- /dev/null +++ b/streamlines.h @@ -0,0 +1,201 @@ +#include <fstream> +#include "newimage/newimageall.h" +#include "utils/log.h" +#include "meshclass/meshclass.h" +#include "probtrackOptions.h" +#include "particle.h" +#include "tractvols.h" + +using namespace std; +using namespace NEWIMAGE; +using namespace Utilities; +using namespace TRACTVOLS; +using namespace mesh; +using namespace PARTICLE; + +namespace TRACT{ + void read_masks(vector<string>& masks, const string& filename); + + + class Streamliner{ + //Everything in DTI space is done INSIDE this class and lower level classes (particle and tractvols) + //This class communicates with higher level classes in Seed voxels. + // + probtrackOptions& opts; + Log& logger; + Particle m_part; + vector<ColumnVector> m_path; + volume<int> m_mask; + volume<int> m_skipmask; + volume<int> m_rubbish; + volume4D<float> m_loopcheck; + vector<volume<int>* > m_waymasks; + vector<bool> m_passed_flags; + vector<bool> m_own_waymasks; + Matrix m_Seeds_to_DTI; + TractVols vols; + float m_lcrat; + float m_x_s_init; + float m_y_s_init; + float m_z_s_init; + public: + //Constructors + Streamliner(); + ~Streamliner(){ + for(unsigned int i=0;i<m_waymasks.size();i++) + if(m_own_waymasks[i]) delete m_waymasks[i]; + } + void add_waymask(volume<int>& myway,const bool& ownership=false){ + //make sure that the waymask to add will not be deleted before + //this streamliner goes out of scope!! + m_waymasks.push_back(&myway); + m_own_waymasks.push_back(ownership); + m_passed_flags.push_back(false); + } + void pop_waymasks(){ + volume<int>* tmpptr=m_waymasks[m_waymasks.size()-1]; + m_waymasks.pop_back(); + m_passed_flags.pop_back(); + if(m_own_waymasks[m_own_waymasks.size()-1]){ + delete tmpptr; + } + m_own_waymasks.pop_back(); + + } + + inline const float get_x_seed() const {return m_x_s_init;} + inline const float get_y_seed() const {return m_y_s_init;} + inline const float get_z_seed() const {return m_z_s_init;} + inline const vector<ColumnVector>& get_path_ref() const{return m_path;} + inline vector<ColumnVector> get_path() const{return m_path;} + inline void reset(){ + m_part.reset(); + } + inline void reverse(){ + m_part.restart_reverse(); + } + bool streamline(const float& x_init,const float& y_init, const float& z_init,const ColumnVector& dim_seeds,const int& fibst); + + }; + + + class Counter{ + probtrackOptions& opts; + Log& logger; + volume<int> m_prob; + volume<int> m_beenhere; + Matrix m_I; + vector<ColumnVector> m_path; + + vector<volume<int> > m_seedcounts; + vector<volume<int> > m_targetmasks; + vector<string> m_targetmasknames; + vector<int> m_targflags; + //vector<vector<int> > m_particle_numbers; + + + volume<int> m_ConMat; + volume<int> m_CoordMat; + int m_Conrow; + + volume<int> m_ConMat2; + volume<int> m_CoordMat2; + volume<int> m_CoordMat_tract2; + volume<int> m_lrmask; + volume4D<int> m_lookup2; + volume<int> m_beenhere2; + int m_Conrow2; + ColumnVector m_lrdim; + + const volume<int>& m_seeds; + ColumnVector m_seedsdim; + const Streamliner& m_stline; + Streamliner& m_nonconst_stline; + + public: + Counter(const volume<int>& seeds,Streamliner& stline):opts(probtrackOptions::getInstance()), + logger(LogSingleton::getInstance()), + m_seeds(seeds),m_stline(stline), + m_nonconst_stline(stline){ + //are they initialised to zero? + m_beenhere.reinitialize(m_seeds.xsize(),m_seeds.ysize(),m_seeds.zsize()); + m_seedsdim.ReSize(3); + m_seedsdim << m_seeds.xdim() <<m_seeds.ydim() <<m_seeds.zdim(); + m_I=Identity(4); + + } + + void initialise(); + + void initialise_path_dist(){ + m_prob.reinitialize(m_seeds.xsize(),m_seeds.ysize(),m_seeds.zsize()); + } + void initialise_seedcounts(); + + void initialise_matrix1(); //Need to make sure that initialise_path_dist is run first + + void initialise_matrix2(); + + void initialise_maskmatrix(){} //not written yet + + inline void store_path(){ m_path=m_stline.get_path();} + + void count_streamline(); + void count_seed(); + void clear_streamline(const bool& forwardflag,const bool& backwardflag); + + + void update_pathdist(); + void reset_beenhere(const bool& forwardflag,const bool& backwardflag); + + void reset_prob(){m_prob=0;} + void update_seedcounts(); + void reset_targetflags(){ + for(unsigned int i=0;i<m_targflags.size();i++) m_targflags[i]=0; + } + + + void update_matrix1(); //update path_dist after each streamline, only run this after each voxel!! + + void update_matrix2_row(); //but run this one every streamline as with the others + void next_matrix2_row(){m_Conrow2++;}//and then run this after each voxel.. + void reset_beenhere2(const bool& forwardflag,const bool& backwardflag); + + void update_maskmatrix(){} //not written yet + + void save(); + void save_pathdist(); + void save_pathdist(string add); + void save_seedcounts(); + void save_matrix1(); + void save_matrix2(); + void save_maskmatrix(){}//not written yet + + + inline const Streamliner& get_streamline() const {return m_stline;} + inline Streamliner& get_nonconst_streamline() const {return m_nonconst_stline;} + inline const volume<int>& get_seeds() const {return m_seeds;} + + + }; + + class Seedmanager{ + probtrackOptions& opts; + Log& logger; + Counter& m_counter; + Streamliner& m_stline; + const volume<int>& m_seeds; + ColumnVector m_seeddims; + public: + Seedmanager(Counter& counter):opts(probtrackOptions::getInstance()), + logger(LogSingleton::getInstance()), + m_counter(counter), + m_stline(m_counter.get_nonconst_streamline()), + m_seeds(m_counter.get_seeds()){ + m_seeddims.ReSize(3); + m_seeddims<<m_seeds.xdim()<<m_seeds.ydim()<<m_seeds.zdim(); + } + void run(const float& x,const float& y,const float& z,bool onewayonly=false); + }; + +} -- GitLab