import sys 
import traceback
import os
import os.path
import math
import doctest
import datetime
import subprocess
from socket import gethostname

# ------------------------------------------------------------------------------------------------------------ 
# ------------------------------------------------------------------------------------------------------------ 
# Setup for force/energy platform comparisons
# ------------------------------------------------------------------------------------------------------------

def forceEnergyPlatformComparisonTestSetup( argumentHash, testName, active ):

    runs                                     = argumentHash['Runs']
    basePath                                 = argumentHash['BasePath']
    baseDataPath                             = argumentHash['BaseDataPath']
    forceEnergyPlatformComparison            = 'ForceEnergyPlatformComparison'
    platforms                                = [ ['Reference', 'Cuda' ], ['Reference', 'OpenCL' ] ]
    #platforms                                = [ ['Reference', 'OpenCL' ] ]
    platforms                                = [ ['Reference', 'Cuda' ] ]
    if( testName.startswith( "CustomForces" ) ):
        platforms                                = [ ['Reference', 'Reference' ], ['Reference', 'Cuda' ], ['Reference', 'OpenCL' ] ]
        platforms                                = [ ['Reference', 'Cuda' ], ['Reference', 'OpenCL' ] ]
#       platforms                                = [ ['Reference', 'Cuda' ] ]
#       platforms                                = [ ['Reference', 'OpenCL' ] ]
#       platforms                                = [ ['Reference', 'Reference' ] ]
    fullTestName                             = testName + forceEnergyPlatformComparison

    runs[fullTestName]                       = {}
    run                                      = runs[fullTestName] 
    run['Active']                            = active
    run['ControlFile']                       = fullTestName
    run['ComparisonPlatforms']               = platforms
    #run['SystemsDirectory']                  = os.path.join(basePath,'test/validation/systems_xml/openmm')
    run['SystemsDirectory']                  = os.path.join(baseDataPath,'systems_xml/openmm')
    run['TestSummaryFileName']               = testName
    run['TestScript']                        = forceEnergyPlatformComparison
    run['OutputSubDirectory']                = forceEnergyPlatformComparison
    #run['SerializeDirectory']                = os.path.join(basePath,'test/validation/systems_test/openmm')
    run['SerializeDirectory']                = os.path.join(baseDataPath,'systems_test/openmm')
    run['DeviceId']                          = 0

    return run
    
# ------------------------------------------------------------------------------------------------------------ 
# Setup for force/energy comparisons between OpenMM and a file generated from another app or OpenMM
# ------------------------------------------------------------------------------------------------------------

def filePlatformComparisonTestSetup( argumentHash, testName, active ):

    runs                                     = argumentHash['Runs']
    basePath                                 = argumentHash['BasePath']
    baseDataPath                             = argumentHash['BaseDataPath']
    filePlatformComparison                   = 'FilePlatformComparison'

    platforms                                = ['Reference', 'Cuda', 'OpenCL' ]
    platforms                                = ['Reference' ]
#   platforms                                = ['Cuda' ]
    fullTestName                             = testName + filePlatformComparison 

    runs[fullTestName]                       = {}
    run                                      = runs[fullTestName] 
    run['Active']                            = active
    run['ControlFile']                       = fullTestName
    run['Platforms']                         = platforms
    run['SystemsDirectory']                  = os.path.join(baseDataPath,'systems_xml/openmm')
    run['TestSummaryFileName']               = testName
    run['TestScript']                        = filePlatformComparison
    run['OutputSubDirectory']                = filePlatformComparison
    run['SerializeDirectory']                = os.path.join(baseDataPath,'systems_test/openmm')
    run['DeviceId']                          = 0

    return run
    
# ------------------------------------------------------------------------------------------------------------ 
# Setup for energy gradient tests
# ------------------------------------------------------------------------------------------------------------

def energyGradientTestSetup( argumentHash, testName, active ):

    runs                                     = argumentHash['Runs']
    allPlatforms                             = ['Reference', 'Cuda', 'OpenCL' ]
    basePath                                 = argumentHash['BasePath']
    baseDataPath                             = argumentHash['BaseDataPath']
    allPlatforms                             = ['Cuda', 'OpenCL' ]
    #allPlatforms                             = ['Reference' ]
    #allPlatforms                             = ['OpenCL' ]
    #allPlatforms                             = ['Cuda', 'Reference' ]
    allPlatforms                             = ['Cuda' ]

    energyGradient                           = 'EnergyGradient'

    fullTestName                             = testName + energyGradient
    runs[fullTestName]                       = {}
    run                                      = runs[fullTestName] 
    run                                      = runs[fullTestName] 
    run['Active']                            = active
    run['ControlFile']                       = fullTestName
    #run['SystemsDirectory']                  = os.path.join(basePath,'test/validation/systems_xml/openmm')
    run['SystemsDirectory']                  = os.path.join(baseDataPath,'systems_xml/openmm')
    run['TestSummaryFileName']               = testName
    run['TestScript']                        = energyGradient
    run['Platforms']                         = allPlatforms
    run['OutputSubDirectory']                = energyGradient
    #run['SerializeDirectory']                = os.path.join(basePath,'test/validation/systems_test/openmm')
    run['SerializeDirectory']                = os.path.join(baseDataPath,'systems_test/openmm')
    run['DeviceId']                          = 0
    
    return run

# ------------------------------------------------------------------------------------------------------------ 
# Setup for energy conservation tests
# ------------------------------------------------------------------------------------------------------------

def setupEnergyConservationRuns( scenario, returnHash ):

# VerletIntegratorTest
# VerletIntegratorNoCutoffTest
# VerletIntegratorCutoffNonPeriodicTest
# VerletIntegratorCutoffPeriodicTest
# VerletIntegratorEwaldTest
# VerletIntegratorPMETest
# VariableVerletIntegratorTest
# LangevinIntegratorTest
# VariableLangevinIntegratorTest
 
    # runSize == 0: small, test runs
    # runSize == 1: long runs
    # runSize == 2: benchmark runs

    runSize        = 0
    stepSize       = 0.001
    pressure       = 3.0
    rns            = 2011
    if( runSize == 1 ):
        runSteps   = 100000
        equilSteps = 30000
    elif( runSize == 0 ):
        runSteps   = 10000
        equilSteps = 300
    elif( runSize == 2 ):
        if( scenario == 4 ):
            stepSize   = 0.002
        else:
            stepSize   = 0.001
        runSteps   = 1000
        equilSteps = 30
 
    preamble                                  = ''
    preamble                                 += "Block\n"
    preamble                                 += "SimulationTotalSteps "    + str( runSteps )   + "\n"
    preamble                                 += "EquilibrationTotalSteps " + str( equilSteps ) + "\n"
    preamble                                 += "SimulationStepSize "      + str( stepSize )   + "\n"
    preamble                                 += "Pressure "                + str( pressure )   + "\n"
    preamble                                 += "RandomNumberSeed "        + str( rns )        + "\n"
    preamble                                 += "End Block\n"
    preamble                                 += "Block * *\n"
    preamble                                 += "Active 0\n"
    preamble                                 += "End Block\n"
 
    # run

    if( scenario == 1 ):
        testNames                                 = [ 'VerletIntegratorTest', 'VariableVerletIntegratorTest', 'LangevinIntegratorTest', 'VariableLangevinIntegratorTest' ]
        testNames                                 = [ 'VerletIntegratorTest', 'VariableVerletIntegratorTest']
        testNames                                 = [ 'VerletIntegratorTest', 'LangevinIntegratorTest' ]
        testNames                                 = [ 'VerletIntegratorTest' ]
        #testNames                                 = [ 'VariableVerletIntegratorTest', 'VariableLangevinIntegratorTest' ]
        #testNames                                 = [ 'VariableVerletIntegratorTest' ];
        #`testNames                                 = [ 'VerletIntegratorNoConstraintsTest' ]

        #systemNames                               = [ 'ala10Implicit' ]
        systemNames                               = [ '1PLXImplicit',   'ala10Implicit',  '6TNAImplicit',  'ProteinAmberImplicit', 'dnaDickersonImplicit' ]
        #systemNames                               = [ '1notGbviImplicit' ]
        #systemNames                               = [ 'CheYGbvi', 'sv582_sdGbvi',  'lambda_sdGbvi', 'bpti_sdGbvi' ]

        #systemNames                               = [ '1PLXImplicit',   'ala10Implicit',  'lambdaImplicit',  'dnaDickersonImplicit' ]
        #ystemNames                               = [ '1PLXImplicit',   'ala10Implicit',  'dnaDickersonImplicit' ]
        #systemNames                               = [ 'sv582Implicit' ]
        systemsDirectory                          = 'test/validation/systems_xml/openmm'

    elif( scenario == 2 ):

        #testNames                                 = [ 'VerletIntegratorTest', 'VariableVerletIntegratorTest', 'LangevinIntegratorTest', 'LangevinIntegratorTest' ]
        testNames                                 = [ 'VerletIntegratorTest', 'VerletIntegratorPMETest', 'VerletIntegratorCutoffNonPeriodicTest', 'VerletIntegratorCutoffPeriodicTest', 'VerletIntegratorEwaldTest' ]
        #testNames                                 = [ 'VerletIntegratorPMETest', 'VerletIntegratorCutoffNonPeriodicTest' ]
        #testNames                                 = [ 'VerletIntegratorPMETest' ]
        #testNames                                 = [ 'VerletIntegratorPMETest' ]
        systemNames                               = [ 'ala10Explicit', 'bptiExplicit', 'bptiExplicitAngleConstraints', 'dnaDickersonExplicit', 'lambdaExplicit', 'sv582Explicit', 'tna6Explicit', ]
        systemNames                               = [ 'ala10Explicit', 'bptiExplicit', 'bptiExplicitAngleConstraints', 'dnaDickersonExplicit', 'lambdaExplicit', 'sv582Explicit' ]
        #systemNames                               = [ 'bptiExplicit', 'bptiExplicitAngleConstraints' ]
        #systemNames                               = [ 'lysoExplicit', 'water12AExplicit' ]
        #systemNames                               = [ 'ala10Explicit', 'bptiExplicit']
        #systemNames                               = [ 'ala10Explicit' ]
 
    # MonteCarloBarostat test

    elif( scenario == 3 ):
        testNames                                 = [ 'MonteCarloBarostatLangevinIntegratorTest' ]
        systemNames                               = [ 'ala10Explicit' ]
 
    # implicit solvent benchmarks

    elif( scenario == 4 ):
        testNames                                 = [ 'VerletIntegratorTest'  ]
        systemNames                               = [ '1PLXImplicit',   'ala10Implicit',  'sv582Implicit', 'lambdaImplicit', 'lysoImplicit', 'bench101' ]
        systemsDirectory                          = 'test/validation/systems_xml/openmm'

    # explicit solvent benchmarks

    elif( scenario == 5 ):
        testNames                                 = [ 'VerletIntegratorTest'  ]
        systemNames                               = [ 'ala10Explicit', 'bptiExplicit', 'dnaDickersonExplicit', 'tna6Explicit', ]
        #systemNames                               = [ 'ala10ExplicitPME' ]
        #systemNames                               = [ 'bptiExplicitPME', 'dnaDickersonExplicitPME', 'tna6ExplicitPME', ]
        #systemNames                               = [ 'tna6ExplicitPME' ]
        systemsDirectory                          = 'test/validation/systems_xml/openmm'

    systemsDirectory                              = 'systems_xml/openmm'
 
    forceEnergyConservation                       = 'EnergyConservation'
    for testName in testNames:
        returnHash[testName]                      = {}
        setupInfoHash                             = returnHash[testName]
        setupInfoHash['Systems']                  = systemNames
        setupInfoHash['SystemsDirectory']         = systemsDirectory
        setupInfoHash['Preamble']                 = preamble
        setupInfoHash['OutputSubDirectory']       = forceEnergyConservation
        setupInfoHash['Sleep']                    = 0

    return returnHash

# ------------------------------------------------------------------------------------------------------------ 
# Setup for energy conservation tests
# ------------------------------------------------------------------------------------------------------------

def generateEnergyConservationRuns( argumentHash, defaultActive ):

    runs                                     = argumentHash['Runs']
    basePath                                 = argumentHash['BasePath']
    baseDataPath                             = argumentHash['BaseDataPath']
    configDirectory                          = argumentHash['ConfigDirectory']
    maxGpus                                  = argumentHash['MaxGpus']

    energyConservationControl                = 'EnergyConservationControl'
    forceEnergyConservation                  = 'EnergyConservation'
    setupHash                                = {}
    setupEnergyConservationRuns( 1, setupHash)
    #setupEnergyConservationRuns( 2, setupHash)
    #setupEnergyConservationRuns( 3, setupHash)

    # benchmarks: 4= implicit, 5= explicit
    
    #setupEnergyConservationRuns( 4, setupHash)
    #setupEnergyConservationRuns( 5, setupHash)
    gpuPlatforms                             = ['Cuda', 'OpenCL' ]
    #gpuPlatforms                             = ['OpenCL' ]
    #gpuPlatforms                             = ['Cuda' ]

    deviceId                                 = 0
    singleRuns                               = 0
    for testName, setupInfoHash in setupHash.iteritems():
        if( singleRuns ):
            for system in setupInfoHash['Systems']:
                run                                      = {}
                run['Active']                            = defaultActive
                fullTestName                             = testName + '_' + system
                runs[fullTestName]                       = run
                run['ControlFile']                       = fullTestName + energyConservationControl
                run['SystemsDirectory']                  = os.path.join(baseDataPath, setupInfoHash['SystemsDirectory'] )
                run['TestSummaryFileName']               = fullTestName
                run['TestScript']                        = forceEnergyConservation
                run['Platforms']                         = gpuPlatforms 
                run['SerializeDirectory']                = os.path.join(baseDataPath,'systems_test/openmm')
                run['Sleep']                             = setupInfoHash['Sleep']

                if( 'OutputSubDirectory' in setupInfoHash ):
                    run['OutputSubDirectory']                = setupInfoHash['OutputSubDirectory']

                if( deviceId > -1 ):
                    run['DeviceId']                      = deviceId
                    deviceId                             = deviceId + 1
                    if( deviceId == maxGpus ):
                        deviceId                         = 0
     
    #           controlText                              = "\n"
                controlText                              = "Block\n"
    #           controlText                             += "Active 1\n"
                controlText                             += "Test " + testName + "\n"
                controlText                             += "System " + system + "\n"
                controlText                             += "Active 1\n"
                controlText                             += "End Block"
    
                controlFileName                          = os.path.join( configDirectory, (run['ControlFile'] + '.txt') )
                controlFile                              = open( controlFileName, 'w') 
                controlFile.write( setupInfoHash['Preamble'] + controlText )
                controlFile.close()
        else:
            run                                      = {}
            run['Active']                            = defaultActive
            fullTestName                             = testName
            runs[fullTestName]                       = run
            run['ControlFile']                       = fullTestName + energyConservationControl
            run['SystemsDirectory']                  = os.path.join(baseDataPath, setupInfoHash['SystemsDirectory'] )
            run['TestSummaryFileName']               = fullTestName
            run['TestScript']                        = forceEnergyConservation
            run['Platforms']                         = gpuPlatforms 
            run['SerializeDirectory']                = os.path.join(basePath,'test/validation/systems_test/openmm')
            run['Sleep']                             = setupInfoHash['Sleep']

            if( 'OutputSubDirectory' in setupInfoHash ):
                run['OutputSubDirectory']                = setupInfoHash['OutputSubDirectory']

            if( deviceId > -1 ):
                run['DeviceId']                      = deviceId
                #deviceId                             = deviceId + 1
                if( deviceId == maxGpus ):
                    deviceId                         = 0
 
            controlText                              = "Block\n"
            controlText                             += "Test " + testName + "\n"
            controlText                             += "System "
            for system in setupInfoHash['Systems']:
                controlText                         += " " + system
            controlText                             += "\nActive 1\n"
            controlText                             += "End Block"

            controlFileName                          = os.path.join( configDirectory, (run['ControlFile'] + '.txt') )
            controlFile                              = open( controlFileName, 'w') 
            controlFile.write( setupInfoHash['Preamble'] + controlText )
            controlFile.close()

# text for qsub shell

def getQsubHeader():

     shellHeader  = "#!/bin/bash\n"
     shellHeader += '#$ -S /bin/bash' + "\n"
     shellHeader += '#$ -V' + "\n"
     shellHeader += '#$ -cwd' + "\n"
     shellHeader += "export CUDA_LIBRARY_PATH=/usr/local/cuda/lib64\n"
     shellHeader += "if [ -z " + '"$' + "LD_LIBRARY_PATH" + '"' + " ]; then\n"
     shellHeader += "    export LD_LIBRARY_PATH=" + '$' + "CUDA_LIBRARY_PATH\n"
     shellHeader += "else\n"
     shellHeader += "    export LD_LIBRARY_PATH=" + '"$' + "CUDA_LIBRARY_PATH:" + '$' + "LD_LIBRARY_PATH" + '"' + "\n"
     shellHeader += "fi\n"
     shellHeader += "sleep 60\n"
     shellHeader += "hostname\n"

     return shellHeader

def printHash(hash, idString = "" ):
    
    outputString = idString
    firstTab     = 40 
    secondTab    = 60 
    for key in sorted( hash.iterkeys() ):
        value         = hash[key]
        outputString += key.rjust(firstTab) + str( value ).rjust(secondTab) + "\n" 
    
    return outputString

########################################################################################################

verbose                                  = 1
productionRun                            = 0
executeCommand                           = 1
useQsub                                  = 0
defaultActive                            = 0

validationDirectory                      = os.path.join(os.getenv('PYOPENMM_SOURCE_DIR'), 'test', 'validation')
configDirectory                          = os.path.join(validationDirectory, 'config')

# used to edits srcipts for Windows vs. Linux
hostname                                 = gethostname()
uname                                    = os.uname()[0]
uname1                                   = os.uname()[1]

#print "Hosts <%s> uname=<%s> os.name=<%s>" % ( hostname, uname, os.name )
#logDirectory                                               = os.path.join(os.getenv('TEST_DIR'), 'log')

pyOpenMMSourceDir                        = '/home/friedrim/source/pyopenmm/trunk'
svnLocation                              = '/usr/bin/svn'
if( hostname.find( 'vspm55' ) > -1 ):
    homeBase                             = '/home/friedrim'
    pythonLocations                      = [ '/home/friedrim/install/python/bin/python' ]
    maxGpus                              = 2               
elif( hostname.find( 'peter' ) > -1 ):
    homeBase                             = '/home/friedrim'
    pythonLocations                      = [ '/home/friedrim/install/python/bin/python' ]
    maxGpus                              = 1               
    pyOpenMMSourceDir                    = '/home/friedrim/source/pyopenmm/trunk'
elif( hostname.find( 't0.simtk.org' ) > -1 ):
    homeBase                             = '/home/friedrim'
    pythonLocations                      = [ '/home/friedrim/source/python/bin/python' ]
    maxGpus                              = 4               
elif( hostname.find( 'snow' ) > -1 ):
    homeBase                             = '/Users/friedrim'
    pythonLocations                      = [ '/usr/bin/python' ]
    pyOpenMMSource                       = '/Users/friedrim/source/pyopenmm/trunk'
    maxGpus                              = 1               
else:
    print "Host <%s> not recognized." % ( hostname )
    sys.exit(-1)

for location in pythonLocations:
   if( os.path.exists( location ) ):
       pythonLocation                    = location

openMMLocation                           = homeBase + '/source/openmm/trunk/OpenMM'
os.environ['PYOPENMM_SOURCE_DIR']        = pyOpenMMSourceDir
basePath                                 = homeBase + '/source/pyopenmm/trunk'
baseDataPath                             = homeBase + '/data'
testScriptDirectory                      = os.path.join(basePath,'test/validation')
outputDirectoryName                      = 'results'
qsubDirectoryName                        = 'qsub'

interCommandSleep                        = 0

argumentHash                             = {}
argumentHash['MaxGpus']                  = maxGpus
argumentHash['BasePath']                 = basePath
argumentHash['BaseDataPath']             = baseDataPath
argumentHash['ConfigDirectory']          = os.path.join( basePath, configDirectory )
argumentHash['Runs']                     = {}
runs                                     = argumentHash['Runs']

# ------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------

# setup for force/energy platform comparison test

forceEnergyPlatformComparisonTestActive = defaultActive

forceEnergyPlatformComparisonTestActive = 0
forceEnergyPlatformComparisonTestSetup( argumentHash, 'LocalForces',      forceEnergyPlatformComparisonTestActive )
forceEnergyPlatformComparisonTestActive = 0
forceEnergyPlatformComparisonTestSetup( argumentHash, 'NbNoCutoffAndObc', forceEnergyPlatformComparisonTestActive )
forceEnergyPlatformComparisonTestActive = 0
forceEnergyPlatformComparisonTestSetup( argumentHash, 'CustomForces',     forceEnergyPlatformComparisonTestActive )
forceEnergyPlatformComparisonTestActive = 0
forceEnergyPlatformComparisonTestSetup( argumentHash, 'NbForces',         forceEnergyPlatformComparisonTestActive )
#forceEnergyPlatformComparisonTestActive = 0

# ------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------

# setup for energy gradient test

energyGradientTestActive = defaultActive
energyGradientTestActive = 0
energyGradientTestSetup( argumentHash, 'LocalForce',       energyGradientTestActive )
energyGradientTestActive = 0
energyGradientTestSetup( argumentHash, 'NbNoCutoffAndObc', energyGradientTestActive )
energyGradientTestActive = 0
energyGradientTestSetup( argumentHash, 'NbForce',          energyGradientTestActive )

# ------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------

# setup for force/energy platform comparison test

filePlatformComparisonTestActive = defaultActive
filePlatformComparisonTestActive = 0
filePlatformComparisonTestSetup( argumentHash, 'LocalForces', filePlatformComparisonTestActive )

# ------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------

energyConservationActive = 1
if( energyConservationActive ):
    generateEnergyConservationRuns( argumentHash, energyConservationActive )

# ------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------

qsubCommands                               = []
testSummaryFileNames                       = {}
testSummaryFileNames['PlatformComparison'] = []
testSummaryFileNames['EnergyGradient']     = []
testSummaryFileNames['Integrator']         = []
testSummaryFileNames['Other']              = []

# if using qsub, then force process to sleep between tests
# if not present, the board is often not available for next test

if( useQsub ):
    sleep                                = 12
else:
    sleep                                = 4

#>>> datetime.datetime.today()
#datetime.datetime(2011, 2, 23, 6, 57, 52, 984163)

todayDate            = datetime.datetime.today()
svnOutput            = subprocess.check_output([ svnLocation, 'info', openMMLocation ] )
print "svnOutput=%s" % (svnOutput)
tokens               = svnOutput.rstrip().split(None)
save                 = 0
revision             = 0
for token in tokens:
    print "svnOutput token <%s>" % (token)
    if( save == 1 ):
       revision = token
    if( token.startswith( 'Revision:' ) ):
        save = 1
    else:
        save = 0

print "Revision=<%s>" % (revision)
if( productionRun ):
   sys.stdout.flush()
   outputDirectoryName += '_' + todayDate.strftime("%m_%d_%Y_%h")
   

fullOutputDirectoryName                    = os.path.join(basePath, outputDirectoryName)

# create directory for qsub output

if( useQsub ): 
    fullQsubDirectoryName    = os.path.join(basePath, qsubDirectoryName)
    fullQsubDirectoryName   += '_' + todayDate.strftime("%m_%d_%Y")
    if( os.path.exists( fullQsubDirectoryName ) == 0 ):
        mkdirCommand                 = 'mkdir -p ' + fullQsubDirectoryName
        os.system( mkdirCommand )
    else:
        rmCommand                    = '/bin/rm -rf ' + os.path.join( fullQsubDirectoryName, '/*sh' )
        os.system( rmCommand )

# main submission loop

commandList = []
try:
    for runName, runHash in runs.iteritems():
        testScriptFileName                    = runHash['TestScript']
        print "testScriptFileName %s xxx " % (testScriptFileName)
        fullTestScriptFileName                = os.path.join(testScriptDirectory, (testScriptFileName + '.py'))

        # loop over platforms

        # Force/Energy platform comparison requires two platforms
        # Force/Energy gradient and energy conservation test require one platform
     
        if( 'ComparisonPlatforms' in runHash ):
            platformsArray  = runHash['ComparisonPlatforms']
            platformRunType = 0
        else:
            platformsArray  = runHash['Platforms']
            platformRunType = 1
    
        for platformArray in platformsArray:
            command  = ''
            command += pythonLocation + ' '
            command += fullTestScriptFileName + ' '
            print "%s" % printHash( runHash, "runHash arguments\n" )
            if( runHash['Active'] == 0 ):
                continue
            if( verbose ):
                command += ' -verbose 1 '
            command += ' -controlFile ' +  runHash['ControlFile'] + '.txt' 
         
            if( runHash['SystemsDirectory'] ):
                #print "xx SystemsDirectory=%s" % (runHash['SystemsDirectory'])
                command += ' -systemsDirectory ' +  runHash['SystemsDirectory']
          
            if( 'SerializeDirectory' in runHash and runHash['SerializeDirectory'] ):
                command += ' -serializeDirectory ' +  runHash['SerializeDirectory']
          

            if( platformRunType == 0 ):
                command += ' -platform0 ' + platformArray[0] 
                command += ' -platform1 ' + platformArray[1] 
                platformName = platformArray[1]
            else:
                command        += ' -platform ' + platformArray
                platformName    = platformArray
     
            if 'TestSummaryFileName' in runHash:  
                baseOutputName = runHash['TestSummaryFileName'] + platformName 
            else:
                baseOutputName = 'run'
    
            # create/set results directory

            resultDirectory    = fullOutputDirectoryName
            if( 'OutputSubDirectory' in runHash ):
                resultDirectory = os.path.join(fullOutputDirectoryName, runHash['OutputSubDirectory'], platformName )

            if( os.path.exists( resultDirectory ) == 0 ):
                mkdirCommand  = 'mkdir -p ' + resultDirectory
                os.system( mkdirCommand )

            # full output file names

            baseOutputName    += '_' + todayDate.strftime("%m_%d_%Y__%H")
            baseOutputName    += '_r' + revision
            fullBaseOutputName = os.path.join(resultDirectory, baseOutputName )
            
            outOutputName      = fullBaseOutputName + '.out'
            summaryOutputName  = fullBaseOutputName + '.summary'
            command           += ' -testSummaryFileName ' + summaryOutputName
            print "%s QQQQ" % summaryOutputName
            if( 'DeviceId' in runHash ):
                command       += ' -deviceId ' + str(runHash['DeviceId'])

            added              = 0
            for typeName, nameArray in testSummaryFileNames.iteritems():
                if( typeName in baseOutputName ):
                    #print "%s %s " % ( typeName, baseOutputName )
                    nameArray.append( summaryOutputName )
                    added = 1
                    break

            if( added == 0 ):
                #print "Other %s " % ( baseOutputName )
                testSummaryFileNames['Other'].append( summaryOutputName )

            if( 'Sleep' in runHash and runHash['Sleep'] ):
                command += ' -sleep ' +  str(runHash['Sleep'])
            elif( sleep ):
                command += ' -sleep ' + str(sleep)

            # branch based on whether submitting jobs via qsub
    
            if( useQsub ):
                qsubCommands.append( [(runName+platformName), command + "\n" ] )
            else:
                command       += ' 2>&1 > ' + outOutputName
                print "%s" % ( command )
                commandList.append( command )
                if( interCommandSleep ):
                    sleepCommand = "sleep " + str( interCommandSleep )
                    print sleepCommand
                    commandList.append( sleepCommand )
                sys.stdout.flush()
                if( executeCommand ):
                    os.system( command )
                    if( interCommandSleep ):
                        cpCommand = 'sleep ' + str(interCommandSleep)
                        os.system( cpCommand )
    
except:
    print repr(traceback.print_exception( sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))

# submit qsub jobs

if( useQsub ):
    qsubHeader = getQsubHeader()
    for qsubid in range( len( qsubCommands )):
        qsubFileName = os.path.join( fullQsubDirectoryName, (qsubCommands[qsubid][0] + '_' + str(qsubid) + '.sh') )
        qsubFile     = open( qsubFileName, 'w') 
        qsubFile.write( qsubHeader + "\n" + qsubCommands[qsubid][1] )
        qsubFile.close()
        if( executeCommand ):
            qsubSubmit = 'cd ' + fullQsubDirectoryName + '; qsub ' + qsubFileName
            os.system( qsubSubmit )

summaryFileName       = os.path.join( fullOutputDirectoryName, 'Summaries' )
outputSummaryFileName = 'summary.txt'
summaryFile           = open( summaryFileName, 'w') 
summaryFile.write( "/bin/rm -rf " + outputSummaryFileName + "\n" )
for type, nameArray in testSummaryFileNames.iteritems():
    for testSummaryFileName in nameArray:
        summaryFile.write( "cat " + testSummaryFileName + ' >> ' + outputSummaryFileName + "\n" )
summaryFile.close()
chmodCommand = 'chmod 755 ' + summaryFileName
os.system( chmodCommand )

# command file

openMMInstallDirectory = homeBase + '/install/openmm'
openMMPluginDirectory  = openMMInstallDirectory + '/lib/plugins'
ld_library_path        = homeBase + '/source/cuda/lib64:/usr/local/cuda/lib64'
ld_library_path       += ':' + openMMInstallDirectory + '/lib'
ld_library_path       += ':' + openMMInstallDirectory + '/lib/plugins'
commandFileName        = os.path.join( fullOutputDirectoryName, 'commands.txt' )
outputSummaryFileName  = 'command.txt'
commandFile            = open( commandFileName, 'w') 
commandFile.write( "export OPENMM_PLUGIN_DIR=" + openMMPluginDirectory + "\n" )
commandFile.write( "export LD_LIBRARY_PATH=" + ld_library_path + "\n" )
commandFile.write( "printenv LD_LIBRARY_PATH" + "\n" )
commandFile.write( "printenv OPENMM_PLUGIN_DIR" + "\n" )
for command in commandList:
    commandFile.write( command + "\n" )
commandFile.close()
chmodCommand = 'chmod 755 ' + commandFileName
os.system( chmodCommand )
