#!/usr/bin/python

from math import *
#import numpy as np
import random
import Manyo as m
import Smoothing as Adv
#import Adv

####    distribution    ####
def dist(x, param):
    sum=param[0]
    for i in range(len(param[1])):
        a, c, w = param[1][i]
        sum = sum + a*exp(-log(2.0)*((x-c)/w)**2)
    return sum

####    sign function    ####
def sign(x):
    if ( x > 0.0):
        s=1.0
    elif ( x==0.0):
        s=0.0
    else:
        s=-1.0
    return s

####    noise for dist    ####
def noise(p, rate):
#    return sign(np.random.rand(1)-0.5)*p*rate*sqrt(-log(np.random.rand(1)))
    return sign(random.random()-0.5)*p*rate*sqrt(-log(random.random()))

####    initialise an element container    ####
def initElementContainer(xmin, xmax, nDiv, param):
    ####    create bins    ####
    delta=(xmax-xmin)/nDiv
    bin=m.DoubleVector()
    for i in range(nDiv+1):
        bin.push_back(xmin+delta*i)

    ####    create frequencies of a histogram and errors    ####
    freq  = m.DoubleVector()
    error = m.DoubleVector()
    rate=0.1
    for i in range(nDiv):
        x=(bin[i]+bin[i+1])/2.0
        p=dist(x, param)
        q=noise(p, rate)
        #print str(i).rjust(4), str(x).rjust(10), str(p).rjust(23), str(q).rjust(23), str(p*rate).rjust(23)
        freq.push_back(p+q)
        error.push_back(p*rate)

    ####    create an element container    ####
    ec=m.ElementContainer()
    ec.AddToHeader("run number", 1)
    ec.AddToHeader("level", 1)
    ec.AddToHeader("Inst.", "manyo")
    ec.Add("TOF",       bin,   "sec.")
    ec.Add("Intensity", freq,  "counts")
    ec.Add("Error",     error, "counts")
    ec.SetKeys("TOF", "Intensity", "Error")

    return ec

####    output an element container    ####
def outputElementContainer(ec):
    bin = ec.Put(ec.PutXKey())
    y   = ec.Put(ec.PutYKey())
    e   = ec.Put(ec.PutEKey())

    print str("No.").rjust(4), str(ec.PutXKey()).rjust(20), str("xc").rjust(7), str(ec.PutYKey()).rjust(23), str(ec.PutEKey()).rjust(23)
    for i in range(y.size()):
        print str(i).rjust(4), "[", str(bin[i]).rjust(6), ", ", str(bin[i+1]).rjust(6), ")", str((bin[i]+bin[i+1])/2.0).rjust(7), str(y[i]).rjust(23), str(e[i]).rjust(23)

####    plot    ####
def plot(src, dest):
    srcBin  = src.Put(src.PutXKey())
    srcY    = src.Put(src.PutYKey())
    destBin = dest.Put(dest.PutXKey())
    destY   = dest.Put(dest.PutYKey())

    counter=0
    g=m.GnuplotInterface()
    g.e("set yrange[0: 150000]")
    g.e("plot '-' using 1:2 with lines lineWidth 1 title'%d', '-' using 1:3 with lines lineWodth 4" %count)

    while 1:
        for i in range(srcY.size()):
            g.e(str( (bin[i]+bin[i+1])/2.0 ) + " " + str( srcY[i] ) + " " + str(destY[i]) )
        g.e("e")
        c=raw_input("")
        if c != "":
            break

####    main    ####
xmin = 0.0
xmax = 15.0
nDiv = 1500
#       background  func1
param1=[1000.0,     [[100000.0, 7.5, 3.0]] ]
ec1=initElementContainer(xmin, xmax, nDiv, param1)
#outputElementContainer(ec1)
#ec1.SaveTextFile("tttt1.txt")

#param2=[[100000.0, 5.0, 1.5],  [100000.0, 10.0, 1.5]]
#ec2=initElementContainer(xmin, xmax, nDiv, background, param2)
#outputElementContainer(ec2)
#ec2.SaveTextFile("tttt2.txt")

smoothing=Adv.Smoothing(ec1, Adv.BSpline)
smoothing.execute()
dest1=smoothing.getResult()

plot(ec1, dest1)



