import sys, copy
try:
    import psyco
    psyco.full()
except:
    print "psyco not running"

from som import SOM

versionString = '%s: version 1.41' % sys.argv[0]
print versionString

timesteps = 1000000
rounds = 100
firstField = 1
dim = -1
theTotology = 'toroid'
if len(sys.argv) < 4:
    print "usage: python %s numRows numCols trainingfile somfile [-topology sheet|toroid] [-testset testfile] [-inputDimensions num] [-startField num] [-trials numRounds] [-timesteps numSteps] [-radius maxNum]" % sys.argv[0]
    sys.exit(0)

somRows = int(sys.argv[1])
somCols = int(sys.argv[2])

trainingfile = sys.argv[3]
somresults = sys.argv[4]

if '-topology' in sys.argv:
    theTopology = sys.argv[sys.argv.index('-topology') + 1]

testfile = trainingfile
if '-testset' in sys.argv:
    testfile = sys.argv[sys.argv.index('-testset') + 1]
    
if '-startField' in sys.argv:
    firstField = int(sys.argv[sys.argv.index('-startField') + 1])

if '-trials' in sys.argv:
    rounds = int(sys.argv[sys.argv.index('-trials') + 1])

if '-timesteps' in sys.argv:
    timesteps = int(sys.argv[sys.argv.index('-timesteps') + 1])

startRadius = -1
if '-radius' in sys.argv:
    startRadius = int(sys.argv[sys.argv.index('-radius') + 1])

configsom = SOM(topology=theTopology)
configsom.resize(inputDim=dim, numRows=somRows,numCols=somCols)
(dim, count) = configsom.datasetSize(trainingfile, startField=firstField)
if '-inputDimension' in sys.argv:
    newdim = int(sys.argv[sys.argv.index('-inputDimension') + 1])
    if dim < newdim:
        print "-inputDimension %d is larger than the number of observed dimensions %d - exiting" % (newdim, dim)
        sys.exit(1)
    dim = newdim
bestScore = 1000000

print "input data: %s (%d examplars)" % (trainingfile, count)
print "\twill use %d dimensions starting from field %d" % (dim, firstField)
print "SOM: %d rows * %d columns for %d timesteps" % (somRows, somCols, timesteps)
print "\tgrid: %s topology: %s" % (configsom.gridType, configsom.topologyType)
print "\twill select based on best score on %s" % testfile
print "\tbest of %d trials will be saved in %s" % (rounds, somresults)
print

print "Building Neighborhood Dictionary once...."
nRadius = startRadius
if nRadius < 1:
    nRadius = max(somRows, somCols) / 2
theNeighborDict = configsom.buildNeighborDict(nRadius)
print "Done."
#del mysom

for trial in range(rounds):
    mysom = SOM(topology=theTopology)
    mysom.resize(inputDim=dim, numRows=somRows,numCols=somCols)
    trainingDict = mysom.getDataset(trainingfile, startField=firstField)
    print "trial %d" % trial
    mysom.initializeWeights(trainingDict)
    mysom.train(trainingDict, timeSteps=timesteps, radius=startRadius, neighborDict=theNeighborDict)
    print "scoring data"
    scoreDict = mysom.getDataset(testfile, startField=firstField)
    currentScore = mysom.scoreData(scoreDict)
    print "trial score = %.3f" % currentScore
    if currentScore < bestScore:
        mysom.saveSOM(somresults)
        bestScore = currentScore

print "bestScore = %.3f" % bestScore
