#!/usr/bin/env python

##################################################################
#                                                                #
#    dtiTest                                                     #
#      created by Stathis Kanterakis <kanterae@uphs.upenn.edu>   #
#      copyright SBIA 2008                                       #
#                                                                #
#    to test the sbiaDTI distribution                            #
#                                                                #
#         contact Stathis Kanterakis <efa@seas.upenn.edu>        #
##################################################################

import csv, sys, os, getopt, tempfile, shutil, subprocess
import numpy

# globals
SVN_FILE_VERSION = "$Id: droidTest_in.py 296 2009-09-23 00:31:23Z rouchdyy@UPHS.PENNHEALTH.PRV $" # SVN substitution variable
EXIT_SUCCESS     = 0

####################
# STATIC FUNCTIONS #
####################

# version information
def version():
  str = """
dtiTest-
    Release       : @RELEASE_ID@
    Svn Revision  : @SVN_REV@
    File Version  : """ + SVN_FILE_VERSION
  print str

# usage information
def usage():
  print r"""
dtiTest--
  tests this distribution of the DTI toolbox by computing a difference with
  pre-computed test cases
  
Usage: dtiTest.py [OPTIONS] ...

Required Options:
  [-d --dataDir]        Specify the directory containing the installation of this distribution
  [-p --precomp]        Specify the pre-computed data prefix
  [-s --subject]        Specify the test subject
  [-t --template]       Specify the template subject

Options:
  [-h --help]           Display this message
  [-u --usage]          Display this message
  [-V --Version]        Display version information

Example:
  dtiTest.py -d /my/bin -p test/pre -s test/data/subject.hdr -t test/data/template.hdr
"""

def execCmd(cmdArray,verbose=False,simulate=False,quiet=True,noFail=False):
  """
  Executes cmdarray
  """
  if verbose or simulate:
    print " ".join(cmdArray)
  
  if (simulate):
    ret = (0,"Simualted","Simulated")

  else:
    output = ["",""]
    try:
      p = subprocess.Popen(cmdArray, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
      output = numpy.array(p.communicate())
      status = p.returncode
      ret = (status,output[0],output[1])  
    except OSError,e: #this might be dumb!
      msg = string.join(cmdArray," ") + "\tCaused an OSError\n"
      msg = msg + "\t"+e.message
      sys.stderr.write(msg)
      raise e
    
  if verbose or simulate:
    print "return Value: %d" % ret[0]

  #pass stderr and stdout along
  if not quiet:
    sys.stdout.write(output[0])
    sys.stderr.write(output[1])
  
  #if this failed then thorw an exception
  if ret[0] != 0 and not noFail:
    msg = "*** " + " ".join(cmdArray) + " Failed!"
    print msg
    sys.exit(2)

  return ret


def checkCmdExist(executable):
  if (execCmd(["which",executable],quiet=True,noFail=True)[0] != 0):
    msg = "*** Error can't find " + executable + " please check your path!"
    print msg
    sys.exit(2)


def main():
  print sys.argv
	
  #the defaults
  rOpts = 0
  
  try:
    opts, files = getopt.gnu_getopt(sys.argv[1:], "hd:p:vVus:t:",
      ["help", "dataDir=", "precomp=","verbose","Version", "usage","subject=","template="])
  
  except getopt.GetoptError, err:
    print str(err) # will print something like "option -a not recognized"
    usage()
    sys.exit(2)
  
  verbose = 0

  for o, a in opts:
    if o == "-v":
      verbose+=1
    elif o in ("-h", "--help","-u","--usage"):
      usage()
      sys.exit(0)
    elif o in ("-V", "--Version"):
      version()
      sys.exit(0)
    elif o in ("-d", "--dataDir"):
      dataDir = os.path.realpath(a)
      rOpts+=1
    elif o in ("-p", "--precomp"):
      precomp = os.path.realpath(a)
      rOpts+=1
    elif o in ("-s", "--subject"):
      subject = os.path.realpath(a)
      rOpts+=1
    elif o in ("-t", "--template"):
      template = os.path.realpath(a)
      rOpts+=1
    else:
      assert False, "unhandled option"

  if rOpts != 4:
    usage()
    print "*** Please specify all required options!"
    sys.exit(2)
  
  if not os.path.isdir(dataDir):
    print "*** " + dataDir + " is not a valid directory!"
    sys.exit(1)
  #if not os.path.isfile(precomp):
  #  print "*** " + precomp + " is not a valid file!"
  #  sys.exit(1)
  if not os.path.isfile(subject):
    print "*** " + subject + " is not a valid file!"
    sys.exit(1)
  if not os.path.isfile(template):
    print "*** " + template + " is not a valid file!"
    sys.exit(1)
  
  if verbose > 0:
    print " dataDir  : " + dataDir
    print " precomp  : " + precomp
    print " subject  : " + subject
    print " template : " + template
  
  testPath = os.path.splitext(os.path.basename(precomp))[0]
  
  # prepend the path
  if verbose > 0:
    print "============ PATH BEFORE ==============="
    print os.environ['PATH']
  os.environ['PATH'] = dataDir + ":" + os.environ['PATH']
  if verbose > 0:
    print "============ PATH AFTER  ==============="
    print os.environ['PATH']
  
  # run droid between subject and template
  checkCmdExist("dtiDroid")
<<<<<<< .mine
  
  useFlirt = "YES"
  if (execCmd(["which","flirt"],quiet=True,noFail=True)[0] != 0): #NO FLIRT
    useFlirt = "NO"
    
  
=======
  checkCmdExist("applyDeformationField")

>>>>>>> .r197
  prefix = "test_warped"
  
  try:
    print os.environ['HOSTNAME']
  except:
    pass
    
  for i in ["0","1","3"]:
    tmp = tempfile.mkdtemp()
    print tmp
<<<<<<< .mine
    cmd = ["dtiDroid","-d",subject,"-t",template,"-p",prefix,"-o",tmp,"-l",i,"-f",useFlirt]
=======
    # run DROID
    cmd = ["dtiDroid","-d",subject,"-t",template,"-p",prefix,"-o",tmp,"-l",i]
>>>>>>> .r197
    print " ".join(cmd)
    execCmd(cmd)
    
    preField  = os.path.join(precomp+i,"pre_warped.Field")
    justField = os.path.join(tmp,prefix+".Field")
    print "Comparing " + preField
    print "To        " + justField
    
    # read in pre-computed Field
    pre_data  = numpy.fromfile(preField,dtype='float32',count=48*48*24*3)
    # read in just-computed Field
    test_data = numpy.fromfile(justField,dtype='float32',count=48*48*24*3)
    diff = abs(test_data-pre_data)
    # take max difference
    maxDiff = diff.max()
    maxInd = numpy.where(diff == diff.max())[0][0]
    print "MAX_DIFF_l" + i + " :" + `maxDiff`
    print "MAX_IND_l" + i + "  :" + `maxInd`
    
    # apply the field again using applyDeformationField
    cmd = ["applyDeformationField","-d",subject,"-t",template,"-f",justField,"-p","apply_"+prefix,"-o",tmp]
    print " ".join(cmd)
    execCmd(cmd)
    # compare tensors
    cmd = ["diff",os.path.join(tmp,prefix+".img"),os.path.join(tmp,"apply_"+prefix+".img")]
    print execCmd(cmd)[1]
    
    shutil.rmtree(tmp)
    if maxDiff > 1:
    	sys.exit(maxDiff)
  
  return EXIT_SUCCESS

if __name__ == '__main__': main()

