#!/usr/bin/env python
from svmprob import read_svm, getarg
from rndForest import findminmax
from sys import argv
from os import system, path, rename
from string import atof, join
from math import sqrt

if len(argv) < 3:
	print """Usage:
	%s [-couplers {ht,pkpd,markov,*minpair,vote,ass}]
	[-s rndseed][-cv full_fold] <train_file> <testing_file>
	this program will automatically determine mtry""" % argv[0]
	raise SystemExit
train_pathname = argv[-2]
test_pathname = argv[-1]
log_pathname = path.split(train_pathname)[1] + '-cvrf'
root_path = path.split(argv[0])[0]
couplers_list = getarg('-couplers','minpair').split(',')
rndseed = int(getarg('-s', 0))
full_cv_folds = int(getarg('-cv', 5))

#cleanup last log
cmd = 'mv %s %s-last >& /dev/null; rm -f %s.*' % ((log_pathname,)*3)
system(cmd)

#determine mtry(s) candidates
# default:
# 	max(floor(ncol(x)/3), 1), floor(sqrt(ncol(x))))
# search space:
#	floor(c(1, sqrt(p), p/3, p/2, p))   
train_x, train_y = read_svm(argv[-2])
test_x,test_y = read_svm(argv[-1])
mM = findminmax(train_x + test_x)
n_attr = mM[1] - mM[0] + 1

last = -1
for mtry in (1, int(sqrt(n_attr)), n_attr/3, n_attr/2, n_attr):
	if mtry == last:  #avoid repetition on same mtry
		continue
	cverr = 0
	cmd = "%s/multiprob.py -couplers %s -base %s -cv %d -logfile %s -seed %d -mtry %d %s" % \
	(root_path, join(couplers_list, ','), 'rf', full_cv_folds, log_pathname+'.@host', rndseed, mtry, train_pathname)
	print "Cross validation...[%s]" % cmd
	system(cmd)
		
#merge data xxx.hostname -> xxx
cmd = 'cat %s.* > %s ; rm %s.*' % ((log_pathname,)*3)
print "mergin files:", cmd
system(cmd)

def sign(x):
	if x==0.0:
		return 0
	elif x>0:
		return 1
	else:
		return -1 
def cmpfun(x, y):
	#mtry, accuracy, mse, logloss, method
	mtry_x, ax, sx, lx, mx = x.split()[0:5]
	mtry_y, ay, sy, lx, my = y.split()[0:5]
	if mx!=my:		#methods ordered as listed
		return couplers_list.index(mx) - couplers_list.index(my)
	elif ax!=ay:	#accuracy larger, first
		return sign(atof(ay) - atof(ax))
	else:			#mtry larger, fisrt
		return sign(atof(mtry_y) - atof(mtry_x))
orderlog = open(log_pathname).readlines()
orderlog.sort(cmpfun)

#test with selection parameter
counter = 0
for coupler in couplers_list:
	while orderlog[counter].find(coupler) == -1:
		counter = counter + 1
	mtry= int(orderlog[counter].split()[0])
	print 'Best (mtry) for ', coupler, mtry
	cmd = "%s/multiprob.py -couplers %s -base %s -logfile %s -seed %d -mtry %d -T %s %s" % \
		(root_path, coupler, 'rf', log_pathname+'-test', rndseed,  mtry, test_pathname, train_pathname)
	print 'Testing [%s]:' % cmd
	system(cmd)
