from __future__ import print_function
import Manyo as mm
import utsusemi.ana.Reduction.BaseCommandsInEla as BaseCom
import Manyo.LevmarTools as ml
import Manyo.Utsusemi as mu

import uGao.MPlot as mp
import os,sys,time,math

ver = float(sys.version_info[0])+float(sys.version_info[1])*0.1
if ver<2.5:
    from elementtree.ElementTree import ElementTree
else:
    from xml.etree.ElementTree import ElementTree

import utsusemi.DNA.ana.Reduction.SearchPathDNA          as SPD

convList = ["lc","gc","dc","pv1c","pv2c","dhoc","alc","cc","p1c","p2c","p3c"]
nullEC=mm.ElementContainer()
nullEC.Add("x",[x*0.01 for x in range(101)])
nullEC.Add("y",[1]*100)
nullEC.Add("e",[1]*100)
nullEC.SetKeys("x","y","e")

#############################################################################
#
#def ReadDataEC( filename ):
#    """
#    @param filename   (string)
#    @retval ec (ElementConteiner)
#    """
#    ec = mm.ElementContainer()
#    flug = os.path.exists(filename)
#    if flug:
#        Min = mm.ReadSerializationFileBinary( filename )
#        Min.Load( ec )
#        del(Min)
#    else:
#        print "ReadData >> ",filename,"is not exist"
#    return ec
#
#############################################################################
#
#def ReadDataECA( filename ):
#    """
#    @param filename   (string)
#    @retval eca (ElementConteinerArray)
#    """
#    eca = mm.ElementContainerArray()
#    flug = os.path.exists(filename)
#    if flug:
#        Min = mm.ReadSerializationFileBinary( filename )
#        Min.Load( eca )
#        del(Min)
#    else:
#        print "ReadData >> ",filename,"is not exist"
#    return eca
#
#############################################################################

def SetResolutionData(ec):
    """
    @param ec      (ElementContainer)
    @retval None
    """
    filenameECbin = "/usr/local/mlf/DNA/tmp/res.dat"
    flug = os.path.exists(filenameECbin)

    if flug:
           os.rename(filenameECbin,filenameECbin+"_bk1" )
    j=0
    f = open(filenameECbin, "w")
    xbin = ec.PutX()
    ybin = ec.PutY()
    ebin = ec.PutE()
    hh= ec.PutHeader()
    flag = ec.PutHeader().CheckKey("CONVOLRANGE")==1

    if flag:
        xr=ec.PutHeader().PutDoubleVector("CONVOLRANGE")
        for i in range(len(ybin)):
            if xr[0]<=(xbin[i]+xbin[i+1])*0.5 and (xbin[i]+xbin[i+1])*0.5<=xr[1]:
                f.write(str(xbin[i])+" "+str(ybin[i])+" "+str(ebin[i])+"\n")
                j=i
        f.write(str(xbin[j+1]))

    else:
        for i in range(len(ybin)):
            f.write(str(xbin[i])+" "+str(ybin[i])+" "+str(ebin[i])+"\n")
        f.write(str(xbin[i+1]))

    f.close()

    return

#############################################################################

def PeakFitBase(ec,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug,useWeight):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ec    (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    @param useWeight       (bool)
    """
    x_bin = ec.PutX()
    binwidth = (x_bin[1]-x_bin[0])

    param_init_string = param.split(",")
    param_ub_string   = param_ub.split(",")
    param_lb_string   = param_lb.split(",")
    link_list_string=link_value.split(",")
    fit_region_string = fit_region.split(",")
    xbin_start = float(fit_region_string[0])
    xbin_end = float(fit_region_string[1])

    param_init = []
    param_ub = []
    param_lb = []
    link_list =[]

    numOfParam=len(param_init_string)

    for i in range(numOfParam):
         param_init.append(float(param_init_string[i]))
         if i< len(param_ub_string):
             param_ub.append(float(param_ub_string[i]))
         if i< len(param_lb_string):
             param_lb.append(float(param_lb_string[i]))
         if i< len(link_list_string):
            if link_list_string[i].isdigit():
                 link_list.append(int(link_list_string[i]))

    if len(link_list)!=numOfParam:
        link_list=range(1,numOfParam+1)

    op = ml.AdvPeakFit(ec,ml.NEW_LEVMAR)
    op.setDefaultParam()
    if useDomain:
         op.setParam(ml.AdvNewLevmar.CONSTRAIN,          ml.AdvNewLevmar.BOX)
    else:
         op.setParam(ml.AdvNewLevmar.CONSTRAIN,          ml.AdvNewLevmar.NO_CONSTRAIN)

    useDiffMode = useJudgementConvolution(function)
    op.setParam(ml.AdvNewLevmar.USE_NUMERICAL_DIFF, useDiffMode)

    op.setParam(ml.AdvNewLevmar.DIFF_METHOD,        ml.AdvNewLevmar.FORWARD)
    op.setParam(ml.AdvNewLevmar.USE_DATA_WEIGHTS,   useWeight)

    #PeakFitInfoPath=os.path.join("/usr","local","mlf","DNA","ana","xml","PeakfitInfo.xml")
    PeakFitInfoPath = SPD.CheckForInput("xml","PeakfitInfo.xml")
    if PeakFitInfoPath=="":
        raise UserWarning("PeakFitBase >> Not found xml/PeakfitInfo.xml")
    if os.path.exists(PeakFitInfoPath):

        xml = ElementTree(file=PeakFitInfoPath)
        xmlRoot = xml.getroot()

        ResiduErrThresh=xmlRoot.find('RESIDU_ERR_THRESH').text
        op.setParam(ml.AdvNewLevmar.RESIDU_ERR_THRESH, float(ResiduErrThresh))
        GradientThresh=xmlRoot.find('GRADIENT_THRESH').text
        op.setParam(ml.AdvNewLevmar.GRADIENT_THRESH, float(GradientThresh))
        PapramDiffThresh=xmlRoot.find('PARAM_DIFF_THRESH').text
        op.setParam(ml.AdvNewLevmar.PARAM_DIFF_THRESH, float(PapramDiffThresh))
        ScalingFactor=xmlRoot.find('SCALING_FACTOR').text
        op.setParam(ml.AdvNewLevmar.SCALING_FACTOR, float(ScalingFactor))
        NumOfItteration=xmlRoot.find('MAX_ITTERATIONS').text

    op.setParam(ml.AdvNewLevmar.MAX_ITERATIONS,     int(NumOfItteration))
    op.setParam(ml.AdvNewLevmar.OUTPUT_INTERVAL,    int(int(NumOfItteration)*0.1))
    op.setParam(ml.AdvNewLevmar.FUNCTIONS, function)
    op.setParam(ml.AdvNewLevmar.PARAMETER_VALUES, param_init)
    op.setParam(ml.AdvNewLevmar.LOWER_BOUNDS, param_lb)
    op.setParam(ml.AdvNewLevmar.UPPER_BOUNDS, param_ub)
    op.setParam(ml.AdvNewLevmar.LINK_IDS, link_list)

    i1 = getBinNumType2(x_bin,binwidth,xbin_start)
    i2 = getBinNumType2(x_bin,binwidth,xbin_end)
    if i1==i2:
        if i1==0:
            i2=i1+1
        else:
            i1=i2-1  
    op.setDomain(int(i1),int(i2))
    op.fit()
    
    while op.isFitting():
        time.sleep(0.5)

    op.eval()

    result=op.getResult()
    fittedParam=op.getFittedParam()

    LatestConvStat=op.getLatestConvergenceStat()
    chi = LatestConvStat.getDouble(ml.AdvNewLevmar.RESIDUAL_ERR_NORM)
     
    s=fittedParam.getVectorSize(ml.AdvNewLevmar.PARAMETER_VALUES)
    param_result = []
    param_result_error = []
    for i in range(s):
        param_result.append(fittedParam.getDouble(ml.AdvNewLevmar.PARAMETER_VALUES,i))
        param_result_error.append(fittedParam.getDouble(ml.AdvNewLevmar.PARAM_ERRORS,i))

    if plotflug:
        ShowResultPlot(result,ec)
        ShowResultParam(fittedParam,chi)

    hh = ec.PutHeaderPointer()
    for i in range(len(param_result)):
        HeaderOverWrite(hh,"FittingParam"+str(i),param_result[i])
        HeaderOverWrite(hh,"FittingParamErr"+str(i),param_result_error[i])
    HeaderOverWrite(hh,"ChiSq",chi)
    HeaderOverWrite(hh,"FittingFunc",function)
    result.InputHeader(hh)

    return param_result,param_result_error,chi,result

#############################################################################

def PeakFit(ec,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ec    (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    """
    useWeight=True
    return PeakFitBase(ec,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug,useWeight)

#############################################################################

def PeakFitEC(ec,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ec    (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    """
    param_result,param_result_error,chi,result= PeakFit(ec,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)
    #each_comp_ec = getFittingEachFunction(function,param_result,ec)
    return result

#############################################################################

def PeakConvFitEC(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ecDet           (ElementContainer)
    @param ecRes           (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    """
    SetResolutionData(ecRes)
    p1 = listParam2Param(param,0)
    p2 = listParam2Param(param_ub,0)
    p3 = listParam2Param(param_lb,0)
    lk = listParam2Param(link_value,0)

    param_result,param_result_error,chi,result= PeakFit(ecDet,function,p1,p2,p3,lk,fit_region,useDomain,NumOfItteration,plotflug)
    #each_comp_ec = getFittingEachFunction(function,param_result,ec)
    return result

#############################################################################

def PeakFitECABase(ecaDet,ecaRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug,useConv):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ecaDet          (ElementContainerArray)
    @param ecaRes          (ElementContainerArray)
    @param function        (string)
    @param param           (list/string)
    @param param_lb        (list/string)
    @param param_ub        (list/string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    @param useConv         (bool)
    @retval result_eca (ElementContainerArray)
    """
    eca_size = ecaDet.PutSize()
    if plotflug:
        p=mp.MPlot()
        p.SetTraceNum(2)

    param_result_list = []
    param_result_error_list = []
    chi_list = []
    result_eca = mm.ElementContainerArray()
    #each_comp_eca = mm.ElementContainerArray()
    #PeakFitStatusPath=os.path.join("/usr","local","mlf","DNA","ana","xml","status")
    PeakFitStatusPath=SPD.CheckForInput( "xml","status" )
    if PeakFitStatusPath=="":
        raise UserWarning("PeakFitECABase >> Not found xml/status")
    os.system("echo \""+str(1)+"\">"+PeakFitStatusPath)
    fitStatus=True
    k=0
    for i in range(eca_size):
        #os.system("echo \""+str(i)+"\">log.txt")
        if os.path.exists(PeakFitStatusPath):
            f=open(PeakFitStatusPath, "r")
            for line in f:
                if "0" in line:
                    fitStatus=False
            f.close()

        p1 = listParam2Param(param,i)
        p2 = listParam2Param(param_ub,i)
        p3 = listParam2Param(param_lb,i)
        lk = listParam2Param(link_value,i)
        if useConv:
            if i<ecaRes.PutSize():
                SetResolutionData(ecaRes(i))

        hh0 = ecaDet(i).PutHeaderPointer()
        fitFlug = False
        if (hh0.CheckKey("FIT")==1):
            if (hh0.PutString("FIT") == "t" or hh0.PutString("FIT") == "T") and fitStatus:
                if plotflug:
                    p.AddData(ecaDet(i))
                #print " >> ",i+1," / ",eca_size, "start Fitting process"
                #print ""
                param_result,param_result_error,chi,result = PeakFit(ecaDet(i),function,p1,p2,p3,lk,fit_region,useDomain,NumOfItteration,False)
                #each_comp_ec = getFittingEachFunction(function,param_result,ecaDet(i))
                #print " >> ",i+1," / ",eca_size, "end Fitting process"
                #print ""
                if plotflug:
                    p.AddData(result)
                    p.SetPlotParam(k*2+1,mc="b",lc="b") # data
                    p.SetPlotParam(k*2+2,ls="-",lw=8,mk="",eb=False,lc="r") # result
                    p.ChangePage(i+2)

                param_result_list.append(param_result)
                param_result_error_list.append(param_result_error)
                chi_list.append(chi)
                #hh = mm.HeaderBase()
                hh = ecaDet(i).PutHeaderPointer()
                for i in range(len(param_result)):
                    HeaderOverWrite(hh,"FittingParam"+str(i),param_result[i])
                    HeaderOverWrite(hh,"FittingParamErr"+str(i),param_result_error[i])
                HeaderOverWrite(hh,"ChiSq",0)
                HeaderOverWrite(hh,"FittingFunc",function)
                result.InputHeader(hh)
                result_eca.Add(result)
                #each_comp_eca.Add(each_comp_ec)
                k=k+1

            else:
                paramForNullData=p1.split(",")
                hh = ecaDet(i).PutHeaderPointer()
                for i in range(len(paramForNullData)):
                    HeaderOverWrite(hh,"FittingParam"+str(i),paramForNullData[i])
                    HeaderOverWrite(hh,"FittingParamErr"+str(i),0)
                HeaderOverWrite(hh,"ChiSq",0)
                HeaderOverWrite(hh,"FittingFunc",function)
                HeaderOverWrite(hh,"FIT","F")
                result = nullEC
                result.InputHeader(hh)

                result_eca.Add(result)
                chi_list.append(0)
                vac = []
                param_result_list.append(vac)
                param_result_error_list.append(vac)

        elif (hh0.CheckKey("FIT")==0):
            param_result,param_result_error,chi,result = PeakFit(ecaDet(i),function,p1,p2,p3,lk,fit_region,useDomain,NumOfItteration,False)
            #each_comp_ec = getFittingEachFunction(function,param_result,ecaDet(i))
            param_result_list.append(param_result)
            param_result_error_list.append(param_result_error)
            chi_list.append(chi)
            for i in range(len(param_result)):
                HeaderOverWrite(hh,"FittingParam"+str(i),param_result[i])
                HeaderOverWrite(hh,"FittingParamErr"+str(i),param_result_error[i])
            HeaderOverWrite(hh,"ChiSq",0)
            HeaderOverWrite(hh,"FittingFunc",function)
            hh = ecaDet(i).PutHeaderPointer()

            result.InputHeader(hh)
            result_eca.Add(result)
            #each_comp_eca.Add(each_comp_ec)

    fit_flug_all=False
    for i in range(eca_size):
        fit_flug =False

        hh2 = ecaDet(i).PutHeaderPointer()
        if (hh2.CheckKey("FIT")==1):
            if (hh2.PutString("FIT") == "t" or hh2.PutString("FIT") == "T"):
                fit_flug =True
        elif (hh2.CheckKey("FIT")==0):
                fit_flug =True
        fit_flug_all = fit_flug_all or fit_flug
        if fit_flug:

            print("##############################################################")
            print(" Fit Result ",i+1," / ",eca_size)

            if (hh2.CheckKey("XRANGE")==1):
                XRange=hh2.PutDoubleVector("XRANGE")
                print("    Q region is",XRange[0]," ------ ",XRange[1])
                print("    chiSq = ",chi_list[i])
                for j in range(len(param_result)):
                    print("    param%i\t%.2e\t::: param%i Error\t%.2e"%(j,param_result_list[i][j],j,param_result_error_list[i][j]))
            #else:
            #    print "    fitting is not performed."
    if fit_flug_all:
        print("##############################################################")
 
    return result_eca

#############################################################################

def PeakFitECA(ecaDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ecaDet          (ElementContainerArray)
    @param function        (string)
    @param param           (list/string)
    @param param_lb        (list/string)
    @param param_ub        (list/string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    """
    useConv = False
    ecaRes=mm.ElementContainerArray()

    return PeakFitECABase(ecaDet,ecaRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug,useConv)

#############################################################################

def PeakConvFitECA(ecaDet,ecaRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ecaDet          (ElementContainerArray)
    @param ecaRes          (ElementContainerArray)
    @param function        (string)
    @param param           (list/string)
    @param param_lb        (list/string)
    @param param_ub        (list/string)
    @param link_value      (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    """
    useConv = True

    return PeakFitECABase(ecaDet,ecaRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug,useConv)

#############################################################################

def listParam2Param(param,num):
    """
    listPrameter => Parameter
    """
    if(type(param)==list):
        if num<=len(param)-1:
            p1=param[num]
        else:
            p1=param[len(param)-1]
    else:
        p1=param

    return p1

#############################################################################

def PeakFitNotUseWeight(ec,function,param,param_ub,param_lb,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, AS Fit
    @param ec    (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param useDomain       (bool)
    @param NumOfItteration (int)
    @param plotflug        (bool)
    """
    useWeight=False
    return PeakFitBase(ec,function,param,param_ub,param_lb,fit_region,useDomain,NumOfItteration,plotflug,useWeight)

#############################################################################

def useJudgementConvolution(function):
    """
    @param function        (string)
    @param flug            (bool)
    """
    flugList = [function.find(c) for c in convList]

    flug = False
    for i in flugList:
        if i != -1:
            flug = True
    if flug:
        #print flugList
        #print "use Numerical Diffrential(Convolution)"
        #print ""
        pass

    return flug

#############################################################################

def ShowResultPlot(ec1,ec2):
    """
    @param ec1        (ElementContainer)
    @param ec2        (ElementContainer)
    """
    p = mp.MPlot()
    p.AddData(ec1)
    p.SetPlotParam(1,ls="-",lw=8,mk="",eb=False)
    p.AddData(ec2)

#############################################################################

def getBinNum(x_bin,binwidth,xbin_num):
    """
    """
    i1 = ( xbin_num - x_bin[0] ) / binwidth
    if i1 < 0 :
        i1 = 0
    if i1 >= x_bin.size():
        i1 = x_bin.size() - 2

    return i1

#############################################################################

def getBinNumType2(x_bin,binwidth,xbin_num):
    """
    """
    iout=0
    for i in range(x_bin.size()-1):
        if (x_bin[i]+x_bin[i+1])*0.5 < xbin_num:
            iout = i

    return iout

#############################################################################

def ShowResultParam(fittedParam,chi):
    """
    """
    s=fittedParam.getVectorSize(ml.AdvNewLevmar.PARAMETER_VALUES)
    param_result = []
    param_result_error = []
    print("##############################################################")
    print(" Fit Result ")
    print("    chiSq = ",chi)
    for i in range(s):
        pr = fittedParam.getDouble(ml.AdvNewLevmar.PARAMETER_VALUES,i)
        pre = fittedParam.getDouble(ml.AdvNewLevmar.PARAM_ERRORS,i)
        param_result.append(pr)
        param_result_error.append(pre)
        print("param%i\t%.2e\t::: param%i Error\t%.2e"%(i,pr,i,pre))
    print("##############################################################")

#############################################################################

def SetInitialParam(paramInit):
    """
    @param    paramInit(string)
    @retval   paramInit(string)
    """
    return paramInit

#############################################################################

def SetFunction(function):
    """
    @param    function (string)
    @retval   function (string)
    """
    return function

#############################################################################

def getFunction(function,paramInit,initial_bin,final_bin,delta_bin):
    """
    @param    function (string)
    @param    paramInit(string)
    @retval   dat (ElementContainer/ElementContenerArray)
    """
    ybin=[]
    ebin=[]
    xbin=[]
    ibin=[]
    num_of_bin=int(math.ceil(math.fabs((initial_bin - final_bin)/delta_bin)))

    for i in range(num_of_bin):
        ibin.append(initial_bin+i*delta_bin)

    if type(paramInit)!=list:
        paramStrList = paramInit.split(",")
        param = [float(c) for c in paramStrList]

        func = ml.AdvFuncComb(function,param)
        for i in ibin:
            ybin.append(func.eval(i))
            ebin.append(0)
            xbin.append(i-delta_bin/2)
        xbin.append(final_bin+delta_bin/2)

        dat=mm.ElementContainer()
        dat.Add("x",xbin)
        dat.Add("y",ybin)
        dat.Add("e",ebin)
        dat.SetKeys("x","y","e")
        return dat

    if type(paramInit)==list:
        paramlist_size = len(paramInit)
        eca=mm.ElementContainerArray()
        for j in range(paramlist_size):
            paramStrList = paramInit[j].split(",")
            param = [float(c) for c in paramStrList]

            func = ml.AdvFuncComb(function,param)
            ybin=[]
            ebin=[]
            xbin=[]
            for i in ibin:
                ybin.append(func.eval(i))
                ebin.append(0)
                xbin.append(i-delta_bin/2)
            xbin.append(final_bin+delta_bin/2)

            ec=mm.ElementContainer()
            ec.Add("x",xbin)
            ec.Add("y",ybin)
            ec.Add("e",ebin)
            ec.SetKeys("x","y","e")
            eca.Add(ec)

        return eca

#############################################################################

def getFittingFunction(function,paramInit,ec):
    """
    @param    function (string)
    @param    paramInit(string)
    @param    ec       (ElementCOntainer)
    @retval   dat (ElementContainer/ElementContenerArray)
    """
    ybin=[]
    ebin=[]
    ecX=ec.PutX()
    xbin = [ecX[i] for i in range(ecX.size())]
    if type(paramInit)!=list:
        paramStrList = paramInit.split(",")
        param = [float(c) for c in paramStrList]

        func = ml.AdvFuncComb(function,param)
        for i in range(len(xbin)-1):
            ybin.append(func.eval( (ecX[i]+ecX[i+1])*0.5 ))
            ebin.append(0)

        dat=mm.ElementContainer()
        dat.Add("x",xbin)
        dat.Add("y",ybin)
        dat.Add("e",ebin)
        dat.SetKeys("x","y","e")

        hh = ec.PutHeaderPointer()
        HeaderOverWrite(hh,"FittingFunc",function)
        dat.InputHeader(hh)

        return dat

    if type(paramInit)==list:
        paramlist_size = len(paramInit)
        eca=mm.ElementContainerArray()
        for j in range(paramlist_size):
            paramStrList = paramInit[j].split(",")
            param = [float(c) for c in paramStrList]

            func = ml.AdvFuncComb(function,param)
            ybin=[]
            ebin=[]
            for i in range(len(xbin)-1):
                ybin.append(func.eval((ecX[i]+ecX[i+1])*0.5))
                ebin.append(0)

            e0c=mm.ElementContainer()
            ec0.Add("x",xbin)
            ec0.Add("y",ybin)
            ec0.Add("e",ebin)
            ec0.SetKeys("x","y","e")

            hh = ec.PutHeaderPointer()
            HeaderOverWrite(hh,"FittingFunc",function)
            ec0.InputHeader(hh)
            eca.Add(ec0)

        return eca

#############################################################################
#
#def getFittingFunction(function,paramInit,ec):
#    """
#    @param    function (string)
#    @param    paramInit(string)
#    @retval   dat (ElementContainer/ElementContenerArray)
#    """
#    DetX = ec.PutX()
#    initial_bin =  DetX[0]
#    final_bin   =  DetX[DetX.size()-1]
#    delta_bin   =  DetX[1]-DetX[0]
#
#    return getFunction(function,paramInit,initial_bin,final_bin,delta_bin)
#
#############################################################################
def getEachFunction(func,param,initial_bin,final_bin,delta_bin):
    """
    """
    ybin=[]
    ebin=[]
    xbin=[]
    ibin=[]
    # calc ibin value
    num_of_bin=int(math.ceil(math.fabs((initial_bin - final_bin)/delta_bin)))
    for i in range(num_of_bin):
        ibin.append(initial_bin+i*delta_bin)

    FuncComp = mm.ElementContainerArray()
    func_list=func.split()

    # calc number of required parameter of each functions
    NumOfParamList = []
    for i in range(len(func_list)):
        func = ml.AdvFuncComb(func_list[i])
        NumOfParam = func.getNumberOfRequiredParam()
        NumOfParamList.append(NumOfParam)

    # calc parameter of each functions
    paramList = []
    l = 0
    for j in range(len(func_list)):
        paramList0 = []
        for k in range(NumOfParamList[j]):
            paramList0.append(float(param[l]))
            l += 1
        paramList.append(paramList0)

    # eval each function and fill ElementContainerArray
    for j in range(len(func_list)):
        func = ml.AdvFuncComb(func_list[j],paramList[j])
        ybin=[]
        ebin=[]
        xbin=[]
        for i in ibin:
            ybin.append(func.eval(i))
            ebin.append(0)
            xbin.append(i-delta_bin/2)
        xbin.append(final_bin+delta_bin/2)
        ec=mm.ElementContainer()
        ec.Add("x",xbin)

        if(ybin[0]!=ybin[0]):
            ec.Add("y",[0]*len(ibin))
            ec.Add("e",[0]*len(ibin))
        if(ybin[0]==ybin[0]):
            ec.Add("y",ybin)
            ec.Add("e",ebin)
        ec.SetKeys("x","y","e")
        FuncComp.Add(ec)

    return FuncComp

#############################################################################
def getFittingEachFunction(func,param,ec):
    """
    """
    ybin=[]
    ebin=[]
    ecX=ec.PutX()
    xbin = [ecX[i] for i in range(ecX.size())]

    FuncComp = mm.ElementContainerArray()
    func_list=func.split()

    # calc number of required parameter of each functions
    NumOfParamList = []
    for i in range(len(func_list)):
        func = ml.AdvFuncComb(func_list[i])
        NumOfParam = func.getNumberOfRequiredParam()
        NumOfParamList.append(NumOfParam)

    # calc parameter of each functions
    paramList = []
    l = 0
    for j in range(len(func_list)):
        paramList0 = []
        for k in range(NumOfParamList[j]):
            paramList0.append(float(param[l]))
            l += 1
        paramList.append(paramList0)

    # eval each function and fill ElementContainerArray
    for j in range(len(func_list)):
        func = ml.AdvFuncComb(func_list[j],paramList[j])

        ybin=[]
        ebin=[]
        for i in range(len(xbin)-1):
            ybin.append(func.eval((xbin[i]+xbin[i+1])*0.5))
            ebin.append(0)
        ec=mm.ElementContainer()
        ec.Add("x",xbin)

        if(ybin[0]!=ybin[0]):
            ec.Add("y",[0]*(len(xbin)-1))
            ec.Add("e",[0]*(len(xbin)-1))
        if(ybin[0]==ybin[0]):
            ec.Add("y",ybin)
            ec.Add("e",ebin)
        ec.SetKeys("x","y","e")

        FuncComp.Add(ec)

    return FuncComp

#############################################################################
#
#def getFittingEachFunction(function,paramInit,ec):
#    """
#    @param    function (string)
#    @param    paramInit(string)
#    @retval   dat (ElementContainer/ElementContenerArray)
#    """
#    DetX = ec.PutX()
#    initial_bin =  DetX[0]
#    final_bin   =  DetX[DetX.size()-1]
#    delta_bin   =  DetX[1]-DetX[0]
#
#    return getEachFunction(function,paramInit,initial_bin,final_bin,delta_bin)
#
#############################################################################

def getResidualDistribution(ec,result):
    """
    @param    ec     (ElementContainer/ElementContainerArray)
    @param    result (ElementContainer/ElementContainerArray)
    @retval   ecOut  (ElementContainer/ElementContainerArray)
    """
    if type(result)==mm.ElementContainer:
        if type(ec)==mm.ElementContainer:
            ecIn = ec
        if type(ec)==mm.ElementContainerArray:
            ecIn = ec(0)
        ecOut = getResidualDistributionBase(ecIn,result)

        return ecOut

    ecOut = mm.ElementContainerArray()
    if type(result)==mm.ElementContainerArray:
        ecaOut = mm.ElementContainerArray()
        for i in range(result.PutSize()):
            if type(ec)==mm.ElementContainer:
                ecIn = ec
            if type(ec)==mm.ElementContainerArray:
                ecIn = ec(i)
            ecOut_buf = getResidualDistributionBase(ecIn,result(i))
            ecOut.Add(ecOut_buf)

        return ecOut

#############################################################################

def getResidualDistributionBase(ecIn,result):
    """
    @param    ecIn     (ElementContainer)
    @param    result (ElementContainer)
    @retval   ecOut  (ElementContainer)
    """
    ecOut = mm.ElementContainer()
    ecIn_xbin_buf = ecIn.PutX()
    ecIn_ybin_buf = ecIn.PutY()
    ecIn_ebin_buf = ecIn.PutE()

    result_xbin = result.PutX()
    result_ybin = result.PutY()
    result_ebin = result.PutE()
    strt_bin = 0
    end_bin  = 0
    if (ecIn_xbin_buf.size() == result_xbin.size()):
        ecIn_xbin = ecIn_xbin_buf
        ecIn_ybin = ecIn_ybin_buf
        ecIn_ebin = ecIn_ebin_buf
    if (ecIn_xbin_buf.size() != result_xbin.size()):
        for i in range(ecIn_xbin_buf.size()):
            #print "#",result_xbin[0],ecIn_xbin_buf[i],result_xbin[result_xbin.size()-1]
            if (abs(result_xbin[0] - ecIn_xbin_buf[i]) < 1e-10):
                start_bin = i
            if (abs(result_xbin[result_xbin.size()-1] - ecIn_xbin_buf[i]) < 1e-10):
                end_bin = i
        #if start_bin == 0 or end_bin ==0: #20120921 "start_bin ==0"condition is removed
        if end_bin == 0:
            print("end_bin == 0")
            return ecOut

        ecIn_xbin = []
        ecIn_ybin = []
        ecIn_ebin = []
        for i in range(start_bin,end_bin):
            ecIn_xbin.append(ecIn_xbin_buf[i])
            ecIn_ybin.append(ecIn_ybin_buf[i])
            ecIn_ebin.append(ecIn_ebin_buf[i])
        ecIn_xbin.append(ecIn_xbin_buf[end_bin])

    ecOut_xbin=result_xbin
    ecOut_ybin=[]
    ecOut_ebin=[]
    for i in range(result_xbin.size()-1):
        if i<len(ecIn_ebin):
            if ecIn_ebin[i] !=0:
                ecOut_ybin.append((ecIn_ybin[i]-result_ybin[i])/ecIn_ebin[i])
            if ecIn_ebin[i] ==0:
                ecOut_ybin.append(0)
            ecOut_ebin.append(0)
        else:
            ecOut_ybin.append(0)
            ecOut_ebin.append(0)

    ecOut.Add("x",ecOut_xbin)
    ecOut.Add("y",ecOut_ybin)
    ecOut.Add("e",ecOut_ebin)
    ecOut.SetKeys("x","y","e")

    return ecOut

#############################################################################

def PeakSearchSimple(ec,window_width,num_of_peak):
    """
    PeakSearch script , AS PeakSearch
    @param ec (ElementContainer)
    @param window_width (int)
    @param num_of_peak  (int)
    @retval outputPeakDataText (string)
    """
    pk = ml.AdvPeakSearch(ec,ml.MOVING_AVERAGE)
    pk.setDefaultParam()
    pk.setParam(ml.AdvMovingAverage.WINDOW_WIDTH,window_width)
    window_upper = int(math.ceil(window_width/2))
    pk.setParam(ml.AdvMovingAverage.WINDOW_UPPER,window_upper)
    #pk.setDomain(lower_bin,upper_bin)

    pk.execute()
    pl=pk.getPeaks()
    v = pl.toVector()
    #pl.Dump()

    peakData=[]
    for i in range(v.size()):
        if i%3==0:
            eachPeakData=[]
            eachPeakData.append(float(v[i]))
        if i%3==1:
            eachPeakData.append(float(v[i]))
        if i%3==2:
            eachPeakData.append(float(v[i]))
            peakData.append(eachPeakData)
    peakData.sort(cmp = lambda x , y: cmp(-x[0],-y[0]) )

    outputPeakData=[]
    outputPeakDataText=""
    #print"[height,position,width]"
    for i in range(int(num_of_peak)):
        #outputPeakData.append(peakData[i])
        outputPeakData.append([ peakData[i][0]*peakData[i][2]*math.pi,peakData[i][1],peakData[i][2] ])
        #print outputPeakData[i]
        if i != int(num_of_peak)-1:
            outputPeakDataText+="%.2f,%.2f,%.2f,"%(outputPeakData[i][0],outputPeakData[i][1],outputPeakData[i][2])
            #print "%.2f,%.2f,%.2f,"%(outputPeakData[i][0],outputPeakData[i][1],outputPeakData[i][2]),
        if i == int(num_of_peak)-1:
            outputPeakDataText+="%.2f,%.2f,%.2f"%(outputPeakData[i][0],outputPeakData[i][1],outputPeakData[i][2])
            #print "%.2f,%.2f,%.2f"%(outputPeakData[i][0],outputPeakData[i][1],outputPeakData[i][2])
    return outputPeakDataText

#############################################################################

def HeaderOverWrite(hh,name,val):
        if (hh.CheckKey(name)==0):
            hh.Add(name,val)
        elif (hh.CheckKey(name)==1):
            hh.OverWrite(name,val)

#############################################################################
#ReadData
#ecaDet = ReadDataECA("ECA_637miya.bst")
#ecaRes = ReadDataECA("ECA_647miya.bst")
#p = mp2.M2Plot(ecaDet)

##QEMask
#QEfilename = "QEMask.txt"
#DoQEMask(ecaDet,QEfilename)

# Q-Slice test-1
#lowerQ = 0.0
#upperQ = 2.0
#ecRes = SliceQE(ecaRes,lowerQ,upperQ)

# Q-Slice test-2
#initialQ =  0.0
#finalQ =    1.0
#deltaQ =    0.1
#eca = SliceQEall(ecaDet,initialQ,finalQ,deltaQ)

# Q-Slice test-3
#Q_list_string = "0.0,0.1,0.3,0.5,0.7,0.9,1.3,1.6,2.0"
#ecaDetS = SliceQEbyText(ecaDet,Q_list_string)
#ecaResS = SliceQEbyText(ecaRes,Q_list_string)

#SelectFittingQbin(eca,"t")
#SelectFittingQbin(ecaDetS,"t,t,t,t,t,t,t,f")
#SelectFittingQbin(ecaDetS,"f,t,t,t,t,f,f,f")

#CheckQbin(ecaDetS)

## set Fitting Parameter
#fit_region = "-0.1,0.1"
#useDomain = False
#useDomain = True
#NumOfItteration = 1000
#plotflug = True

## peakSearch
#peakData = PeakSearchSimple(ecaDetS(3),1,1)

#function = SetFunction("lc dc")

#param set common
#param       = SetInitialParam("40,0.0,2e-2,0.0,8000") #0 lc dc

#lc dc
#param       = SetInitialParam("10 ,   0.0, 2e-2,   0.0,8000") #1,2,3,4,--5,6,7 lc dc
#param_ub    = SetInitialParam("100, 0.001,  1,   0.001,80000")
#param_lb    = SetInitialParam("1  ,-0.001, 1e-4,-0.001,  100")

#param set each ec
#param = []
#param.append(SetInitialParam("10 ,0,5e-2"))
#param.append(SetInitialParam("10 ,0,5e-2"))
#param.append(SetInitialParam("200,0,5e-2"))
#param.append(SetInitialParam("80,0,5e-2"))
#param.append(SetInitialParam("30 ,0,5e-2"))
#param.append(SetInitialParam("20 ,0,5e-2"))

## fitting single
#result   = PeakConvFitEC(ecaDetS(2),ecaResS(2),function,param,param_ub,param_lb,fit_region,useDomain,NumOfItteration,plotflug)

## fitting multi
# QENS_Base de NumOfItteration,plotflug ha settei
#result = PeakConvFitECA(ecaDetS,ecaResS,function,param,param_ub,param_lb,fit_region,useDomain,NumOfItteration,plotflug)

## get ElementContainer of fitted function
#ecInit   = getFittingFunction(function,param,ecaDetS(0))

## get residual data(EC) between original-data and fitting-result-function 
#residual = getResidualDistribution(ecInit,result)

## plot fitting parameter 
#ecP = getFittingParameterEC(result,0,"Q")
#ecP = getFittingParameterEC(result,"x","Q")

## plot EISF 
#ecP=getEisfEC(result,"0,2","4","Q2")
#ecP=getEisfEC(result,"4,1,2","0,4","Q2")
#p=mp.MPlot()
#p.AddData(ecP)
