Skip to content
Snippets Groups Projects
tractvolsx.h 6.96 KiB
/*  tractvolsx.h

    Tim Behrens, FMRIB Image Analysis Group

    Copyright (C) 2004 University of Oxford  */

/*  CCOPYRIGHT  */

#ifndef __TRACTVOLSX_H_
#define __TRACTVOLSX_H_

/////////////////////////////////////////////////////////
//         Class TractVolsx                             //
/////////////////////////////////////////////////////////

#include "newimage/newimageall.h"
#include <iostream>
#include "stdlib.h"
#include "probtrackxOptions.h"
using namespace std;
using namespace NEWIMAGE;
using namespace TRACT;

namespace TRACTVOLSX{
  class Tractvolsx
    {
    private:
      probtrackxOptions& opts;
      vector<volume4D<float>* > thsamples;
      vector<volume4D<float>* > phsamples;
      vector<volume4D<float>* > fsamples;
      bool init_sample;
      int fibst;
      bool usef;
      
    public:
      //constructors::
      Tractvolsx(const bool& usefin=false):opts(probtrackxOptions::getInstance()),init_sample(true),fibst(0),usef(usefin){}
      Tractvolsx():opts(probtrackxOptions::getInstance()){}
      ~Tractvolsx(){
	for(unsigned int m=0;m<thsamples.size();m++)
	  delete thsamples[m]; //ask flitney, do you just delete the ptr??
	for(unsigned int m=0;m<phsamples.size();m++)
	  delete phsamples[m];
	for(unsigned int m=0;m<fsamples.size();m++)
	    delete fsamples[m];
      }
      inline int nfibres()const{return (int)thsamples.size();}
      
      void reset(const int& fibst_in){
	init_sample=true;
	fibst=fibst_in;
      }
      //Initialise
      void initialise(const string& basename){
	

	if(fsl_imageexists(basename+"_thsamples")){
	  volume4D<float> *tmpthptr= new volume4D<float>;
	  volume4D<float> *tmpphptr= new volume4D<float>;
	  volume4D<float> *tmpfptr= new volume4D<float>;
	  cout<<"1"<<endl;
	  read_volume4D(*tmpthptr,basename+"_thsamples");
	  cout<<"2"<<endl;
	  thsamples.push_back(tmpthptr);
	  cout<<"3"<<endl;
	  read_volume4D(*tmpphptr,basename+"_phsamples");
	  cout<<"4"<<endl;
	  phsamples.push_back(tmpphptr);
	  cout<<"5"<<endl;
	  read_volume4D(*tmpfptr,basename+"_fsamples");
	  fsamples.push_back(tmpfptr);
	  cout<<"6"<<endl;
	}
	else{
	  int fib=1;
	  bool fib_existed=true;
	  while(fib_existed){
	    if(fsl_imageexists(basename+"_th"+num2str(fib)+"samples")){
	      volume4D<float> *tmpthptr= new volume4D<float>;
	      volume4D<float> *tmpphptr= new volume4D<float>;
	      volume4D<float> *tmpfptr= new volume4D<float>;
	      cout<<fib<<"_1"<<endl;
	      read_volume4D(*tmpthptr,basename+"_th"+num2str(fib)+"samples");
	      thsamples.push_back(tmpthptr);
	      cout<<fib<<"_2"<<endl;
	      read_volume4D(*tmpphptr,basename+"_ph"+num2str(fib)+"samples");
	      phsamples.push_back(tmpphptr);
	      cout<<fib<<"_3"<<endl;
	      read_volume4D(*tmpfptr,basename+"_f"+num2str(fib)+"samples");
	      fsamples.push_back(tmpfptr);
	      fib++;
	    }
	    else{
	      fib_existed=false;
	    }
	  }
	  
	}
	cout<<"7"<<endl;
      }
      
      
      ColumnVector sample(const float& x,const float& y,const float&z,const float& r_x,const float& r_y,const float& r_z,
			  float& prefer_x,float& prefer_y,float& prefer_z){

	////////Probabilistic interpolation
	int cx =(int) ceil(x),fx=(int) floor(x);
	int cy =(int) ceil(y),fy=(int) floor(y);
	int cz =(int) ceil(z),fz=(int) floor(z);
	
	//cerr<<x<<" "<<y<<" "<<z<<" "<<cx<<" "<<cy<<" "<<cz<<" "<<fx<<" "<<fy<<" "<<fz<<endl;
	float pcx,pcy,pcz;
	if(cx==fx)
	  pcx=1;
	else
	  pcx=(x-fx)/(cx-fx);
	
	if(cy==fy)
	  pcy=1;
	else
	  pcy=(y-fy)/(cy-fy);
	
	if(cz==fz)
	  pcz=1;
	else
	  pcz=(z-fz)/(cz-fz);
	
	///////new xyz values from probabilistic interpolation
	int newx,newy,newz; 
	float tmp=(float)rand()/float(RAND_MAX);
	if(tmp>pcx)
	  newx=fx;
	else
	  newx=cx;
	
	tmp=(float)rand()/float(RAND_MAX);
	if(tmp>pcy)
	  newy=fy;
	else
	  newy=cy;
	
	tmp=(float)rand()/float(RAND_MAX);
	if(tmp>pcz)
	  newz=fz;
	else
	  newz=cz;
 
	ColumnVector th_ph_f(3);	
	float samp=(float)rand()/float(RAND_MAX);
	samp=round(samp*((*thsamples[0]).tsize()-1));
	float theta=0,phi=0;
	float dotmax=0,dottmp=0;
	int fibind=0;
	if(thsamples.size()>1){//more than 1 fibre
	  if(init_sample){//go for the specified fibre on the first jump or generate at random
	    if(opts.randfib.value()==1){//this generates startfib at random (except for fibres where f<fibthresh)
	      vector<int> fibvec;
	      for(unsigned int fib=0;fib<thsamples.size();fib++){	    
		float ft=(*fsamples[fib])(int(newx),int(newy),int(newz),int(samp));
		if(ft>opts.fibthresh.value()){
		  fibvec.push_back(fib);
		}
	      }
	      
	      if(fibvec.size()==0){
		fibst=0;
	      }
	      else{
		float rtmp=(float)rand()/float(RAND_MAX) * float(fibvec.size()-1);
		fibst = fibvec[ (int)round(rtmp) ];	      
	      }
	      
	    }
	    else if(opts.randfib.value()==2){ //this generates startfib with probability proportional to f (except for fibres where f<fibthresh). 
	      //this chooses at random but in proportion to fsamples. 
	      float fsumtmp=0;
	      for(unsigned int fib=0;fib<thsamples.size();fib++){	    
		float ft=(*fsamples[fib])(int(newx),int(newy),int(newz),int(samp));
		if(ft>opts.fibthresh.value()){
		  fsumtmp+=ft;  //count total weight of f in this voxel. 
		}
	      }
	      
	      if(fsumtmp==0){
		fibst=0;
	      }
	      else{
		float ft,fsumtmp2=0;
		float rtmp=fsumtmp * (float)rand()/float(RAND_MAX);
		
		for(unsigned int fib=0;fib<thsamples.size();fib++){
		  ft=(*fsamples[fib])(int(newx),int(newy),int(newz),int(samp));
		  if(ft>opts.fibthresh.value())
		    fsumtmp2 += ft;
		  if(rtmp<=fsumtmp2){
		    fibst=(int)fib;
		    break;
		  }
		}		
	      }
	    }  

	    theta=(*thsamples[fibst])(int(newx),int(newy),int(newz),int(samp));
	    phi=(*phsamples[fibst])(int(newx),int(newy),int(newz),int(samp));
	    init_sample=false;
	  }
	  else{
	    if((fabs(prefer_x)+fabs(prefer_y)+fabs(prefer_z))==0){
	      prefer_x=r_x;prefer_y=r_y;prefer_z=r_z;
	    }
	    for(unsigned int fib=0;fib<thsamples.size();fib++){
	      if((*fsamples[fib])(int(newx),int(newy),int(newz),int(samp))>opts.fibthresh.value()){
		float phtmp=(*phsamples[fib])(int(newx),int(newy),int(newz),int(samp));
		float thtmp=(*thsamples[fib])(int(newx),int(newy),int(newz),int(samp));
		dottmp=fabs(sin(thtmp)*cos(phtmp)*prefer_x + sin(thtmp)*sin(phtmp)*prefer_y + cos(thtmp)*prefer_z);
		if(dottmp>dotmax){
		  dotmax=dottmp;
		  theta=thtmp;
		  phi=phtmp;
		  fibind=fib;
		}
		
	      }
	      
	    }
	    if(dotmax==0){
	      theta=(*thsamples[0])(int(newx),int(newy),int(newz),int(samp));
	      phi=(*phsamples[0])(int(newx),int(newy),int(newz),int(samp));
	    }
	  }
	}
	else{
	  theta=(*thsamples[0])(int(newx),int(newy),int(newz),int(samp));
	  phi=(*phsamples[0])(int(newx),int(newy),int(newz),int(samp));
	}

	
	float f;
	
	if(usef){
	  f = (*fsamples[fibind])(int(newx),int(newy),int(newz),int(samp));
	}
	else
	  f=1;
	
	th_ph_f(1)=theta;
	th_ph_f(2)=phi;
	th_ph_f(3)=f;
	return th_ph_f;
      }

      ColumnVector dimensions() const{
	ColumnVector dims(3);
	dims << (*thsamples[0]).xdim() <<(*thsamples[0]).ydim() << (*thsamples[0]).zdim();
	return dims;
      }
    };
}

#endif