#!/usr/bin/env python

"""This computes centers for classes.
You give it a classified.fiat file on the argument list,
as obtained from *_classifier.py, and it
produces a list of files, class names, and the feature vector
at the center of each class.

To define the center, it takes the component-by-component
median of the feature vector, including only
data that are correctly classified.
"""


import math
import gpkavg
from gmisclib import gpkmisc
from gmisclib import Num
from gmisclib import die
from gmisclib import dictops
import q_classifier_r

CLIP = 0.15


def process(f):
	h, data, c = q_classifier_r.read_fiat(open(f, 'r'))
	lp = []
	nic = {}
	for datum in data:
		if datum['trueclass'] == datum['compclass']:
			lp.append( datum['V'].shape[0] )
			tc = datum['trueclass']
			dictops.add_doc(nic, tc, 1)
	n = int(math.ceil(gpkmisc.median(lp)))

	index = {}
	psa = {}
	for (cl, nicl) in nic.items():
		psa[cl] = Num.zeros( (n, nicl), Num.Float)
		index[cl] = 0

	for datum in data:
		if datum['trueclass'] == datum['compclass']:
			v = datum['V']
			ml = min( v.shape[0], n )
			tc = datum['trueclass']
			psa[tc][:n,index[tc]] = v[:n]
			index[tc] += 1
	o = {}
	for cl in nic.keys():
		acoef = Num.zeros((n,), Num.Float)
		vcoef = Num.zeros((n,), Num.Float)
		for j in range(n):
			thisAvg, thisVar = gpkavg.avg(psa[cl][j,:], None, CLIP)
			acoef[j] = thisAvg
			vcoef[j] = thisVar
		o[cl] = (acoef, vcoef)
	return o


def format(v):
	return ' '.join( [ '%f' % x for x in v ] )


if __name__ == '__main__':
	import sys
	arglist = sys.argv[1:]
	Var = False
	while arglist and arglist[0].startswith('-'):
		arg = arglist.pop(0)
		if arg == '--':
			break
		elif arg == '-var':
			Var = True
		elif arg == '-clip':
			CLIP = float(arglist.pop(0))
		else:
			die.die('Unrecognized flag: %s' % arg)

	for f in arglist:
		typ = process(f)
		for (cl, (acoef, vcoef)) in typ.items():
			if Var:
				print f, cl, format(vcoef)
			else:
				print f, cl, format(acoef)
