Skip to content
Snippets Groups Projects
volumeseries.cc 5.82 KiB
/*  volumeseries.cc

    Mark Woolrich - FMRIB Image Analysis Group

    Copyright (C) 2002 University of Oxford  */

/*  CCOPYRIGHT  */

#include <iostream>
#include <cstdlib>
#include "avwio/avwio.h"

#include "newmatap.h"
#include "newmatio.h"
#include "volumeseries.h"
#include "miscmaths.h"
#include "utils/time_tracer.h"

using namespace NEWMAT;
using namespace Utilities;

namespace MISCMATHS {

  void VolumeSeries::replaceMeans()
  {
    Time_Tracer ts("VolumeSeries::replaceMeans");
    for(int i = 1; i <= getNumSeries(); i++)
      {
	Column(i) = Column(i) + means(i);
      }
  }

  void VolumeSeries::unthresholdSeries()
    {
       Time_Tracer ts("VolumeSeries::unthresholdSeries");

       int numUnThresholdedSeries = getUnthresholdNumSeries();
       int numThresholdedSeries = getNumSeries();
       int numVolumes = getNumVolumes();
      
       // Increase this to required size and set to 0
       Release();        
       Matrix X=*this; 
       ReSize(numVolumes, numUnThresholdedSeries);
       Matrix::operator=(0);
       
       // Loop through restoring non thresholded series: 
       for(int i = 1; i <= numThresholdedSeries; i++)
	 {
	   Column(int(preThresholdPositions(i)))=X.Column(i);
	 }
    }

  void VolumeSeries::thresholdSeries()
  {
    Time_Tracer ts("VolumeSeries::thresholdSeries");

       int numSeries = preThresholdPositions.Nrows();
       int numVolumes = getNumVolumes();

       Matrix X(numVolumes, numSeries); 
      
       for(int i = 1; i <= numSeries; i++)
	 {
	   X.Column(i)=Column(int(preThresholdPositions(i)));
	 }

       *this = X;
    }
  
   void VolumeSeries::thresholdSeries(float thresh, bool removeMean)
     {
       Time_Tracer ts("VolumeSeries::thresholdSeries");

       int numSeries = getNumSeries();
       int j = 0;

       if(removeMean)
	 {
	   means.ReSize(numSeries);
	   means = 0;
	 }

       preThresholdPositions.ReSize(numSeries);
       
       float m = 0,s = 0;
       for(int i = 1; i <= numSeries; i++)
	 {
	   m = MISCMATHS::mean(ColumnVector(getSeries(i))).AsScalar();
	   s = MISCMATHS::var(ColumnVector(getSeries(i))).AsScalar();
	   /*
	   if(m > thresh && s == 0.0)
	     {
	       cerr << "m = " << m << endl;
	       cerr << "s = " << s << endl;
	       cerr << "i = " << i << endl;
	       cerr << "j = " << j+1 << endl;
	     }
	   */
	   if(m > thresh && s > 0.0)
	     {
	       j++;	
	       preThresholdPositions(j) = i;
	     
	       if(removeMean)
		 {
		   Column(j) = getSeries(i) - m;
		   means(i) = m;
		 }
	       else
		 Column(j) = getSeries(i);
	     }
	 }

       // Discard rest:
       *this = Columns(1,j);

       preThresholdPositions = preThresholdPositions.Rows(1,j);
     }

  void VolumeSeries::removeSeriesMeans()
    {
      int numSeries = getNumSeries();
    
      for(int i = 1; i <= numSeries; i++)
	{
	  float m = MISCMATHS::mean(ColumnVector(getSeries(i))).AsScalar();
	  Column(i) = getSeries(i) - m;
	}
    }

  void VolumeSeries::read(const string& fname)
    {
      Time_Tracer ts(string("VolumeSeries::read-" + fname).c_str());

      AVW* IP = AvwOpen(fname.c_str(), "r");
      Matrix& output = *this;

      short x,y,z,v,type;
      float vx,vy,vz,tr;

      AvwGetDim(IP,&x,&y,&z,&v);
      AvwGetVoxDim(IP,&vx,&vy,&vz,&tr);
      AvwGetOriginator(IP,volinfo.originator);

      volinfo.x = x; volinfo.y = y; volinfo.z = z; volinfo.v = v;
      volinfo.vx = vx; volinfo.vy = vy; volinfo.vz = vz; volinfo.tr = tr;

      size_t imagesize=x*y*z*v;
      AvwGetDataType(IP,&type);
  
      output.ReSize(v,x*y*z);
  
      switch(type)
	{
	case DT_SIGNED_SHORT:
	  {
	    short* sbuffer=new short[imagesize];
	
	    AvwReadVolumes(IP, sbuffer,v);
	
	    size_t volsize = volinfo.x*volinfo.y*volinfo.z;
	    size_t volstart = 1;

	    for(size_t i=1; i<=(size_t)v; i++)
	      {
		volstart = (i-1)*volsize;
		for(size_t j = 1; j<=(size_t)x*y*z; j++)
		  {
		    output(i,j)=sbuffer[volstart+j-1];
		  }
	      }
	  
	    delete[] sbuffer;
	  }
	  break;
	case DT_FLOAT:
	  {
	    float* fbuffer=new float[imagesize];
	    AvwReadVolumes(IP,fbuffer,v);

	    size_t volsize = volinfo.x*volinfo.y*volinfo.z;
	    size_t volstart = 1;
	    for(size_t i=1; i<=(size_t)v; i++)
	      {
		volstart = (i-1)*volsize;
		for(size_t j = 1; j<=(size_t)x*y*z; j++)
		  {
		    output(i,j)=fbuffer[volstart+j-1];
		  }
	      }
	    delete[] fbuffer;
	  }
	  break;
	case DT_UNSIGNED_CHAR:
	  {
	    unsigned char* cbuffer=new unsigned char[imagesize];
	    AvwReadVolumes(IP,cbuffer,v);

	    size_t volsize = volinfo.x*volinfo.y*volinfo.z;
	    size_t volstart = 1;
	    for(size_t i=1; i<=(size_t)v; i++)
	      {
		volstart = (i-1)*volsize;
		for(size_t j = 1; j<=(size_t)x*y*z; j++)
		  {
		    output(i,j)=cbuffer[volstart+j-1];
		  }
	      }
	    delete[] cbuffer;
	  }
	  break;
	default:
	  perror("AvwRead: DT not supported");
	}

      AvwClose(IP);

      return;
    }
  
  void VolumeSeries::unthresholdSeries(const VolumeInfo& pvolinfo,const ColumnVector& in)
  {
    volinfo = pvolinfo;
    preThresholdPositions = in;
    unthresholdSeries();
  }

  void VolumeSeries::writeAsFloat(const string& fname)
    {
       Time_Tracer ts(string("VolumeSeries::writeAsFloat" + fname).c_str());

       AVW* OP = AvwOpen(fname.c_str(), "wc");

       AvwSetDim(OP,volinfo.x, volinfo.y, volinfo.z, volinfo.v);
       AvwSetVoxDim(OP,volinfo.vx, volinfo.vy, volinfo.vz, volinfo.tr);
       AvwSetDataType(OP, DT_FLOAT);
       AvwSetOriginator(OP, volinfo.originator);

       int volStart = 1;
       int volSize = getNumSeries();
       int volNum = getNumVolumes();

       float *qv = new float[volSize*volNum];
     
       for(int i = 1; i<= volNum; i++)
	 {
	   volStart = (i-1)*volSize;
	    for(int j = 1; j <= volSize; j++)
	     {
	        qv[volStart+j-1] = (*this)(i,j);
	     }
	 }
            
       AvwWriteVolumes(OP, qv, volNum);

       delete [] qv;

       AvwClose(OP);
       
    }

}