import fileinput
import math
import collections
import time
import numpy as np
from pylab import *
from matplotlib import pyplot as plt
import matplotlib.mlab as mlab

#file_path = '/media/ABB4-4F3A/DATALOG.TXT'
file_path = 'DATALOG.TXT'

def split_in_blocks(txt_file, pattern):
	'''
	Find the last appears of the text that indicate a new flight and divide in the number of blocks generated by the rocket
	Return: A list that contains all the different blocks of data and a list containing the header.
	'''
	num_times_find_pattern = []
	for num_line, line in enumerate(fileinput.input(txt_file)):
		if pattern in line:
			num_times_find_pattern.append(num_line)
		if num_line == 0:
			header = list(line.strip().split(","))
			#print header
	blocks_of_data = []
	with open(txt_file) as f:
		lines = f.readlines()
		for num_header_line in num_times_find_pattern:
			if num_header_line == 0:
				num_header_line_prev = num_header_line
			else:
				block_lines = lines[num_header_line_prev + 1 : num_header_line - 1]
				blocks_of_data.append(block_lines)
				num_header_line_prev = num_header_line
		block_lines = lines[num_header_line_prev + 1 : num_line + 1]
		blocks_of_data.append(block_lines)
	return blocks_of_data, header

def manage_data_from_blocks(blocks, header):
	'''
	Divide al the text in blocks tagged with their type of data (accelaration, temperature, ...) continued by a number of block
	Return: A dict that contains all the different types of data diferentiated and numbered.
	'''
	# TODO: Automatize this function to accept more headers!!
	blocks_dict = collections.OrderedDict()
	for block_number, block in enumerate(blocks):
		for item in header:
			blocks_dict['%s%s' % (item,block_number)] = []
		for line in block:
			line_list = line.strip().split(",")
			blocks_dict['f%s' % block_number].append(int(line_list[0]))
			blocks_dict['ax%s' % block_number].append(float(line_list[1]))
			blocks_dict['ay%s' % block_number].append(float(line_list[2]))
			blocks_dict['az%s' % block_number].append(float(line_list[3]))
			blocks_dict['gx%s' % block_number].append(float(line_list[4]))
			blocks_dict['gy%s' % block_number].append(float(line_list[5]))
			blocks_dict['gz%s' % block_number].append(float(line_list[6]))
			blocks_dict['mx%s' % block_number].append(float(line_list[7]))
			blocks_dict['my%s' % block_number].append(float(line_list[8]))
			blocks_dict['mz%s' % block_number].append(float(line_list[9]))
			blocks_dict['t%s' % block_number].append(float(line_list[10]))
			blocks_dict['p%s' % block_number].append(int(line_list[11]))
			blocks_dict['h%s' % block_number].append(float(line_list[12]))
	return blocks_dict

def process_data(blocks_dict, header):
	block_list_header_based = []
	for num, item in enumerate(header):
		block_list_header_based.append([])
		for block in blocks_dict:
			if block.startswith(header[num]):
				block_list_header_based[num].append(block)
				# DEBUG! print "%s: %s" % (block, blocks_dict[block])
	print block_list_header_based
	#fingerprint_basic_info = basic_process_only_for_fingerprints(block_list_header_based[0])
	temp_basic_info = basic_process_data(block_list_header_based[12])
	#height_basic_info = basic_process_data(block_list_header_based[12])

	print_basic_histograms(block_list_header_based[12])
	print_basic_scatters(block_list_header_based[12])
	print_basic_evolution_2_axis(block_list_header_based[0], block_list_header_based[12])

def basic_process_only_for_fingerprints(fingerprints):
	fingerprint_basic_info = collections.OrderedDict()
	fingerprint_list = []
	for num, fingerprint_block in enumerate(fingerprints):
		millis_interval_list = []
		for position, millis in enumerate(blocks_dict[fingerprint_block]):
		 	if position != 0:
		 		millis_interval = millis - millis_prev
		 		millis_interval_list.append(millis_interval)
		 	millis_prev = millis
		blocks_dict["fp%s" % (num)] = millis_interval_list
		fingerprint_list.append("fp%s" % (num))
	fingerprint_basic_info = basic_process_data(fingerprint_list)
	return fingerprint_basic_info

def basic_process_data(data_list):
	data_basic_info = collections.OrderedDict()
	for data_block in data_list:
		data_basic_info[data_block] = {}
		data_avg_mean = np.mean(blocks_dict[data_block])		# Average
		data_avg_weighted = np.average(blocks_dict[data_block])	# Average weighted
		data_amax = np.amax(blocks_dict[data_block])			# MAX
		data_amin = np.amin(blocks_dict[data_block])			# MIN
		data_med = np.median(blocks_dict[data_block])			# Median
		data_std = np.std(blocks_dict[data_block])				# Standard deviation
		data_ptp = np.ptp(blocks_dict[data_block])				# Distance MAX to MIN
		data_var = np.var(blocks_dict[data_block])				# Variance
		data_basic_info[data_block] = {"AVM" : "%.3f" % data_avg_mean, "AVW" : "%.3f" % data_avg_weighted, "MAX" : "%.3f" % data_amax,
										"MIN" : "%.3f" % data_amin, "MED" : "%.3f" % data_med, "STD" : "%.3f" % data_std,
										"PTP" : "%.3f" % data_ptp, "VAR" : "%.3f" % data_var}
		# PLOT NORMAL PDF FROM THA DATA
		#sigma = sqrt(data_var)
		#x = np.linspace(data_amin,data_amax)
		#plt.plot(x,mlab.normpdf(x,data_avg_mean,sigma))

		plt.show()
	for key in data_basic_info:
		print data_basic_info[key]
	return data_basic_info

def print_basic_histograms(data_list):
	#plt.ion()
	plt.figure(1)
	for num, data in enumerate(data_list):
		nrows = int(math.ceil(float(len(data_list) / 3.0)))
		ncols = 3
		subplot_index = "%s%s%s" % (nrows, ncols, num + 1)
		plt.subplot(subplot_index)
		plt.hist(blocks_dict[data], bins=20)
		#data_new = np.histogramdd(blocks_dict[data])
		#plt.hist(data_new, bins=20)
		plt.xlabel("Value", fontsize=8)
		plt.ylabel("Frequency", fontsize=8)
	plt.suptitle("Gaussian Histogram", fontsize=12)
	plt.show()
	#plt.show(block=True)

def print_basic_scatters(data_list):
	#plt.ion()
	plt.figure(1)
	for num, data in enumerate(data_list):
		nrows = int(math.ceil(float(len(data_list) / 3.0)))
		ncols = 3
		subplot_index = "%s%s%s" % (nrows, ncols, num + 1)
		plt.subplot(subplot_index)
		plt.scatter(np.random.randn(1000), np.random.randn(1000))
	plt.suptitle("Gaussian Histogram", fontsize=12)
	plt.show()
	#plt.show(block=True)

def print_basic_evolution_2_axis(x_axis_data_list, y_axis_data_list):
	plt.figure(1)
	for num in range(len(x_axis_data_list)):
		x = blocks_dict[x_axis_data_list[num]]
		y = blocks_dict[y_axis_data_list[num]]
		#subplot(nrows, ncols, plot_number)
		nrows = int(math.ceil(float(len(x_axis_data_list) / 3.0)))
		ncols = 3
		subplot_index = "%s%s%s" % (nrows, ncols, num + 1)
		plt.subplot(subplot_index)

		plt.plot(x, y, linewidth=1.0, color="green")
		xlabel('time (milliseconds)', fontsize = 8)
		#ylabel('temperature (C)', fontsize = 8)
		#title('', fontsize=10)
		grid(True)
		plt.xticks(blocks_dict[x_axis_data_list[num]][::len(blocks_dict[x_axis_data_list[num]])/10], rotation=30, fontsize=8)
		#plt.annotate('Despegue', xy=(2200, 34.82), xytext=(2300, 34.88),
		#		bbox=dict(boxstyle="round", fc="0.8"),
	    #        arrowprops=dict(facecolor='black', shrink=0.05),
	    #        )
		#plt.annotate('Paracaidas', xy=(7200, 34.82), xytext=(6300, 34.88),
	    #        arrowprops=dict(facecolor='black', shrink=0.05),
	    #        )
		#axvline(x=2200)
		#axhspan(34.80, 34.82, facecolor='0.5', alpha=0.5, color="red")
		plt.ylim(min(blocks_dict[y_axis_data_list[num]]) - 0.02, max(blocks_dict[y_axis_data_list[num]]) + 0.02)
		plt.yticks(fontsize=8)
	#plt.suptitle('temperatures in data', fontsize=12)
	plt.show()

#start = time.time()
blocks, header = split_in_blocks(file_path, "m")
blocks_dict = manage_data_from_blocks(blocks, header)
process_data(blocks_dict, header)

#stop = time.time()
#total_time = stop -start
#print total_time