Skip to content
Snippets Groups Projects
meloptions.cc 7.29 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");

  // 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())
    {
      print_version();
      cout << endl;
      cout << "Usage: melodic <options> -i <filename>" << endl <<
	"Please specify input file name correctly or try melodic --help" 
	   << endl << endl;
      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"){
    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);
    exit(2);
  }
  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"; 
      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;
  }
  
  //transform inputfname to its basename
  string basename = inputfname.value();
  make_basename(basename);
  inputfname.set_T(basename);

  //create melodic directory name
  if(logdir.value()==string("melodic.log")){
    logdir.set_T(string(inputfname.value()+".ica"));
    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[])
{
  print_version();
  options.usage();
  /* cout << "Usage: " << argv[0] << " ";
Mark Jenkinson's avatar
Mark Jenkinson committed

    Have own usage output here
  */
}

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

void MelodicOptions::print_copyright()
{
  print_version();
  cout << endl << "Copyright (C) 1999-2002 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() << endl;
  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;
  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;
}

}