import sys
import fire
import pandas as pd
from flask import request, Flask
import json
from sqlalchemy import create_engine
import pymysql
# from RedisConfig import RedisClient as rd

from sklearn.cluster import DBSCAN
from sklearn.cluster import AffinityPropagation
from sklearn import metrics

from QMS_Algorithms import *
from QMS_Visual import *
import warnings

from configparser import ConfigParser

warnings.filterwarnings('ignore')

config=ConfigParser()
config.read(r"/usr/local/server/TemporaryFiles/PythonQMSBI/configuration.ini")  #/usr/local/server/TemporaryFiles/PythonQMSBI/configuration.ini
#D:\siger-skf-atc4\Server\Apis\Bin\netcoreapp2.1\TemporaryFiles\PythonQMSBI\configuration.ini

global tarce_header
global detail_header

SQL_host = config.get('SQL','SQL_host')
SQL_port = config.getint('SQL','SQL_port')
SQL_username = config.get('SQL','SQL_username')
SQL_password = config.get('SQL','SQL_password')
SQL_db = config.get('SQL','SQL_db')
SQL_middle_db = config.get('SQL','SQL_middle_db')

trace_header = config.get('SQL','trace_header')
detail_header = config.get('SQL','detail_header')

def getControlLimits(Section_in, Product_in,conn_in):

        CLQueryStr = '''SELECT * FROM siger_qms_inspection_standard tb WHERE
        tb.sectionid in({SectionNum}) AND status = 1 AND
        tb.productid = {ProdID}'''.format(
            SectionNum = str(list(map(int,Section_in)))[1:-1],
            ProdID = '\'' + str(Product_in) + '\''
        )
        ControlLimits = pd.read_sql(CLQueryStr,con = conn_siger_middle)

        return ControlLimits


def DrawSQLData(Section_in, Product_in, Machine_in, start_t, end_t, conn_in):
    st = pd.to_datetime(start_t)

    et = pd.to_datetime(end_t)

    dayseq = pd.date_range(st,et,freq = 'D')

    table_tail =np.sort(pd.Series(dayseq).apply(lambda x: x.strftime('%Y%m')).unique())

    if len(table_tail) == 1:

        currQueryStr = '''SELECT a.ID,a.SN,a.SectionID,a.CreateTime,a.ProductID,a.Result,a.MachineID,b.ItemName,b.Value FROM 
        {TraceName} a , {DetailName} b WHERE 
        a.ID=b.TraceID  AND 
        a.SectionID in ({SectionNum}) AND 
        a.ProductID = {ProdID} AND
        a.CreateTime>{StartPoint} AND
        a.CreateTime<{EndPoint}
        ORDER BY a.CreateTime'''.format(
                TraceName = trace_header,
                DetailName = detail_header+table_tail[0],
                SectionNum = str(list(map(int,Section_in)))[1:-1],
                ProdID = '\'' + str(Product_in) + '\'',
                StartPoint = '\''+str(start_t)+'\'',
                EndPoint = '\''+str(end_t)+'\''
        )

        rawdata = pd.read_sql(currQueryStr,con = conn_in)

    else:
        rawdata = pd.DataFrame({})

        for i in range(len(table_tail)):
            currTablename = table_tail[i]
            currQueryStr = '''SELECT a.ID,a.SN,a.SectionID,a.CreateTime,a.ProductID,a.Result,a.MachineID,b.ItemName,b.Value FROM 
                {TraceName} a , {DetailName} b WHERE 
                a.ID=b.TraceID  AND 
                a.SectionID in ({SectionNum}) AND 
                a.ProductID = {ProdID}
                ORDER BY a.CreateTime'''.format(
                    TraceName = trace_header,
                    DetailName = detail_header+table_tail[i],
                    SectionNum = str(list(map(int,Section_in)))[1:-1],
                    ProdID = '\'' + str(Product_in) + '\'',
                    StartPoint = '\''+str(start_t)+'\'',
                    EndPoint = '\''+str(end_t)+'\'')

            currDF = pd.read_sql(currQueryStr,con = conn_in)

            rawdata = pd.concat([rawdata,currDF], ignore_index  = True)
    
    return rawdata


def DrawSQLCountData(Section_in, Product_in, Machine_in, start_t, end_t, conn_in):
    st = pd.to_datetime(start_t)

    et = pd.to_datetime(end_t)

    currQueryStr = '''SELECT a.ID,a.SN,a.SectionID,a.CreateTime,a.ProductID,a.MachineID,a.Result FROM 
        {TraceName} a WHERE 
        a.SectionID in ({SectionNum}) AND 
        a.ProductID = {ProdID} AND
        a.CreateTime>{StartPoint} AND
        a.CreateTime<{EndPoint}
        ORDER BY a.CreateTime'''.format(
                TraceName = trace_header,
                SectionNum = str(list(map(int,Section_in)))[1:-1],
                ProdID = '\'' + str(Product_in) + '\'',
                StartPoint = '\''+str(start_t)+'\'',
                EndPoint = '\''+str(end_t)+'\''
        )

    rawdata = pd.read_sql(currQueryStr,con = conn_in)

    return rawdata

def PivotData(data_in):
    data_in = data_in.sort_values(by = 'CreateTime')

    data_in['CreateTime'] = data_in.CreateTime.astype('datetime64')
    
    startT = data_in.CreateTime.min()
    endT = data_in.CreateTime.max()

    data_in = data_in.loc[data_in.CreateTime.ne(startT) & data_in.CreateTime.ne(endT)]

    CreateT = data_in.CreateTime.unique()

    dropped_data = data_in.loc[:,data_in.columns.isin(['ID', 'ItemName', 'Value'])]
    dropped_data = dropped_data.pivot(index = 'ID', columns = 'ItemName', values = 'Value')
    dropped_data['time'] = CreateT

    return dropped_data


def CorrUnpivot(df):
    corr_unpivot = pd.melt(df.reset_index(), id_vars='index')
    corr_unpivot.columns = ['x', 'y', 'value']    
    return(corr_unpivot)



conn_siger = create_engine("mysql+pymysql://{SQL_username}:{SQL_password}@{SQL_host}:{SQL_port}/{SQL_db}".format(
        SQL_username = SQL_username,SQL_password = SQL_password,
        SQL_host = SQL_host,SQL_port = SQL_port,SQL_db = SQL_db))

conn_siger_middle = create_engine("mysql+pymysql://{SQL_username}:{SQL_password}@{SQL_host}:{SQL_port}/{SQL_db}".format(
        SQL_username = SQL_username,SQL_password = SQL_password,
        SQL_host = SQL_host,SQL_port = SQL_port,SQL_db = SQL_middle_db))



def ActivatePlotControl(json_str_in):     
        kwargs = json_str_in
        
        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']        

        raw_data = DrawSQLData(currSection,currProduct,currMachine,currStart,currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        # redis.hash_hset('QMS_API_test', 'raw', str(raw_data))

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)

        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return

        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)      

        #ControlLimits = ControlLimits.loc[ControlLimits.inspection == 1]

        if (currFtr in ControlLimits.item_en.values) != True:
                print(json.dumps({'Activated':513, 'data':'Current itemname not in inspection.' + json.dumps(ControlLimits)}))
                return

        target_seq = filtered_data[currFtr].dropna()

        # redis.hash_hset('QMS_API_test', 'target_seq', str(target_seq))

        if len(filtered_data)<25:
                print(json.dumps({'Activated':512, 'data':'Too few records in data, it should be at least 25.'}))
                return

        currUCL = ControlLimits.loc[ControlLimits.item_en == currFtr].max_value.iloc[0]
        currLCL = ControlLimits.loc[ControlLimits.item_en == currFtr].min_value.iloc[0]

        currControlPlotArgs = CalcControlArgs(target_seq, currUCL, currLCL)
        
        # currFigname = 'Control Plot of ' + currFtr
        currFigname = '单测量值控制图'
        htmlScript = ControlPlot(target_seq,currControlPlotArgs,currFigname)
        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotMRControl(json_str_in):
        kwargs = json_str_in

        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']
        

        raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart, currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
                

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return
        
        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)

        #ControlLimits = ControlLimits.loc[ControlLimits.inspection == 1]

        if (currFtr in ControlLimits.item_en.values) != True:
                print(json.dumps({'Activated':513, 'data':'Current itemname not in inspection.'}))
                return


        target_seq = filtered_data[currFtr].dropna()
        
        if len(target_seq)<25:
                print(json.dumps({'Activated':512, 'data':'Too few records in data, it should be at least 25.'}))
                return

        currMR, currMRControlPlotArgs = CalcMRArgs(target_seq)
        
        currFigname = '移动极差控制图(MR)'

        htmlScript = ControlPlot(currMR,currMRControlPlotArgs,currFigname)

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return



def ActivatePlotXbarControl(json_str_in):

        kwargs = json_str_in

        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']
        currSize = kwargs['setChunkSize']
        
        if (int(currSize) <=2) | (int(currSize)>=10):
                print(json.dumps({'Activated':513, 'data':'Incorrect subgroup size, must be between 2 and 9.'}))
                return

        raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart, currEnd, conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        # redis.hash_hset('QMS_API_test', 'raw', str(raw_data))

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return

        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)

        #ControlLimits = ControlLimits.loc[ControlLimits.inspection == 1]

        if (currFtr in ControlLimits.item_en.values) != True:
                print(json.dumps({'Activated':513, 'data':'Current itemname not in inspection.'}))
                return
                
        target_seq = filtered_data[currFtr].dropna()

        min_len = int(currSize)*2

        if len(target_seq)< min_len:
                print(json.dumps({'Activated':514, 'data':'Too few records in SQL.'}))
                return
        # redis.hash_hset('QMS_API_test', 'target_seq', str(target_seq))

        currXbar,currXbarControlPlotArgs = CalcXbarControlArgs(target_seq, int(currSize))
        
        currFigname = '均值控制图(Xbar)'

        htmlScript = ControlPlot(currXbar,currXbarControlPlotArgs,currFigname)

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotXbarMRControl(json_str_in):
        kwargs = json_str_in

        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']
        currSize = kwargs['setChunkSize']

        if (int(currSize) <=2) | (int(currSize)>=10):
                print(json.dumps({'Activated':513, 'data':'Incorrect subgroup size, must be between 2 and 9.'}))
                return

        raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart,currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        # redis.hash_hset('QMS_API_test', 'raw', str(raw_data))

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return
        
        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)

        #ControlLimits = ControlLimits.loc[ControlLimits.inspection == 1]

        if (currFtr in ControlLimits.item_en.values) != True:
                print(json.dumps({'Activated':513, 'data':'Current itemname not in inspection.'}))
                return

        target_seq = filtered_data[currFtr].dropna()

        # redis.hash_hset('QMS_API_test', 'target_seq', str(target_seq))
        min_len = int(currSize)*2

        if len(target_seq)< min_len:
                print(json.dumps({'Activated':514, 'data':'Too few records in SQL.'}))
                return
        
        currXbarR, currControlPlotArgs = CalcXbarMRControlArgs(target_seq, int(currSize))
        
        currFigname = '均值移动极差控制图(Xbar - MR)'

        htmlScript = ControlPlot(currXbarR,currControlPlotArgs,currFigname)

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotPControl(json_str_in):

    kwargs = json_str_in
    currSection = kwargs['setSection']
    currProduct = kwargs['setProductID']
    currStart = kwargs['setStarttime']
    currEnd = kwargs['setEndtime']
    currMachine = kwargs['setMachineID']
    
    raw_data = DrawSQLCountData(currSection,currProduct,currMachine,currStart,currEnd,conn_siger)

    raw_data = raw_data.sort_values(by = 'CreateTime').ffill().bfill()

    if len(raw_data) == 0:
            print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
            return

    beginTS = raw_data.CreateTime.astype('datetime64').min()
    endTS = raw_data.CreateTime.astype('datetime64').max()
    duration = endTS - beginTS

    if duration/pd.Timedelta(hours = 1) >2:
        raw_data['group'] = ((raw_data.CreateTime.astype('datetime64') - beginTS)/pd.Timedelta(hours = 1)).apply(int)
    else:
        raw_data['group'] = ((raw_data.CreateTime.astype('datetime64') - beginTS)/pd.Timedelta(minutes = 10)).apply(int)

    def countNG(datablock_in):
        return datablock_in[datablock_in.Result == 'NG'].shape[0]

    NG_count = np.array(raw_data.groupby('group').apply(countNG))
    Group_size = np.array(raw_data.groupby('group').apply(len))

    currPvec, currArgs = CalcPControlArgs(Group_size,NG_count)
    
    currFigname = 'P控制图'

    htmlScript = ControlPlot(currPvec, currArgs, currFigname)

    print(json.dumps({'Activated':1,'data':htmlScript}))
    return


def ActivatePlotUControl(json_str_in):

    kwargs = json_str_in
    currSection = kwargs['setSection']
    currProduct = kwargs['setProductID']
    currStart = kwargs['setStarttime']
    currEnd = kwargs['setEndtime']
    currMachine = kwargs['setMachineID']
    
    raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart,currEnd,conn_siger)
    if len(raw_data) == 0:
            print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
            return
    
    filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
    if len(filtered_data) == 0:
            print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
            return

    filtered_data = filtered_data.sort_values(by = 'time').ffill().bfill()
    if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return
    
    beginTS = filtered_data.time.astype('datetime64').min()
    endTS = filtered_data.time.astype('datetime64').max()
    duration = endTS - beginTS

    if duration/pd.Timedelta(hours = 1) >2:
        filtered_data['group'] = ((filtered_data.time.astype('datetime64') - beginTS)/pd.Timedelta(hours = 1)).apply(int)
    else:
        filtered_data['group'] = ((filtered_data.time.astype('datetime64') - beginTS)/pd.Timedelta(minutes = 10)).apply(int)
    
    filtered_data['incontrol'] = bool(1)

    ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)

    #ControlLimits = ControlLimits.loc[ControlLimits.inspection ==1]

    ftr_list = ControlLimits.item_en.unique()

    faultCountArray = np.array(np.repeat(0,len(filtered_data['group'].unique())))
    totalCountArray = np.array(np.repeat(0,len(filtered_data['group'].unique())))

    def countFault(datablock_in):
        return(len(datablock_in) - np.sum(datablock_in.incontrol))

    for currFtr in ftr_list:
        currUCL = ControlLimits.loc[ControlLimits.item_en == currFtr].max_value.iloc[0]
        currLCL = ControlLimits.loc[ControlLimits.item_en == currFtr].min_value.iloc[0]

        filtered_data['incontrol'] = filtered_data[currFtr].between(currLCL,currUCL)
        currFaultCount = np.array(filtered_data.groupby('group').apply(countFault))
        currSampleSize = np.array(filtered_data.groupby('group').apply(len))

        faultCountArray = faultCountArray+currFaultCount
        totalCountArray = totalCountArray+currSampleSize


    currUvec, currArgs = CalcUControlArgs(totalCountArray,faultCountArray)
    
    currFigname = 'U控制图'

    htmlScript = ControlPlot(currUvec, currArgs, currFigname)

    print(json.dumps({'Activated':1,'data':htmlScript}))
    return







#--------------------------------------------------------------------------------------------------------------------------------

def ActivatePlotCorr(json_str_in):

        kwargs = json_str_in
        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID'] 

        raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart,currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        # redis.hash_hset('QMS_API_test', 'raw', str(raw_data))

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)

        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)
        var_dict = dict( (en, ch) for en ,ch in zip(ControlLimits.item_en, ControlLimits.item) )
        
        if currFtr == 'All':
            # corrMat = filtered_data.corr()
            ftr_vec = ControlLimits.item_en.unique().tolist()
        else:
            ftr_vec = currFtr.split(';')

        if len(ftr_vec)<=1:
                print(json.dumps({'Activated':501, 'data':'Too few variables.'}))
                return

        filtered_data = filtered_data.loc[:,filtered_data.columns.isin(ftr_vec)]
        
        corrMat = filtered_data.corr()

        corrMat.index.name = 'index'

        longCorrMat = CorrUnpivot(corrMat)

        xlabel_ch = longCorrMat['x'].map(var_dict)
        ylabel_ch = longCorrMat['y'].map(var_dict)

        #valueMat = corrMat.values
        #matLabel_en = list(filtered_data.columns)

        #matLabel_ch = [var_dict[currEn] for currEn in matLabel_en]

        #htmlScript = CorrPlot(valueMat,pd.Series(matLabel_ch))

        htmlScript = CorrPlot(xlabel_ch, ylabel_ch, longCorrMat['value'])
        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotCpk(json_str_in):
        kwargs = json_str_in
        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']

        currGroupNum = kwargs['setGroupNum']
        currGroupSize = kwargs['setGroupSize']
        

        raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart,currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return

        target_seq = filtered_data[currFtr].dropna()

        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)

        currUCL = ControlLimits.loc[ControlLimits.item_en == currFtr].max_value.iloc[0]
        currLCL = ControlLimits.loc[ControlLimits.item_en == currFtr].min_value.iloc[0]


        if int(currGroupNum)>len(target_seq):
            print(json.dumps({'Activated':502,'data':'Too many subgroups, greater than data length.'}))
            return
        else:
            currCpkPlotArgs = CalcCpkArgs(target_seq,currUCL, currLCL,int(currGroupSize),int(currGroupNum))
        
        currFigname = 'Cpk Plot of ' + currFtr

        htmlScript = CPKBoxPlot(target_seq,currCpkPlotArgs,currFigname)   

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotPpk(json_str_in):
        kwargs = json_str_in

        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']

        raw_data = DrawSQLData(currSection,currProduct,currMachine, currStart, currEnd, conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)

        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return

        target_seq = filtered_data[currFtr].dropna()

        if len(target_seq) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return

        ControlLimits = getControlLimits(currSection, currProduct, conn_siger_middle)

        currUCL = ControlLimits.loc[ControlLimits.item_en == currFtr].max_value.iloc[0]
        currLCL = ControlLimits.loc[ControlLimits.item_en == currFtr].min_value.iloc[0]


        var_dict = dict( (en, ch) for en ,ch in zip(ControlLimits.item_en, ControlLimits.item) )

        ftr_name = var_dict[currFtr]

        currPpkPlotArgs = CalcPpkArgs(target_seq, currUCL, currLCL)
        
        currFigname = 'Ppk of ' + str(ftr_name)

        htmlScript = PPKHistPlot(target_seq,currPpkPlotArgs,ftr_name)

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return

def ActivatePlotObsCluster(json_str_in):
        kwargs = json_str_in

        currStation = kwargs['setLocation']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        

        rawdata = DrawSQLData(currSection,currProduct,currStart,currEnd,conn_siger)


        if len(raw_data) < 2:
                print(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'}))
                return
        
        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
        filtered_data = filtered_data.dropna()
        currFigname = 'Dendrogram Plot of Observations Cluster'
        data_array = filtered_data.loc[:,~filtered_data.columns.isin(['SN','time'])]
        
        htmlScript = DendrogramPlot(data_array.values,filtered_data.SN.tolist(),currFigname,'complete',pdist,'完全聚类','相关系数距离')

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return



def ActivatePlotVarCluster(json_str_in):
        kwargs = json_str_in
        currStation = kwargs['setLocation']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        
        rawdata = DrawSQLData(currSection,currProduct,currStart,currEnd,conn_siger)


        if len(raw_data) < 2:
                print(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'}))
                return
        
        filtered_data = DFPreprocessComplete(raw_data,feature_mapping)
        
        filtered_data = filtered_data.dropna()

        filtered_data = filtered_data.transpose()

        tmp_df = filtered_data.loc[~filtered_data.index.isin(['SN','time'])]

        currFigname = 'Dendrogram Plot of Variable Cluster'

        tmp_df.columns = filtered_data.loc['SN',]
        
        htmlScript = DendrogramPlot(tmp_df.values,tmp_df.index.tolist(),currFigname,'complete',pdist,'完全聚类','相关系数距离')

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotXGBTree(json_str_in):

        kwargs = json_str_in
        currStation = kwargss['setLocation']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currLabels = kwargs['setClasslabels']
        

        rawdata = DrawSQLData(currSection,currProduct,currStart,currEnd,conn_siger)


        if len(raw_data) < 2:
                print(json.dumps(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'})))
                return
        
        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)

        filtered_data = filtered_data.drop(columns = ['time'])

        if len(currLabels) == 0:
            db = DBSCAN(eps=0.03, min_samples=3).fit(filtered_data)
            currLabels = db.labels_
        
        if len(currLabels) != len(filtered_data):
            print(json.dumps({'Activated':504,'data':'Labels and dataset must be with equal length.'}))
            return

        filtered_data['Labels'] = currLabels

        filtered_data = filtered_data.loc[filtered_data.Labels != -1]

        if len(filtered_data.Labels.unique()) == 1:
            msg = 'The data can not be separated.' 
            print(json.dumps({'Activated':505,'data':msg}))
            return
        else:
            currXGBArgs = CalcXGBArgs(filtered_data,labels_in)

            htmlScript = XGBPlot(currXGBArgs,currLabels)

            print(json.dumps({'Activated':1,'data':htmlScript}))
            return


def ActivatePlotTS(json_str_in):

        kwargs = json_str_in
        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']

        raw_data = DrawSQLData(currSection, currProduct, currMachine, currStart,currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        # redis.hash_hset('QMS_API_test', 'raw', str(raw_data))

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return
                
        target_seq = filtered_data[currFtr].dropna()

        if len(target_seq) == 0:
                print(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'}))
                return

        htmlScript = TimeSeriesPlot(pd.Series(range(len(target_seq))), target_seq.values.tolist())

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return

def ActivatePlotProb(json_str_in):
        kwargs = json_str_in

        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currMachine = kwargs['setMachineID']

        raw_data = DrawSQLData(currSection,currProduct,currMachine,currStart,currEnd,conn_siger)

        if len(raw_data) == 0:
                print(json.dumps({'Activated':500, 'data':'Empty record in SQL.'}))
                return
        
        # redis.hash_hset('QMS_API_test', 'raw', str(raw_data))

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)
        
        if len(filtered_data) == 0:
                print(json.dumps({'Activated':511, 'data':'Empty record in SQL.'}))
                return
                
        target_seq = filtered_data[currFtr].dropna()

        if len(target_seq) == 0:
                print(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'}))
                return

        htmlScript = ProbPlot(target_seq)

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return


def ActivatePlotScatterGroup(json_str_in):

        kwargs = json_str_in
        currSection = kwargs['setSection']
        currProduct = kwargs['setProductID']
        currStart = kwargs['setStarttime']
        currEnd = kwargs['setEndtime']
        currFtr = kwargs['setTargetfeature']
        currSize = kwargs['setChunkSize']
        currMachine = kwargs['setMachineID']

        raw_data = DrawSQLData(currSection,currProduct,currMachine,currStart,currEnd,conn_siger)

        if len(raw_data) < 2:
                print(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'}))
                return
        
        # filtered_data = DFPreprocessComplete(raw_data,feature_mapping)

        filtered_data = PivotData(raw_data)#DFPreprocess(raw_data)

        target_seq = filtered_data[currFtr].dropna()

        if len(target_seq) <=25:
                print(json.dumps({'Activated':503, 'data':'Not enough data in SQL records.'}))
                return


        splitted_seq = np.array_split(target_seq, len(target_seq)/(int(currSize)+1))

        if len(splitted_seq) >25:
            splitted_seq = splitted_seq[-25:]

        label_count = list(map(len,splitted_seq))

        currX = np.repeat(range(len(splitted_seq)), label_count)

        currY = []

        for ele in splitted_seq:
            currY = currY+ele.tolist()

        htmlScript = GroupScatterPlot(currX,currY)

        print(json.dumps({'Activated':1,'data':htmlScript}))
        return

if __name__ == "__main__":
        fire.Fire()






























