-
Mark Woolrich authoredMark Woolrich authored
volumeseries.cc 7.15 KiB
/* volumeseries.cc
Mark Woolrich - FMRIB Image Analysis Group
Copyright (C) 2002 University of Oxford */
/* CCOPYRIGHT */
#include <iostream>
#include <cstdlib>
#include "fslio/fslio.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 > 1e-10)
{
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());
FSLIO* IP = FslOpen(fname.c_str(), "rb");
Matrix& output = *this;
short x,y,z,v,type;
float vx,vy,vz,tr;
float slope, intercept;
int doscaling;
FslGetDim(IP,&x,&y,&z,&v);
FslGetVoxDim(IP,&vx,&vy,&vz,&tr);
FslGetIntent(IP, &(volinfo.intent_code), &(volinfo.intent_p1), &(volinfo.intent_p2),
&(volinfo.intent_p3));
doscaling = FslGetIntensityScaling(IP,&slope,&intercept);
volinfo.x = x; volinfo.y = y; volinfo.z = z; volinfo.v = v;
volinfo.vx = vx; volinfo.vy = vy; volinfo.vz = vz; volinfo.tr = tr;
volinfo.miscinfo = FslInit();
FslCloneHeader(volinfo.miscinfo,IP);
size_t imagesize=x*y*z;
FslGetDataType(IP,&type);
output.ReSize(v,x*y*z);
for(size_t i=1; i<=(size_t)v; i++)
{
switch(type)
{
case DT_SIGNED_SHORT:
{
short* sbuffer=new short[imagesize];
FslReadVolumes(IP, sbuffer,1);
for(size_t j = 1; j<=imagesize; j++)
{
if (doscaling==0) { output(i,j)=sbuffer[j-1]; }
else { output(i,j)=(slope * sbuffer[j-1]) + intercept;}
}
delete[] sbuffer;
}
break;
case DT_FLOAT:
{
float* fbuffer=new float[imagesize];
FslReadVolumes(IP,fbuffer,1);
for(size_t j = 1; j<=imagesize; j++)
{
if (doscaling==0) { output(i,j)=fbuffer[j-1]; }
else { output(i,j)=(slope * fbuffer[j-1]) + intercept;}
}
delete[] fbuffer;
}
break;
case DT_UNSIGNED_CHAR:
{
unsigned char* cbuffer=new unsigned char[imagesize];
FslReadVolumes(IP,cbuffer,1);
for(size_t j = 1; j<=imagesize; j++)
{
if (doscaling==0) { output(i,j)=cbuffer[j-1]; }
else { output(i,j)=(slope * cbuffer[j-1]) + intercept;}
}
delete[] cbuffer;
}
break;
default:
perror("FslRead: DT not supported");
}
}
FslClose(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());
FSLIO* OP = FslOpen(fname.c_str(), "wb");
FslCloneHeader(OP,volinfo.miscinfo);
FslSetCalMinMax(OP,Minimum(),Maximum());
FslSetDim(OP,volinfo.x, volinfo.y, volinfo.z, volinfo.v);
FslSetVoxDim(OP,volinfo.vx, volinfo.vy, volinfo.vz, volinfo.tr);
FslSetDataType(OP, DT_FLOAT);
FslSetIntent(OP, volinfo.intent_code, volinfo.intent_p1, volinfo.intent_p2,
volinfo.intent_p3);
int volSize = getNumSeries();
int volNum = getNumVolumes();
FslWriteHeader(OP);
float *qv = new float[volSize];
for(int i = 1; i<= volNum; i++)
{
for(int j = 1; j <= volSize; j++)
qv[j-1] = (*this)(i,j);
FslWriteVolumes(OP, qv, 1);
}
delete [] qv;
FslClose(OP);
}
void VolumeSeries::writeThresholdedSeriesAsFloat(const VolumeInfo& pvolinfo,const ColumnVector& in,const string& fname)
{
volinfo = pvolinfo;
preThresholdPositions = in;
Time_Tracer ts(string("VolumeSeries::writeThresholdedSeriesAsFloat" + fname).c_str());
FSLIO* OP = FslOpen(fname.c_str(), "wb");
FslCloneHeader(OP,volinfo.miscinfo);
FslSetCalMinMax(OP,Minimum(),Maximum());
FslSetDim(OP,volinfo.x, volinfo.y, volinfo.z, volinfo.v);
FslSetVoxDim(OP,volinfo.vx, volinfo.vy, volinfo.vz, volinfo.tr);
FslSetDataType(OP, DT_FLOAT);
FslSetIntent(OP, volinfo.intent_code, volinfo.intent_p1, volinfo.intent_p2, volinfo.intent_p3);
int volSize = getUnthresholdNumSeries();
int numThresholdedSeries = getNumSeries();
int volNum = getNumVolumes();
FslWriteHeader(OP);
float *qv = new float[volSize];
for(int i = 1; i<= volNum; i++)
{
for(int j = 1; j <= volSize; j++)
qv[j-1]=0;
for(int j = 1; j <= numThresholdedSeries; j++)
qv[int(preThresholdPositions(j))-1] = (*this)(i,j);
FslWriteVolumes(OP, qv, 1);
}
delete [] qv;
FslClose(OP);
}
}