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

    Mark Woolrich, FMRIB Image Analysis Group

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

/*  CCOPYRIGHT  */

#include <sstream>
#include <fstream>
Stephen Smith's avatar
Stephen Smith committed
#include "ContrastMgr.h"
Mark Woolrich's avatar
Mark Woolrich committed
#include "ContrastMgrOptions.h"
#include "miscmaths/miscmaths.h"
#include "utils/log.h"
Stephen Smith's avatar
Stephen Smith committed
#include "gaussComparer.h"
#include "miscmaths/t2z.h"
#include "miscmaths/f2z.h"
Mark Woolrich's avatar
Mark Woolrich committed
#include "paradigm.h"
#include "utils/tracer_plus.h"
#include "fslio/fslio.h"
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
using namespace Utilities;
Mark Woolrich's avatar
Mark Woolrich committed
using namespace MISCMATHS;
Christian Beckmann's avatar
Christian Beckmann committed
using namespace std;
Mark Woolrich's avatar
Mark Woolrich committed

namespace FILM {
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
  ContrastMgr::ContrastMgr() :    
    tc(),
    fc(),
Stephen Smith's avatar
Stephen Smith committed
    c_counter(0),
Mark Woolrich's avatar
Mark Woolrich committed
    numParams(0),
Mark Woolrich's avatar
Mark Woolrich committed
    num_Ccontrasts_in_Fcontrast(0),
Mark Woolrich's avatar
Mark Woolrich committed
    contrast_valid(false),
    contrast_num(0),
    parad(),
Stephen Smith's avatar
Stephen Smith committed
    corrections(),
    b(),
Mark Woolrich's avatar
Mark Woolrich committed
    dof(),
Stephen Smith's avatar
Stephen Smith committed
    sigmaSquareds(),
    varcb(),
    cb(),
    neff(),
    numTS(0)
Mark Woolrich's avatar
Mark Woolrich committed
  {}

  void ContrastMgr::SetFContrast(const int p_num, const int p_c_counter)
  {
    fc.ReSize(parad.getTContrasts().Nrows(),numParams);
    int count = 0;

    for(int c = 1; c <= parad.getTContrasts().Nrows(); c++)
      {	
	if(parad.getFContrasts()(p_num,c) == 1)
	  {	    
	    count++;
	    fc.Row(count) = parad.getTContrasts().Row(c);	
	  }
      }

    fc = fc.Rows(1,count);
    contrast_num = p_num;
    contrast_valid = true;

Mark Woolrich's avatar
Mark Woolrich committed
    num_Ccontrasts_in_Fcontrast = fc.Nrows();

Mark Woolrich's avatar
Mark Woolrich committed
    c_counter = p_c_counter;
  }

  void ContrastMgr::run()
  {
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::run");
Mark Woolrich's avatar
Mark Woolrich committed

    Load();

    // Loop through tcontrasts:
    for(int c = 1; c <= parad.getTContrasts().Nrows(); c++)
      {
	if(ContrastMgrOptions::getInstance().verbose)
	  {
	    cerr << "T contrast no. " << c << endl;
	    cerr << parad.getTContrasts().Row(c) << endl;
	  }

	SetTContrast(c, c+ContrastMgrOptions::getInstance().copenumber-1);
	ComputeNeff();    
	ComputeCope();
	ComputeVarCope();
	ComputeZStat();
	
	SaveTContrast(ContrastMgrOptions::getInstance().suffix);
      }

    // Loop through fcontrasts:
    for(int c = 1; c <= parad.getFContrasts().Nrows(); c++)
      {
	SetFContrast(c, c+ContrastMgrOptions::getInstance().copenumber-1);

	if(ContrastMgrOptions::getInstance().verbose)
	  {
	    cerr << "F contrast no." << c << endl;
	    cerr << parad.getFContrasts().Row(c) << endl;
	    cerr << fc << endl;
	  }

	ComputeFStat();
	
	if(contrast_valid)
	  SaveFContrast(ContrastMgrOptions::getInstance().suffix);

      }
  }
Stephen Smith's avatar
Stephen Smith committed

  void ContrastMgr::Load()
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::Load");
Mark Woolrich's avatar
Mark Woolrich committed
    // Need to read in b, sigmaSquareds, corrections and dof 
Mark Woolrich's avatar
Mark Woolrich committed
    Log& logger = LogSingleton::getInstance();
Mark Woolrich's avatar
Mark Woolrich committed
    // Load contrasts:     
    parad.load("", ContrastMgrOptions::getInstance().contrastfname, ContrastMgrOptions::getInstance().fcontrastfname, false, 0);
       
    numParams = parad.getTContrasts().Ncols(); 
Mark Woolrich's avatar
Mark Woolrich committed
    if(ContrastMgrOptions::getInstance().verbose)
      {
Mark Woolrich's avatar
Mark Woolrich committed
	cerr << "T Contrasts:" << endl << parad.getTContrasts();
	cerr << "F Contrasts:" << endl << parad.getFContrasts();
Mark Woolrich's avatar
Mark Woolrich committed
      }

    // sigmaSquareds:
    sigmaSquareds.read(logger.getDir() + "/sigmasquareds");
    sigmaSquareds.threshold(0.0);
Mark Woolrich's avatar
Mark Woolrich committed
    numTS = sigmaSquareds.getVolumeSize();    
 
Mark Woolrich's avatar
Mark Woolrich committed
    // b:
    Volume peVol;
    b.ReSize(numTS, numParams);
    for(int i = 1; i <= numParams; i++)
      { 
	// Add param number to "pe" to create filename:
	ostringstream osc;
	osc << i;
Stephen Smith's avatar
Stephen Smith committed
	  
	peVol.read(logger.getDir() + "/pe" + osc.str().c_str());
Stephen Smith's avatar
Stephen Smith committed

David Flitney's avatar
David Flitney committed
	peVol.setInfo(sigmaSquareds.getInfo());
Mark Woolrich's avatar
Mark Woolrich committed
	peVol.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
	peVol.threshold();
Stephen Smith's avatar
Stephen Smith committed
	  
Mark Woolrich's avatar
Mark Woolrich committed
	b.Column(i) = peVol; 
      }

Mark Woolrich's avatar
Mark Woolrich committed
    // dof: - maybe single value ASCII or avw file:
Mark Woolrich's avatar
Mark Woolrich committed
    ifstream in;
Mark Woolrich's avatar
Mark Woolrich committed
    in.open(string(logger.getDir() + "/dof").c_str(), ios::in);    
    if(!in)
      {
	// avw format	
	dof.read(logger.getDir() + "/dof");	

	// threshold avw
	dof.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
	dof.threshold();
      }
    else
      {
	// single value ascii format
	in.close();
	ColumnVector dofVec = MISCMATHS::read_ascii_matrix(logger.getDir() + "/dof");
	dof = sigmaSquareds;
	dof = dofVec(1);
      }      

    // corrections - maybe ASCII (old version) or avw file:    
    // corrections are the correlation matrix of the pes.
Mark Woolrich's avatar
Mark Woolrich committed
    in.open(string(logger.getDir() + "/corrections").c_str(), ios::in);    
    if(!in)
      {
	// avw format
	is_avw_corrections = true;
	corrections.read(logger.getDir() + "/corrections");
David Flitney's avatar
David Flitney committed
	if(corrections.getInfo().x == sigmaSquareds.getInfo().x)
Mark Woolrich's avatar
Mark Woolrich committed
	  {
	    // unthresholded avw
	    corrections.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
	    corrections.thresholdSeries();
	  }
Mark Woolrich's avatar
Mark Woolrich committed
      }
    else
      {
	// old ascii format
	in.close();      
	is_avw_corrections = false;
	corrections.ReSize(numTS,numParams*numParams);
	parad.read_vest_waveform(logger.getDir() + "/corrections", corrections);
	corrections = corrections.t();
      }
Mark Woolrich's avatar
Mark Woolrich committed
  }

  void ContrastMgr::SaveFContrast(const string& suffix)
  {
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::SaveFContrast");
Mark Woolrich's avatar
Mark Woolrich committed
    Log& logger = LogSingleton::getInstance();
Mark Woolrich's avatar
Mark Woolrich committed

    // prepare contrast number:
    ostringstream osc;
    osc << suffix << c_counter;
    VolumeInfo tmpinfo;

Mark Woolrich's avatar
Mark Woolrich committed
    // Write out fstat:
    tmpinfo = sigmaSquareds.getInfo();
    tmpinfo.intent_code = NIFTI_INTENT_FTEST;
    tmpinfo.intent_p1 = 0.0;
    fstat.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    fstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    fstat.unthreshold();
    fstat.writeAsFloat(logger.getDir() + "/fstat" + osc.str().c_str());
Mark Woolrich's avatar
Mark Woolrich committed

    // Write out zstat:
    tmpinfo = sigmaSquareds.getInfo();
    tmpinfo.intent_code = NIFTI_INTENT_ZSCORE;
    tmpinfo.intent_p1 = 0.0;
    zstat.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    zstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    zstat.unthreshold();
    zstat.writeAsFloat(logger.getDir() + "/zfstat" + osc.str().c_str());
Mark Woolrich's avatar
Mark Woolrich committed
  }

  void ContrastMgr::SaveTContrast(const string& suffix)
  {
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::SaveTContrast");
Mark Woolrich's avatar
Mark Woolrich committed
    Log& logger = LogSingleton::getInstance();
Mark Woolrich's avatar
Mark Woolrich committed
    
    // prepare contrast number:
    ostringstream osc;
    osc << suffix << c_counter;
    VolumeInfo tmpinfo;

Mark Woolrich's avatar
Mark Woolrich committed
    // Write out neffs:
    tmpinfo = sigmaSquareds.getInfo();
Mark Woolrich's avatar
Mark Woolrich committed
    tmpinfo.intent_code = NIFTI_INTENT_NONE;
    neff.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    neff.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    neff.unthreshold();
    neff.writeAsFloat(logger.getDir() + "/neff" + osc.str().c_str());
Mark Woolrich's avatar
Mark Woolrich committed

    // Write out cope:
    tmpinfo = sigmaSquareds.getInfo();
Mark Woolrich's avatar
Mark Woolrich committed
    tmpinfo.intent_code = NIFTI_INTENT_ESTIMATE;
    tmpinfo.intent_p1 = 0.0;
    cb.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    cb.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    cb.unthreshold();
    cb.writeAsFloat(logger.getDir() + "/cope" + osc.str().c_str());
Mark Woolrich's avatar
Mark Woolrich committed

    // Write out varcope:
    tmpinfo = sigmaSquareds.getInfo();
Mark Woolrich's avatar
Mark Woolrich committed
    tmpinfo.intent_code = NIFTI_INTENT_ESTIMATE;
    tmpinfo.intent_p1 = 0.0;
    varcb.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    varcb.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    varcb.unthreshold();
    varcb.writeAsFloat(logger.getDir() + "/varcope" + osc.str().c_str());
Mark Woolrich's avatar
Mark Woolrich committed

    // Write out tstat:
    tmpinfo = sigmaSquareds.getInfo();
    tmpinfo.intent_code = NIFTI_INTENT_TTEST;
    tmpinfo.intent_p1 = 0.0;
    tstat.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    tstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    tstat.unthreshold();
    tstat.writeAsFloat(logger.getDir() + "/tstat" + osc.str().c_str());
Mark Woolrich's avatar
Mark Woolrich committed

    // Write out zstat:
    tmpinfo = sigmaSquareds.getInfo();
    tmpinfo.intent_code = NIFTI_INTENT_ZSCORE;
    tmpinfo.intent_p1 = 0.0;
    zstat.setInfo(tmpinfo);
Mark Woolrich's avatar
Mark Woolrich committed
    zstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    zstat.unthreshold();
    zstat.writeAsFloat(logger.getDir() + "/zstat" + osc.str().c_str());
Stephen Smith's avatar
Stephen Smith committed

  void ContrastMgr::GetCorrection(Matrix& corr, const int ind)
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::GetCorrection");
Mark Woolrich's avatar
Mark Woolrich committed

    // puts ColumnVector of length p*p from correction
    // into Matrix corr which is p*p:
    corr.ReSize(numParams, numParams);

    for (int i = 1; i <= numParams; i++)
      {
	for (int j = 1; j <= numParams; j++)
	  {
	    corr(i,j) = corrections((i-1)*numParams + j, ind); 
	  }
      }
  }
Stephen Smith's avatar
Stephen Smith committed

  void ContrastMgr::ComputeZStat()
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::ComputeZStat");
Mark Woolrich's avatar
Mark Woolrich committed
    Log& logger = LogSingleton::getInstance();
Mark Woolrich's avatar
Mark Woolrich committed

    // calulate Zstat:
    tstat.ReSize(numTS);
    for(int i = 1; i <= numTS; i++)
      {
	if(varcb(i) > 0 && neff(i) > 0)
	  {
	    tstat(i) = cb(i)/sqrt(varcb(i));
	  }
	else
	  tstat(i) = 0.0;
      }
Stephen Smith's avatar
Stephen Smith committed
      
Mark Woolrich's avatar
Mark Woolrich committed
    // Calculate tstat:
    zstat.ReSize(numTS);
Mark Woolrich's avatar
Mark Woolrich committed
    T2z::ComputeZStats(varcb, cb, dof, zstat);
Mark Woolrich's avatar
Mark Woolrich committed

    // Compare with theory:
    GaussComparer gaussComp(zstat);
    gaussComp.setup();

    ColumnVector ratios(5);
    ColumnVector probs(5);
    int co = 1;
    for(float p = 0.05; p >= 0.0005; p=p/sqrt(10))
      {
	float temp = gaussComp.computeRatio(p, logger.str());
	logger.str() << "p = " << p << ": ratio = " << temp << endl;
	ratios(co) = temp;
	probs(co) = p;
	co++;
      }
Stephen Smith's avatar
Stephen Smith committed
      
Mark Woolrich's avatar
Mark Woolrich committed
    write_ascii_matrix(logger.appendDir("ratios"), ratios);
    write_ascii_matrix(logger.appendDir("probs"), probs);
Stephen Smith's avatar
Stephen Smith committed
      
Stephen Smith's avatar
Stephen Smith committed

  void ContrastMgr::ComputeCope()
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::ComputeCope");
Mark Woolrich's avatar
Mark Woolrich committed
    cb.ReSize(numTS);

    for(int i = 1; i <= numTS; i++)
      {	
	cb(i) = (tc.t()*b.Row(i).t()).AsScalar();
      }
  }

  void ContrastMgr::ComputeNeff()
  {
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::ComputeNeff");
Stephen Smith's avatar
Stephen Smith committed
   
Mark Woolrich's avatar
Mark Woolrich committed
    //Log& logger = LogSingleton::getInstance();
Mark Woolrich's avatar
Mark Woolrich committed
    Matrix corr;
Stephen Smith's avatar
Stephen Smith committed
      
Mark Woolrich's avatar
Mark Woolrich committed
    neff.ReSize(numTS);
    neff = 0;
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
    int numNegs = 0;
    int maxNeff = 0;
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
    for(int i = 1; i <= numTS; i++)
      {	
	GetCorrection(corr, i);
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
	neff(i) = 1/(tc.t()*corr*tc).AsScalar();
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
	if(maxNeff < neff(i))
	  maxNeff = (int)neff(i);
Stephen Smith's avatar
Stephen Smith committed
	  
Mark Woolrich's avatar
Mark Woolrich committed
	if(neff(i) < 0.0 && i > 1)
	  {
	    neff(i) = neff(i-1);
	    numNegs++;
	  }  
      }
  }

  void ContrastMgr::ComputeFStat()
  {
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::ComputeFStat");
Mark Woolrich's avatar
Mark Woolrich committed
    //Log& logger = LogSingleton::getInstance();
Mark Woolrich's avatar
Mark Woolrich committed
    Matrix corr;

    fstat.ReSize(numTS);
    fstat = 1;

    for(int i = 1; i <= numTS; i++)
Mark Woolrich's avatar
Mark Woolrich committed
	GetCorrection(corr, i);

	try
Mark Woolrich's avatar
Mark Woolrich committed
	  {	    	    
	    fstat(i) = (b.Row(i)*fc.t()*(fc*corr*fc.t()*sigmaSquareds(i)).i()*fc*b.Row(i).t()).AsScalar()/num_Ccontrasts_in_Fcontrast;
Mark Woolrich's avatar
Mark Woolrich committed
	  }
	catch(SingularException& ex)
	  {	    
	    cerr << ex.what() << endl;
	    cerr << "F contrast no. " << contrast_num << " produces singular variance matrix." << endl; 
	    cerr << "No results will be produced for this contrast"  << endl;
	    contrast_valid = false;
	    break;	    
	  }
      }
   
    // Calculate zstat:
    zstat.ReSize(numTS);
Mark Woolrich's avatar
Mark Woolrich committed
    F2z::ComputeFStats(fstat, num_Ccontrasts_in_Fcontrast, dof, zstat);
Stephen Smith's avatar
Stephen Smith committed

  void ContrastMgr::ComputeVarCope()
Mark Woolrich's avatar
Mark Woolrich committed
    Tracer_Plus ts("ContrastMgr::ComputeVarCope");
Mark Woolrich's avatar
Mark Woolrich committed
    varcb.ReSize(numTS);

    for(int i = 1; i <= numTS; i++)
      {
	if(neff(i) > 0)
	  varcb(i) = sigmaSquareds(i)/neff(i);
	else
	  varcb(i) = 0;
      }
  }
Stephen Smith's avatar
Stephen Smith committed

}