#! python

import sys
import math
import random
import read_results as RR
from gmisclib import dict_vector as DV
from gmisclib import dictops as DO
import pylab


def filter(data, n):
	for datum in data:
		if int(datum.get('dof', 0)) <= 0:
			continue
		if int(datum['significant'])==1 and int(datum['N'])==n:
			yield datum

def sign(x):
	if x >= 0:
		return 1
	return -1

MAXPASSES = 30


def fix_signs(dlist):
	targetfac = None
	predictorfac = None
	distfac = None
	ipass = 0
	while ipass < MAXPASSES:
		ntf = DV.dict_vector()
		npf = DV.dict_vector()
		ndf = DV.dict_vector()
		for d in dlist:
			target = d['target']
			tgt_std = math.sqrt(float(d['err'])/int(d['dof']))
			for k in d.keys():
				if k.startswith('I:'):
					i, dist, pred = k.split(':')
					x = float(d[k])/tgt_std
					if targetfac is not None:
						x *= targetfac[target]
					if predictorfac is not None:
						x *= predictorfac[pred]
					if distfac is not None:
						x *= distfac[dist]
					ntf.incr(target, x)
					npf.incr(pred, x)
					ndf.incr(dist, x)
		ttf = ntf.sign()
		ttfs = sign(ntf.sum())
		ttf *= ttfs
		tpf = npf.sign()
		tpfs = sign(npf.sum())
		tpf *= tpfs
		tdf = ndf.sign()
		tdf *= ttfs * tpfs
		diff = 0
		if targetfac is not None:
			print 'difft', ttf-targetfac
			diff += abs(ttf-targetfac).sum()
		if predictorfac is not None:
			print 'diffp', tpf-predictorfac
			diff += abs(tpf-predictorfac).sum()
		if distfac is not None:
			print 'diffd', tdf-distfac
			diff += abs(tdf-distfac).sum()
		if (targetfac is not None and predictorfac is not None and distfac is not None) and diff==0:
			break
		if random.random() < 0.5:
			targetfac = ttf
		if random.random() < 0.5:
			predictorfac = tpf
		if random.random() < 0.5:
			distfac = tdf
		ipass += 1
	return (targetfac, predictorfac, distfac)


def plot_d(targetfac, predictorfac, distfac, dlist):
	a = DO.dict_of_lists()
	for d in dlist:
		target = d['target']
		tgt_std = math.sqrt(float(d['err'])/int(d['dof']))
		for k in d.keys():
			if k.startswith('I:'):
				i, dist, pred = k.split(':')
				x = float(d[k])/tgt_std
				if targetfac is not None:
					x *= targetfac[target]
				if predictorfac is not None:
					x *= predictorfac[pred]
				# if distfac is not None:
					# x *= distfac[dist]
				a.add(dist, x)
	x = []
	posns = []
	for (k,v) in a.items():
		posns.append(int(k))
		x.append(v)

	pylab.boxplot(x, posns)
	pylab.axhline(0.0)
	pylab.show()


def plot_pred(targetfac, predictorfac, distfac, dlist):
	a = DO.dict_of_lists()
	for d in dlist:
		target = d['target']
		tgt_std = math.sqrt(float(d['err'])/int(d['dof']))
		for k in d.keys():
			if k.startswith('I:'):
				i, dist, pred = k.split(':')
				x = float(d[k])/tgt_std
				if targetfac is not None:
					x *= targetfac[target]
				# if predictorfac is not None:
					# x *= predictorfac[pred]
				if distfac is not None:
					x *= distfac[dist]
				a.add(pred, x)
	x = []
	posns = []
	for (i,(k,v)) in enumerate(a.items()):
		posns.append(i)
		print 'i=', i, 'k=', k
		x.append(v)

	pylab.boxplot(x, posns)
	pylab.axhline(0.0)
	pylab.show()


def plot_target(targetfac, predictorfac, distfac, dlist):
	a = DO.dict_of_lists()
	for d in dlist:
		target = d['target']
		tgt_std = math.sqrt(float(d['err'])/int(d['dof']))
		for k in d.keys():
			if k.startswith('I:'):
				i, dist, pred = k.split(':')
				x = float(d[k])/tgt_std
				# if targetfac is not None:
					# x *= targetfac[target]
				if predictorfac is not None:
					x *= predictorfac[pred]
				if distfac is not None:
					x *= distfac[dist]
				a.add(target, x)
	x = []
	posns = []
	for (i,(k,v)) in enumerate(a.items()):
		posns.append(i)
		print 'i=', i, 'k=', k
		x.append(v)

	pylab.boxplot(x, posns)
	pylab.axhline(0.0)
	pylab.show()


def process(flist, n):
	data = RR.read_many(flist)
	data = list(filter(data, n))
	tf, pf, df = fix_signs(data)
	print 'tf=', tf
	print 'pf=', pf
	print 'df=', df
	plot_d(tf, pf, df, data)
	plot_pred(tf, pf, df, data)
	plot_target(tf, pf, df, data)


if __name__ == '__main__':
	N = 7
	process(sys.argv[1:], N)

