'''
Created on Mar 25, 2013

@author: gohew
'''
import os
from numpy import *
import sys
from com.signal.SignalProcessing import SignalClass

class SVMProblemGenerator:
    '''
    This Class formats the numpy array format into SVMLib compatible problem files. The labels and nodes are all automatically
    generated by iterating into the respective folders
    Default SVM Folders are:
        SVM_Running
        SVM_Slow
        SVM_Walk
    '''
    freq_scale = arange(0,150,1)
    precision = 0.5
    truncate = 66
    offset = 6
    period = 2
    path = ""
    def __init__(self,path):
        '''
        Constructor
        '''
        self.signal = SignalClass()
        self.title = "motion"
        self.path = path
    
    def setPath(self,dir):
        self.path = dir
    
    def loadRange(self,path):
        f = open(path)
        f.seek(6)
        ctr = 0
        i = 0
        min = [""]
        max = [""]
        for line in f:
            min.append("")
            max.append("")
            for letter in line:
                if letter == " ":
                    ctr = ctr + 1
                elif not letter =="\n":
                    if ctr == 1:
                        min[i] += letter
                    elif ctr == 2:
                        max[i] += letter
            i = i + 1
            ctr = 0
        return min, max
    def generate(self):                
        f = [open('/home/gohew/workspace/WM_Detection_Server/src/problem/' + self.title + "top", 'wb'),
             open('/home/gohew/workspace/WM_Detection_Server/src/problem/' + self.title + "mid", 'wb'),
             open('/home/gohew/workspace/WM_Detection_Server/src/problem/' + self.title + "bot", 'wb')]    
        class_ctr = [0,0,0]
        for j in range(0,3):
            f[j].seek(0)
            #Generate for Running Classification
            os.chdir(self.path + "/SVM_Running") 
            for files in os.listdir("."):
                if files.endswith("t.npy"):
                        print "t"
                else: 
                    data_arr, time_arr, data_ctr = self.openFile(str(files))
                    fourier_val, freq, rate = self.calcFFT(data_arr[j,:],time_arr[j,:])
                    fourier_ave = self.normalizeFreq(fourier_val,freq)
                    #y-Label
                    f[j].write("+1 ")
                    #x nodes
                    for i in range(0,fourier_ave.size): 
                        f[j].write(str(i + 1) + ":" + str(fourier_ave[0,i]) + " ")
                    f[j].write("\n")
                    if j == 0 :
                        class_ctr[0] = class_ctr[0] + 1
            #Generate for Running Classification    
            os.chdir(self.path + "/SVM_Slow")
            for files in os.listdir("."):
                if files.endswith("t.npy"):
                        print "t"
                else: 
                    data_arr, time_arr, data_ctr = self.openFile(str(files))
                    fourier_val, freq, rate = self.calcFFT(data_arr[j,:],time_arr[j,:])
                    fourier_ave = self.normalizeFreq(fourier_val,freq)
                    #y-Label
                    f[j].write("+2 ")
                    #x nodes
                    for i in range(0,fourier_ave.size): 
                        f[j].write(str(i + 1) + ":" + str(fourier_ave[0,i]) + " ")
                    f[j].write("\n")
                    if(j == 0):
                        class_ctr[1] = class_ctr[1] + 1
                        
            os.chdir(self.path + "/SVM_Walking")
            for files in os.listdir("."):
                if files.endswith("t.npy"):
                        print "t"
                else: 
                    data_arr, time_arr, data_ctr = self.openFile(str(files))
                    fourier_val, freq, rate = self.signal.calcFFT(data_arr[j,:],time_arr[j,:])
                    fourier_ave = self.normalizeFreq(fourier_val,freq)
                    #y-Label
                    f[j].write("+3 ")
                    #x nodes
                    for i in range(0,fourier_ave.size): 
                        f[j].write(str(i + 1) + ":" + str(fourier_ave[0,i]) + " ")
                    f[j].write("\n")
                    if(j == 0):
                        class_ctr[2] = class_ctr[2] + 1
            f[j].close()
        return class_ctr

    def setTitle(self,text):
        self.title = text
        
    def openFile(self,filename):
        #Open data number from page
        index = str(filename).find(".npy")
        data_in = load(str(filename))
        data_ctr = data_in.size/3
        #print filename[0:index] +"t.npy"
        time_arr = load(str(filename[0:index]) +"t.npy")
        return data_in,time_arr,data_ctr
    
    def normalizeScale(self, X, low=0, high=1,minX=0,maxX=1):
        #X = asanyarray(X)
        #minX = min(X)
        #maxX = max(X)
        # Normalize to [0...1].    
        X = X - minX
        X = X / (maxX - minX)
        # Scale to [low...high].
        X = X * (high-low)
        X = X + low
        return X
    
    def normalizeFreq(self,fourier_val,freq):
        fourier_ave = zeros((1,self.freq_scale.size))
        temp = list()
        j = 0
        m = 0
        while freq[m] < 0:
            m = m + 1
        while j < self.freq_scale.size and m < freq.size:
            if abs(freq[m] - self.freq_scale[j]) < 0.5:
                k = 0
                temp = list()
                while abs(freq[m+k] - self.freq_scale[j]) < self.precision:
                    # print str(freq.size) + " m " + str(m) + "k " + str(k)
                    temp.append(fourier_val[m + k])
                    k = k + 1
                    if  m + k > freq.size -1:
                        break
                #Find mean of range of values
                mean_val = 0
                '''
                print str(j) + ":"
                print temp
                '''
                for l in range(0,len(temp)):
                    mean_val = temp[l] + mean_val
                mean_val = mean_val/len(temp)
                fourier_ave[0,j] = mean_val
                m = m + k
            else:
                j = j + 1
        '''
            Reduce the number of features by taking samples of 2Hz intervals and truncating the range to 1 - 60
        '''
        fourier_final = zeros((1,(self.truncate - self.offset) / self.period))
        for i in range(self.offset,self.truncate):
            if(not i % self.period):
                fourier_final[0,i/2 - 5 ] = fourier_ave[0,i]
        return fourier_final

    '''
    *****************************************************
            Signal Processing Function definitions
    *****************************************************
    ''' 
    def calcFFT(self,_data_arr,_time_arr):
        
        #Calculate Sample spacing for DFT
        _data_ctr = _data_arr.size
        sample_rate = _time_arr[_data_ctr -1]/_data_ctr
        
        #Calculate Frequency bins with frequency shifting
        freq = fft.fftfreq(_data_ctr,sample_rate/1000)
        freq = fft.fftshift(freq)
            
        #Calculate Fourier Transform with Mean Normalization 
        u = mean(_data_arr)
        sigma = std(_data_arr)
        data_norm = copy(_data_arr) #To prevent original data array from being modified due to lists being mutable
        for i in range(0,_data_ctr) :
            data_norm[i] = (data_norm[i] - u)/sigma
        fourier_val = fft.fft(data_norm)
        fourier_val = fft.fftshift(fourier_val)
        fourier_val = abs(fourier_val)
    
        return (fourier_val,freq, sample_rate)
          
          
        