Skip to content
Snippets Groups Projects
ContrastMgr.cc 8.84 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 <strstream>
#include "ContrastMgr.h"
Mark Woolrich's avatar
Mark Woolrich committed
#include "ContrastMgrOptions.h"
Stephen Smith's avatar
Stephen Smith committed
#include "miscmaths.h"
#include "Log.h"
#include "gaussComparer.h"
#include "t2z.h"
Mark Woolrich's avatar
Mark Woolrich committed
#include "f2z.h"
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
using namespace Utilities;

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),
    contrast_valid(false),
    contrast_num(0),
    parad(),
Stephen Smith's avatar
Stephen Smith committed
    corrections(),
    b(),
    dof(0.0),
    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;

    c_counter = p_c_counter;
  }

  void ContrastMgr::run()
  {
    Tracer ts("ContrastMgr::run");

    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 ts("ContrastMgr::Load");
    // Need to read in b, sigmaSquareds, corrections and dof 
    Log& logger = Log::getInstance();
Stephen Smith's avatar
Stephen Smith committed
     
Mark Woolrich's avatar
Mark Woolrich committed
    // Load contrasts:     
    parad.load("", ContrastMgrOptions::getInstance().contrastfname, ContrastMgrOptions::getInstance().fcontrastfname, false, 0);
       
    numParams = parad.getTContrasts().Ncols(); 
    if(ContrastMgrOptions::getInstance().verbose)
      {
	logger.str() << "T Contrasts:" << endl << parad.getTContrasts();
	logger.str() << "F Contrasts:" << endl << parad.getFContrasts();
      }

    // sigmaSquareds:
    sigmaSquareds.read(logger.getDir() + "/sigmasquareds");
    sigmaSquareds.threshold(0.0);
    numTS = sigmaSquareds.getVolumeSize();
Stephen Smith's avatar
Stephen Smith committed
     
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:
	char strc[4];
	ostrstream osc(strc,4);
	osc << i << '\0';
Stephen Smith's avatar
Stephen Smith committed
	  
Mark Woolrich's avatar
Mark Woolrich committed
	peVol.read(logger.getDir() + "/pe" + strc);
Stephen Smith's avatar
Stephen Smith committed

Mark Woolrich's avatar
Mark Woolrich committed
	peVol.setDims(sigmaSquareds.getDims());
	peVol.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
	peVol.threshold();
Stephen Smith's avatar
Stephen Smith committed
	  
Mark Woolrich's avatar
Mark Woolrich committed
	b.Column(i) = peVol; 
      }

    // dof:
Mark Woolrich's avatar
Mark Woolrich committed
    ColumnVector dofVec = MISCMATHS::read_ascii_matrix(logger.getDir() + "/dof");
Mark Woolrich's avatar
Mark Woolrich committed
    dof = dofVec(1);

    // corrections:
    corrections.read(logger.getDir() + "/corrections");
    
  }

  void ContrastMgr::SaveFContrast(const string& suffix)
  {
    Tracer ts("ContrastMgr::SaveFContrast");
    Log& logger = Log::getInstance();

    // prepare contrast number:
    char strc[50];
    ostrstream osc(strc,50);
    osc << suffix << c_counter << '\0';
   
    // Write out tstat:
    fstat.setDims(sigmaSquareds.getDims());
    fstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    fstat.unthreshold();
    fstat.writeAsFloat(logger.getDir() + "/fstat" + strc);

    // Write out zstat:
    zstat.setDims(sigmaSquareds.getDims());
    zstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    zstat.unthreshold();
    zstat.writeAsFloat(logger.getDir() + "/zfstat" + strc);
  }

  void ContrastMgr::SaveTContrast(const string& suffix)
  {
    Tracer ts("ContrastMgr::SaveTContrast");
    Log& logger = Log::getInstance();
    
    // prepare contrast number:
    char strc[50];
    ostrstream osc(strc,50);
    osc << suffix << c_counter << '\0';

    // Write out neffs:
    neff.setDims(sigmaSquareds.getDims());
    neff.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    neff.unthreshold();
    neff.writeAsFloat(logger.getDir() + "/neff" + strc);

    // Write out cope:
    cb.setDims(sigmaSquareds.getDims());
    cb.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    cb.unthreshold();
    cb.writeAsFloat(logger.getDir() + "/cope" + strc);

    // Write out varcope:
    varcb.setDims(sigmaSquareds.getDims());
    varcb.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    varcb.unthreshold();
    varcb.writeAsFloat(logger.getDir() + "/varcope" + strc);

    // Write out tstat:
    tstat.setDims(sigmaSquareds.getDims());
    tstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    tstat.unthreshold();
    tstat.writeAsFloat(logger.getDir() + "/tstat" + strc);

    // Write out zstat:
    zstat.setDims(sigmaSquareds.getDims());
    zstat.setPreThresholdPositions(sigmaSquareds.getPreThresholdPositions());
    zstat.unthreshold();
    zstat.writeAsFloat(logger.getDir() + "/zstat" + strc);
  }

Stephen Smith's avatar
Stephen Smith committed

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

    // 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 ts("ContrastMgr::ComputeZStat");

    Log& logger = Log::getInstance();

    // 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);
    T2z::ComputeZStats(varcb, cb, (int)dof, zstat);

    // 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
    logger.out("ratios", ratios);
    logger.out("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 ts("ContrastMgr::ComputeCope");
    cb.ReSize(numTS);

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

  void ContrastMgr::ComputeNeff()
  {
    Tracer ts("ContrastMgr::ComputeNeff");
Stephen Smith's avatar
Stephen Smith committed
   
Mark Woolrich's avatar
Mark Woolrich committed
    Log& logger = Log::getInstance();
    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++;
	  }  
      }

    // Logging:
    logger.str() << "maxNeff = " << maxNeff << endl;
    logger.str() << "Number of negative neffs calculated = " << numNegs << endl;    
Mark Woolrich's avatar
Mark Woolrich committed
    logger.str() << "mean neff = " << MISCMATHS::mean(neff) << endl;
    logger.str() << "std neff = " << sqrt(MISCMATHS::var(neff)) << endl;
Mark Woolrich's avatar
Mark Woolrich committed
  }

  void ContrastMgr::ComputeFStat()
  {
    Tracer ts("ContrastMgr::ComputeFStat");
    
    //Log& logger = Log::getInstance();
    Matrix corr;

    fstat.ReSize(numTS);
    fstat = 1;

    for(int i = 1; i <= numTS; i++)
      {	
	GetCorrection(corr, i);

	try
	  {
	    fstat(i) = (b.Row(i)*fc.t()*(fc*corr*fc.t()*sigmaSquareds(i)).i()*fc*b.Row(i).t()).AsScalar()/numParams;
	  }
	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);
    F2z::ComputeFStats(fstat, numParams, (int)dof, zstat);
  }
Stephen Smith's avatar
Stephen Smith committed

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

    for(int i = 1; i <= numTS; i++)
      {
	if(neff(i) > 0)
	  varcb(i) = sigmaSquareds(i)/neff(i);
	else
	  varcb(i) = 0;
      }
  }