<gh_stars>10-100
import sys, os, json, logging, random
import matplotlib
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

# from matplotlib import gridspec
import numpy as np

class pca_demo:
    def __init__(self, logger, data_path_prefix='../amd_data'):
        self.result_path        = './'
        self.data_path_prefix   = data_path_prefix
        self.logger             = logger

    def load(self):
        with open(self.data_path_prefix + 'amd_metadata/pca_eigenvalues.txt', 'r') as data_file:
            pca_eigen_values    = json.load(data_file)
        data_file.close()
         
        with open(self.data_path_prefix + 'amd_metadata/pca_eigenvector.txt', 'r') as data_file:
            pca_eigenvector     = json.load(data_file)
        data_file.close()
         
        self.logger.info("Loading malware")
        with open(self.data_path_prefix + 'amd_malware_metadata/pca_data_dict.txt.new', 'r') as data_file:
            raw_malware         = json.load(data_file)
        data_file.close()

        self.logger.info("Loading benignware")
        with open(self.data_path_prefix + 'amd_benign_metadata/pca_data_dict.txt', 'r') as data_file:
            raw_benignware      = json.load(data_file)
        data_file.close()
         
        data_base   = {}
        #selected_benignware = random.choice(raw_benignware.keys())
        selected_benignware = 'creative1'
        selected_malware    = random.choice(raw_malware.keys())
        selected_malware    = '37375106291becca8427766e24f54887' 
        selected_experiment =\
        random.sample(raw_malware[selected_malware].keys(), 5)

        # with open('pca_demo.json', 'w') as outfile:
        #     json.dump(selected_experiment, outfile, indent=2)
        # outfile.close()
        with open('pca_demo.json', 'r') as infile:
            selected_experiment = json.load(infile)
        infile.close()

        #selected_event      = random.choice(raw_malware[selected_malware]['0'].keys())
        selected_event      = '0x02904'

        self.selected_benignware = selected_benignware 
        self.selected_malware    = selected_malware    
        self.selected_event      = selected_event      
        
        def generate_display(raw_data, testbench_name):
            display = []
            for experiment_number in raw_data[testbench_name]:
                if experiment_number in selected_experiment:
                    if display == []:
                        display = \
                            np.array(raw_data[testbench_name][experiment_number][selected_event])
                    else:
                        display = np.vstack((\
                                display,\
                                np.array(raw_data[testbench_name][experiment_number][selected_event])\
                                ))
            return display

        self.display_malware     = generate_display(raw_malware,     selected_malware)
        self.display_benignware  = generate_display(raw_benignware,  selected_benignware)

        def pca_display(raw_data, testbench_name):
            display = []
            for experiment_number in raw_data[testbench_name]:
                if experiment_number in selected_experiment:
                    if display == []:
                        display = np.dot(\
                            np.array(raw_data[testbench_name][experiment_number][selected_event]),\
                            -1 * np.transpose(np.array(pca_eigenvector[selected_event]))\
                        )[0:2]
                    else:
                        display = np.vstack((\
                                display,\
                                np.dot(\
                                    np.array(raw_data[testbench_name][experiment_number][selected_event]),\
                                    -1 * np.transpose(np.array(pca_eigenvector[selected_event]))\
                                    )[0:2]
                                ))
            return display

        self.display_pca_malware    = pca_display(raw_malware,     selected_malware)
        self.display_pca_benignware = pca_display(raw_benignware,  selected_benignware)

    def plot(self):

        # matplotlib.rcParams['text.usetex'] = True
        # matplotlib.rcParams['pdf.fonttype'] = 42
        # matplotlib.rcParams['ps.fonttype'] = 42

        matplotlib.rcParams['pdf.use14corefonts'] = True
        malware_boxprops            = dict(linewidth=3, color='red')
        benign_boxprops             = dict(linewidth=3, color='blue')

        benign_flierprops           = dict(marker='o', markerfacecolor='blue', markersize=8,\
                                        markeredgecolor='k',\
                                        linestyle='none', linewidth=2)
        malware_flierprops          = dict(marker='o', markerfacecolor='red', markersize=8,\
                                        markeredgecolor='k',\
                                        linestyle='none', linewidth=2)
        malware_capprops            = dict(color='r', linewidth=2, linestyle='-')
        benign_capprops             = dict(color='b', linewidth=2, linestyle='-')
        malware_whiskerprops        = dict(color='r', linewidth=2, linestyle='-')
        benign_whiskerprops         = dict(color='b', linewidth=2, linestyle='-')
        malware_meanpointprops      = dict(marker='D', markeredgecolor='black',
                                        markerfacecolor='firebrick', markersize=5)
        benign_meanpointprops       = dict(marker='D', markeredgecolor='black',
                                        markerfacecolor='blue', markersize=5)
        malware_medianprops = dict(linestyle='-.', linewidth=2.5, color='red')
        benign_medianprops = dict(linestyle='-.', linewidth=2.5, color='blue')
        sigma_3pt5                  = 99.7
        
        fig, ax = plt.subplots(1, 2, figsize=(32, 3), \
                            gridspec_kw={'width_ratios':[32, 3], 'wspace':0.23})
        #gs1.update(wspace=0.025, hspace=0.05) # set the spacing between axes. 
        
        ax[0].boxplot(self.display_malware,\
                    boxprops=malware_boxprops,\
                    whiskerprops=malware_whiskerprops,\
                    capprops=malware_capprops,\
                    meanline=False,\
                    medianprops=malware_medianprops,\
                    # showmeans=True,\
                    meanprops=malware_meanpointprops,\
                    showfliers=False)
        box_width = 0.5
        ax[1].boxplot(self.display_pca_malware,\
                    boxprops=malware_boxprops,\
                    whiskerprops=malware_whiskerprops,\
                    capprops=malware_capprops,\
                    meanline=False,\
                    medianprops=malware_medianprops,\
                    # showmeans=True,\
                    meanprops=malware_meanpointprops,\
                    showfliers=False,\
                    widths=(box_width, box_width))
        

        ax[0].boxplot(self.display_benignware,\
                    boxprops=benign_boxprops,\
                    whiskerprops=benign_whiskerprops,\
                    capprops=benign_capprops,\
                    meanline=False,\
                    medianprops=benign_medianprops,\
                    # showmeans=True,\
                    meanprops=benign_meanpointprops,\
                    showfliers=False)

        ax[1].boxplot(self.display_pca_benignware,\
                    boxprops=benign_boxprops,\
                    whiskerprops=benign_whiskerprops,\
                    capprops=benign_capprops,\
                    meanline=False,\
                    medianprops=benign_medianprops,\
                    # showmeans=True,\
                    meanprops=benign_meanpointprops,\
                    showfliers=False,\
                    widths=(box_width, box_width))

        ax[0].set_xlabel( "Features\n" \
                            + 'Event: The number of Load operations dispatched \
to the Load-Store unit\n' \
                            + 'Benignware (red box): ' + self.selected_benignware \
                            + ', Malware (blue box): ' + self.selected_malware + '\n(a)\n')
        ax[0].set_ylabel('Values\nof examples')
        ax[1].set_ylabel('PCA values')
        ax[1].set_xlabel('PCA\nFeatures\n(b)')
        
        ax[0].yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
        ax[1].yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
        # vals        = ax[0].get_yticks()
        # ax[0].set_yticklabels(['{:4g}'.format(x) for x in vals])
        # vals        = ax[1].get_yticks()
        # ax[1].set_yticklabels(['{:4g}'.format(x) for x in vals])
        #plt.show()
        savefig_name = PdfPages(self.result_path + 'pca_demo.pdf')
        plt.savefig(savefig_name, format='pdf', bbox_inches='tight')
        savefig_name.close()
        plt.close()
    
    def run(self):
        self.load()
        self.plot()


if __name__ == "__main__":
    
    font = {\
            'family' : 'serif',\
            'size'   : 30}
    plt.rc('font', **font)

    logger  = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    logger_handler = logging.StreamHandler()
    logger_handler.setFormatter(\
        logging.Formatter('%(asctime)s [%(levelname)s]\
            %(filename)s [%(lineno)d]: %(funcName)s(): %(message)s'))
    logger.addHandler(logger_handler)

    pca1 = pca_demo(logger, \
            data_path_prefix='../amd_data/')
            #data_path_prefix='/home/bobzhou/2017_summer/data_analysis/amd_data_analysis/')
    pca1.result_path = 'figures/'
    pca1.run()
