# This script is for analyzing the editing events. 
# After editing the SWC file, the editing events are stored in ~/.neutube.z/log.txt
# run this program immediately after the editing is done. 
# Commond:
# 	To analyze log.txt at the default directory, ~/.neutube.z/log.txt, use
#		python analyzeNEO.py
#	To analyze another log.txt file, do 
#		python analyzeNEO.py dirName/log.txt
#

#---Analyze log file----
#
#	Analyze log file from ShuTu software for number of operation in tracing neuron. 
#	logFilename is where the logs are stored.	
#		startDate ='2016-06-07'	# start time. keep this format, year-month-day
#		startTime ='17:43:00'	# start time. keep this format, hour:minute:second
#		endDate ='2016-06-07'	# end time. keep this format, year-month-day
#		endTime ='18:08:00'		# end time. keep this format, hour:minute:second
#	If the start date and time are not specified, the last session in the log file is analyzed. 

import datetime
import time
import pylab as plt
import os, os.path, glob, re, fnmatch, sys
from numpy import *

def analyzeLogFile(logFilename,startDate='',startTime='',endDate='',endTime=''):
	logFilename = os.path.expanduser(logFilename)
	print 'reading activity log from ', logFilename
	# parameters
	dt = 0.1 # if time between consecutive same actions smaller than this time the are the same action (this is how the log file is generated.
	ts = -1
	tend = sys.maxint
	if len(startDate) > 0 and len(startTime) > 0 and len(endDate) > 0 and len(endTime) > 0:
		iuseStartEndTime = 1
		print 'Analyzing log from ',startDate,startTime,' to ',endDate,endTime
		x = time.strptime(startDate+'T'+startTime,'%Y-%m-%dT%H:%M:%S')
		ts = time.mktime(x)
		x = time.strptime(endDate+'T'+endTime,'%Y-%m-%dT%H:%M:%S')
		tend = time.mktime(x)
	
	editT = []
	editAct = []
	editActUnique = []
	editActC = []
	
	# parse the log file.
	tt = -1
	t0 = -1
	previousAct = ''
	fileana = ''	
	fpt = open(logFilename,'r')
	timeAutoSave = 0;
	fflag = 0
	tt0 = 0
	for line in fpt:
		if line.find('INFO  ') == -1:
			continue

		timestr = line[6:6+19]
		x = time.strptime(timestr,'%Y-%m-%dT%H:%M:%S')
		t = time.mktime(x)
		if ts == -1:
			ts = t
	
		# keep track of autosave times for taking out the idle times. 
		if line.find('Autosave triggered') != -1 and (t >= ts or t <= tend):
			if fflag == 0:
				fflag = 1
			else:
				timeAutoSave += t - tt0
			tt0 = t
			continue
		else:
			fflag = 0			
						
		iid = line.find('"')
		if iid == -1:
			continue			
		if t < ts or t > tend:
			continue
		
		actstr=line[iid+1:-3]
		if actstr.find('Start reconstruction:') == 0:
			t0 = t
			fileana = actstr[30:-3]
			print 'Analyzing reconstruction of neuron in ',fileana
			print 'startTime = ',t
			timeAutoSave = 0
			editT = []
			editAct = []
			editActUnique = []
			editActC = []
		if t0 == -1:
			continue	
		if t - tt <= dt and previousAct == actstr:
			continue
		else:	
			tt = t
			previousAct = actstr			
		editT.append(t-t0)
		editAct.append(actstr)
	fpt.close()

	# get unique actions and the counts. 
	editActUnique = []
	editActCounts = []
	for i in range(len(editAct)):
		aa = editAct[i]
		flag = 0
		for k in range(len(editActUnique)):
			bb = editActUnique[k]
			if aa == bb:
				editActCounts[k] += 1
				flag = 1
				break;
		if flag == 0:
			editActUnique.append(aa)
			editActCounts.append(1)
	editActCounts = array(editActCounts)		
	sind = argsort(editActCounts)[::-1]					

	# output the results. 		
	print 'Total number of edits: ',len(editAct)
	mm = (editT[-1] - timeAutoSave)/60.0	# time between autosaves are typically idle times. Remove them.
	hh = (editT[-1] - timeAutoSave)/3600.0
	print 'Total time: ',mm,' minutes or ',hh,' hours.'
	print 'List of actions (counts, action):'
	for iid in sind:
		print '  ',editActCounts[iid],'	',editActUnique[iid]
		
	# plot the tally
	plt.figure(11); plt.clf()
	ys = [10,9,8,7,6,5,4,3,2,1]
	ainds = list(sind[0:len(ys)])
	xs = editActCounts[ainds]
	plt.barh(ys,xs,align='center',height=0.3,color='green')
	for i in range(len(ys)):
		plt.text(0,ys[i]+0.25,editActUnique[ainds[i]])
		plt.text(-2,ys[i]-0.15,editActCounts[ainds[i]],horizontalalignment='right') 
	plt.text(-2,0,sum(editActCounts),horizontalalignment='right')
	plt.text(0,0,'= Total number of edits.')
	plt.text(-2,-1,"{:4.2f}".format(hh),horizontalalignment='right')
	plt.text(0,-1,'= Estimated manual time (hours).')
	
	plt.axis('off')
	plt.show()


if len(sys.argv) > 1:
	logFilename = sys.argv[1]
else:
	logFilename = '~/.neutube.z/log.txt'	

analyzeLogFile(logFilename)

