"""
Created on Tue Jul  7 18:40:37 CEST 2015

@author: Elena Cuoco
simple starting script, without the use of MNE
Thanks to @author: alexandrebarachant for his wornderful starting script


"""

import numpy as np
import pandas as pd
from scipy.signal import butter, lfilter, boxcar
from numpy import convolve
from sklearn.linear_model import LogisticRegression
from glob import glob
from joblib import delayed, Parallel
import os
from sklearn.lda import LDA
from sklearn.preprocessing import StandardScaler

#############function to read data###########

def prepare_data_train(fname):
    """ read and prepare training data """
    # Read data
    data = pd.read_csv(fname)
    # events file
    events_fname = fname.replace('_data','_events')
    # read event file
    labels= pd.read_csv(events_fname)
    clean=data.drop(['id' ], axis=1)#remove id
    labels=labels.drop(['id' ], axis=1)#remove id
    return  clean,labels

def butterworth_filter(X,t,k,l):
    if t==0:
        freq=[k, l]
        b,a = butter(5,np.array(freq)/250.0,btype='bandpass')
        X = lfilter(b,a,X)
    elif t==1:
        b,a = butter(5,k/250.0,btype='lowpass')
        X = lfilter(b,a,X)
    elif t==2:
        b,a = butter(5,l/250.0,btype='highpass')
        X = lfilter(b,a,X)
    return X

def prepare_data_test(fname):
    """ read and prepare test data """
    # Read data
    data = pd.read_csv(fname)
    return data


def data_preprocess_train(X):
    X_prep_normal = scaler.fit_transform(X)
    X_prep_low = np.zeros((np.shape(X_prep_normal)[0],10))
    for i in range(10):
        X_prep_low[:,i] = butterworth_filter(X[:,0],1,2-(i*0.2),3)
        X_prep_low[:,i] = scaler.fit_transform(X_prep_low[:,i])
    X_prep_low_pow = X_prep_low ** 2
    X_prep_low_pow = np.array(Parallel(n_jobs=-1)(delayed(convolve)(s,boxcar(nwin),'full') for s in X_prep_low_pow.T)).T
    X_prep_low_pow = X_prep_low_pow[0:X_prep_low.shape[0],:]
    X_prep = np.concatenate((X_prep_low,X_prep_normal,X_prep_low_pow),axis=1)
    #do here your preprocessing
    return X_prep

def data_preprocess_test(X):
    X_prep_normal = scaler.fit_transform(X)
    X_prep_low = np.zeros((np.shape(X_prep_normal)[0],10))
    for i in range(10):
        X_prep_low[:,i] = butterworth_filter(X[:,0],1,2-(i*0.2),3)
        X_prep_low[:,i] = scaler.fit_transform(X_prep_low[:,i])
    X_prep_low_pow = X_prep_low ** 2
    X_prep_low_pow = np.array(Parallel(n_jobs=-1)(delayed(convolve)(s,boxcar(nwin),'full') for s in X_prep_low_pow.T)).T
    X_prep_low_pow = X_prep_low_pow[0:X_prep_low.shape[0],:]
    X_prep = np.concatenate((X_prep_low,X_prep_normal,X_prep_low_pow),axis=1)
    return X_prep

if __name__ == '__main__':
    nwin = 10
    scaler= StandardScaler()
    # training subsample.if you want to downsample the training data
    subsample = 100
    #######columns name for labels#############
    cols = ['HandStart','FirstDigitTouch',
            'BothStartLoadPhase','LiftOff',
            'Replace','BothReleased']




    #######number of subjects###############
    subjects = range(1,13)
    ids_tot = []
    pred_tot = []

    ###loop on subjects and 8 series for train data + 2 series for test data
    for subject in subjects:
        y_raw= []
        raw = []
        ################ READ DATA ################################################
        fnames =  glob('../input/train/subj%d_series*_data.csv' % (subject))
        for fname in fnames:
          data,labels=prepare_data_train(fname)
          raw.append(data)
          y_raw.append(labels)

        X = pd.concat(raw)
        y = pd.concat(y_raw)
        #transform in numpy array
        #transform train data in numpy array
        X_train =np.asarray(X.astype(float))
        y = np.asarray(y.astype(float))


        ################ Read test data #####################################
        #
        fnames =  glob('../input/test/subj%d_series*_data.csv' % (subject))
        test = []
        idx=[]
        for fname in fnames:
          data=prepare_data_test(fname)
          test.append(data)
          idx.append(np.array(data['id']))
        X_test= pd.concat(test)
        ids=np.concatenate(idx)
        ids_tot.append(ids)
        X_test=X_test.drop(['id' ], axis=1)#remove id
        #transform test data in numpy array
        X_test =np.asarray(X_test.astype(float))


        ################ Train classifiers ########################################
        lr = LDA()
        pred = np.empty((X_test.shape[0],6))
        X_train=data_preprocess_train(X_train)
        X_test=data_preprocess_test(X_test)
        for i in range(6):
            y_train= y[:,i]
            print('Train subject %d, class %s' % (subject, cols[i]))
            lr.fit(X_train[::subsample,:],y_train[::subsample])
            pred[:,i] = lr.predict_proba(X_test)[:,1]

        pred_tot.append(pred)

    # submission file
    submission_file = 'grasp-sub-simple.csv'
    # create pandas object for sbmission
    submission = pd.DataFrame(index=np.concatenate(ids_tot),
                              columns=cols,
                              data=np.concatenate(pred_tot))

    # write file
    submission.to_csv(submission_file,index_label='id',float_format='%.3f')