Skip to content
Snippets Groups Projects
film_gls.cc 7.57 KiB
Newer Older
Stephen Smith's avatar
Stephen Smith committed
/*  film_gls.cc

    Mark Woolrich, FMRIB Image Analysis Group

    Copyright (C) 1999-2000 University of Oxford  */

Stephen Smith's avatar
Stephen Smith committed
/*  CCOPYRIGHT  */
Stephen Smith's avatar
Stephen Smith committed

#include <iostream>
#include <fstream>
#include <sstream>
Stephen Smith's avatar
Stephen Smith committed
#define WANT_STREAM
#define WANT_MATH

#include "newimage/newimageall.h"
#include "newmatap.h"
#include "newmatio.h"
David Flitney's avatar
David Flitney committed
#include "miscmaths/volumeseries.h"
#include "miscmaths/volume.h"
#include "miscmaths/miscmaths.h"
#include "utils/log.h"
Stephen Smith's avatar
Stephen Smith committed
#include "AutoCorrEstimator.h"
#include "paradigm.h"
#include "FilmGlsOptions.h"
#include "glimGls.h"
#include <vector>
#include <string>
Stephen Smith's avatar
Stephen Smith committed

using namespace NEWMAT;
Mark Woolrich's avatar
Mark Woolrich committed
using namespace FILM;
using namespace Utilities;
Mark Woolrich's avatar
Mark Woolrich committed
using namespace MISCMATHS;
using namespace NEWIMAGE;
Stephen Smith's avatar
Stephen Smith committed

int main(int argc, char *argv[])
{
  try{
Stephen Smith's avatar
Stephen Smith committed
    // Setup logging:
Mark Woolrich's avatar
Mark Woolrich committed
    Log& logger = LogSingleton::getInstance();
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
    // parse command line
    FilmGlsOptions& globalopts = FilmGlsOptions::getInstance();
    globalopts.parse_command_line(argc, argv, logger);
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
    // load data
    volume4D<float> input_data;
    volumeinfo vinfo;
    read_volume4D(input_data,globalopts.inputfname,vinfo);
    int sizeTS = input_data.tsize();

    Matrix datam;
    VolumeSeries x,y;
    y.read(globalopts.inputfname);
    x.setInfo(y.getInfo());
    x=input_data.matrix();
    x.thresholdSeries(globalopts.thresh, true);

    //save_volume_dtype(input_data[int(sizeTS/2)-1],logger.getDir() + "/" + globalopts.epifname,DT_SIGNED_INT );
    save_volume(input_data[int(sizeTS/2)-1],logger.getDir() + "/" + globalopts.epifname);
    volume<float> mask(input_data[0]);
    volume4D<float> epivol2(mask.xsize(),mask.ysize(),mask.zsize(),1);
    epivol2[0]=input_data[int(sizeTS/2)-1];
    mask=0;
    for(int t=0;t<input_data.tsize();t++) mask+=input_data[t];
    mask/=input_data.tsize();
    for(int z=0;z<input_data.zsize();z++)
      for(int y=0;y<input_data.ysize();y++)          
	for(int x=0;x<input_data.xsize();x++)
	  if ( mask(x,y,z) > globalopts.thresh )
	    for(int t=0;t<input_data.tsize();t++) input_data(x,y,z,t)-= mask(x,y,z);
    mask.binarise(globalopts.thresh,mask.max()+1,exclusive);
    input_data*=mask;
    datam=input_data.matrix(mask);
    int numTS = mask.sum();
Stephen Smith's avatar
Stephen Smith committed
    
Mark Woolrich's avatar
Mark Woolrich committed
    // Load paradigm:
Stephen Smith's avatar
Stephen Smith committed
    Paradigm parad;
Mark Woolrich's avatar
Mark Woolrich committed
    if(!globalopts.ac_only)
      {	
	parad.load(globalopts.paradigmfname, "", "", false, sizeTS);
      }
    else
      {
	// set design matrix to be one ev with all ones:
	Matrix mat(sizeTS,1);
	mat = 1;
	parad.setDesignMatrix(mat);
      }
Stephen Smith's avatar
Stephen Smith committed

    if(globalopts.verbose)
      {
Mark Woolrich's avatar
Mark Woolrich committed
	write_vest(logger.appendDir("Gc"), parad.getDesignMatrix());
Stephen Smith's avatar
Stephen Smith committed
      }
    
Mark Woolrich's avatar
Mark Woolrich committed

    OUT(parad.getDesignMatrix().Nrows());
    OUT(parad.getDesignMatrix().Ncols());
    OUT(sizeTS);
    OUT(numTS);

Mark Woolrich's avatar
Mark Woolrich committed
    // Setup GLM:
Mark Woolrich's avatar
Mark Woolrich committed
    int numParams = parad.getDesignMatrix().Ncols();
    GlimGls glimGls(numTS, sizeTS, numParams);
Mark Woolrich's avatar
Mark Woolrich committed
    // Residuals container:
David Flitney's avatar
David Flitney committed
    VolumeSeries residuals(sizeTS, numTS, x.getInfo(), x.getPreThresholdPositions());
    Matrix residualsm = datam;
Mark Woolrich's avatar
Mark Woolrich committed

    // Setup autocorrelation estimator:
Mark Woolrich's avatar
Mark Woolrich committed
    AutoCorrEstimator acEst(residuals);
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
    if(!globalopts.noest)
Stephen Smith's avatar
Stephen Smith committed
      {
Mark Woolrich's avatar
Mark Woolrich committed
	cout << "Calculating residuals..." << endl; 
Mark Woolrich's avatar
Mark Woolrich committed
	for(int i = 1; i <= numTS; i++)
	  {						    
            glimGls.setData(datam.Column(i), parad.getDesignMatrix(), i);
	    residuals.setSeries(glimGls.getResiduals(),i);
Mark Woolrich's avatar
Mark Woolrich committed
	cout << "Completed" << endl; 
Mark Woolrich's avatar
Mark Woolrich committed
	cout << "Estimating residual autocorrelation..." << endl; 
Mark Woolrich's avatar
Mark Woolrich committed
	if(globalopts.fitAutoRegressiveModel)
	  {
	    volume4D<float> beta;
	    beta.setmatrix(acEst.fitAutoRegressiveModel(),mask);
	    copybasicproperties(input_data,beta);
	    FslSetCalMinMax(&vinfo,beta.min(),beta.max());
	    save_volume4D(beta,LogSingleton::getInstance().getDir() + "/betas",vinfo);
Mark Woolrich's avatar
Mark Woolrich committed
	  }
	else if(globalopts.tukey)
	  {    
Mark Woolrich's avatar
Mark Woolrich committed
	    if(globalopts.tukeysize == 0)
	      globalopts.tukeysize = (int)(2*sqrt(sizeTS))/2;

	    acEst.calcRaw();

Mark Woolrich's avatar
Mark Woolrich committed
	    // SUSAN smooth raw estimates:
	    if(globalopts.smoothACEst)
		ColumnVector epivol = epivol2.matrix(mask).t();
		acEst.spatiallySmooth(logger.getDir() + "/" + globalopts.epifname, epivol, globalopts.ms, globalopts.epifname, globalopts.epith, globalopts.tukeysize);	
Mark Woolrich's avatar
Mark Woolrich committed
	    acEst.tukey(globalopts.tukeysize);
	  }
	else if(globalopts.multitaper)
	  {
Mark Woolrich's avatar
Mark Woolrich committed
	    acEst.calcRaw();
	    acEst.multitaper(int(globalopts.multitapersize));
Mark Woolrich's avatar
Mark Woolrich committed
	  }
	else if(globalopts.pava)
	  {
Mark Woolrich's avatar
Mark Woolrich committed
	    acEst.calcRaw();

Mark Woolrich's avatar
Mark Woolrich committed
	    // Smooth raw estimates:
	    if(globalopts.smoothACEst)
	      { 
		ColumnVector epivol = epivol2.matrix(mask).t();
		acEst.spatiallySmooth(logger.getDir() + "/" + globalopts.epifname, epivol, globalopts.ms, globalopts.epifname, globalopts.epith);
Stephen Smith's avatar
Stephen Smith committed
	    
Mark Woolrich's avatar
Mark Woolrich committed
	    acEst.pava();
Stephen Smith's avatar
Stephen Smith committed
	  }
Stephen Smith's avatar
Stephen Smith committed
      }
Mark Woolrich's avatar
Mark Woolrich committed
    cout << "Completed" << endl; 
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
    cout << "Prewhitening and Computing PEs..." << endl;
    cout << "Percentage done:" << endl;
Mark Woolrich's avatar
Mark Woolrich committed
    int co = 1;
Mark Woolrich's avatar
Mark Woolrich committed
    Matrix mean_prewhitened_dm(parad.getDesignMatrix().Nrows(),parad.getDesignMatrix().Ncols());
    mean_prewhitened_dm=0;

Stephen Smith's avatar
Stephen Smith committed
    for(int i = 1; i <= numTS; i++)
Mark Woolrich's avatar
Mark Woolrich committed
      {						
	ColumnVector xw(sizeTS);
	ColumnVector xprew(sizeTS);
Mark Woolrich's avatar
Mark Woolrich committed
	   
	if(!globalopts.noest)
	  {
	    acEst.setDesignMatrix(parad.getDesignMatrix());
Mark Woolrich's avatar
Mark Woolrich committed
	    // Use autocorr estimate to prewhiten data:
	    xprew = datam.Column(i); 
Mark Woolrich's avatar
Mark Woolrich committed
	    Matrix designmattw;
	    acEst.preWhiten(xprew, xw, i, designmattw);
Stephen Smith's avatar
 
Stephen Smith committed
	    if ( (100.0*i)/numTS > co )
Stephen Smith's avatar
 
Stephen Smith committed
		cout << co << ",";
Mark Woolrich's avatar
Mark Woolrich committed
		cout.flush();
Stephen Smith's avatar
 
Stephen Smith committed
		co++;
            datam.Column(i)=xw;
	    glimGls.setData(datam.Column(i), designmattw, i);
	    residuals.setSeries(glimGls.getResiduals(),i);
Mark Woolrich's avatar
Mark Woolrich committed

	    if(globalopts.output_pwdata || globalopts.verbose)
	      {
		mean_prewhitened_dm=mean_prewhitened_dm+designmattw;		
	      }
Stephen Smith's avatar
Stephen Smith committed
	  }
Mark Woolrich's avatar
Mark Woolrich committed
	else
Stephen Smith's avatar
 
Stephen Smith committed
	    if ( (100.0*i)/numTS > co )
Stephen Smith's avatar
 
Stephen Smith committed
		cout << co << ",";
Mark Woolrich's avatar
Mark Woolrich committed
		cout.flush();
Stephen Smith's avatar
 
Stephen Smith committed
		co++;
	    glimGls.setData(datam.Column(i), parad.getDesignMatrix(), i);
	    residuals.setSeries(glimGls.getResiduals(),i);
Mark Woolrich's avatar
Mark Woolrich committed

	    if(globalopts.output_pwdata || globalopts.verbose)
	      {
		mean_prewhitened_dm=mean_prewhitened_dm+parad.getDesignMatrix();		
	      }
Stephen Smith's avatar
Stephen Smith committed
      }
Mark Woolrich's avatar
Mark Woolrich committed
    if(globalopts.output_pwdata || globalopts.verbose)
      {
	mean_prewhitened_dm=mean_prewhitened_dm/numTS;
      }

Stephen Smith's avatar
Stephen Smith committed
    cerr << "Completed" << endl;

Mark Woolrich's avatar
Mark Woolrich committed
    cerr << "Saving results... " << endl;

    // write residuals
    residuals.writeThresholdedSeriesAsFloat(x.getInfo(),x.getPreThresholdPositions(),logger.getDir() + "/res4d");
    residuals.CleanUp();

Mark Woolrich's avatar
Mark Woolrich committed
    if(globalopts.output_pwdata || globalopts.verbose)
Mark Woolrich's avatar
Mark Woolrich committed
	// Write out whitened data
        input_data.setmatrix(datam,mask);
	FslSetCalMinMax(&vinfo,input_data.min(),input_data.max());
        save_volume4D(input_data,logger.getDir() + "/prewhitened_data",vinfo);
Mark Woolrich's avatar
Mark Woolrich committed
	// Write out whitened design matrix
	write_vest(logger.appendDir("mean_prewhitened_dm.mat"), mean_prewhitened_dm);
		
Mark Woolrich's avatar
Mark Woolrich committed
    x.CleanUp();

    // Write out threshac:
    Matrix& threshacm = acEst.getEstimates();
Mark Woolrich's avatar
Mark Woolrich committed
    int cutoff = sizeTS/2;
    if(globalopts.tukey)
      cutoff = globalopts.tukeysize;
    threshacm = threshacm.Rows(1,cutoff); 
    volume4D<float> threshac;
    threshac.setmatrix(threshacm,mask);
    copybasicproperties(input_data,threshac);
    threshac.set_intent(NIFTI_INTENT_ESTIMATE,0,0,0);
    FslSetCalMinMax(&vinfo,threshac.min(),threshac.max());
    save_volume4D(threshac,logger.getDir() + "/threshac1",vinfo);
    threshacm.CleanUp();
Mark Woolrich's avatar
Mark Woolrich committed

    // save gls results:
David Flitney's avatar
David Flitney committed
    glimGls.Save(x.getInfo(), x.getPreThresholdPositions());
Mark Woolrich's avatar
Mark Woolrich committed
    glimGls.CleanUp();

Stephen Smith's avatar
Stephen Smith committed
    cerr << "Completed" << endl;
  }  
  catch(Exception p_excp) 
    {
      cerr << p_excp.what() << endl;
    }
  catch(...)
    {
      cerr << "Uncaught exception!" << endl;
    }
Stephen Smith's avatar
Stephen Smith committed
  return 0;
}