Skip to content
Snippets Groups Projects
meloptions.cc 7.87 KiB
Newer Older
Mark Jenkinson's avatar
Mark Jenkinson committed

/*  MELODIC - Multivariate exploratory linear optimized decomposition into 
              independent components
    
    meloptions.cc - class for command line options

    Christian F. Beckmann, FMRIB Image Analysis Group
     
Christian Beckmann's avatar
Christian Beckmann committed
    Copyright (C) 1999-2004 University of Oxford */
Mark Jenkinson's avatar
Mark Jenkinson committed

/*  CCOPYRIGHT  */

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include "utils/log.h"
Mark Jenkinson's avatar
Mark Jenkinson committed
#include "meloptions.h"
#include "newimage/newimageall.h"
Mark Jenkinson's avatar
Mark Jenkinson committed

using namespace Utilities;
using namespace NEWIMAGE;

namespace Melodic {

MelodicOptions* MelodicOptions::gopt = NULL;

  void MelodicOptions::parse_command_line(int argc, char** argv, Log& logger, const string &p_version)
{
  //set version number and some other stuff
  version = p_version;
  filtermode = false;
  explicitnums = false;
  logfname = string("melodic.log");
Mark Jenkinson's avatar
Mark Jenkinson committed

  // work out the path to the $FSLDIR/bin directory
  if(getenv("FSLDIR")!=0){
    binpath = (string) getenv("FSLDIR") + "/bin/";
  }
  else{
    binpath = argv[0];
    binpath = binpath.substr(0,binpath.length()-7);
  }

  // parse once to establish log directory name
  for(int a = options.parse_command_line(argc, argv); a < argc; a++);

  // act on simple command line arguments
  if(help.value())
    {
      print_usage(argc, argv);
      exit(0);
    } 
  if(vers.value())
    {
      print_version();
      cout << endl;
      exit(0);
    } 
  if(copyright.value())
    {
      print_copyright();
      exit(0);
    } 
  if(! options.check_compulsory_arguments())
    {
Christian Beckmann's avatar
Christian Beckmann committed
			print_usage(argc, argv);
Mark Jenkinson's avatar
Mark Jenkinson committed
      exit(2);
    }     

  // check for invalid values
  if (inputfname.value().size()<1) {
    cerr << "ERROR:: Input volume not found\n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (approach.value() != "symm" && approach.value() != "defl"  && 
      approach.value() != "jade" && approach.value() != "maxent" &&
Christian Beckmann's avatar
Christian Beckmann committed
      approach.value() != "tica" && approach.value() != "concat"){
Mark Jenkinson's avatar
Mark Jenkinson committed
    cerr << "ERROR:: unknown approach \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (nonlinearity.value() != "pow3" && nonlinearity.value() != "pow4" && nonlinearity.value() != "tanh" 
      && nonlinearity.value() != "gauss" ){
    cerr << "ERROR:: unknown nonlinearity \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (maxNumItt.value() < 1){
    cerr << "ERROR:: maxItt too small \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (epsilon.value() < 0.000000001){
    cerr << "ERROR:: epsilon too small  \n\n";
    print_usage(argc,argv);
Mark Jenkinson's avatar
Mark Jenkinson committed
  }
  if (epsilon.value() >= 0.01){
    cerr << "ERROR:: epsilon too large  \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (nlconst1.value() <= 0){
    cerr << "ERROR:: nlconst1 negative  \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (!remove_meanvol.value()){
    varnorm.set_T(false);
  }
  if (filter.value().length()>0){
    if (filtermix.value().length()<0){
      cerr << "ERROR:: no mixing matrix for filtering (use --mix='filename') \n\n"; 
Mark Jenkinson's avatar
Mark Jenkinson committed
      print_usage(argc,argv);
      exit(2);
    } else {   
      filtermode = true;
      varnorm.set_T(false);
    } 
  }
  if (threshold.value()<=0){
    use_mask.set_T(false);
  }
  if (output_all.value()){
    output_unmix.set_T(true);
    output_MMstats.set_T(true);
    output_pca.set_T(true);
    output_white.set_T(true);
    output_origIC.set_T(true);
    output_mean.set_T(true);
  }
Mark Jenkinson's avatar
Mark Jenkinson committed
  if (output_pca.value()){
    output_white.set_T(true);
  }
  if(threshold.value()>=1){
    threshold.set_T(threshold.value()/100);
    if(threshold.value()>=1){
      cerr << "ERROR:: threshold level not a percentage value  \n\n";
      print_usage(argc,argv);
      exit(2);
    }
  }
  if (nlconst2.value() <= 0){
    cerr << "ERROR:: nlconst2 negative  \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (dummy.value() < 0){
    cerr << "ERROR:: negative dummy value  \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (repeats.value() < 1){
    cerr << "ERROR:: repeats < 1 \n\n";
    print_usage(argc,argv);
    exit(2);
  }
  if (numICs.value() > 0){
    explicitnums = true;
  }
  
Christian Beckmann's avatar
Christian Beckmann committed
  //in the case of indirect inputs, create the vector of input names here
  if( inputindirect.value()){
    std::vector< string > tmpfnames;
    ifstream fs(inputfname.value().at(0).c_str());
    string cline;
    while (!fs.eof()) {
      getline(fs,cline);
      if(cline.length()>0)
Christian Beckmann's avatar
Christian Beckmann committed
				tmpfnames.push_back(cline);
    }	
Christian Beckmann's avatar
Christian Beckmann committed
    fs.close();
    inputfname.set_T(tmpfnames);
  }

  //transform inputfnames to their basenames
  std::vector< string > tmpfnames;
  for(int ctr=0; ctr < (int)inputfname.value().size() ; ctr++){
    string basename;
    basename = inputfname.value().at(ctr);
    make_basename(basename);
    tmpfnames.push_back(basename);
  }
  inputfname.set_T(tmpfnames);
Mark Jenkinson's avatar
Mark Jenkinson committed

  //create melodic directory name
  if(logdir.value()==string("melodic.log")){
    logdir.set_T(string(inputfname.value().at(0)+".ica"));
Mark Jenkinson's avatar
Mark Jenkinson committed
    logger.makeDir(logdir.value(),logfname);
  }
  else{
    // setup logger directory
    system(("mkdir "+ logdir.value() + " 2>/dev/null").c_str());
    logger.setDir(logdir.value(),logfname);
  }
  message(endl << "Melodic Version " << version << endl << endl);

  // parse again so that options are logged
  for(int a = 0; a < argc; a++)
    logger.str() << argv[a] << " ";
  logger.str() << endl << "---------------------------------------------" << endl << endl;

  message("Melodic results will be in " << logger.getDir() << endl << endl);
}

void MelodicOptions::print_usage(int argc, char *argv[])
{
Christian Beckmann's avatar
Christian Beckmann committed
  print_copyright();
Mark Jenkinson's avatar
Mark Jenkinson committed
  options.usage();
  /* cout << "Usage: " << argv[0] << " ";
Mark Jenkinson's avatar
Mark Jenkinson committed

    Have own usage output here
  */
}

void MelodicOptions::print_version()
{
Christian Beckmann's avatar
Christian Beckmann committed
  cout << endl <<"MELODIC Version " << version;
  cout.flush();
Mark Jenkinson's avatar
Mark Jenkinson committed
}

void MelodicOptions::print_copyright()
{
  print_version();
Christian Beckmann's avatar
Christian Beckmann committed
  cout << endl << "Copyright (C) 1999-2007 University of Oxford " << endl;
  cout.flush();
Mark Jenkinson's avatar
Mark Jenkinson committed
}

void MelodicOptions::status()
{
  cout << " version = " << version << endl;
 
  cout << " logdir = "  << logdir.value() << endl;
  cout << " inputfname = "  << inputfname.value().at(0) << inputfname.value().at(inputfname.value().size()-1) << endl;
Mark Jenkinson's avatar
Mark Jenkinson committed
  cout << " outputfname = "  << outputfname.value() << endl;
  cout << " guessfname = "  << guessfname.value() << endl;
  cout << " maskfname = "  << maskfname.value() << endl;
  cout << " paradigmfname = "  <<  paradigmfname.value() << endl;
  cout << " nonlinearity = "  << nonlinearity.value() << endl;
  cout << " approach = "  << approach.value() << endl;
  
  cout << " pca_dim = "  << pca_dim.value() << endl;
  cout << " segment = "  << segment.value() << endl;
  cout << " numICs = "  << numICs.value() << endl;
  cout << " maxNumItt = "  << maxNumItt.value() << endl;
  cout << " maxRestart = "  << maxRestart.value() << endl;
  cout << " dummy = "  << dummy.value() << endl;
  cout << " repeats = "  << repeats.value() << endl;
  cout << " nlconst1 = "  << nlconst1.value() << endl;
  cout << " nlconst2 = "  << nlconst2.value() << endl;
Christian Beckmann's avatar
Christian Beckmann committed
  cout << " smooth_probmap = "  << smooth_probmap.value() << endl;
Mark Jenkinson's avatar
Mark Jenkinson committed
  cout << " epsilon = "  << epsilon.value() << endl;
  cout << " threshold = "  << threshold.value() << endl;
  
  cout << " help = "  << help.value() << endl;
  cout << " verbose = "  << verbose.value() << endl;
  cout << " vers = "  << vers.value() << endl;
  cout << " copyright = "  << copyright.value() << endl;
  cout << " perf_bet = "  << perf_bet.value() << endl;
  cout << " remove_meanvol = "  << remove_meanvol.value() << endl;
  cout << " remove_endslices  = " << remove_endslices.value() << endl;
  cout << " output_pca = "  << output_pca.value() << endl;
  cout << " output_white = "  << output_white.value() << endl;
  cout << " output_mean = "  << output_mean.value() << endl;
  cout << " use_mask = "  << use_mask.value() << endl;
  cout << " output_unmix = "  << output_unmix.value() << endl;
  cout << " guess_remderiv = "  << guess_remderiv.value() << endl;
  cout << " filter  = " << filter.value() << endl;
  cout << " logPower  = " << logPower.value() << endl;
}

}