diff --git a/AutoCorrEstimator.bak2 b/AutoCorrEstimator.bak2
new file mode 100755
index 0000000000000000000000000000000000000000..ea876a31398704b39370c2ad0f748aae1e583699
--- /dev/null
+++ b/AutoCorrEstimator.bak2
@@ -0,0 +1,536 @@
+#include <iostream>
+#include <strstream>
+// Written by Mark Woolrich 6/1/99
+
+#include "AutoCorrEstimator.h"
+#include "miscmaths.h"
+#include "Log.h"
+#include "Volume.h"
+#include "histogram.h"
+
+using namespace NEWMAT;
+using namespace UTILS;
+namespace TACO {
+
+  void AutoCorrEstimator::setDesignMatrix(const Matrix& dm) {
+    Tracer tr("AutoCorrEstimator::setDesignMatrix");
+
+    int sizeTS = xdata.getNumVolumes();
+    int numPars = dm.Ncols();
+    
+    dminFFTReal.ReSize(zeropad, numPars);
+    dminFFTImag.ReSize(zeropad, numPars);
+      
+    ColumnVector dmrow;
+    dmrow.ReSize(zeropad);
+
+    ColumnVector dm_fft_real, dm_fft_imag;
+    ColumnVector dummy(zeropad);
+    ColumnVector realifft(zeropad);
+
+    // FFT design matrix
+    for(int k = 1; k <= numPars; k++)
+      {
+	dummy = 0;
+	dmrow = 0;
+	mn(k) = MISCMATHS::mean(dm.Column(k));
+	dmrow.Rows(1,sizeTS) = dm.Column(k) - mn(k);
+
+	FFT(dmrow, dummy, dm_fft_real, dm_fft_imag);
+	
+	dminFFTImag.Column(k) = dm_fft_imag;
+	dminFFTReal.Column(k) = dm_fft_real;
+      } 
+  }
+
+  void AutoCorrEstimator::preWhiten(ColumnVector& in, ColumnVector& ret, int i, Matrix& dmret) {
+      Tracer tr("AutoCorrEstimator::preWhiten");
+
+      int sizeTS = xdata.getNumVolumes();
+      int numPars = dminFFTReal.getNumSeries();
+
+      ret.ReSize(sizeTS);
+      dmret.ReSize(sizeTS, numPars);
+
+      // FFT auto corr estimate
+      dummy = 0;
+      vrow = 0;
+      vrow.Rows(1,sizeTS/2) = acEst.getSeries(i).Rows(1,sizeTS/2);
+      vrow.Rows(zeropad - sizeTS/2 + 2, zeropad) = acEst.getSeries(i).Rows(2, sizeTS/2).Reverse();
+
+      FFT(vrow, dummy, ac_fft_real, ac_fft_im);      
+
+      // FFT x data
+      dummy = 0;
+      xrow = 0;
+      xrow.Rows(1,sizeTS) = in;
+     
+      FFT(xrow, dummy, x_fft_real, x_fft_im);
+
+      // inverse auto corr to give prewhitening filter:
+      // no DC component so set first value to 0;
+      ac_fft_real(1) = 0.0;	 
+      for(int j = 2; j <= zeropad; j++)
+	{
+	  ac_fft_real(j) = 1.0/ac_fft_real(j);
+	}
+
+      // filter design matrix
+      for(int k = 1; k <= numPars; k++)
+	{
+	  dm_fft_real = dminFFTReal.getSeries(k);
+	  dm_fft_imag = dminFFTImag.getSeries(k);
+	  FFTI(SP(ac_fft_real, dm_fft_real), SP(ac_fft_real, dm_fft_imag), realifft, dummy);
+
+	  // place result into ret:
+	  dmret.Column(k) = realifft.Rows(1,sizeTS);
+	  float std = pow(MISCMATHS::var(dmret.Column(k)),0.5);
+	  dmret.Column(k) = (dmret.Column(k)/std) + mn(k);
+	}
+
+      // Do filtering and inverse FFT:
+      FFTI(SP(ac_fft_real, x_fft_real), SP(ac_fft_real, x_fft_im), realifft, dummy);
+      
+      // place result into ret:
+      ret = realifft.Rows(1,sizeTS);     
+
+    }
+
+  void AutoCorrEstimator::preWhiten(VolumeSeries& in, VolumeSeries& ret)
+    {
+      Tracer tr("AutoCorrEstimator::preWhiten");
+
+      cerr << "Prewhitening... ";
+
+      int sizeTS = xdata.getNumVolumes();
+      int numTS = xdata.getNumSeries();
+
+      ret.ReSize(sizeTS, numTS);
+
+      // make sure p_vrow is cyclic (even function)
+      ColumnVector vrow, xrow;
+      vrow.ReSize(zeropad);
+      xrow.ReSize(zeropad);
+
+      ColumnVector x_fft_real, ac_fft_real;
+      ColumnVector x_fft_im, ac_fft_im;
+      ColumnVector dummy(zeropad);    
+      ColumnVector realifft(zeropad);
+      int co = 1;
+
+      for(int i = 1; i <= numTS; i++)
+	{
+	  // FFT auto corr estimate
+	  dummy = 0;
+	  vrow = 0;
+	  vrow.Rows(1,sizeTS/2) = acEst.getSeries(i).Rows(1,sizeTS/2);
+	  vrow.Rows(zeropad - sizeTS/2 + 2, zeropad) = acEst.getSeries(i).Rows(2, sizeTS/2).Reverse();
+	  FFT(vrow, dummy, ac_fft_real, ac_fft_im);      
+	  
+	  // FFT x data
+	  dummy = 0;
+	  xrow = 0;
+	  xrow.Rows(1,sizeTS/2) = in.getSeries(i).Rows(1,sizeTS/2);
+	  xrow.Rows(zeropad - sizeTS/2 + 2, zeropad) = in.getSeries(i).Rows(2, sizeTS/2).Reverse();
+	  FFT(xrow, dummy, x_fft_real, x_fft_im);
+
+	  // inverse auto corr to give prewhitening filter:
+	  // no DC component so set first value to 0;
+	  ac_fft_real(1) = 0.0;	 
+	  for(int j = 2; j <= zeropad; j++)
+	    {
+	      ac_fft_real(j) = 1.0/ac_fft_real(j);
+	    }
+
+	  // Do filtering and inverse FFT:
+	  FFTI(SP(ac_fft_real, x_fft_real), SP(ac_fft_real, x_fft_im), realifft, dummy);
+	
+	  // place result into ret:
+	  ret.Column(i) = realifft.Rows(1,sizeTS);
+
+	  if(co > 100)
+	    {
+	      co = 1;
+	      cerr << (float)i/(float)numTS << ",";
+	    }
+	  else
+	    co++;
+	}
+
+      cerr << " Completed" << endl;
+    }
+
+  void AutoCorrEstimator::fitAutoRegressiveModel()
+    {
+      Tracer trace("AutoCorrEstimator::fitAutoRegressiveModel");
+      
+      cerr << "Fitting autoregressive model..." << endl;
+      
+      const int maxorder = 10;
+      const int minorder = 1;
+
+      int sizeTS = xdata.getNumVolumes();
+      int numTS = xdata.getNumSeries();
+      
+      // setup temp variables
+      ColumnVector x(sizeTS);
+      ColumnVector order(numTS);
+      ColumnVector betas(maxorder);
+      acEst.ReSize(sizeTS, numTS);
+      acEst = 0;
+      int co = 1;
+       
+      for(int i = 1; i <= numTS; i++)
+	{
+	  x = xdata.getSeries(i).AsColumn();
+	  order(i) = SIGPROC::Pacf(x, minorder, maxorder, betas);
+	  if(order(i) != -1)
+	    {
+	      // Calculate auto corr:
+	      ColumnVector Krow(sizeTS);
+	      Krow = 0;
+	      Krow(sizeTS) = 1;
+	      Krow.Rows(sizeTS-order(i), sizeTS-1) = -betas.Reverse();
+	      
+	      Matrix Kinv(sizeTS, sizeTS);
+	      Kinv = 0;
+	      for(int j = 1; j <= sizeTS; j++)
+		{
+		  Kinv.SubMatrix(j,j,1,j) = Krow.Rows(sizeTS-j+1,sizeTS).t();
+		}
+	      
+	      // Kinv now becomes V:
+	      Kinv = (Kinv.t()*Kinv).i();
+	      acEst.SubMatrix(1,sizeTS/2+1,i,i) = (Kinv.SubMatrix(sizeTS/2, sizeTS/2, sizeTS/2, sizeTS)/Kinv.MaximumAbsoluteValue()).AsColumn();
+	       
+	      if(co > 200)
+		{
+		   co = 1;
+		   cerr << (float)i/(float)numTS << ",";
+		 }
+	      else
+		co++;
+	    }
+	}
+      
+      Log::getInstance().out("order", order);
+      cerr << " Completed" << endl; 
+    }
+  
+  int AutoCorrEstimator::establishUsanThresh(const Volume& epivol)
+    {
+      int usanthresh = 100;      
+      int num = epivol.getVolumeSize();
+
+      Histogram hist(epivol, num/200);
+      hist.generate();
+      float mode = hist.mode();
+      cerr << "mode = " << mode << endl;
+ 
+      float sum = 0.0;
+      int count = 0;
+
+      // Work out standard deviation from mode for values greater than mode:
+      for(int i = 1; i <= num; i++) {
+	if(epivol(i) > mode) {
+	  sum = sum + (epivol(i) - mode)*(epivol(i) - mode);
+	  count++;
+	}
+      }
+
+      int sig = (int)pow(sum/num, 0.5);
+      cerr << "sig = " << sig << endl;
+
+      usanthresh = sig/3;
+
+      return usanthresh;
+    } 
+
+  void AutoCorrEstimator::spatiallySmooth(const string& usanfname, const Volume& epivol, int masksize, const string& epifname, const string& susanpath) {
+    Tracer trace("AutoCorrEstimator::spatiallySmooth");
+    
+    Log& logger = Log::getInstance();
+
+    // Establish epi thresh to use:
+    int usanthresh = establishUsanThresh(epivol);
+     
+    // Setup external call to susan program:
+    char callsusanstr[1000];
+    ostrstream osc3(callsusanstr,1000);
+    string preSmoothVol = "preSmoothVol";
+    string postSmoothVol = "postSmoothVol";
+
+    osc3 << susanpath << " "
+	 << logger.getDir() << "/" << preSmoothVol << " 1 " 
+	 << logger.getDir() << "/" << postSmoothVol << " " 
+	 << masksize << " 3D 0 1 " << usanfname << " " << usanthresh << " " 
+	 << logger.getDir() << "/" << "usanSize" << '\0';
+    
+    // Loop through first third of volumes
+    // assume the rest are zero
+    int factor = 10000;
+
+    // Setup volume for reading and writing volumes:
+    Volume vol(acEst.getNumSeries());
+    vol.setDims(xdata.getDims());
+    vol.setPreThresholdPositions(xdata.getPreThresholdPositions());
+   
+    acEst.setDims(xdata.getDims());
+    acEst.setPreThresholdPositions(xdata.getPreThresholdPositions());
+    int i = 2;
+
+    acEst.unthresholdSeries();
+    
+    cerr << "Spatially smoothing auto corr estimates" << endl;
+
+    cerr << callsusanstr << endl;
+
+    for(; i < 20; i++)
+      {
+	// output unsmoothed estimates:
+	vol = acEst.getVolume(i).AsColumn()*factor;
+	vol.writeAsInt(logger.getDir() + "/" + preSmoothVol);
+
+	// call susan:
+	system(callsusanstr);
+
+	// read in smoothed volume:
+	vol.read(logger.getDir() + "/" + postSmoothVol);
+
+	acEst.getVolume(i) = vol.AsRow()/factor;
+	cerr << ".";
+      }
+    cerr << endl;
+
+    // Clear unwanted written files
+    char rmfilesstr[1000];
+    ostrstream osc(rmfilesstr,1000);
+    osc << "rm -rf " 
+	<< logger.getDir() + "/" + postSmoothVol + "* "
+	<< logger.getDir() + "/" + preSmoothVol + "* "
+	<< logger.getDir() + "/" + epifname + "* "
+	<< logger.getDir() + "/usanSize*" << '\0';
+    
+    cerr << rmfilesstr << endl;
+
+    system(rmfilesstr);
+
+    cerr << "Completed" << endl;
+
+    acEst.thresholdSeries();
+  }
+
+  void AutoCorrEstimator::calcRaw() { 
+    
+    cerr << "Calculating raw AutoCorrs...";      
+
+    Matrix fts;
+    AutoCorr(xdata.t(), acEst, fts, zeropad);
+    acEst = acEst.t();
+
+    cerr << " Completed" << endl;  
+  }
+  
+  void AutoCorrEstimator::filter(const ColumnVector& filterFFT) {
+
+    Tracer tr("AutoCorrEstimator::filter");
+
+    cerr << "Combining temporal filtering effects with AutoCorr estimates... ";
+
+    // This function adjusts the autocorrelations as if the
+    // xdata has been filtered by the passed in filterFFT
+    // DOES NOT filter the xdata itself
+    ColumnVector vrow;
+
+    // make sure p_vrow is cyclic (even function)
+    vrow.ReSize(zeropad);
+
+    ColumnVector fft_real;
+    ColumnVector fft_im;
+    ColumnVector dummy(zeropad);    
+    ColumnVector realifft(zeropad);
+    int sizeTS = xdata.getNumVolumes();
+
+    for(int i = 1; i <= xdata.getNumSeries(); i++)
+      {
+	dummy = 0;
+	vrow = 0;
+	vrow.Rows(1,sizeTS/2) = acEst.getSeries(i).Rows(1,sizeTS/2);
+	vrow.Rows(zeropad - sizeTS/2 + 2, zeropad) = acEst.getSeries(i).Rows(2, sizeTS/2).Reverse();
+      
+	FFT(vrow, dummy, fft_real, fft_im);
+
+	FFTI(SP(fft_real, filterFFT), dummy, realifft, dummy);
+	
+	// place result into acEst:
+	acEst.Column(i) = realifft.Rows(1,sizeTS)/realifft(1);
+      }
+
+    cerr << " Completed" << endl;
+    
+  }
+  
+  void AutoCorrEstimator::pava() {
+    
+    Tracer tr("AutoCorrEstimator::pava");
+    
+    cerr << "Using New PAVA on AutoCorr estimates... ";
+
+    for(int i = 1; i <= xdata.getNumSeries(); i++) {
+	int sizeTS = xdata.getNumVolumes();
+	int stopat = (int)sizeTS/2;
+
+	// 5% point of distribution of autocorr about zero
+	const float th = (-1/sizeTS)+(2/sqrt(sizeTS));
+
+	ColumnVector values = acEst.Column(i);
+	ColumnVector zero(1);
+	zero = 0;
+	values = values.Rows(1,stopat) & zero;
+
+	ColumnVector gm(stopat + 1);
+	for(int j = 1; j <= stopat + 1; gm(j) = j++);
+	  
+	ColumnVector weights(stopat+1);
+	weights = 1;
+
+	bool anyviolators = true;
+
+	while(anyviolators) {
+	  anyviolators = false;
+	  
+	  for(int k = 2; k <= values.Nrows(); k++) {
+	    if(values(k) > values(k-1)) {
+	      anyviolators = true;
+	      values(k-1) = (values(k-1)*weights(k-1) + values(k)*weights(k))/(weights(k-1) + weights(k));
+	      values = values.Rows(1,k-1) & values.Rows(k+1,values.Nrows());
+	      weights(k-1) = weights(k) + weights(k-1);
+	      weights = weights.Rows(1,k-1) & weights.Rows(k+1,weights.Nrows());
+
+	      for(int j = 1; j <= stopat + 1; j++) {
+		if(gm(j) >= k)  
+		  gm(j) = gm(j)-1;
+	      }
+
+	      break;
+	    }
+	  }
+	}
+	
+	acEst.Column(i) = 0.0;
+	int j=1;
+
+	for(; j <= stopat; j++) {
+	  
+	  acEst(j,i) = values(gm(j));
+	  if(acEst(j,i) <= 0.0)
+	    {
+	      acEst(j,i) = 0.0;
+	      break;
+	    }
+	}
+	
+	if(acEst(2,i) < th/2)
+	  {
+	    acEst.SubMatrix(3,stopat,i,i) = 0;
+	  }
+	else if(j > 2)
+	  {
+	    int endst = j;
+	    int stst = j-(int)(1+(j/8.0));
+
+	    const int expwidth = MISCMATHS::Max((endst - stst)/2,1);
+	    const int exppow = 2;
+	
+	    for(j = stst; j <= endst; j++)
+	      {
+		acEst(j,i) = acEst(j,i)*exp(-pow((j-stst)/expwidth,exppow));
+	      }	
+	  }
+    }
+    cerr << " Completed" << endl;
+  }
+  
+  void AutoCorrEstimator::applyConstraints() {
+
+    Tracer tr("AutoCorrEstimator::applyConstraints");
+
+    cerr << "Applying constraints to AutoCorr estimates... ";
+
+    for(int i = 1; i <= xdata.getNumSeries(); i++)
+      {
+	int sizeTS = xdata.getNumVolumes();
+	int j = 3;
+	int stopat = (int)sizeTS/4;
+
+	// found1 is last valid value above threshold
+	int found1 = stopat;
+
+	// 5% point of distribution of autocorr about zero
+	const float thresh = (-1/sizeTS)+(2/sqrt(sizeTS));
+
+	acEst(2,i) = (acEst(2,i)+ acEst(3,i))/2;
+	if(acEst(2,i) < 0)
+	  {
+	    acEst(2,i) = 0;
+	  }
+	else
+	  {
+	    float grad = 0.0;
+
+	    while(j <= stopat && j < found1 + 2)
+	      {    
+		grad = ((acEst(j,i) + acEst(j+1,i))/2 - acEst(j-1,i))/1.5;
+		if(grad < 0)
+		  acEst(j,i) = grad + acEst(j-1,i);
+		else
+		  acEst(j,i) = acEst(j-1,i);
+		
+		// look for threshold
+		if(acEst(j,i) < thresh/3.0 && found1 == stopat)
+		  {
+		    found1 = j;
+		  }
+	   
+		if(acEst(j,i) < 0)
+		  {
+		    acEst(j,i) = 0;
+		  }
+		
+		j++;
+	      }
+	  }
+
+	// set rest to zero:
+	for(; j <= sizeTS; j++)
+	  {
+	      acEst(j,i) = 0;
+	  }
+      }
+    cerr << "Completed" << endl;
+  }
+
+  void AutoCorrEstimator::getMeanEstimate(ColumnVector& ret)
+    {
+      Tracer tr("AutoCorrEstimator::getMeanEstimate");
+
+      ret.ReSize(acEst.getNumVolumes());
+      // Calc global Vrow:
+      for(int i = 1; i <= acEst.getNumVolumes(); i++)
+	{
+	  ret(i) = MISCMATHS::mean(acEst.getVolume(i).AsColumn());
+	}
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/deb b/deb
new file mode 100755
index 0000000000000000000000000000000000000000..48ffaa2e39a2f4819b679cc4126f71fb24050398
--- /dev/null
+++ b/deb
@@ -0,0 +1 @@
+   1.2246468e-16
diff --git a/film_gls.ccbak b/film_gls.ccbak
new file mode 100755
index 0000000000000000000000000000000000000000..7cb5e6d56b45b1b860887e7a846bbb9ed0dfa3b0
--- /dev/null
+++ b/film_gls.ccbak
@@ -0,0 +1,216 @@
+/*  film_gls.cc
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#include <iostream>
+#include <fstream>
+#include <strstream>
+#define WANT_STREAM
+#define WANT_MATH
+
+#include "newmatap.h"
+#include "newmatio.h"
+#include "VolumeSeries.h"
+#include "Volume.h"
+#include "glim.h"
+#include "sigproc.h"
+#include "miscmaths.h"
+#include "gaussComparer.h"
+#include "Log.h"
+#include "AutoCorrEstimator.h"
+#include "paradigm.h"
+#include "FilmGlsOptions.h"
+#include "glimGls.h"
+
+#include <string>
+
+#ifndef NO_NAMESPACE
+using namespace NEWMAT;
+using namespace SIGPROC;
+using namespace TACO;
+using namespace UTILS;
+#endif
+
+int main(int argc, char *argv[])
+{
+  try{
+    rand();
+    // parse command line to find out directory name for logging:
+    ofstream out2;
+    FilmGlsOptions& globalopts = FilmGlsOptions::getInstance();
+    globalopts.parse_command_line(argc, argv, out2);
+
+    // Setup logging:
+    Log& logger = Log::getInstance();
+    logger.setLogFile("glslogfile");
+    logger.establishDir(globalopts.datadir);
+
+    // parse command line again to output arguments to logfile
+    globalopts.parse_command_line(argc, argv, logger.str());
+
+    // load non-temporally filtered data
+    VolumeSeries x;
+    x.read(globalopts.inputfname);
+
+    // if needed output the 12th volume for use later
+    Volume epivol;
+    if(globalopts.smoothACEst)
+      {
+	epivol = x.getVolume(12).AsColumn();
+	epivol.setDims(x.getDims());
+	
+	epivol.writeAsInt(logger.getDir() + "/" + globalopts.epifname);
+      }
+
+    // This also removes the mean from each of the time series:
+    x.thresholdSeries(globalopts.thresh, true);
+
+    // if needed later also threshold the epi volume
+    if(globalopts.smoothACEst)
+      {
+	epivol.setPreThresholdPositions(x.getPreThresholdPositions());
+	epivol.threshold();
+      }
+
+    int sizeTS = x.getNumVolumes();
+    int numTS = x.getNumSeries();
+    
+    // Load paradigm: 
+    Paradigm parad;
+    parad.load(globalopts.paradigmfname, "", false, sizeTS);
+
+    // Sort out detrending:
+    if(globalopts.detrend)
+      {
+	SIGPROC::Detrend(x, false);
+      }
+
+    if(globalopts.verbose)
+      {
+	logger.out("Gc", parad.getDesignMatrix());
+      }
+
+    // Set up OLS GLM for non-whitened data 
+    Glim glim(x, parad.getDesignMatrix());
+	    
+    cerr << "Computing residuals for non-whitened data... ";
+    VolumeSeries& rnotw = glim.ComputeResids();
+    cerr << "Completed" << endl;
+    
+    // Estimate Autocorrelations:
+    AutoCorrEstimator acEst(rnotw);
+
+    if(globalopts.fitAutoRegressiveModel)
+      {
+	acEst.fitAutoRegressiveModel();
+	if(globalopts.verbose)
+	  {
+	    AutoCorrEstimator acEstForLogging(rnotw);
+	    acEstForLogging.calcRaw();
+	    logger.out("rawac", acEstForLogging.getEstimates());
+	    logger.out("autoregac", acEst.getEstimates());
+	  }
+      }
+    else
+      {
+	acEst.calcRaw();
+	    
+	if(globalopts.verbose)
+	  {
+	    //logger.out("rawac", acEst.getEstimates());
+	  }
+	    
+	// Smooth raw estimates:
+	if(globalopts.smoothACEst)
+	  { 
+	    acEst.spatiallySmooth(logger.getDir() + "/" + globalopts.epifname, epivol, globalopts.ms, globalopts.epifname, globalopts.susanpath, globalopts.epith);
+	    
+	  }
+	
+	// Apply constraints to estimate autocorr:
+	acEst.pava();
+	    
+      }
+    
+    ColumnVector I(sizeTS);
+    I = 0;
+    I(1) = 1;
+    
+    // Setup OLS GLM for temporally filtered data:
+    int numParams = parad.getDesignMatrix().Ncols();
+    GlimGls glimGls(numTS, sizeTS, numParams);
+    
+    ColumnVector xw(sizeTS);
+    ColumnVector xprew(sizeTS);
+
+    acEst.setDesignMatrix(parad.getDesignMatrix());
+    int co = 1;
+    
+    // Loop through voxels:
+    cerr << "Calculating params..." << endl;
+
+    for(int i = 1; i <= numTS; i++)
+      {	
+	// Use autocorr estimate to prewhiten data:
+	xprew = x.getSeries(i);
+	    
+	Matrix designmattw;
+
+	acEst.preWhiten(xprew, xw, i, designmattw);
+
+	if(co > 1000 || i == 5618 || i == 5582)
+	  {
+	    co = 1;
+	    cerr << (float)i/(float)numTS << ",";
+	  }
+	else
+	  co++;
+	    
+	glimGls.setData(xw, designmattw, i);   
+      }
+    cerr << "Completed" << endl;
+    
+
+    if(globalopts.verbose)
+      {	
+	// Save E
+	VolumeSeries& E = acEst.getE();
+	ColumnVector& countLargeE = acEst.getCountLargeE();
+	
+	logger.out("countLargeE", countLargeE);
+	VolumeSeries::Dims dims = x.getDims();
+	dims.v = acEst.getZeroPad();
+
+	E.setDims(dims);
+	E.setPreThresholdPositions(x.getPreThresholdPositions());
+	E.unthresholdSeries();	
+	E.writeAsFloat(logger.getDir() + "/E");
+  
+	VolumeSeries& threshac = acEst.getEstimates();
+	threshac.unthresholdSeries(x.getDims(),x.getPreThresholdPositions());
+	threshac.writeAsFloat(logger.getDir() + "/threshac");
+	  
+	rnotw.unthresholdSeries(x.getDims(),x.getPreThresholdPositions());
+	rnotw.writeAsFloat(logger.getDir() + "/rnotw");
+      }
+
+    // Write out necessary data:
+    cerr << "Saving results... ";
+    glimGls.Save(x.getDims(), x.getPreThresholdPositions());
+    cerr << "Completed" << endl;
+  }  
+  catch(Exception p_excp) 
+    {
+      cerr << p_excp.what() << endl;
+    }
+  catch(...) 
+    {
+      cerr << "Image error" << endl;
+    } 
+  return 0;
+}
+
diff --git a/glim.baccc b/glim.baccc
new file mode 100755
index 0000000000000000000000000000000000000000..e8e87d201cfbceb91faadce83169956f053177c5
--- /dev/null
+++ b/glim.baccc
@@ -0,0 +1,210 @@
+/*  glim.cc
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#include <strstream>
+
+#include "glim.h"
+#include "miscmaths.h"
+#include "Log.h"
+#include "Volume.h"
+
+#ifndef NO_NAMESPACE
+using namespace MISCMATHS;
+using namespace UTILS;
+using namespace TACO;
+namespace SIGPROC {
+#endif
+
+  Glim::Glim(const VolumeSeries& p_y, const Matrix& p_x):
+    y(p_y),
+    x(p_x),
+    numTS(p_y.Ncols()),
+    sizeTS(p_y.Nrows()),
+    numParams(p_x.Ncols()),
+    r(sizeTS, numTS, p_y.getDims(), p_y.getPreThresholdPositions()),
+    pinv_x(p_x.Ncols(), sizeTS),
+    V(sizeTS,sizeTS),
+    RV(sizeTS,sizeTS),
+    RMat(sizeTS,sizeTS),
+    batch_size(BATCHSIZE),
+    corrections(numTS, numParams*numParams),
+    b(numTS, numParams),
+    sigmaSquareds(numTS),
+    dofs(numTS),
+    traceRVs(numTS)
+    { 
+    }
+
+  void Glim::Save()
+    {
+      // Need to save b, sigmaSquareds, corrections and dof 
+      Log& logger = Log::getInstance();
+     
+      // b:
+      Volume peVol;
+      for(int i = 1; i <= numParams; i++)
+	{
+	  peVol = b.Row(i).AsColumn();
+	  peVol.setDims(y.getDims());
+	  peVol.setPreThresholdPositions(y.getPreThresholdPositions());
+	  peVol.unthreshold();	
+	  
+	  // Add param number to "pe" to create filename:
+	  char strc[4];
+	  ostrstream osc(strc,4);
+	  osc << i << '\0';
+	  
+	  peVol.writeAsFloat(logger.getDir() + "/pe" + strc);
+	}
+
+      // sigmaSquareds:
+      sigmaSquareds.setDims(y.getDims());
+      sigmaSquareds.setPreThresholdPositions(y.getPreThresholdPositions());
+      sigmaSquareds.unthreshold();	
+      sigmaSquareds.writeAsFloat(logger.getDir() + "/sigmasquareds");
+
+      // dof:
+      dofs.setDims(y.getDims());
+      dofs.setPreThresholdPositions(y.getPreThresholdPositions());
+      dofs.unthreshold();	
+      dofs.writeAsFloat(logger.getDir() + "/dofs");
+
+      // traceRVs:
+      traceRVs.setDims(y.getDims());
+      traceRVs.setPreThresholdPositions(y.getPreThresholdPositions());
+      traceRVs.unthreshold();	
+      traceRVs.writeAsFloat(logger.getDir() + "/traceRVs");
+
+      // corrections:
+      logger.out("corrections", corrections);
+    }
+
+  // Called on entire data set:
+  const VolumeSeries& Glim::ComputeResids()
+    {
+      Tracer ts("ComputeResids");
+
+      int batch_pos = 1;
+
+      // pinv(x) = inv(x'x)x'
+      pinv_x = (x.t()*x).i()*x.t();
+
+      // R = I - x*pinv(x)
+      Matrix I(sizeTS, sizeTS);
+      Identity(I);
+
+      RMat = I - x*pinv_x;
+      
+      while(batch_pos <= numTS)
+	{
+	  if(batch_pos+batch_size - 1 > numTS)
+	    r.Columns(batch_pos, numTS) = RMat*y.Columns(batch_pos, numTS);
+	  else
+	    r.Columns(batch_pos, batch_pos+batch_size-1) = RMat*y.Columns(batch_pos, batch_pos+batch_size-1);
+	
+	  batch_pos += batch_size;
+	}
+      
+      return r;
+    }
+
+  // Called on entire data set:
+  void Glim::ComputePes()
+    { 
+      Tracer ts("ComputePe");
+      
+      b = pinv_x*y;
+    }
+
+  void Glim::ConstructV(const ColumnVector& p_vrow)
+    {
+      Tracer ts("ConstructV");
+      V = 0;
+
+      for (int i = 1; i <= sizeTS; i++)
+	{
+	  V.SubMatrix(i,i,i,sizeTS) = p_vrow.Rows(1,sizeTS-i+1).t();
+	  V.SubMatrix(i,i,1,i) = p_vrow.Rows(1,i).Reverse().t();
+	}
+    }
+
+  void Glim::SetVrow(const ColumnVector& p_vrow, const int ind)
+    {
+      Tracer ts("SetVrow");
+      
+      ConstructV(p_vrow);
+
+      // var/e = inv(x'x)x'*V*x*inv(x'x)
+      Matrix corr = pinv_x*V*pinv_x.t();
+      SetCorrection(corr, ind);
+      RV = RMat*V;
+      traceRVs(ind) = Trace(RV);
+
+      dofs(ind) = traceRVs(ind)*traceRVs(ind)/Trace(RV*RV);
+    }
+
+  void Glim::SetGlobalVrow(const ColumnVector& p_vrow)
+    {
+      Tracer ts("Glim::SetGlobalVrow");
+
+      ConstructV(p_vrow);
+      RV = RMat*V;
+
+      traceRVs = Trace(RV);
+ 
+      dofs = Trace(RV)*Trace(RV)/Trace(RV*RV);
+    }
+
+
+  void Glim::UseGlobalVrow()
+    {
+      Tracer ts("Glim::UseGlobalVrow");
+
+      // var/e = inv(x'x)x'*V*x*inv(x'x)
+      Matrix corr = pinv_x*V*x*(x.t()*x).i();
+
+      for(int i = 1; i <= numTS; i++)
+	{
+	  SetCorrection(corr, i);
+	}
+    }
+
+  void Glim::ComputeSigmaSquared(const int ind)
+    {
+      Tracer ts("Glim::ComputeSigmaSquared");
+
+      sigmaSquareds(ind) = (r.Column(ind).t()*r.Column(ind)/traceRVs(ind)).AsScalar();
+    }
+
+  void Glim::SetCorrection(const Matrix& corr, const int ind)
+    {
+      Tracer ts("SetCorrection");
+
+      // puts Matrix corr which is p*p into Matrix correction
+      // as a p*p length row:
+      int p = corr.Nrows();
+      
+      for (int i = 1; i <= p; i++)
+	{
+	  for (int j = 1; j <= p; j++)
+	    {
+	      corrections(ind, (i-1)*p + j) = corr(i,j); 
+	    }
+	}
+    }
+
+#ifndef NO_NAMESPACE
+}
+#endif
+
+
+
+
+
+
+
diff --git a/glim.bach b/glim.bach
new file mode 100755
index 0000000000000000000000000000000000000000..41cfe361a7002a73964743d2380c7347204518fc
--- /dev/null
+++ b/glim.bach
@@ -0,0 +1,89 @@
+/*  glim.h
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#include <iostream>
+#include <fstream>
+#define WANT_STREAM
+#define WANT_MATH
+
+#include "newmatap.h"
+#include "newmatio.h"
+#include "VolumeSeries.h"
+#include "Volume.h"
+
+#ifndef NO_NAMESPACE
+using namespace NEWMAT;
+using namespace TACO;
+namespace SIGPROC{
+#endif
+
+#if !defined(__glim_h)
+#define __glim_h
+ 
+#define FALSE 0
+#define TRUE 1
+
+#define BATCHSIZE 50
+
+  class Glim
+    {
+    public:
+      Glim(const VolumeSeries& p_y, const Matrix& p_x); 
+
+      void Save();
+
+      const VolumeSeries& ComputeResids();      
+      void ComputePes();
+      void SetVrow(const ColumnVector& p_vrow, const int ind);
+      void SetGlobalVrow(const ColumnVector& p_vrow);
+      void ComputeSigmaSquared(const int ind);
+      void UseGlobalVrow();
+
+    private:
+      Glim();
+      Glim(const Glim&);
+      Glim& operator=(const Glim& p_glim);
+      
+      void SetCorrection(const Matrix& corr, const int ind);
+      void ConstructV(const ColumnVector& p_vrow);
+
+      // y = bx + r
+      const VolumeSeries& y;
+      const Matrix& x;
+
+      int numTS;
+      int sizeTS;
+      int numParams;
+
+      VolumeSeries r;
+      Matrix pinv_x;
+      Matrix V;
+      Matrix RV;
+      Matrix RMat;
+
+      int batch_size;
+
+      // Data to be saved:
+      Matrix corrections;
+      Matrix b;
+      Volume sigmaSquareds;
+      Volume dofs;
+      Volume traceRVs;
+
+    };
+
+
+#ifndef NO_NAMESPACE
+       }
+#endif
+
+#endif
+
+
+
+
diff --git a/logfile b/logfile
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ols.ccbak b/ols.ccbak
new file mode 100755
index 0000000000000000000000000000000000000000..0cfe9730faba4812d91eac5dd217c3dd6a3cf463
--- /dev/null
+++ b/ols.ccbak
@@ -0,0 +1,238 @@
+/*  ols.cc
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#include "ols.h"
+#include "miscmaths.h"
+#include "Log.h"
+
+#ifndef NO_NAMESPACE
+using namespace MISCMATHS;
+namespace FILM {
+#endif
+
+  Ols::Ols(const Matrix& p_y, const Matrix& p_x, const Matrix& p_contrasts):
+    y(p_y),
+    x(p_x),
+    contrasts(p_contrasts),
+    numTS(p_y.Ncols()),
+    sizeTS(p_y.Nrows()),
+    r(sizeTS,numTS),
+    pinv_x(p_x.Ncols(), sizeTS),
+    var_on_e(0.0),
+    cb(numTS),
+    b(p_x.Ncols()),
+    var(numTS),
+    dof(sizeTS - p_x.Ncols()),
+    V(sizeTS,sizeTS),
+    RV(sizeTS,sizeTS),
+    RMat(sizeTS,sizeTS),
+    batch_size(BATCHSIZE)
+    {
+      SetContrast(1);
+    }
+  
+//    void Ols::ConstructV(const ColumnVector& p_vrow)
+//      {
+//        Tracer ts("ConstructV");
+//        V = 0;
+
+//        for (int i = 1; i <= sizeTS; i++)
+//         {
+//  	 V.SubMatrix(i,i,i,sizeTS) = p_vrow.Rows(1,sizeTS-i+1).t();
+//  	 V.SubMatrix(i,i,1,i) = p_vrow.Rows(1,i).Reverse().t();
+//         }
+//      }
+
+//    float Ols::SetupWithV(const ColumnVector& p_vrow, bool p_justvarone)
+//      {
+//        Tracer ts("SetupWithV");
+      
+//        ConstructV(p_vrow);
+
+//        // var/e = c'inv(x'x)x'*V*x*inv(x'x)*c
+//        var_on_e = (c.t()*pinv_x*V*x*(x.t()*x).i()*c).AsScalar();
+
+//        if(!p_justvarone)
+//  	{
+//  	  // dof = 2*trace(RV)^2/trace(R*V*R*V);
+//  	  RV = RMat*V;
+//  	  dof = Trace(RV)*Trace(RV)/Trace(RV*RV);
+//  	}
+
+//        return dof;
+//      }
+
+//    float Ols::SetupWithV(const ColumnVector& p_vrow, const ColumnVector& p_kfft, ColumnVector& vrow, bool p_justvarone, const int zeropad)
+//      {
+//        Tracer ts("SetupWithV");
+
+//        // make sure p_vrow is cyclic (even function)
+//        //ColumnVector vrow(zeropad);
+//        vrow.ReSize(zeropad);
+
+//        vrow = 0;
+//        vrow.Rows(1,sizeTS/2) = p_vrow.Rows(1,sizeTS/2);
+//        vrow.Rows(zeropad - sizeTS/2 + 2, zeropad) = p_vrow.Rows(2, sizeTS/2).Reverse();
+
+//        // fft vrow
+//        ColumnVector fft_real;
+//        ColumnVector fft_im;
+//        ColumnVector dummy(zeropad);
+//        dummy = 0;
+      
+//        ColumnVector realifft(zeropad);
+
+//        FFT(vrow, dummy, fft_real, fft_im);
+
+//        FFTI(SP(fft_real, p_kfft), dummy, realifft, dummy);
+      
+//        vrow = realifft.Rows(1,sizeTS);
+
+//        // Normalise vrow:
+//        vrow = vrow/vrow(1);
+
+//        ConstructV(vrow);     
+
+//        // var/e = c'inv(x'x)x'*V*x*inv(x'x)*c
+//        var_on_e = (c.t()*pinv_x*V*x*(x.t()*x).i()*c).AsScalar();
+      
+//        if(!p_justvarone)
+//  	{
+//  	  // dof = 2*trace(RV)^2/trace(R*V*R*V);
+//  	  RV = RMat*V;
+//  	  dof = Trace(RV)*Trace(RV)/Trace(RV*RV);
+//  	}
+
+//        return dof;
+//      }
+
+  const Matrix& Ols::ComputeResids()
+    {
+      Tracer ts("ComputeResids");
+
+      int batch_pos = 1;
+
+      // pinv(x) = inv(x'x)x'
+      pinv_x = (x.t()*x).i()*x.t();
+
+      // R = I - x*pinv(x)
+      Matrix I(sizeTS, sizeTS);
+      Identity(I);
+
+      RMat = I - x*pinv_x;
+      
+      while(batch_pos <= numTS)
+	{
+	  if(batch_pos+batch_size - 1 > numTS)
+	    r.Columns(batch_pos, numTS) = RMat*y.Columns(batch_pos, numTS);
+	  else
+	    r.Columns(batch_pos, batch_pos+batch_size-1) = RMat*y.Columns(batch_pos, batch_pos+batch_size-1);
+	
+	  batch_pos += batch_size;
+	}
+      
+      return r;
+    }
+
+//    const ColumnVector& Ols::Computecb()
+//      { 
+//        Tracer ts("Computecb");
+      
+//        //     cerr << "Computing cbs";
+//        int batch_pos = 1;
+      
+//        while(batch_pos <= numTS)
+//  	{
+//  	  if(batch_pos+batch_size - 1 > numTS)
+//  	    cb.Rows(batch_pos, numTS) = (c.t()*pinv_x*y.Columns(batch_pos, numTS)).t();
+//  	  else
+//  	    cb.Rows(batch_pos, batch_pos+batch_size-1) = (c.t()*pinv_x*y.Columns(batch_pos, batch_pos+batch_size-1)).t();
+//  	  batch_pos += batch_size;
+//  	  //	  cerr << ".";
+//  	}
+//        //cerr << endl;
+//        return cb;
+//      }
+
+//    const float Ols::Computecb(const int ind)
+//      { 
+//        Tracer ts("Computecb");
+
+//        cb(ind) = ((c.t()*pinv_x*y.Column(ind)).t()).AsScalar();
+//        return cb(ind);
+//      }
+
+//    const ColumnVector& Ols::Computeb(const int ind)
+//      { 
+//        Tracer ts("Computeb");
+      
+//        b = pinv_x*y.Column(ind);
+//        return b;
+//      }
+
+//    const ColumnVector& Ols::ComputeVar()
+//      { 
+//        Tracer ts("ComputeVar");
+
+//        //      cerr << "Computing Vars";
+//        int batch_pos = 1;
+
+//        Matrix varmatfull(batch_size, batch_size);
+//        ColumnVector vartempfull(batch_size);
+
+//        while(batch_pos <= numTS)
+//  	{
+//  	  if(batch_pos+batch_size - 1 > numTS)
+//  	    {
+//  	      // var = e*var_on_e
+//  	      // e is the estimate of the variance of the timeseries, sigma^2
+//  	      Matrix varmat = (r.Columns(batch_pos, numTS).t()*r.Columns(batch_pos, numTS)/Trace(RV))*var_on_e;
+//  	      ColumnVector vartemp;
+//  	      //getdiag(vartemp, varmat);  // obsolete fn
+//  	      vartemp = diag(varmat);  // MJ NOTE: new fn
+//  	      var.Rows(batch_pos, numTS) = vartemp;
+//  	    }      
+//  	  else
+//  	    {
+//  	      varmatfull = (r.Columns(batch_pos, batch_pos+batch_size-1).t()*r.Columns(batch_pos, batch_pos+batch_size-1)/Trace(RV))*var_on_e;
+//  	      //getdiag(vartempfull, varmatfull);  // obsolete fn
+//  	      vartempfull = diag(varmatfull);  // MJ NOTE: new fn
+//  	      var.Rows(batch_pos, batch_pos+batch_size-1) = vartempfull;
+//  	    }
+//  	  batch_pos += batch_size;
+//  	  //  cerr << ".";
+//  	}
+      
+//        // cerr << endl;
+//        return var;
+//      }
+
+//    const float Ols::ComputeVar(const int ind)
+//      { 
+//        Tracer ts("ComputeVar");
+   
+//        // var = e*var_on_e
+//        // e is the estimate of the variance of the timeseries, sigma^2
+//        var(ind) = ((r.Column(ind).t()*r.Column(ind)/Trace(RV))*var_on_e).AsScalar();
+//        // var(ind) = (r.Column(ind).t()*r.Column(ind)*var_on_e).AsScalar();
+
+//        return var(ind);
+//      }
+
+#ifndef NO_NAMESPACE
+}
+#endif
+
+
+
+
+
+
+
+
+
diff --git a/ols.hbak b/ols.hbak
new file mode 100755
index 0000000000000000000000000000000000000000..6755f729ec3dc2e706323e143c6756696c1cf881
--- /dev/null
+++ b/ols.hbak
@@ -0,0 +1,96 @@
+/*  ols.h
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#if !defined(__ols_h)
+#define __ols_h
+
+#include <iostream>
+#include <fstream>
+#define WANT_STREAM
+#define WANT_MATH
+
+#include "newmatap.h"
+#include "newmatio.h"
+
+using namespace NEWMAT;
+namespace FILM {
+ 
+#define BATCHSIZE 50
+
+  class Ols
+    {
+    public:
+     
+      Ols(const Matrix& p_y, const Matrix& p_x, const Matrix& p_contrasts); 
+
+      const Matrix& ComputeResids();
+      const ColumnVector& ComputeVar();
+      const ColumnVector& Computecb();
+      const float ComputeVar(const int ind);
+      const float Computecb(const int ind);
+      const ColumnVector& Computeb(const int ind);
+
+      float SetupWithV(const ColumnVector& p_vrow, bool p_justvarone = false);
+      float SetupWithV(const ColumnVector& p_vrow, const ColumnVector& p_krowspec, ColumnVector& p_res, bool p_justvarone = false, const int zeropad = 512);
+
+      const Matrix& Getr() const {return r;}
+     
+      const ColumnVector& Getvar() const {return var;}
+      const ColumnVector& Getcb() const {return cb;}
+      float Getdof() const {return dof;}
+      float Getvarone() const {return var_on_e;}
+
+      void SetContrast(const int p_num) {c = contrasts.Row(p_num).t();}
+      void Setvarone(const float p_varone) {var_on_e = p_varone;}
+      
+    private:
+      Ols();
+      Ols(const Ols&);
+      Ols& operator=(const Ols& p_ols);
+       
+      void ConstructV(const ColumnVector& p_vrow);
+
+      // y = bx + r
+      const Matrix& y;
+      const Matrix& x;
+   
+      // Contrast
+      const Matrix& contrasts;
+      ColumnVector c;
+
+      int numTS;
+      int sizeTS;
+
+      Matrix r;
+
+      Matrix pinv_x;
+      float var_on_e;
+
+      ColumnVector cb;
+      
+      ColumnVector b;
+
+      ColumnVector var;
+      float dof;
+
+      // Covariance matrix is sigma^2*V:
+      Matrix V;
+      Matrix RV;
+
+      Matrix RMat;
+      
+      // batch stuff
+      int batch_size;
+    };
+
+}
+
+#endif
+
+
+
diff --git a/sigprocbak.ccbak b/sigprocbak.ccbak
new file mode 100755
index 0000000000000000000000000000000000000000..fed675c4ee315dd83dedb1bf874e2a17f25a0fa0
--- /dev/null
+++ b/sigprocbak.ccbak
@@ -0,0 +1,302 @@
+/*  sigproc.cc
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#include "ols.h"
+#include "sigproc.h"
+#include "miscmaths.h"
+#include "glm.h"
+
+#ifndef NO_NAMESPACE
+namespace SIGPROC {
+  using namespace MISCMATHS;
+#endif
+
+  void Out(string p_fname, const Matrix& p_mat)
+    {
+      ofstream out;
+      out.open(p_fname.c_str(), ios::out);
+      out << "/Matrix" << endl;
+      out << p_mat;
+      out.close();
+    }
+
+  void Out(string p_fname, const ColumnVector& p_mat)
+    {
+      ofstream out;
+      out.open(p_fname.c_str(), ios::out);
+      out << p_mat;
+      out.close();
+    }
+
+  void Out(string p_fname, const RowVector& p_mat)
+    {
+      ofstream out;
+      out.open(p_fname.c_str(), ios::out);
+      out << p_mat;
+      out.close();
+    }
+
+  void In(string p_fname, ColumnVector& p_mat)
+    {
+      int size = p_mat.Nrows();
+
+      ifstream in;
+      in.open(p_fname.c_str(), ios::in);
+      
+      if(!in)
+	{
+	  string err("Unable to open ");
+	  err =  err +  p_fname;
+	  throw Exception(err.c_str());
+	}
+
+      for(int i = 1; i <= size; i++)
+	{
+	  in >> p_mat(i);
+	}
+
+      in.close();
+    }
+
+  void In(string p_fname, Matrix& p_mat)
+    {
+      ifstream in;
+      in.open(p_fname.c_str(), ios::in);
+      
+      if(!in)
+	{
+	  cerr << "Unable to open " << p_fname << endl;
+	  throw;
+	}
+
+      int numWaves = 0;
+      int numPoints = 0;
+       
+      string str;
+
+      while(true)
+	{
+	  in >> str;
+	  if(str == "/Matrix")
+	    break;
+	  else if(str == "/NumWaves")
+	    {
+	      in >> numWaves;
+	    }
+	  else if(str == "/NumPoints" || str == "/NumContrasts")
+	    {
+	      in >> numPoints;
+	    }
+	}
+
+      if(numWaves != 0)
+	{
+	  p_mat.ReSize(numPoints, numWaves);
+	}
+      else
+	{
+	  numWaves = p_mat.Ncols();
+	  numPoints = p_mat.Nrows();
+	}
+      
+      for(int i = 1; i <= numPoints; i++)
+	{
+	  for(int j = 1; j <= numWaves; j++)    
+	    {
+	      in >> p_mat(i,j);
+	    }
+	  }
+
+      in.close();
+    }
+
+  int EstablishZeroPadding(int sizeTS) {
+    
+    Tracer tr("EstablishZeroPadding");
+    
+    return (int)pow(2,ceil(log(sizeTS)/log(2)));
+  }
+
+  void BandPass(Matrix& p_ts, int lowcut, int highcut)
+  {
+    Tracer tr("BandPass");
+
+      int sizeTS = p_ts.Nrows();
+      int numTS = p_ts.Ncols();
+      
+      int zeropad = EstablishZeroPadding(sizeTS);
+      ColumnVector x(zeropad);
+      x = 0;
+      ColumnVector fft_real;
+      ColumnVector fft_im;
+      ColumnVector dummy(zeropad);
+      ColumnVector dummy2;
+      dummy = 0;
+      ColumnVector realifft(zeropad);
+
+      // convert cutofs to zeropad cutoffs:
+      lowcut = (int)(lowcut*zeropad/(float)sizeTS);
+      highcut = (int)(highcut*zeropad/(float)sizeTS);
+
+      for(int i = 1; i <= numTS; i++)
+	{
+	  x.Rows(1,sizeTS) = p_ts.Column(i);
+
+	  FFT(x, dummy, fft_real, fft_im);
+
+	  // Perform cutoff here:
+	  // everything greater than highcut and lower than lowcut is removed
+	  if(lowcut > 0 && lowcut < sizeTS){
+	    fft_real.Rows(1, lowcut) = 0;
+	    fft_im.Rows(1, lowcut) = 0;
+	    fft_real.Rows(zeropad - lowcut, zeropad) = 0;
+	    fft_im.Rows(zeropad - lowcut, zeropad) = 0;
+	  }
+	  if(highcut < sizeTS && highcut > 0){
+	    fft_real.Rows(highcut, zeropad - highcut) = 0;
+	    fft_im.Rows(highcut, zeropad - highcut) = 0;
+	  }
+	  //////////////////////
+
+	  FFTI(fft_real, fft_im, realifft, dummy2);
+	  p_ts.Column(i) = realifft.Rows(1,sizeTS);
+	} 
+  }
+
+  void AutoCorr(const Matrix& p_ts, Matrix& p_ret, Matrix& fts, int p_zeropad)
+    {
+      Tracer tr("AutoCorr");
+
+      int sizeTS = p_ts.Nrows();
+      int numTS = p_ts.Ncols();
+
+      ColumnVector x(p_zeropad);
+      x = 0;
+      ColumnVector fft_real;
+      ColumnVector fft_im;
+      ColumnVector dummy(p_zeropad);
+      ColumnVector dummy2;
+      dummy = 0;
+      ColumnVector realifft(p_zeropad);
+      p_ret.ReSize(sizeTS,numTS);
+      fts.ReSize(p_zeropad,numTS);
+
+      for(int i = 1; i <= numTS; i++)
+	{
+	  x.Rows(1,sizeTS) = p_ts.Column(i);
+	  FFT(x, dummy, fft_real, fft_im);
+
+	  for(int j = 1; j <= p_zeropad; j++)
+	    {
+	      // (x+iy)(x-iy) = x^2 + y^2
+	      fft_real(j) = fft_real(j)*fft_real(j) + fft_im(j)*fft_im(j);
+	      fft_im(j) = 0;
+	      fts(j,i) = fft_real(j)*fft_real(j) + fft_im(j)*fft_im(j);      
+	    }
+
+	  // normalise fts:
+	  fts.Column(i) = fts.Column(i)/fts.Column(i).Sum();
+	  
+	  FFTI(fft_real, fft_im, realifft, dummy2);
+
+	  float varx = var(ColumnVector(x.Rows(1,sizeTS)));
+	  p_ret.Column(i) = realifft.Rows(1,sizeTS);
+ 
+	  for(int j = 1; j <= sizeTS-1; j++)
+	    {
+	       // Correction to make autocorr unbiased and normalised
+	       p_ret(j,i) = p_ret(j,i)/((sizeTS-j)*varx);
+	    }  
+	}
+
+    }
+
+  int Pacf(const ColumnVector& x, int minorder, int maxorder, ColumnVector& betas)
+    { 
+      Tracer ts("pacf");
+      int order = -1;
+      int sizeTS = x.Nrows();
+
+      // Set c
+      Matrix c(1,1);
+      c(1,1) = 1;
+      
+      Glm glm;
+
+      for(int i = minorder+1; i <= maxorder+1; i++)
+	{
+	  ColumnVector y = x.Rows(i+1,sizeTS);
+
+	  // Setup design matrix
+	  Matrix X(sizeTS-i, i);
+	  X = 0;
+	  
+	  for(int j = 1; j <= i; j++)
+	    {
+	      X.Column(j) = x.Rows(i+1-j,sizeTS-j).AsColumn();	    
+	    }
+	  
+	  glm.setData(y, X, c);
+	  
+	  glm.ComputeResids();
+	  betas = glm.Getb();
+	  
+	  if((abs(betas(i)) < (1/sizeTS) + (2/pow(sizeTS,0.5)) && order == -1) 
+	     || i == maxorder+1)
+          {      
+	    order = i-1;
+	    break;
+	  }
+	}
+      return order; 
+    }
+
+  void Detrend(Matrix& p_ts, bool p_justremovemean)
+    {
+      Tracer trace("SIGPROC::Detrend");
+
+      cerr << "Detrending...";
+      int sizeTS = p_ts.Nrows();
+     
+      // Set c
+      Matrix c(1,1);
+      c(1,1) = 1;
+
+      // p_ts = b*a + p_ret OLS regression
+      Matrix a(sizeTS, 3);
+
+      if(p_justremovemean) a.ReSize(sizeTS,1);
+
+      // Create a
+      for(int i = 1; i <= sizeTS; i++)
+	{
+	  a(i,1) = 1;
+	  if(!p_justremovemean)
+	    {
+	      a(i,2) = (float)i/sizeTS;
+	      a(i,3) = pow((float)i/sizeTS,2);
+	    }
+	}
+          
+      // Do OLS for all TS:
+      Ols ols(p_ts, a, c);
+
+      p_ts = ols.ComputeResids();
+      
+      cerr << " Completed" << endl;
+    }
+
+#ifndef NO_NAMESPACE
+}
+#endif
+
+
+
+
+
+
diff --git a/sigprocbak.hbak b/sigprocbak.hbak
new file mode 100755
index 0000000000000000000000000000000000000000..68a13540c7c9bb5e4e5386c931ed85c4740392f7
--- /dev/null
+++ b/sigprocbak.hbak
@@ -0,0 +1,38 @@
+/*  sigproc.h
+
+    Mark Woolrich, FMRIB Image Analysis Group
+
+    Copyright (C) 1999-2000 University of Oxford  */
+
+/*  CCOPYRIGHT  */
+
+#include <iostream>
+#include <fstream>
+#define WANT_STREAM
+#define WANT_MATH
+#include <string>
+
+#include "newmatap.h"
+#include "newmatio.h"
+  
+#if !defined(__sigproc_h)
+#define __sigproc_h
+  
+using namespace NEWMAT;
+namespace SIGPROC{
+
+  int EstablishZeroPadding(int num);
+  void BandPass(Matrix& p_ts, int lowcut, int highcut);
+  void AutoCorr(const Matrix& p_ts, Matrix& p_ret, Matrix& fts, int p_zeropad);
+  void Detrend(Matrix& p_ts, bool p_justremovemean = false);
+  int Pacf(const ColumnVector& x, int minorder, int maxorder, ColumnVector& betas);
+  void Out(string p_fname, const Matrix& out);
+  void Out(string p_fname, const ColumnVector& out);
+  void Out(string p_fname, const RowVector& out);
+  void In(string p_fname, ColumnVector& p_mat);
+  void In(string p_fname, Matrix& p_mat); 
+
+}
+#endif
+
+
diff --git a/tmp b/tmp
new file mode 100755
index 0000000000000000000000000000000000000000..5f2f042bdd3ae5e3785fae363fa1f89517ac623b
--- /dev/null
+++ b/tmp
@@ -0,0 +1,2 @@
+x = sin(pi)
+save -ASCII deb x
\ No newline at end of file