#! python

import re
import sys
import math
import numpy

from gmisclib import dictops

import pylab

sys.path.insert(0, '.')
import cross_eval




def read_and_split_per_ltN(root):
	per_lt = {}
	dlist = cross_eval.read_models(root)
	for d in dlist:
		key = (d['lbl'], d['target'])
		if key not in per_lt:
			per_lt[key] = dictops.dict_of_lists()
		per_lt[key].add(int(d['N']), d)
	return per_lt


def std(x):
	n = len(x)
	return numpy.std(x)*math.sqrt(float(n)/float(n-1))

Tname = {'ldur': '   Ldur', 'fdur': '   Fdur', 'lskew': 'Lskew',
		'duration': r' $\log(\Delta )$', 'complex_dur': '  dSdt'
	}

def fmt(lt):
	lts = re.sub(r'\^', '!', lt[0]).split(',')
	n = len(lts)
	assert n%2 == 1
	n = n//2
	s = r"%s,$\mathit{%s}$,%s" % (','.join(lts[:n]), lts[n], ','.join(lts[n+1:]))
	return '%s  %s' % (s, Tname[lt[1]])


def twosort(x,y):
	ox = []
	oy = []
	for (xx, yy) in sorted(zip(x,y)):
		ox.append(xx)
		oy.append(yy)
	return (ox, oy)



def plot(per_ltN, ordering, linespec, markerspec, shift):
	if ordering is None:
		ordering = []
		for (lt,per_N) in per_ltN.items():
			vv = []
			for (n, datalist) in per_N.items():
				vv.append(float(numpy.mean([float(d['effect_size']) for d in datalist if 'effect_size' in d])))
			ordering.append((float(numpy.mean(vv)), lt))
		print 'ordering=', ordering
		ordering.sort()
	ordermap = dict([(lt,i) for (i,(v,lt)) in enumerate(ordering)])
	x = dictops.dict_of_lists()
	y = dictops.dict_of_lists()
	# xerr = []
	for (lt, per_N) in per_ltN.items():
		errs1l = [float(d['effect_size']) for d in per_N[1] if 'effect_size' in d and 'dof' in d and int(d['dof'])>40 ]
		errs7l = [float(d['effect_size']) for d in per_N[7] if 'effect_size' in d and 'dof' in d and int(d['dof'])>40 ]
		if len(errs1l)<= 15 or len(errs7l)<=15:
			continie
		errs1 = float(numpy.mean(errs1l))
		errs1s = std(errs1l)/math.sqrt(len(errs1l))
		errs7 = float(numpy.mean(errs7l))
		errs7s = std(errs7l)/math.sqrt(len(errs7l))
		if linespec:
			pylab.plot([errs1,errs7,], [ordermap[lt]+shift, ordermap[lt]+shift], linespec)
		if markerspec and (errs7-errs1) > 3*math.hypot(errs1s,errs7s):
			pylab.plot([errs1,errs7,], [ordermap[lt]+shift, ordermap[lt]+shift], markerspec)
		print 'for', lt, 'err7-err1=', errs7-errs1
	return ordering


def go():
	ordering = plot(read_and_split_per_ltN('.'), None, 'k--', 'ko', -0.1)
	plot(read_and_split_per_ltN('poetry'), ordering, 'g-', 'gs', 0.10)
	pylab.yticks([i for (i,(v,lt)) in enumerate(ordering)], [fmt(lt) for (v,lt) in ordering])
	pylab.xlabel("Pearson's $r^2$")
	pylab.xlim(-0.01, 0.8)
	pylab.ylim(-0.5, 30.5)
	# pylab.axis('tight')
	pylab.show()


if __name__ == '__main__':
	go()
