#!/usr/bin/python3

# orthologer - Pipeline for deducing orthology from fasta files.
# Copyright (C) 2005-2023 E. Zdobnov lab: F. Tegenfeldt
# <fredrik.tegenfeldt@unige.ch> based on code by E. Kriventseva
#
# This file is part of orthologer.
#
# orthologer is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# orthologer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with orthologer.  If not, see <http://www.gnu.org/licenses/>.
'''
Plot evolutionary rate.
Pipeline usage: -
'''
import argparse
import re
import numpy as np

class BenchStats:
    def __init__(self):
        self.names = {}
        self.vsum  = []
        self.vsum2 = []
        self.N     = []
        
    def add(self,name,value):
        v2 = value*value
        if name not in self.names:
            index = len(self.vsum)
            self.vsum.append(value)
            self.vsum2.append(v2)
            self.N.append(1)
            self.names[name] = index
        else:
            index = self.names[name]
            self.vsum[index]  += value
            self.vsum2[index] += v2
            self.N[index] += 1
            
    def mean(self,index):
        N = self.N[index]
        if N>0:
            return self.vsum[index]/self.N[index]
        return None

    def stdev(self,index):
        N = self.N[index]
        if N==0:
            return None
        if N==1:
            return 0

        mean = self.vsum[index]/self.N[index]
        v2   = self.vsum2[index]
        s = ( v2 - N*mean*mean )/(N-1)
        if s>0:
            return np.sqrt(s)
        return 0

    def dump(self):
        lastrow=None
        line=None
        for name,index in self.names.items():
            elems = name.split(b'|')
            rowname = elems[0]+b'_'+elems[1]
            if lastrow is None:
                lastrow = rowname
            if rowname != lastrow:
                print(line)
                lastrow = rowname
                line = None

            colname = elems[2]
            mean  = self.mean(index)
            stdev = self.stdev(index)
            if line is None:
                line = '%-40s'%(rowname.decode())
            line += ' %.2f %.2f'%(mean, stdev)
                
            
    #2021-02-19 10:52:08    BM:pairdb read 9030 0.0940 96063.83 145.04 1.05
def read_logfile( filename, benchstats ):
    pattern = re.compile('(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})')
    columns = []
    with open(filename,'rb') as fh:
        for line in fh:
            # empty line
            if len(line)==0:
                continue
            # check for commented lines
            if line[0] in b'#':
                continue
            # find BM:
            pos=line.find(b' BM:')
            if pos==-1:
                continue
            # skip tag
            data = line[pos+4:]
            
            # split data in columns
            elems = data.split()

            # check if header line
            if elems[0]==b'group':
                columns = elems
                continue
            # create name
            base = elems[0]+b'|'+elems[1]+b'|'
            icol=2
            for col in columns[2:]:
                name=base+col
                val=float(elems[icol])
                benchstats.add(name,val)
                icol +=1
                



parser = argparse.ArgumentParser(description='BM stats')

parser.add_argument('-f', '--file', action='append', dest='filename',
                  help='read data from FILE', metavar='FILE', required=True, default=[])

options = parser.parse_args()

##########################################################################
benchstats = BenchStats()
for f in options.filename:
    read_logfile(f,benchstats)

benchstats.dump()
