from pygraphc.preprocess.PreprocessLog import PreprocessLog
from pygraphc.similarity.StringSimilarity import StringSimilarity
from itertools import combinations
import networkx as nx
import csv


class LogTextSimilarity(object):
    """A class for calculating cosine similarity between a log pair. This class is intended for
       non-graph based clustering method.
    """
    def __init__(self, mode, logtype, logs, clusters, h5file=''):
        """The constructor of class LogTextSimilarity.

        Parameters
        ----------
        mode        : str
            Mode of operation, i.e., text and text-h5
        logtype     : str
            Type for event log, e.g., auth, syslog, etc.
        logs        : list
            List of every line of original logs.
        clusters    : dict
            Dictionary of clusters. Key: cluster_id, value: list of log line id.
        h5file      : str
            File name for h5 file to save cosine similarity result.
        """
        self.mode = mode
        self.logtype = logtype
        self.logs = logs
        self.clusters = clusters
        self.h5file = h5file

    def get_cosine_similarity(self):
        """Get cosine similarity from a pair of log lines in a file.

        Returns
        -------
        cosine_similarity   : dict
            Dictionary of cosine similarity in non-graph clustering. Key: (log_id1, log_id2),
            value: cosine similarity distance.
        """
        preprocess = PreprocessLog(self.logtype)
        preprocess.preprocess_text(self.logs)
        events = preprocess.events_text
        cosines_similarity = {}

        if self.mode == 'text':
            # calculate cosine similarity
            for log_pair in combinations(range(preprocess.loglength), 2):
                cosines_similarity[log_pair] = StringSimilarity.get_cosine_similarity(events[log_pair[0]]['tf-idf'],
                                                                                      events[log_pair[1]]['tf-idf'],
                                                                                      events[log_pair[0]]['length'],
                                                                                      events[log_pair[1]]['length'])
            return cosines_similarity

        elif self.mode == 'text-csv':
            print self.mode
            for nodex in xrange(preprocess.loglength):
                csv_file = '/tmp/cosine-' + str(nodex) + '.csv'
                f = open(csv_file, 'wb')
                writer = csv.writer(f)

                for cluster_id, cluster in self.clusters.iteritems():
                    row = []
                    for c in cluster:
                        if nodex != c:
                            similarity = StringSimilarity.get_cosine_similarity(events[nodex]['tf-idf'],
                                                                                events[c]['tf-idf'],
                                                                                events[nodex]['length'],
                                                                                events[c]['length'])
                            # if similarity > 0:
                            row.append(1 - similarity)
                    if row:
                        row.append(cluster_id)
                        writer.writerow(row)
                f.close()

@@ -165,33 +165,34 @@
 ort 
-networkx as nx%0Aimport csv
+csv%0Aimport multiprocessing
 %0A%0A%0Ac
@@ -425,19 +425,8 @@
 ters
-, h5file=''
 ):%0A 
@@ -869,102 +869,8 @@
 id.%0A
-        h5file      : str%0A            File name for h5 file to save cosine similarity result.%0A
     
@@ -1008,23 +1008,996 @@
 elf.
-h5file = h5file
+events = %7B%7D%0A%0A    def write_cosine_csv(self, node):%0A        csv_file = '/tmp/cosine-' + str(node) + '.csv'%0A        f = open(csv_file, 'wb')%0A        writer = csv.writer(f)%0A        for cluster_id, cluster in self.clusters.iteritems():%0A            row = %5B%5D%0A            for c in cluster:%0A                if node != c:%0A                    similarity = StringSimilarity.get_cosine_similarity(self.events%5Bnode%5D%5B'tf-idf'%5D,%0A                                                                        self.events%5Bc%5D%5B'tf-idf'%5D,%0A                                                                        self.events%5Bnode%5D%5B'length'%5D,%0A                                                                        self.events%5Bc%5D%5B'length'%5D)%0A                    if similarity %3E 0:%0A                        row.append(1 - similarity)%0A            if row:%0A                row.append(cluster_id)%0A                writer.writerow(row)%0A        f.close()%0A%0A    def __call__(self, node):%0A        return self.write_cosine_csv(node)
 %0A%0A  
@@ -2420,24 +2420,29 @@
 gs)%0A        
+self.
 events = pre
@@ -2688,16 +2688,38 @@
 _pair%5D =
+ %5C%0A                   
  StringS
@@ -2746,24 +2746,29 @@
 _similarity(
+self.
 events%5Blog_p
@@ -2849,35 +2849,13 @@
     
-                           
+self.
 even
@@ -2944,35 +2944,13 @@
     
-      
-                     
+self.
 even
@@ -3039,35 +3039,13 @@
     
-                           
+self.
 even
@@ -3192,22 +3192,16 @@
     
-for nodex in x
+nodes = 
 rang
@@ -3223,17 +3223,16 @@
 glength)
-:
 %0A       
@@ -3240,975 +3240,128 @@
     
-    csv_file = '/tmp/cosine-' + str(nodex) + '.csv'%0A                f = open(csv_file, 'wb')%0A                writer = csv.writer(f)%0A%0A                for cluster_id, cluster in self.clusters.iteritems():%0A                    row = %5B%5D%0A                    for c in cluster:%0A                        if nodex != c:%0A                            similarity = StringSimilarity.get_cosine_similarity(events%5Bnodex%5D%5B'tf-idf'%5D,%0A                                                                                events%5Bc%5D%5B'tf-idf'%5D,%0A                                                                                events%5Bnodex%5D%5B'length'%5D,%0A                                                                                events%5Bc%5D%5B'length'%5D)%0A                            # if similarity %3E 0:%0A                            row.append(1 - similarity)%0A                    if row:%0A                        row.append(cluster_id)%0A                        writer.writerow(row)%0A                f.close
+pool = multiprocessing.Pool(processes=4)%0A            pool.map(self, nodes)%0A            pool.close()%0A            pool.join
 ()%0A

Add multiprocessing support to LogTextSimilarity