/* film_gls.cc Mark Woolrich and Matthew Webster, FMRIB Image Analysis Group Copyright (C) 1999-2008 University of Oxford */ /* CCOPYRIGHT */ #include <iostream> #define WANT_STREAM #define WANT_MATH #include "newimage/newimageall.h" #include "utils/log.h" #include "AutoCorrEstimator.h" #include "paradigm.h" #include "FilmGlsOptions.h" #include "glimGls.h" #include <vector> #include <string> using namespace NEWMAT; using namespace FILM; using namespace Utilities; using namespace MISCMATHS; using namespace NEWIMAGE; int main(int argc, char *argv[]) { try{ // Setup logging: Log& logger = LogSingleton::getInstance(); // parse command line FilmGlsOptions& globalopts = FilmGlsOptions::getInstance(); globalopts.parse_command_line(argc, argv, logger); // load data volume4D<float> input_data; volumeinfo vinfo; read_volume4D(input_data,globalopts.inputfname,vinfo); int sizeTS = input_data.tsize(); Matrix datam; volume<float> mask(input_data[0]); volume4D<float> reference(mask.xsize(),mask.ysize(),mask.zsize(),1); reference[0]=input_data[int(sizeTS/2)-1]; copybasicproperties(input_data,reference); FslSetCalMinMax(&vinfo,reference.min(),reference.max()); save_volume_dtype(reference[0],logger.getDir() + "/" + globalopts.epifname,DT_SIGNED_SHORT,vinfo); mask=0; for(int t=0;t<input_data.tsize();t++) mask+=input_data[t]; mask/=input_data.tsize(); input_data-=mask; mask.binarise(globalopts.thresh,mask.max()+1,exclusive); input_data*=mask; datam=input_data.matrix(mask); int numTS = datam.Ncols(); ColumnVector epivol = reference.matrix(mask).t(); //epivol = datam.Row(int(sizeTS/2)).AsColumn(); // Load paradigm: Paradigm parad; 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); } if(globalopts.verbose) { write_vest(logger.appendDir("Gc"), parad.getDesignMatrix()); } OUT(parad.getDesignMatrix().Nrows()); OUT(parad.getDesignMatrix().Ncols()); OUT(sizeTS); OUT(numTS); // Setup GLM: int numParams = parad.getDesignMatrix().Ncols(); GlimGls glimGls(numTS, sizeTS, numParams); // Residuals container: Matrix residuals(sizeTS, numTS); Matrix residualsm = datam; // Setup autocorrelation estimator: AutoCorrEstimator acEst(residuals); acEst.mask=mask; if(!globalopts.noest) { cout << "Calculating residuals..." << endl; for(int i = 1; i <= numTS; i++) { glimGls.setData(datam.Column(i), parad.getDesignMatrix(), i); residuals.Column(i)=glimGls.getResiduals(); } cout << "Completed" << endl; cout << "Estimating residual autocorrelation..." << endl; 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); } else if(globalopts.tukey) { if(globalopts.tukeysize == 0) globalopts.tukeysize = (int)(2*sqrt(sizeTS))/2; acEst.calcRaw(); // SUSAN smooth raw estimates: if(globalopts.smoothACEst) { acEst.spatiallySmooth(logger.getDir() + "/" + globalopts.epifname, epivol, globalopts.ms, globalopts.epifname, globalopts.epith, globalopts.tukeysize); } acEst.tukey(globalopts.tukeysize); } else if(globalopts.multitaper) { acEst.calcRaw(); acEst.multitaper(int(globalopts.multitapersize)); } else if(globalopts.pava) { acEst.calcRaw(); // Smooth raw estimates: if(globalopts.smoothACEst) { acEst.spatiallySmooth(logger.getDir() + "/" + globalopts.epifname, epivol, globalopts.ms, globalopts.epifname, globalopts.epith); } acEst.pava(); } } cout << "Completed" << endl; cout << "Prewhitening and Computing PEs..." << endl; cout << "Percentage done:" << endl; int co = 1; Matrix mean_prewhitened_dm(parad.getDesignMatrix().Nrows(),parad.getDesignMatrix().Ncols()); mean_prewhitened_dm=0; for(int i = 1; i <= numTS; i++) { ColumnVector xw(sizeTS); ColumnVector xprew(sizeTS); if(!globalopts.noest) { acEst.setDesignMatrix(parad.getDesignMatrix()); // Use autocorr estimate to prewhiten data: xprew = datam.Column(i); Matrix designmattw; acEst.preWhiten(xprew, xw, i, designmattw); if ( (100.0*i)/numTS > co ) { cout << co << ","; cout.flush(); co++; } datam.Column(i)=xw; glimGls.setData(datam.Column(i), designmattw, i); residuals.Column(i)=glimGls.getResiduals(); if(globalopts.output_pwdata || globalopts.verbose) { mean_prewhitened_dm=mean_prewhitened_dm+designmattw; } } else { if ( (100.0*i)/numTS > co ) { cout << co << ","; cout.flush(); co++; } glimGls.setData(datam.Column(i), parad.getDesignMatrix(), i); residuals.Column(i)=glimGls.getResiduals(); if(globalopts.output_pwdata || globalopts.verbose) { mean_prewhitened_dm=mean_prewhitened_dm+parad.getDesignMatrix(); } } } if(globalopts.output_pwdata || globalopts.verbose) { mean_prewhitened_dm=mean_prewhitened_dm/numTS; } cerr << "Completed" << endl; cerr << "Saving results... " << endl; input_data.setmatrix(residuals,mask); FslSetCalMinMax(&vinfo,input_data.min(),input_data.max()); save_volume4D(input_data,logger.getDir() + "/res4d",vinfo); if(globalopts.output_pwdata || globalopts.verbose) { // 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); // Write out whitened design matrix write_vest(logger.appendDir("mean_prewhitened_dm.mat"), mean_prewhitened_dm); } // Write out threshac: Matrix& threshacm = acEst.getEstimates(); int cutoff = sizeTS/2; if(globalopts.tukey) cutoff = globalopts.tukeysize; //cutoff = MISCMATHS::Max(1,cutoff); threshacm = threshacm.Rows(1,MISCMATHS::Max(1,cutoff)); input_data.setmatrix(threshacm,mask); input_data.settdim(reference.tdim()); input_data.set_intent(NIFTI_INTENT_ESTIMATE,0,0,0); FslSetCalMinMax(&vinfo,input_data.min(),input_data.max()); save_volume4D(input_data,logger.getDir() + "/threshac1",vinfo); threshacm.CleanUp(); // save gls results: glimGls.Save(vinfo,mask,reference.tdim()); glimGls.CleanUp(); cerr << "Completed" << endl; } catch(Exception p_excp) { cerr << p_excp.what() << endl; } catch(...) { cerr << "Uncaught exception!" << endl; } return 0; }