import os
import matplotlib.pyplot as plt
import pandas as pd
import swat   # SAS Viya Python interface

%matplotlib inline

"""
Explanation: Import required packages
End of explanation
"""


DATA_URL = 'https://ti.arc.nasa.gov/m/project/prognostic-repository/Challenge_Data.zip'
DATA_DIR = '.'

train_tsv = os.path.join(DATA_DIR, 'train.txt')
test_tsv = os.path.join(DATA_DIR, 'test.txt')

if not os.path.isfile(train_tsv) or not os.path.isfile(test_tsv):
    import zipfile
    from six.moves import urllib
    try:
        filename, headers = urllib.request.urlretrieve(DATA_URL)
        with zipfile.ZipFile(filename, 'r') as data_zip:
            data_zip.extract('train.txt', DATA_DIR)
            data_zip.extract('test.txt', DATA_DIR)
    finally:
        urllib.request.urlcleanup()

"""
Explanation: Download and Prep NASA's Turbofan Engine Degradation Simulation (PHM08 Challenge) Data Set
End of explanation
"""


# Create list of x1-x24
x = ['x%s' % i for i in range(1, 25)]

df = pd.read_table(train_tsv, delim_whitespace=True, names=['engine', 'cycle'] + x)
df.head()

"""
Explanation: Read training data into a DataFrame.
End of explanation
"""


train = df[df['engine'].isin([7, 28, 32, 38, 40, 51, 65, 84, 90, 95, 99, 107, 
                              120, 124, 135, 137, 138, 148, 151, 160, 166, 178,
                              182, 188, 197, 199, 200, 207, 210, 211])]

# Keep first 50 observations per engine to train SVDD 
train = train[train['cycle'] <= 50]
train['index'] = train.index

train.tail()

"""
Explanation: Create training data with 30 random engines
End of explanation
"""


df = pd.read_table('test.txt', delim_whitespace=True, names=['engine', 'cycle'] + x)

# create a scoring data set with 9 random engines from the test data set
df['index'] = df.index
score = df[df['engine'].isin([1, 8, 22, 53, 63, 86, 102, 158, 170, 202])]
score.tail()

"""
Explanation: Read test data into a DataFrame.
End of explanation
"""


s = swat.CAS('localhost', 5570)

"""
Explanation: Connect to SAS Viya CAS Engine
End of explanation
"""


train_tbl = s.upload_frame(train, casout=dict(name='train', replace=True))
score_tbl = s.upload_frame(score, casout=dict(name='score', replace=True))

"""
Explanation: Load  pandas DataFrames into CAS
End of explanation
"""


s.tableinfo()

"""
Explanation: Check details of loaded tables.
End of explanation
"""


s.loadactionset('svdd')

"""
Explanation: Import SVDD action set
End of explanation
"""


# Run svdd.svddTrain action set on training data
ysvdd_state = s.CASTable('ysvddstate', replace=True)
state_s = s.CASTable('state_s', replace=True)

train_tbl.svdd.svddtrain(gauss=11,
                         solver='actset',
                         inputs=x,
                         savestate=ysvdd_state,
                         output=dict(casout=state_s),
                         id='index')

sv = state_s.to_frame()
sv

"""
Explanation: Create SVDD model for training data
End of explanation
"""


# Load astore action set
s.loadactionset('astore')

# Score resulting SVDD astore (ysvddstate) against the scoring data (score) and output results (svddscored)
svdd_scored = s.CASTable('svddscored', replace=True)
score_tbl.astore.score(rstore=ysvdd_state, out=svdd_scored)

# Create local dataframe of scored data to plot using Matplotlib
output = svdd_scored.to_frame()
output.head()

# Add SVDD scored values to original score DataFrame for plotting purposes
df = score.merge(output, how='left')
df.head()

df = df.loc[df['engine'] < 150]
for index, group in df.groupby('engine'):
    group.plot(x='cycle', y='_SVDDDISTANCE_', title=index, label='engine', figsize=(15, 4))

plt.show()

"""
Explanation: Score SVDD astore against scoring data
End of explanation
"""


# Download SVDD astore for use in SAS Event Stream Processing (ESP)
results = s.astore.download(rstore=ysvdd_state)

# Check details of loaded data
s.tableinfo()

"""
Explanation: Save SVDD astore for use in SAS Event Stream Processing
End of explanation
"""


