# Cut the experiment session in small fragments
# Input: ../bin/data/records/{session}/body.csv and skeletok.csv
# Output: fragments/{fragment_number}.json and fragments/log.csv

import os
import numpy
import json

DELAY = 15
LENGTH = 30
OVERLAP = 0.719999
FREQUENCY = 60
MARGIN = 5


FREQUENCY = 60
CUTOFF_FREQUENCY = 10
buf_length = FREQUENCY / CUTOFF_FREQUENCY 

kernel = numpy.blackman(buf_length)
kernel_summ = numpy.sum(kernel)

to_filter = [
	9, 10, 11,	#r_shoulder
	12, 13, 14,	#r_elbow
	15, 16, 17,	#r_hand
	18, 19, 20,	#l_shoulder
	21, 22, 23,	#l_elbow
	24, 25, 26,	#l_hand
	27, 28, 29,	#r_hip
	30, 31, 32,	#r_knee
	36, 37, 38,	#r_foot
	39, 40, 41,	#l_hip
	42, 43, 44,	#l_knee
	48, 49, 50	#l_foot
]

buffers = [[0] * buf_length] * len(to_filter)

values = [0] * len(to_filter)
values2 = [0] * len(to_filter)

# emg filtering
CUTOFF_EMG_FREQUENCY = 6
buf_emg_length = FREQUENCY / CUTOFF_EMG_FREQUENCY 
kernel_emg = numpy.blackman(buf_emg_length)
kernel_emg_summ = numpy.sum(kernel_emg)

emg2_buffer = [0] * buf_emg_length

# acc filtering
CUTOFF_ACC_FREQUENCY = 10
buf_acc_length = FREQUENCY / CUTOFF_ACC_FREQUENCY 
kernel_acc = numpy.blackman(buf_acc_length)
kernel_acc_summ = numpy.sum(kernel_acc)

acc_buffer = [[0] * buf_acc_length] * 3


# clean the folder
for f in os.listdir("fragments"):
	os.remove(os.path.join('fragments', f))


# cut fragments
record_counter = 0

def cut_fragment(participant, track_number):
	global record_counter
	global values
	global values2
	global buffers
	global emg2_buffer
	global acc_buffer

	print "Cut participant " + participant + ", track " + str(track_number)

	result_data = {
		'acc1': [],
		'acc2': [],
		'acc2_nf': [],
		'emg1': [],
		'emg2': [],
		'emg2_nf': [],
		'skeleton': [],
		'skeleton_nf': [],
	}

	path = "../bin/data/records/"
	for rec in os.listdir(path):
		if rec.split(' ')[0] == participant:
			with open(path + rec + "/body.csv", 'r') as f_read_body:
				with open(path + rec + "/skeleton.csv", 'r') as f_read_skeleton:
					i = 0
					while i < (DELAY + (OVERLAP + LENGTH) * (track_number + 1) - MARGIN) * FREQUENCY:

						line_body = f_read_body.readline().strip().split('\t')
						line_skeleton = f_read_skeleton.readline().strip().split('\t')
						
						values3 = [0] * len(to_filter)

						if i >= (DELAY + OVERLAP + (OVERLAP + LENGTH) * track_number) * FREQUENCY:
							values = [float(line_skeleton[j]) for j in to_filter]

							for j in range(2, len(values), 3):
								if values[j] > 1.4:
									values2[j - 2] = values[j - 2]
									values2[j - 1] = values[j - 1]
									values2[j] = values[j]

							for j in range(len(values)):
								buffers[j].append(values2[j])
								buffers[j] = buffers[j][1:]

								for k in range(buf_length):
									values3[j] += buffers[j][k] * kernel[k]

								values3[j] /= kernel_summ

							#emg filtering
							emg2 = float(line_body[7])
							emg2_nf = emg2 
							emg2_buffer.append(emg2)
							emg2_buffer = emg2_buffer[1:]
							emg2 = 0

							for k in range(buf_emg_length):
								emg2 += emg2_buffer[k] * kernel_emg[k]
							emg2 /= kernel_emg_summ

							line_body[7] = str(emg2)

							#acc filtering
							acc_values = [float(v) for v in line_body[3:6]]
							for j in range(3):
								v  = float(line_body[3 + j])

								acc_buffer[j].append(v)
								acc_buffer[j] = acc_buffer[j][1:]

								v2 = 0

								for k in range(buf_acc_length):
									v2 += acc_buffer[j][k] * kernel_acc[k]

								v2 /= kernel_acc_summ

								line_body[j + 3] = str(v2)


						if i >= (DELAY + OVERLAP + (OVERLAP + LENGTH) * track_number + MARGIN) * FREQUENCY:
							result_data['acc1'].append([float(v) - 512 for v in line_body[0:3]])
							result_data['acc2'].append([float(v) - 512 for v in line_body[3:6]])
							result_data['acc2_nf'].append(acc_values)
							result_data['emg1'].append(float(line_body[6]))
							result_data['emg2'].append(float(line_body[7]))
							result_data['emg2_nf'].append(emg2_nf)
							result_data['skeleton'].append({
								'r_shoulder': values3[0:3],
								'r_elbow': values3[3:6],
								'r_hand': values3[6:9],
								'l_shoulder': values3[9:12],
								'l_elbow': values3[12:15],
								'l_hand': values3[15:18],
								'r_hip': values3[18:21],
								'r_knee': values3[21:24],
								'r_foot': values3[24:27],
								'l_hip': values3[27:30],
								'l_knee': values3[30:33],
								'l_foot': values3[33:36]
							})
							result_data['skeleton_nf'].append({
								'r_shoulder': values[0:3],
								'r_elbow': values[3:6],
								'r_hand': values[6:9],
								'l_shoulder': values[9:12],
								'l_elbow': values[12:15],
								'l_hand': values[15:18],
								'r_hip': values[18:21],
								'r_knee': values[21:24],
								'r_foot': values[24:27],
								'l_hip': values[27:30],
								'l_knee': values[30:33],
								'l_foot': values[33:36]
							})

						i += 1

					with open('fragments/' + str(record_counter) + '.json', "w") as f_write:
						json.dump(result_data, f_write)
			break
	else:
		print "Cannot find data for participant ", participant, "\n"
		return None

	record_counter += 1
	return record_counter - 1

with open('selftest/results.txt', 'r') as f:
	with open('fragments/log.csv', 'w') as log:
		log.write('Participant\tTrack number\tTrack order\tValence\tArousal\tFragment\n')

		participant = -1
		track_number = 0
		for line in f:
			ar = line.strip().split(' ');

			if ar[0] != participant:
				track_number = 0
				participant = ar[0]

			track_real_number = ar[1]
			valence = ar[2]
			arousal = ar[3]

			record = cut_fragment(participant, track_number)
			log.write(participant + '\t' + track_real_number + '\t' + str(track_number) + '\t' + valence + '\t' + arousal + '\t' + str(record) + '\n')

			track_number += 1

			#break
