import sys
import csv
import numpy as np
import pandas as pd
from math import sqrt, exp, pi
import matplotlib.pyplot as plt
import matplotlib.widgets as wg


from tklib.tkutils import replace_path, getarg, getintarg, getfloatarg, pint, pfloat
from tklib.tkvariousdata import tkVariousData
from tklib.tkapplication import tkApplication



"""
Smoothing by convolution with Gauss function
"""

#======================
# parameters
#======================
infile  = 'dos.xlsx'
outfile = 'convolution.xlsm'
template = "StandardGraph.xlsm"


func_type = 'gauss'
width = 0.2


argv = sys.argv
n = len(argv)
if n >= 1:
    infile = argv[1]
if n >= 2:
    width = float(argv[2])
if n >= 3:
    func_type = argv[2]


def convolve_func(x, width, func_type = 'gauss'):
    if func_type == 'lorentz':
        coeff = 1.0 / width / pi
        dvx = x / width
        return 1.0 / (1.0 + dvx * dvx)
    else:
        coeff = 1.0 / sqrt(pi)/ width
        dvx = x / width
        return coeff * exp(-dvx*dvx)

def convolution(x, y, width, func_type):
    ndata = len(x)
    dx     = x[1] - x[0]
    xrange = x[ndata-1] - x[0]
# integration range, converted to number of the list index
    di = int( (width * 5.0) / dx + 1.1 )
# the coefficient of Gauss function
    coeff = 1.0 / sqrt(pi)/ width
# deconvoluted data
    ys = [0.0]*ndata
    for j in range(0, ndata):
        x0 = x[j];
        y0 = y[j];
        for k in range(-di, di+1):
            if j+k < 0 or j+k >= ndata:
                continue
                
            f = dx * convolve_func(dx * k, width, func_type)                
            ys[j+k] += y0 * f

    return ys;


def main():
    global infile
    global outfile
    global width

    app = tkApplication()
#    cparams = app.cparams

#    print(f"Initialize parameters")
#    initialize(app)
#    print(f"Update parameters by command-line arguments")
#    update_vars(app)

    logfile = app.replace_path(infile)
    outfile = app.replace_path(infile, template = ["{dirname}", "{filebody}-convoluted.xlsm"])
    print(f"Open logfile [{logfile}]")
    app.redirect(targets = ["stdout", logfile], mode = 'w')

    print("")
    print(f"Convolute data in [{infile}] with {func_type} function of width={width}")
    print("infile  : ", infile)
    print("outfile : ", outfile)
    print(f"func_type: {func_type}")
    print(f"width: {width}")

    print("")
    print("Read data from [{}]".format(infile))
    datafile = tkVariousData(infile)
    header, datalist = datafile.Read_minimum_matrix(close_fp = True)#, usage = usage)
    label_x, x = header[0], datalist[0] #datafile.FindDataArray(cparams.Tlabel, flag = 'i')
    label_y, y = header[1], datalist[1] #datafile.FindDataArray(cparams.Plabel, flag = 'i')
    ndata = len(x)

    ys = convolution(x, y, width, func_type)
    for i in range(0, ndata):
         print("{}\t{}\t{}".format(x[i], y[i], ys[i]))

    print("")
    print(f"Save to [{outfile}]")
    tkVariousData().to_excel(outfile, ['x', 'y(input)', 'y(convoluted)'], [x, y, ys], template = template)


#=============================
# Plot graphs
#=============================
    print("")
    print("plot")
    fig = plt.figure()

    ax1 = fig.add_subplot(1, 1, 1)

    ax1.plot(x, y,  label = 'raw data', linestyle = '-', linewidth = 0.5, marker = 'o', markersize = 0.5)
    ax1.plot(x, ys, label = 'convoluted')
    ax1.set_xlabel("x")
    ax1.set_ylabel("y")
    ax1.legend()
    plt.tight_layout()

    plt.pause(0.1)
    print("Press ENTER to exit>>", end = '')
    input()

    exit()


if __name__ == '__main__':
    main()
 