# -*- coding: utf-8 -*-
from __future__ import print_function
import Manyo as mm
#import ana.Reduction.BaseCommands as BaseCom
import utsusemi.DNA.ana.Reduction.SliceBase as Slice
import utsusemi.DNA.ana.Reduction.PeakFitBase as PF
import utsusemi.DNA.ana.Reduction.DataFormatBase as DFB

#import ana.Reduction.ElasticScanBase as ES
#import vis.MPlot as mp
#import vis.M2Plot as mp2
import os
import time
import math

#########################################
#
#def getDataOfDNA(runNo=314,HwParam=" ",LambParam=" ",QParam=" ",TimeParam=" ",initFile="GetQEDataOfDNA.ini",outputData="QE",fileTag="_",search_dir=""):
#    """
#    Load EventData and convert to QE map
#    - GetHistogramHW(runNo,dHW,hw_min,hw_max,tof_offset,startTime,endTime)
#    - DoMask(DAT)
#    - ILambdaCorrDNA(dat,ec)
#    - SolidAngleCorrDNA(dat)
#    - CreateQEMap(dat,startQ,endQ,deltaQ)
#
#    @param runNo        (int) Run Number
#    @param HwParam      (string)
#    @param LambParam    (string)
#    @param QParam       (string)
#    @param TimeParam    (string)
#    @param initFile     (string)
#    @param fileTag      (string)   
#    @retval ECM      (ElementContainerMatrix)
#    """
#
#    return ES.GetDataOfDNA(runNo, HwParam, LambParam, QParam, TimeParam, initFile, outputData, fileTag,search_dir)
#
#############################################################################

def sliceQE(dat,lowerQ,upperQ):
    """
    最小値、最大値を入力して、その範囲に含まれるECを返す。
    @param dat       (ElementContaienrArray)
    @param lowerQ    (double) lowerQ
    @param upperQ    (double) upperQ
    @retval ec    (ElementContainer)
    """
    return Slice.SliceQE(dat,lowerQ,upperQ)

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

def setQbin(dat,initialQ,finalQ,deltaQ):
    """
    最小値、最大値、刻み幅を入力して、Qビニングを行う。
    @param dat       (ElementContaienrArray)
    @param initialQ  (double)
    @param finalQ    (double)
    @param deltaQ    (double)
    """
    return Slice.SliceQEall(dat,initialQ,finalQ,deltaQ)

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

def setQbinbyText(dat,Q_list_string):
    """
    カンマ区切りテキストのテーブルを新しいQの境界として、Qビニングを行う。
    @param dat    (ElementContaienrArray)
    @param Q_list_string         (string)
    """
    return Slice.SliceQEbyText(dat,Q_list_string)

##########################################
#
def setEbinForECA(eca,initial,final,delta):
    """
    最小値、最大値、刻み幅を入力してECAをEビニングを行う。
    @param  eca        (ElementContaienrArray)
    @param  initial    (double)
    @param  final      (double)
    @param  delta      (double)
    """
    return Slice.OutputECABinning(eca,initial,final,delta)

##########################################
#
def setEbinForEC(ec,initial,final,delta):
    """
    最小値、最大値、刻み幅を入力してECをEビニングを行う。
    @param  ec         (ElementContaienr)
    @param  initial    (double)
    @param  final      (double)
    @param  delta      (double)
    """
    return Slice.OutputECBinning(ec,initial,final,delta)

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

def setEbin(ec,initial,final,delta):
    """
    最小値、最大値、刻み幅を入力してEビニングを行う。
    @param  ec         (ElementContainer/Array)
    @param  initial    (double)
    @param  final      (double)
    @param  delta      (double)
    """
    if type(ec) == mm.ElementContainer:
        return setEbinForEC(ec,initial,final,delta)
    if type(ec) == mm.ElementContainerArray:
        return setEbinForECA(ec,initial,final,delta)

##########################################
#
#def setEbinForECA(eca,initial,final):
#    """
#    @param  eca        (ElementContaienrArray)
#    @param  initial    (double)
#    @param  final      (double)
#    """
#    return Slice.OutputPartOfECA(eca,initial,final)
#
##########################################
#
#def setEbinForEC(ec,initial,final):
#    """
#    @param  ec         (ElementContaienr)
#    @param  initial    (double)
#    @param  final      (double)
#    """
#    return Slice.OutputPartOfEC(ec,initial,final)
#
##########################################
#
#def setEbin(ec,initial,final):
#    """
#    @param  ec         (ElementContainer/Array)
#    @param  initial    (double)
#    @param  final      (double)
#    """
#    if type(ec) == mm.ElementContainer:
#        return setEbinForEC(ec,initial,final)
#    if type(ec) == mm.ElementContainerArray:
#        return setEbinForECA(ec,initial,final)
#
##########################################

def getIntegralHWData(dat,emin,emax):
    """
    I(Q,E)を入力し、入力した範囲にE方向に積分したI(Q)の数値リストを返す。
    @param dat    (ElementContaienrArray)
    @param emiin   (float)
    @param emax    (float)
    @retval ret    (list)
    """
    if dat==None:
        null_list=[]
        return [null_list,null_list,null_list]

    if emin==emax:

        dat_X_min=[dat.Put(i).PutX()[0] for i in range(dat.PutTableSize())]
        dat_X_max=[dat.Put(i).PutX()[-1] for i in range(dat.PutTableSize())]

        emin = min(dat_X_min)
        emax = max(dat_X_max)

    ec = getIntegralHW(dat,emin,emax)

    resultECX=ec.PutX()
    resultECY=ec.PutY()
    resultECE=ec.PutE()

    resultDataX=[(resultECX[i]+resultECX[i+1])*0.5 for i in range(resultECX.size()-1)]
    resultDataY=[resultECY[i] for i in range(resultECY.size())]
    resultDataE=[resultECE[i] for i in range(resultECE.size())]

    resultlist=[resultDataX,resultDataY,resultDataE]

    return resultlist
##########################################

def getIntegralHW(dat,emin,emax):
    """
    I(Q,E)を入力し、入力した範囲にE方向に積分したI(Q)のECを返す。
    @param dat     (ElementContaienrArray)
    @param emin    (double)
    @param emax    (double)
    @retval EC     (ElementContainer)
    """
    num_of_bin = dat.PutSize()
    Xbin = []
    Ybin = []
    Ebin = []
    import utsusemi.DNA.ana.Reduction.PeakIntegral as PI
    xinitial=dat(0).PutHeader().PutDoubleVector("XRANGE")
    xbuf = xinitial[0]
    Xbin.append(xbuf)

    for i in range(num_of_bin):
       ec = dat(i)
       hh = ec.PutHeader()
       Xrange = hh.PutDoubleVector("XRANGE")
       dX=(Xrange[1]-Xrange[0])
       XCenter=dX*0.5+Xrange[0]

       sum_val,sum_val_e = PI.GetECPeakIntegral(ec,emin,emax)

       if (sum_val == sum_val):
           xbuf=xbuf + (XCenter-xbuf)*2
           Xbin.append(xbuf)
           Ybin.append(sum_val)
           Ebin.append(sum_val_e)

    EC = mm.ElementContainer()
    EC.Add("x",Xbin,"meV")
    EC.Add("y",Ybin,"")
    EC.Add("e",Ebin)
    EC.SetKeys("x","y","e")
    
    return EC

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

def selectFittingQbin(dat,fitlist):
    """
    カンマ区切り文字列で指定したBoolにより、Fittingを行うかどうかを書き込む。
    @param dat        (ElementContaienrArray)
    @param fitlist    (string)
    @retval None
    """
    eca_size = dat.PutSize()

    if (fitlist == "t" or fitlist == "T"):
        fitlist = "t"
        for i in range(eca_size-1):
            fitlist += ",t"
    if (fitlist == "f" or fitlist == "F"):
        fitlist = "f"
        for i in range(eca_size-1):
            fitlist += ",f"
    fitlist_v=fitlist.split(",")

    if len(fitlist_v)!=eca_size:
        print("eca_size and fitlist is incorrect!!")
    if len(fitlist_v)==eca_size:
        for j in range(eca_size):
            hh = dat(j).PutHeader()
            if (hh.CheckKey("FIT")==0):
                hh.Add("FIT",fitlist_v[j])
            if (hh.CheckKey("FIT")==1):
                hh.OverWrite("FIT",fitlist_v[j])
            dat(j).InputHeader(hh)

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

def CheckQbin(dat):
    """
    Fittingを行うかどうかのCheck。標準出力へ書き込む。
    @param dat    (ElementContaienrArray)
    @retval eca None
    """
    print("Qens >>  ## Check Fitting Q bin ##")
    print("Qens >>  Q_bin")
    print("Qens >>      // Fittinng")
    print("Qens >>  -------------------------")

    eca_size = dat.PutSize()
    for i in range(eca_size):
        Xrange = dat(i).PutHeaderPointer().PutDoubleVector("XRANGE")

        hh = dat(i).PutHeaderPointer()
        if (hh.CheckKey("FIT")==0):
            hh2 = "Not Setting"
        if (hh.CheckKey("FIT")==1):
            if (hh.PutString("FIT") == "t" or hh.PutString("FIT") == "T"):
                hh2 = "True"
            else:
                hh2 = "False"
        print("Qens >>  ",str(Xrange[0])) 
        print("Qens >>      > "+hh2)

    Xrange_final = dat(eca_size-1).PutHeaderPointer().PutDoubleVector("XRANGE")
    print("Qens >>  ",Xrange_final[1])
    Xbin = dat(0).PutX()
    emin = Xbin[0]
    emax = Xbin[Xbin.size()-1]

    return getIntegralHW(dat,emin,emax)

##########################################
def DoQEMask(eca, QEfilename):
    """
    QEマスクを実行する
    @param eca (ElementContainerArray)
    @param filename (string)
    @retval None
    """
    return Slice.DoQEMask(eca, QEfilename)

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

def transpose(ccIn):
    """
    入力したListを転置させる。
    @param ccIn   (list)
    @retval ccOut (list)
    """
    ccOut = []
    for j in range(len(ccIn[0])):
        ccOut.append([ccIn[i][j] for i in range (len(ccIn))])

    return ccOut

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

def getFittingParameterEC(result_eca,parameter,axis):
    """
    パラメータプロットの数値データを返す。
    @param result_eca  (ElementContainerArray)
    @param parameter   (int/string)
    @param axis        (string)
    @retval ecOut      (ElementContainer)
    """
    xbinc = []
    xbin = []
    ybin = []
    ebin = []
    ebin2 = []
    ybinAll = []
    ebinAll = []

    ecOut=mm.ElementContainer()
    if type(result_eca)== mm.ElementContainer:
        print("ECA fitting(-multi fitting) is not performed")
        print("input is ElementContainer")
    if type(result_eca)== mm.ElementContainerArray:
        ecaSize = result_eca.PutSize()
        for i in range(ecaSize):
            if type(parameter)==str:
                hh = result_eca(i).PutHeaderPointer()
                XRange=hh.PutDoubleVector("XRANGE")
                CenterVal = (XRange[0]+XRange[1])*0.5
                xbinc.append(CenterVal)

                valAll,valeAll=checkFittingParam(-1,hh)
                ybinAll.append(valAll)
                ebinAll.append(valeAll)

        xbinNew=[]
        if len(ybinAll)>0:
            import utsusemi.DNA.ana.Reduction.ParamPlotBase as eisf 
            eisfY=eisf.eisf()

            print("Function >> ",parameter)
            param    = transpose(ybinAll)
            paramErr = transpose(ebinAll)
#            ybin=eisfY.main(parameter,param)
            ybin,ebin=eisfY.mainWithError(parameter,param,paramErr)

            eisfX=eisf.eisf()
            xbinNew,ebin2=eisfX.mainWithError(axis,param,paramErr)

        if (xbinNew==[]):
            xbin.append((-xbinc[1]+3*xbinc[0])*0.5)
            for i in range(len(xbinc)):
                xbin.append(2*xbinc[i]-xbin[i])
        else:
            xbin.append((-xbinNew[1]+3*xbinNew[0])*0.5)
            for i in range(len(xbinNew)):
                xbin.append(2*xbinNew[i]-xbin[i])

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

        ec.SetKeys("x","y","e")

        hh = ec.PutHeader()
        if type(parameter)==str:
            hh.Add("Param",parameter)
        if type(parameter)==int:
            hh.Add("Param",str(parameter))

    print("")
    print("  [ Plot Fitting Parameter ]")
    print("  Parameter = "+str(parameter))
    print("  Q\tval")
    print("")
    for i in range(len(ybin)):
        print((xbin[i]+xbin[i+1])*0.5, ybin[i],ebin[i])
    return ec

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

def getFittingParameterData(result_eca,parameter,axis):
    """
    パラメータプロットのElementContainerを返す。
    @param result_eca  (ElementContainerArray)
    @param parameter   (int/string)
    @param axis        (string)
    @retval resultlist      (list)
    """
    ec = getFittingParameterEC(result_eca,parameter,axis)

    resultECX=ec.PutX()
    resultECY=ec.PutY()
    resultECE=ec.PutE()

    resultDataX=[(resultECX[i]+resultECX[i+1])*0.5 for i in range(resultECX.size()-1)]
    resultDataY=[resultECY[i] for i in range(resultECY.size())]
    resultDataE=[resultECE[i] for i in range(resultECE.size())]
    flag = False
    for res in resultDataE:
        if res!=0.0:
            flag=True
    if flag:
        while 1:
            if 0.0 in resultDataE:
                ind = resultDataE.index(0.0)
                resultDataX.pop(ind)
                resultDataY.pop(ind)
                resultDataE.pop(ind)
            else:
                break

    resultlist=[resultDataX,resultDataY,resultDataE]

    return resultlist

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

def checkFittingParam(Comp,hh):
    """
    ヘッダーに含まれるFitting結果の指定したパラメータ結果の値と誤差をタプルで返す。
    @param Comp  (int)
    @param hh    (HeaderBase)
    """
    if type(Comp)==int:
        param = str(Comp)
        if Comp>=0:
            if (hh.CheckKey("FittingParam"+param)==0):
                print("Fitting parameter no."+param+" is not available")
                val = 0
                vale = 0
            else:
                val = hh.PutDouble("FittingParam"+param)
                vale = hh.PutDouble("FittingParamErr"+param)
        else:
            val=[]
            vale=[]
            param="0"
            while hh.CheckKey("FittingParam"+param)==1:
                val_tmp = hh.PutDouble("FittingParam"+param)
                vale_tmp = hh.PutDouble("FittingParamErr"+param)

                if val_tmp=="nan":
                    val_tmp=0
                if vale_tmp=="nan":
                    vale_tmp=0

                val.append(val_tmp)
                vale.append(vale_tmp)

                param=str(int(param)+1)

            XRange=hh.PutDoubleVector("XRANGE")   #20130124 add-line, start
            CenterVal = (XRange[0]+XRange[1])*0.5
            val.append(CenterVal)
            vale.append(0)                        #20130124 add-line, end
    else:
        val = 0
        vale = 0

    return val,vale

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

def getFittingParamResult(result):
    """
    全フィッティングパラメータ結果の値、誤差をQ毎のListにして返す
    @param result          (ElementContainerArray)
    """
    paramList=[]
    if type(result) == mm.ElementContainerMatrix:
        fit_result_eca = result.Put(0)
        num_of_Q = fit_result_eca.PutSize()
        hh=fit_result_eca(0).PutHeaderPointer()

        for i in range(num_of_Q):
            hh=fit_result_eca(i).PutHeaderPointer()
            paramListEachRes = []
            paramListEachErr = []

            if (hh.CheckKey("ChiSq")==1):
                chisq = hh.PutDouble("ChiSq")
                flug = True
                if chisq==chisq:
                    pnum = 0
                    while flug:
                        if (hh.CheckKey("FittingParam"+str(pnum))==1):
                            paramListEachRes.append(hh.PutDouble("FittingParam"+str(pnum)))
                            paramListEachErr.append(hh.PutDouble("FittingParamErr"+str(pnum)))
                            pnum += 1
                        if (hh.CheckKey("FittingParam"+str(pnum))==0):
                            flug = False
                elif chisq!=chisq:
                    pnum = 0
                    while flug:
                        if (hh.CheckKey("FittingParam"+str(pnum))==1):
                            paramListEachRes.append(0)
                            paramListEachErr.append(0)
                            pnum += 1
                        if (hh.CheckKey("FittingParam"+str(pnum))==0):
                            flug = False

            paramListEach = [paramListEachRes,paramListEachErr]
            paramList.append(paramListEach)

    if type(result) == mm.ElementContainerArray:

        fit_result_ec = result.Put(0)
        hh=fit_result_ec.PutHeaderPointer()
        paramListRes = []
        paramListErr = []
        flug = True
        if (hh.CheckKey("ChiSq")==1):
            chisq = hh.PutDouble("ChiSq")
            if chisq==chisq:
                pnum = 0
                while flug:
                    if (hh.CheckKey("FittingParam"+str(pnum))==1):
                        paramListRes.append(hh.PutDouble("FittingParam"+str(pnum)))
                        paramListErr.append(hh.PutDouble("FittingParamErr"+str(pnum)))
                        pnum += 1
                    if (hh.CheckKey("FittingParam"+str(pnum))==0):
                        flug = False
            elif chisq!=chisq:
                pnum = 0
                while flug:
                    if (hh.CheckKey("FittingParam"+str(pnum))==1):
                        paramListRes.append(hh.PutDouble(0))
                        paramListErr.append(hh.PutDouble(0))
                        pnum += 1
                    if (hh.CheckKey("FittingParam"+str(pnum))==0):
                        flug = False
        paramList = [paramListRes,paramListErr]

    return paramList

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

def peakConvFitEC(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar(with Covolution),for EC
    @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)
    @retval result_eca     (ElementContainerArray)
    """
    result_eca = mm.ElementContainerArray()
    function=replacePlusStr(function)
    result_ec_buf =  PF.PeakConvFitEC(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)

    if (result_ec_buf.PutY())[0]!=(result_ec_buf.PutY())[0]:
        result_ec = mm.ElementContainer(result_ec_buf.PutHeader())
        result_ec.Add("x",(result_ec_buf.PutX()))
        result_ec.Add("y",[0]*(len(result_ec_buf.PutY())))
        result_ec.Add("e",[0]*(len(result_ec_buf.PutY())))
        result_ec.SetKeys("x","y","e")
    else:
        result_ec = result_ec_buf

    if type(param)==list:
        p1 = param[0]
    if type(param)!=list:
        p1 = param
    initial_ec = PF.getFittingFunction(function,p1,ecDet)
    residual_ec = PF.getResidualDistribution(ecDet,result_ec)

    result_ec.SetUnit(result_ec.PutXKey(),'meV')
    result_ec.SetUnit(result_ec.PutYKey(),'')
    initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
    initial_ec.SetUnit(initial_ec.PutYKey(),'')
    residual_ec.SetUnit(residual_ec.PutXKey(),'meV')
    residual_ec.SetUnit(residual_ec.PutYKey(),'')
    ecDet.SetUnit(ecDet.PutXKey(),'meV')
    ecDet.SetUnit(ecDet.PutYKey(),'')

    result_eca.Add(result_ec)
    result_eca.Add(ecDet)
    result_eca.Add(initial_ec)
    result_eca.Add(residual_ec)
    result_eca.Add(ecRes)
    #ShowResultECFit(result_eca)
    return result_eca

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

def peakConvFitECA(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar,(with Covolution),for ECA
    @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)
    @retval result_ecm     (ElementContainerMatrix)
    """
    function=replacePlusStr(function)
    result_eca_buf = PF.PeakConvFitECA(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)

    initial_eca  = mm.ElementContainerArray()
    observed_eca = mm.ElementContainerArray()
    residual_eca = mm.ElementContainerArray()
    result_eca   = mm.ElementContainerArray()
    resolution_eca = mm.ElementContainerArray()
    result_ecm = mm.ElementContainerMatrix()

    for i in range(result_eca_buf.PutSize()):
        if ((result_eca_buf.Put(i)).PutY())[0]!=((result_eca_buf.Put(i)).PutY())[0]:

            result_tmp = mm.ElementContainer(result_eca_buf.Put(i).PutHeader())
            result_tmp.Add("x",(result_eca_buf.Put(i)).PutX())
            result_tmp.Add("y",[0]*(len((result_eca_buf.Put(i)).PutY())))
            result_tmp.Add("e",[0]*(len((result_eca_buf.Put(i)).PutY())))
            result_tmp.SetKeys("x","y","e")
        else:
            result_tmp = result_eca_buf.Put(i)

        result_tmp.SetUnit(result_tmp.PutXKey(),'meV')
        result_tmp.SetUnit(result_tmp.PutYKey(),'')
        result_eca.Add(result_tmp)

    j=0
    for i in range(ecDet.PutSize()):
        PF.SetResolutionData(ecRes(i))
        hh = ecDet(i).PutHeaderPointer()
        fit_flug = False
        if (hh.CheckKey("FIT")==1):
            if (hh.PutString("FIT") == "t" or hh.PutString("FIT") == "T"):
                fit_flug = True
        elif (hh.CheckKey("FIT")==0):
                hh.Add("FIT","t")
                fit_flug = True
        if fit_flug:
            if type(param) == list:
                if i<len(param):
                    initial_ec = PF.getFittingFunction(function,param[i],ecDet(i))
                else:
                    initial_ec = PF.getFittingFunction(function,param[len(param)-1],ecDet(i))
            if type(param) == str:
                initial_ec = PF.getFittingFunction(function,param,ecDet(i))
            if (type(param) == str) or (type(param) == list):
                initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
                initial_ec.SetUnit(initial_ec.PutYKey(),'')
                initial_eca.Add(initial_ec)
            residual_ec = PF.getResidualDistribution(ecDet(i),result_eca(j))
            residual_ec.SetUnit(initial_ec.PutXKey(),'meV')
            residual_ec.SetUnit(initial_ec.PutYKey(),'')
            ecDet(i).SetUnit(ecDet(i).PutXKey(),'meV')
            ecDet(i).SetUnit(ecDet(i).PutYKey(),'')
            residual_eca.Add(residual_ec)
            observed_eca.Add(ecDet(i))
            resolution_eca.Add(ecRes(i))
            j+=1
        else:#20121226
            if type(param) == list:
                if i<len(param):
                    initial_ec = PF.getFittingFunction(function,param[i],ecDet(i))
                else:
                    initial_ec = PF.getFittingFunction(function,param[len(param)-1],ecDet(i))
            if type(param) == str:
                initial_ec = PF.getFittingFunction(function,param,ecDet(i))
            if (type(param) == str) or (type(param) == list):
                initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
                initial_ec.SetUnit(initial_ec.PutYKey(),'')
                initial_eca.Add(initial_ec)
            residual_ec = PF.getResidualDistribution(ecDet(i),initial_ec)
            residual_ec.SetUnit(initial_ec.PutXKey(),'meV')
            residual_ec.SetUnit(initial_ec.PutYKey(),'')
            ecDet(i).SetUnit(ecDet(i).PutXKey(),'meV')
            ecDet(i).SetUnit(ecDet(i).PutYKey(),'')
            residual_eca.Add(residual_ec)
            observed_eca.Add(ecDet(i))
            resolution_eca.Add(ecRes(i))
            j+=1

    result_ecm.Add(result_eca)
    result_ecm.Add(observed_eca)
    result_ecm.Add(initial_eca)
    result_ecm.Add(residual_eca)
    result_ecm.Add(resolution_eca)

    # re-define result_eca and rsidual distribution
    # Manyoに組み込んだ関数の結果出力のビン数が一つ少ないので計算をし直す。
     # それに伴い残渣も計算し直す。(test)


    result_eca=getTotalResultDistribution(result_ecm)
    while result_ecm.PutTableSize()!=0:
        result_ecm.EraseElement(0)

    result_ecm.Add(result_eca)
    result_ecm.Add(observed_eca)
    result_ecm.Add(initial_eca)
    result_ecm.Add(residual_eca)
    result_ecm.Add(resolution_eca)

    residual_eca=getResidualDistribution(result_ecm)
    result_ecm.EraseElement(4)
    result_ecm.EraseElement(3)
    result_ecm.Add(residual_eca)
    result_ecm.Add(resolution_eca)

    return result_ecm

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

def peakConvFit(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, (with Covolution)
    @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)
    @retval result_ecm     (ElementContainerMatrix)
    """
    if type(ecDet) == mm.ElementContainer:
        return peakConvFitEC(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)
    if type(ecDet) == mm.ElementContainerArray:
        return peakConvFitECA(ecDet,ecRes,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)

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

def peakFitEC(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, (without Covolution),for EC
    @param ecDet           (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param link_value      (string)
    @param useDomain       (bool)
    @retval result_eca     (ElementContainerArray)
    """
    result_eca = mm.ElementContainerArray()
    function=replacePlusStr(function)
    result_ec_buf = PF.PeakFitEC(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)

    if (result_ec_buf.PutY())[0]!=(result_ec_buf.PutY())[0]:
        result_ec = mm.ElementContainer(result_ec_buf.PutHeader())
        result_ec.Add("x",(result_ec_buf.PutX()))
        result_ec.Add("y",[0]*(len(result_ec_buf.PutY())))
        result_ec.Add("e",[0]*(len(result_ec_buf.PutY())))
        result_ec.SetKeys("x","y","e")
    else:
        result_ec = result_ec_buf

    initial_ec = PF.getFittingFunction(function,param,ecDet)
    residual_ec = PF.getResidualDistribution(ecDet,result_ec)

    result_eca.Add(result_ec)
    result_eca.Add(ecDet)
    result_eca.Add(initial_ec)
    result_eca.Add(residual_ec)
    result_eca.Add(ecRes)

    #ShowResultECFit(result_eca)
    return result_eca

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

def peakFitECA(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, (without Covolution),for ECA
    @param ecDet           (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param link_value      (string)
    @param useDomain       (bool)
    @retval result_ecm     (ElementContainerMatrix)
    """
    initial_eca  = mm.ElementContainerArray()
    observed_eca = mm.ElementContainerArray()
    resolution_eca = mm.ElementContainerArray()
    residual_eca = mm.ElementContainerArray()
    result_eca   = mm.ElementContainerArray()

    result_ecm = mm.ElementContainerMatrix()
    function=replacePlusStr(function)
    result_eca_buf = PF.PeakFitECA(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)

    for i in range(result_eca_buf.PutSize()):
        if ((result_eca_buf.Put(i)).PutY())[0]!=((result_eca_buf.Put(i)).PutY())[0]:

            result_tmp = mm.ElementContainer(result_eca_buf.Put(i).PutHeader())
            result_tmp.Add("x",(result_eca_buf.Put(i)).PutX())
            result_tmp.Add("y",[0]*(len((result_eca_buf.Put(i)).PutY())))
            result_tmp.Add("e",[0]*(len((result_eca_buf.Put(i)).PutY())))
            result_tmp.SetKeys("x","y","e")
        else:
            result_tmp = result_eca_buf.Put(i)

        result_tmp.SetUnit(result_tmp.PutXKey(),'meV')
        result_tmp.SetUnit(result_tmp.PutYKey(),'')
        result_eca.Add(result_tmp)

    j=0
    for i in range(ecDet.PutSize()):
        hh = ecDet(i).PutHeaderPointer()
        fit_flug = False
        if (hh.CheckKey("FIT")==1):
            if (hh.PutString("FIT") == "t" or hh.PutString("FIT") == "T"):
                fit_flug = True
        elif (hh.CheckKey("FIT")==0):
                hh.Add("FIT","t")
                fit_flug = True
        if fit_flug:
            if type(param) == list:
                if i<len(param):
                    initial_ec = PF.getFittingFunction(function,param(i),ecDet(i))
                else:
                    initial_ec = PF.getFittingFunction(function,param(len(param)-1),ecDet(i))
            if type(param) == str:
                initial_ec = PF.getFittingFunction(function,param,ecDet(i))
            if (type(param) == str) or (type(param) == list):
                initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
                initial_ec.SetUnit(initial_ec.PutYKey(),'')
                initial_eca.Add(initial_ec)
            residual_ec = PF.getResidualDistribution(ecDet(i),result_eca(j))
            residual_ec.SetUnit(initial_ec.PutXKey(),'meV')
            residual_ec.SetUnit(initial_ec.PutYKey(),'')
            ecDet(i).SetUnit(ecDet(i).PutXKey(),'meV')
            ecDet(i).SetUnit(ecDet(i).PutYKey(),'')
            residual_eca.Add(residual_ec)
            observed_eca.Add(ecDet(i))
            resolution_eca.Add(ecRes(i))
            j+=1

    result_ecm.Add(result_eca)
    result_ecm.Add(observed_eca)
    result_ecm.Add(initial_eca)
    result_ecm.Add(residual_eca)
    result_ecm.Add(resolution_eca)
    #ShowResultECAFit(result_ecm)
    return result_ecm

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

def peakFit(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug):
    """
    PeakFitting script by using Levmar, (without Covolution)
    @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)
    @retval result_ecm     (ElementContainerMatrix)
    """
    if type(ecDet) == mm.ElementContainer:
        return peakFitEC(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)
    if type(ecDet) == mm.ElementContainerArray:
        return peakFitECA(ecDet,function,param,param_ub,param_lb,link_value,fit_region,useDomain,NumOfItteration,plotflug)

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

def getConvFitGuessEC(ecDet,ecRes,function,param,fit_region,plotflug):
    """
    Fitting初期値の計算、QensFitAnaでは未使用、(with Covolution) for EC
    @param ecDet           (ElementContainer)
    @param ecRes           (ElementContainer)
    @param function        (string)
    @param param           (string)
    @param param_lb        (string)
    @param param_ub        (string)
    @param useDomain       (bool)
    @retval result_eca     (ElementContainerArray)
    """
    result_eca = mm.ElementContainerArray()
    result_ec =  NoneEC()
    function=replacePlusStr(function)
    PF.SetResolutionData(ecRes)

    if type(param)==list:
        paramInit = param[0]
        print("input type of Param was list")
        print("first parameter was selected")
    if type(param)==str:
        paramInit = param

    initial_ec = PF.getFittingFunction(function,paramInit,ecDet)
    residual_ec = PF.getResidualDistribution(ecDet,initial_ec)

    result_ec.SetUnit(result_ec.PutXKey(),'meV')
    result_ec.SetUnit(result_ec.PutYKey(),'')
    initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
    initial_ec.SetUnit(initial_ec.PutYKey(),'')
    residual_ec.SetUnit(residual_ec.PutXKey(),'meV')
    residual_ec.SetUnit(residual_ec.PutYKey(),'')
    ecDet.SetUnit(ecDet.PutXKey(),'meV')
    ecDet.SetUnit(ecDet.PutYKey(),'')

    result_eca.Add(result_ec)
    result_eca.Add(ecDet)
    result_eca.Add(initial_ec)
    result_eca.Add(residual_ec)
    result_eca.Add(ecRes)

    #ShowResultECFit(result_eca)
    return result_eca

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

def getConvFitGuessECA(ecDet,ecRes,function,param,fit_region,plotflug):
    """
    Fitting初期値の計算、QensFitAnaでは未使用、(with Covolution) for ECA
    @param ecDet           (ElementContainer)
    @param ecRes           (ElementContainer)
    @param function        (string)
    @param param           (string)
    @retval result_ecm     (ElementContainerMatrix)
    """
    initial_eca  = mm.ElementContainerArray()
    observed_eca = mm.ElementContainerArray()
    residual_eca = mm.ElementContainerArray()
    result_eca = mm.ElementContainerArray()
    resolution_eca = mm.ElementContainerArray()
    result_ec   = NoneEC()
    function=replacePlusStr(function)
    result_ecm = mm.ElementContainerMatrix()
    for i in range(ecDet.PutSize()):
        hh = ecDet(i).PutHeaderPointer()
        PF.SetResolutionData(ecRes(i))
        fit_flug = False
        if (hh.CheckKey("FIT")==1):
            if (hh.PutString("FIT") == "t" or hh.PutString("FIT") == "T"):
                fit_flug = True
        elif (hh.CheckKey("FIT")==0):
                hh.Add("FIT","t")
                fit_flug = True
        #fit_flug = True
        if fit_flug:
            if type(param) == list:
                if i<len(param):
                    initial_ec = PF.getFittingFunction(function,param[i],ecDet(i))
                else:
                    initial_ec = PF.getFittingFunction(function,param[len(param)-1],ecDet(i))
            if type(param) == str:
                initial_ec = PF.getFittingFunction(function,param,ecDet(i))
            if (type(param) == str) or (type(param) == list):
                initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
                initial_ec.SetUnit(initial_ec.PutYKey(),'')
                initial_eca.Add(initial_ec)
            residual_ec = PF.getResidualDistribution(ecDet(i),initial_ec)
            residual_ec.SetUnit(initial_ec.PutXKey(),'meV')
            residual_ec.SetUnit(initial_ec.PutYKey(),'')
            ecDet(i).SetUnit(ecDet(i).PutXKey(),'meV')
            ecDet(i).SetUnit(ecDet(i).PutYKey(),'')

            hh = ecDet(i).PutHeaderPointer()
            paramVal = param[i].split(",")
            for j in range(len(paramVal)):
                if (hh.CheckKey("FittingParam"+str(j))==0):
                    hh.Add("FittingParam"+str(j),float(paramVal[j]))
                if (hh.CheckKey("FittingParam"+str(j))==1):
                    hh.OverWrite("FittingParam"+str(j),float(paramVal[j]))
            for j in range(len(paramVal)):
                if (hh.CheckKey("FittingParamErr"+str(j))==0):
                    hh.Add("FittingParamErr"+str(j),0.0)
                if (hh.CheckKey("FittingParamErr"+str(j))==1):
                    hh.OverWrite("FittingParamErr"+str(j),0.0)
            if (hh.CheckKey("ChiSq")==0):
                hh.Add("ChiSq",0)
            if (hh.CheckKey("ChiSq")==1):
                hh.OverWrite("ChiSq",0)
            if (hh.CheckKey("FittingFunc")==0):
                hh.Add("FittingFunc",function)
            if (hh.CheckKey("FittingFunc")==1):
                hh.OverWrite("FittingFunc",function)
            residual_eca.Add(residual_ec)
            observed_eca.Add(ecDet(i))
            resolution_eca.Add(ecRes(i))
            result_eca.Add(result_ec)

    result_ecm.Add(result_eca)
    result_ecm.Add(observed_eca)
    result_ecm.Add(initial_eca)
    result_ecm.Add(residual_eca)
    result_ecm.Add(resolution_eca)

    return result_ecm

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

def getConvFitGuess(ecDet,ecRes,function,param,fit_region,plotflug):
    """
    Fitting初期値の計算、QensFitAnaでは未使用、(with Covolution)
    @param ecDet           (ElementContainer/Array)
    @param ecRes           (ElementContainer/Array)
    @param function        (string)
    @param param           (string)
    @retval result_ecm     (ElementContainerArray/Matrix)
    """
    if type(ecDet) == mm.ElementContainer:
        return getConvFitGuessEC(ecDet,ecRes,function,param,fit_region,plotflug)
    if type(ecDet) == mm.ElementContainerArray:
        return getConvFitGuessECA(ecDet,ecRes,function,param,fit_region,plotflug)

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

def getFitGuessEC(ecDet,function,param,fit_region,plotflug):
    """
    Fitting初期値の計算、QensFitAnaでは未使用、(without Covolution) for ECA
    @param ecDet           (ElementContainer)
    @param function        (string)
    @param param           (string)
    @retval result_eca     (ElementContainerArray)
    """
    result_eca = mm.ElementContainerArray()
    function=replacePlusStr(function)
    result_ec = NoneEC()

    if type(param)==list:
        paramInit = param[0]
        print("input type of Param was list")
        print("first parameter was selected")
    if type(param)==str:
        paramInit = param

    initial_ec = PF.getFittingFunction(function,paramInit,ecDet)
    residual_ec = PF.getResidualDistribution(ecDet,initial_ec)

    result_eca.Add(result_ec)
    result_eca.Add(ecDet)
    result_eca.Add(initial_ec)
    result_eca.Add(residual_ec)

    #ShowResultECFit(result_eca)
    return result_eca

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

def getFitGuessECA(ecDet,function,param,fit_region,plotflug):
    """
    Fitting初期値の計算、QensFitAnaでは未使用、(without Covolution) for ECA
    @param ecDet           (ElementContainerArray)
    @param function        (string)
    @param param           (string)
    @retval result_ecm     (ElementContainerMatrix)
    """

    initial_eca  = mm.ElementContainerArray()
    observed_eca = mm.ElementContainerArray()
    residual_eca = mm.ElementContainerArray()
    result_eca   = mm.ElementContainerArray()
    result_ec   = NoneEC()
    function=replacePlusStr(function)
    result_ecm = mm.ElementContainerMatrix()

    for i in range(ecDet.PutSize()):
        hh = ecDet(i).PutHeaderPointer()
        fit_flug = True
        if fit_flug:
            if type(param) == list:
                if i<len(param):
                    initial_ec = PF.getFittingFunction(function,param[i],ecDet(i))
                else:
                    initial_ec = PF.getFittingFunction(function,param(len(param)-1),ecDet(i))
            if type(param) == str:
                initial_ec = PF.getFittingFunction(function,param,ecDet(i))
            if (type(param) == str) or (type(param) == list):
                initial_ec.SetUnit(initial_ec.PutXKey(),'meV')
                initial_ec.SetUnit(initial_ec.PutYKey(),'')
                initial_eca.Add(initial_ec)
            residual_ec = PF.getResidualDistribution(ecDet(i),initial_ec)
            residual_ec.SetUnit(initial_ec.PutXKey(),'meV')
            residual_ec.SetUnit(initial_ec.PutYKey(),'')
            ecDet(i).SetUnit(ecDet(i).PutXKey(),'meV')
            ecDet(i).SetUnit(ecDet(i).PutYKey(),'')
            residual_eca.Add(residual_ec)
            observed_eca.Add(ecDet(i))
            result_eca.Add(result_ec)

    result_ecm.Add(result_eca)
    result_ecm.Add(observed_eca)
    result_ecm.Add(initial_eca)
    result_ecm.Add(residual_eca)

    #ShowResultECAFit(result_ecm)
    return result_ecm

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

def getFitGuess(ecDet,function,param,fit_region,plotflug):
    """
    Fitting初期値の計算、QensFitAnaでは未使用、(without Covolution)
    @param ecDet           (ElementContainer/Array)
    @param function        (string)
    @param param           (string)
    @retval result_ecm     (ElementContainerArray/Matrix)
    """
    if type(ecDet) == mm.ElementContainer:
        return getFitGuessEC(ecDet,function,param,fit_region,plotflug)
    if type(ecDet) == mm.ElementContainerArray:
        return getFitGuessECA(ecDet,function,param,fit_region,plotflug)

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

def NoneEC():
    """
    強度ZeroのECを返す
    @retval ec     (ElementContainer)
    """
    xbin = []
    ybin = []
    ebin = []

    for i in range(100):
        xbin.append(i)
        ybin.append(0)
        ebin.append(0)
    xbin.append(100)
    ec = mm.ElementContainer()
    ec.Add("x",xbin)
    ec.Add("y",ybin)
    ec.Add("e",ebin)
    ec.SetKeys("x","y","e")

    return ec

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

def getFitEachResult(result):
    """
    Fitting結果の各関数要素をElementContainerMatrix/Arrayで返す
    @param result          (ElementContainerMatrix/Array)
    """
    if type(result)==mm.ElementContainerMatrix:
        result_eca = result.Put(1)
        ecaRes = result.Put(4)

        each_comp_ecm = mm.ElementContainerMatrix()

        NumECA = result_eca.PutSize()
        for i in range(NumECA):
            result_ec = result_eca(i)
            hh=result_ec.PutHeaderPointer()

            #if "xOrg" in result_ec.PutKeysList():
            #    result_ec.SetKeys("xOrg","yOrg","eOrg")

            ecRes = ecaRes(i)
            if (hh.CheckKey("FittingFunc")==1):
                func=hh.PutString("FittingFunc")
            if (hh.CheckKey("FittingFunc")==0):
                print("Fitting function is unknown")
            flug = True
            pnum = 0
            param = []
            while flug:
                if (hh.CheckKey("FittingParam"+str(pnum))==1):
                    param.append(hh.PutDouble("FittingParam"+str(pnum)))
                    #param.append(float(hh.PutDouble("FittingParam"+str(pnum))))
                    pnum += 1
                if (hh.CheckKey("FittingParam"+str(pnum))==0):
                    flug = False
            PF.SetResolutionData(ecRes)
            each_comp_eca=PF.getFittingEachFunction(func,param,result_ec)
            each_comp_ecm.Add(each_comp_eca)

        return each_comp_ecm

    if type(result)==mm.ElementContainerArray:
        result_ec = result.Put(1)
        hh=result_ec.PutHeaderPointer()
        if "xOrg" in result_ec.PutKeysList()==1:
            result_ec.SetKeys("xOrg","yOrg","eOrg")

        ecRes = result.Put(4)

        if (hh.CheckKey("FittingFunc")==1):
            func=hh.PutString("FittingFunc")
        if (hh.CheckKey("FittingFunc")==0):
            print("Fitting function is unknown")
        flug = True
        pnum = 0
        param = []
        while flug:
            if (hh.CheckKey("FittingParam"+str(pnum))==1):
                param.append(hh.PutDouble("FittingParam"+str(pnum)))
                pnum += 1
            if (hh.CheckKey("FittingParam"+str(pnum))==0):
                flug = False
        PF.SetResolutionData(ecRes)
        each_comp_eca=PF.getFittingEachFunction(func,param,result_ec)

        return each_comp_eca

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

def getSigma(result):
    """
    FittingのSigmaを返す。
    @param result          (ElementContainerArray/Matrix)
    """
    if type(result) == mm.ElementContainerArray:

        residual = result.Put(3).PutY()
        error = result.Put(1).PutE()

        sumResidual = 0
        for i in range(residual.size()):
            if(error[i]!=0):
                sumResidual += residual[i]*residual[i]/error[i]/error[i]
        normResidual = sumResidual/residual.size()
        return normResidual

    if type(result) == mm.ElementContainerMatrix:

        residual_eca = result.Put(3)
        error_eca = result.Put(1)

        numEca = residual_eca.PutSize()

        normResidualList = []

        for i in range(numEca):
            residual = residual_eca.Put(i).PutY()
            error_ec=error_eca.Put(i)
            #if "xOrg" in error_ec.PutKeysList():       #20130305 start
            #    error_ec.SetKeys("xOrg","yOrg","eOrg") #20130305 end
            error = error_ec.PutE()
            #print "#",residual.size(),error.size()
            sumResidual = 0
            for i in range(residual.size()):
                if i <len(error):
                    if(error[i]!=0):
                        sumResidual += residual[i]*residual[i]/error[i]/error[i]

            if residual.size()!=0:
                normResidual = sumResidual/residual.size()
            else:
                normResidual = 0
                print("residual-list size is zero")
            normResidualList.append(normResidual)
        #print normResidualList
        return normResidualList

##########################################
#
#def showFitResultECA(result):
#    """
#    @param result          (ElementContainerMatrix)
#    """
#    p=mp.MPlot()
#    p.SetMainTitle("Fitting result")
#    p.SetYLabel("S(Q,E)")
#    p.SetXLabel("Hw")
#    eachComp = GetFitEachResult(result)
#    numComp = eachComp(0).PutSize()
# #    p.SetTraceNum(2)
# #    for i in range(result(0).PutSize()):
# #        p.AddData(result.Put(1).Put(i))
# #        p.AddData(result.Put(0).Put(i))
# #        p.SetYScale()
# #        p.SetPlotParam(i*2+1,mc="b",lc="b")
# #        p.SetPlotParam(i*2+2,ls="-",lw=8,mk="",eb=False,lc="r") 
# #        p.ChangePage(i+2)
#
#    p.SetTraceNum(2+numComp)
#    for i in range(result(0).PutSize()):
#        p.AddData(result.Put(1).Put(i))
#        p.AddData(result.Put(0).Put(i))
#        for j in range(numComp):
#            p.AddData(eachComp.Put(i).Put(j))
#        p.SetYScale()
#        p.SetPlotParam(i*(2+numComp)+1,mc="b",lc="b")
#        p.SetPlotParam(i*(2+numComp)+2,ls="-",lw=8,mk="",eb=False,lc="r")
#        for j in range(numComp):
#            p.SetPlotParam(i*(2+numComp)+3+j,ls="--",lw=8,mk="",eb=False,lc="g")
#        p.ChangePage(i+2+numComp)
#
#    p2=mp.MPlot()
#    p2.SetTraceNum(1)
#    p2.SetMainTitle("Residual Distribution")
#    p2.SetYLabel("(S(Q,E)$_{Obs}$ - S(Q,E)$_{Cal}$) / $\sigma$")
#    p2.SetXLabel("Hw")
#    #print (result.Put(3)).PutSize()
#    for i in range(result(0).PutSize()):
#        p2.AddData(result.Put(3).Put(i))
#        p2.SetPlotParam(i+1,mc="b",lc="b")
#        p2.ChangePage(i+1)
#
##########################################
#
#def showFitResultEC(result):
#    """
#    @param result          (ElementContainerArray)
#    """
#    eachComp = GetFitEachResult(result)
#    numComp = eachComp.PutSize()
#    p=mp.MPlot()
#    p.SetMainTitle("Fitting result")
#    p.SetYLabel("S(Q,E)")
#    p.SetXLabel("Hw")
#    p.AddData(result.Put(1))
#    p.AddData(result.Put(0))
#    for j in range(numComp):
#        p.AddData(eachComp.Put(j))
#    p.SetYScale()
#    p.SetPlotParam(1,mc="b",lc="b")
#    p.SetPlotParam(2,ls="-",lw=8,mk="",eb=False,lc="r") 
#    for j in range(numComp):
#        p.SetPlotParam(3+j,ls="--",lw=8,mk="",eb=False,lc="g")
#
#    p2=mp.MPlot()
#    p2.SetTraceNum(1)
#    p2.SetMainTitle("Residual Distribution")
#    p2.SetYLabel("(S(Q,E)$_{Obs}$ - S(Q,E)$_{Cal}$) / $\sigma$")
#    p2.SetXLabel("Hw")
#    p2.AddData(result.Put(3))
#    p2.SetPlotParam(1,mc="b",lc="b")
#
##########################################
#
#def showFitResult(result):
#    """
#    @param result          (ElementContainerArray/Matrix)
#    """
#    if type(result) == mm.ElementContainerArray:
#        return ShowFitResultEC(result)
#    if type(result) == mm.ElementContainerMatrix:
#        return ShowFitResultECA(result)
#
##########################################
#
#def showFitGuessECA(result):
#    """
#    @param result          (ElementContainerMatrix)
#    """
#    p=mp.MPlot()
#    p.SetMainTitle("initial Function")
#    p.SetYLabel("S(Q,E)")
#    p.SetXLabel("Hw")
#
#    p.SetTraceNum(2)
#    for i in range(result(0).PutSize()):
#        p.AddData(result.Put(1).Put(i))
#        p.AddData(result.Put(2).Put(i))
#        p.SetYScale()
#        p.SetPlotParam(i*2+1,mc="b",lc="b")
#        p.SetPlotParam(i*2+2,ls="-",lw=8,mk="",eb=False,lc="r") 
#        p.ChangePage(i+2)
#
#    p2=mp.MPlot()
#    p2.SetTraceNum(1)
#    p2.SetMainTitle("Residual Distribution(innitial)")
#    p2.SetYLabel("(S(Q,E)$_{Obs}$ - S(Q,E)$_{init}$) / $\sigma$")
#    p2.SetXLabel("Hw")
#    print (result.Put(3)).PutSize()
#    for i in range(result(0).PutSize()):
#        p2.AddData(result.Put(3).Put(i))
#        p2.SetPlotParam(i+1,mc="b",lc="b")
#        p2.ChangePage(i+1)
#
##########################################
#
#def showFitGuessEC(result):
#    """
#    @param result          (ElementContainerArray)
#    """
#    p=mp.MPlot()
#    p.SetMainTitle("initial function")
#    p.SetYLabel("S(Q,E)")
#    p.SetXLabel("Hw")
#    p.AddData(result.Put(1))
#    p.AddData(result.Put(2))
#    p.SetYScale()
#    p.SetPlotParam(1,mc="b",lc="b")
#    p.SetPlotParam(2,ls="-",lw=8,mk="",eb=False,lc="r") 
#
#    p2=mp.MPlot()
#    p2.SetTraceNum(1)
#    p2.SetMainTitle("Residual Distribution(innitial)")
#    p2.SetYLabel("(S(Q,E)$_{Obs}$ - S(Q,E)$_{init}$) / $\sigma$")
#    p2.SetXLabel("Hw")
#    p2.AddData(result.Put(3))
#    p2.SetPlotParam(1,mc="b",lc="b")
#
##########################################
#
#def showFitGuess(result):
#    """
#    @param result          (ElementContainerArray/Matrix)
#    """
#    if type(result) == mm.ElementContainerArray:
#        return ShowFitGuessEC(result)
#    if type(result) == mm.ElementContainerMatrix:
#        return ShowFitGuessECA(result)
#
##########################################
#def showFittingParameterPlot(result):
#    """
#    @param result          (ElementContainer)
#    """
#    hh=result.PutHeader()
#    if (hh.CheckKey("Axis")==0):
#        print "x-Axis label is not define" 
#    else:
#        Axis=result.PutHeader().PutString("Axis")
#    if (hh.CheckKey("Param")==0):
#        print "Parameter label is not define"
#        Param="" 
#    else:
#        Param=result.PutHeader().PutString("Param")
#    p=mp.MPlot()
#    p.SetMainTitle("Fitting Parameter result")
#    p.SetYLabel("Parameter "+Param)
#
#    if(Axis=="Q"):
#        p.SetXLabel("Q")
#    if(Axis=="Q2"):
#        p.SetXLabel("Q$^{2}$")
#
#    p.AddData(result)
#
##########################################

def LoadFittingParam(filename):
    """
    Load Initial Fitting Parameter
    @param filename  (str)
    """
    param_buf = []
    param     = []
    param_lb  = []
    param_ub  = []
    link      = []
    k=0
    function = None

    #flie read
    fi = open(filename,'r')
    for line in fi:
        if line[0]=="#":
            print("comment >> line[",k,"]",line)
        elif line[0:4]=="func":
            print("")
            print("function is set ",line.split(":")[1].strip("\n").strip("\r"))
            function = line.split(":")[1].strip("\n").strip("\r")
        else:
            param_buf.append(line.split(","))
        k += 1
    #print "number_of_list     \t=",len(param_buf)
    if len(param_buf[0])%4 ==0:
        NumParam = len(param_buf[0])/4
        #print "number_of_parameter \t=",NumParam
    else:
        print("file format is incorrect")
        print("file format is param1,param2,param3,....param1ub,param2ub,param3ub,,....param1lb,param2lb,param3lb")
        print("lb is lower boundary, ub is upper boundary")
    # create parameter strings-list
    for p in param_buf:
        p0=""
        for i in range(0,NumParam*4):#20130305 start
            if p[i] =="": 
                p[i]=" "             #20130305   end

        for i in range(0,NumParam):
            if p0=="":p0 = p[i].strip("\n").strip("\r")
            else:p0 = p0 + ","+ p[i].strip("\n").strip("\r")
        param.append(p0)
        p0=""
        for i in range(NumParam,NumParam*2):
            if p0=="":p0 = p[i].strip("\n").strip("\r")
            else:p0 = p0 + ","+ p[i].strip("\n").strip("\r")
        param_lb.append(p0)
        p0=""
        for i in range(NumParam*2,NumParam*3):
            if p0=="":p0 = p[i].strip("\n").strip("\r")
            else:p0 = p0 + ","+ p[i].strip("\n").strip("\r")
        param_ub.append(p0)
        p0=""
        for i in range(NumParam*3,NumParam*4):
            if p0=="":p0 = p[i].strip("\n").strip("\r")
            else:p0 = p0 + ","+ p[i].strip("\n").strip("\r")
        link.append(p0)

    print("")
    print("initial parameter")
    for i in range(len(param)):print("param",i," >> ",param[i])

    print("")
    print("upper boundary parameter")
    for i in range(len(param_ub)):print("param",i," >> ",param_ub[i])

    print("")
    print("lower boundary parameter")
    for i in range(len(param_lb)):print("param",i," >> ",param_lb[i])

    print("")
    print("link")
    for i in range(len(link)):print("param",i," >> ",link[i])

    return param,param_lb,param_ub,link,function

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

def saveFittingParam(function,param,param_ub,param_lb,link,filename):
    """
    Save Initial Fitting Parameter
    @param function (str)
    @param param (str/list)
    @param param_ub (str/list)
    @param param_lb (str/list)
    @param link (str/list)
    @param filename  (str)
    """
    fw = open(filename,'w')
    fw.write("func:"+function+"\n")
    if type(param)==str and type(param_lb)==str and type(param_ub)==str and type(link)==str:
        fw.write(param+","+param_lb+","+param_ub+","+link)
        fw.close()
    if type(param)==list and type(param_lb)==list and type(param_ub)==list and type(link)==list:
        for i in range(len(param)):
            fw.write(param[i]+","+param_lb[i]+","+param_ub[i]+","+link[i]+"\n")
        fw.close()

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

def exportCsvFitResult(result,filename):
    """
    export Fitting Result, function plotting data 
    @param result          (ElementContainerArray)
    @param filename        (str)
    """
    fw = open(filename,'w')

    if type(result) == mm.ElementContainerMatrix:

        inputECM=mm.ElementContainerMatrix()
        ecaDet=result.Put(1)
        inputEcaDet=mm.ElementContainerArray()
        for i in range(ecaDet.PutTableSize()):
            ecDet=ecaDet.Put(i)
            ecDet.SetKeys("xOrg","yOrg","eOrg")
            inputEcaDet.Add(ecDet)

        inputECM.Add(result.Put(0))
        inputECM.Add(inputEcaDet)
        inputECM.Add(result.Put(2))
        inputECM.Add(result.Put(3))
        inputECM.Add(result.Put(4))

        #eachComp = getFitEachResult(result)
        eachComp = getFitEachResult(inputECM)

        numComp = eachComp(0).PutSize()

        fit_result_eca = result.Put(0)
        num_of_Q = fit_result_eca.PutSize()
        observed_eca = result.Put(1)

        hh=fit_result_eca(0).PutHeaderPointer()
        func = ""  
        if (hh.CheckKey("FittingFunc")==1):
            func=hh.PutString("FittingFunc")
        funcName = getFunctionName(func)
        resultList = []
        headerText = ""

        for Q in range(num_of_Q):
            hh2=observed_eca(Q).PutHeaderPointer()
            xrange =[-100.0,100]
            if (hh.CheckKey("XRANGE")==1):
                xrange=hh2.PutDoubleVector("XRANGE")

            fit_result_x = []
            Q_min =[]
            Q_max =[]
            if "xOrg" in observed_eca.Put(Q).PutKeysList():
                observed_x = observed_eca.Put(Q).Put("xOrg")
                observed_y = observed_eca.Put(Q).Put("yOrg")
                observed_e = observed_eca.Put(Q).Put("eOrg")
                fitted_x = observed_eca.Put(Q).PutX()
                fitted_y = observed_eca.Put(Q).PutY()
                fitted_e = observed_eca.Put(Q).PutE()
            else:
                observed_x = observed_eca.Put(Q).PutX()
                observed_y = observed_eca.Put(Q).PutY()
                observed_e = observed_eca.Put(Q).PutE()

            #fit_result_y = fit_result_eca.Put(Q).PutY()
            for i in range(observed_y.size()):
                fit_result_x.append((observed_x[i]+observed_x[i+1])*0.5)
                Q_min.append(xrange[0])
                Q_max.append(xrange[1])

            resultList.append(Q_min)
            resultList.append(Q_max)
            resultList.append(fit_result_x)
            resultList.append(observed_y)
            resultList.append(observed_e)

            eachComp_eca = eachComp.Put(Q)
            totalComp_ec = eachComp_eca.Put(0)
            for i in range(numComp-1):
                totalComp_ec = totalComp_ec + eachComp_eca.Put(i+1)
            fit_result_y = totalComp_ec.PutY()
            #fit_result_y=[]
            #j=0
            #for i in range(observed_y.size()):
            #    if observed_y[i]==fitted_y[j]:
            #        fit_result_y.append(totalComp_ec.PutY()[j])
            #        if j<fitted_y.size()-1:
            #            j=j+1
            #    else:
            #        fit_result_y.append(0)
            resultList.append(fit_result_y)

            for i in range(numComp):
                eachComp_ec_y = eachComp_eca.Put(i).PutY()
                #eachComp_ec_y=[]
                #j=0
                #for k in range(observed_y.size()):
                #    if observed_y[k]==fitted_y[j]:
                #        eachComp_ec_y.append(eachComp_eca.Put(i).PutY()[j])
                #        if j<fitted_y.size()-1:
                #            j=j+1
                #    else:
                #        eachComp_ec_y.append(0)
                resultList.append(eachComp_ec_y)

            headerText += ("Qmin"+str(Q+1)+",")
            headerText += ("Qmax"+str(Q+1)+",")
            headerText += ("E(Q"+str(Q+1)+"),")
            headerText += ("I(Q"+str(Q+1)+"),")
            headerText += ("Isd(Q"+str(Q+1)+"),")
            headerText += ("Fitted(Q"+str(Q+1)+"),")
            for k in range(len(funcName)):
                headerText += (funcName[k]+"(Q"+str(Q+1)+"),")
        headerText = headerText.rstrip(',')

        num_text = len(resultList)
        fw.write(headerText+"\n")
        for j in range(observed_y.size()):
        #for j in range(len(resultList)):
            text = ""
            for i in range(num_text):
                #print "###",len(resultList[i])
                val=resultList[i][j]
                text += str(val)
                if i != (num_text - 1):
                    text += ","
            fw.write(text+"\n")

    if type(result) == mm.ElementContainerArray:
        eachComp = getFitEachResult(result)
        numComp = eachComp.PutSize()

        observed_ec = result.Put(1)
        hh=fit_result_ec.PutHeaderPointer()
        hh2=observed_ec.PutHeaderPointer()
        func = ""
        xrange =[-100.0,100]
        if (hh.CheckKey("FittingFunc")==1):
            func=hh.PutString("FittingFunc")
        if (hh.CheckKey("XRANGE")==1):
            xrange=hh2.PutDoubleVector("XRANGE")

        funcName = getFunctionName(func)
        headerText = ""
        resultList = []
        fit_result_x_buf = fit_result_ec.PutX()
        fit_result_x = []
        Q_min =[]
        Q_max =[]
        if "xOrg" in observed_eca.Put(Q).PutKeysList():
            observed_x = observed_ec.Put("xOrg")
            observed_y = observed_ec.Put("yOrg")
            observed_e = observed_ec.Put("eOrg")
        else:
            observed_x = observed_ec.PutX()
            observed_y = observed_ec.PutY()
            observed_e = observed_ec.PutE()

        fit_result_y = fit_result_ec.PutY()
        for i in range(observed_y.size()):
            fit_result_x.append((observed_x[i]+observed_x[i+1])*0.5)
            Q_min.append(xrange[0])
            Q_max.append(xrange[1])

        resultList.append(Q_min)
        resultList.append(Q_max)
        resultList.append(fit_result_x)
        resultList.append(observed_y)
        resultList.append(observed_e)

        eachComp_eca = eachComp
        totalComp_ec = eachComp_eca.Put(0)
        for i in range(numComp-1):
            totalComp_ec = eachComp_eca.Put(i+1)
        fit_result_y = totalComp_ec.PutY()
        resultList.append(fit_result_y)

        for i in range(numComp):
            eachComp_ec_y = eachComp_eca.Put(i).PutY()
            resultList.append(eachComp_ec_y)

        headerText += ("Qmin,")
        headerText += ("Qmax,")
        headerText += ("E,")
        headerText += ("I,")
        headerText += ("Isd,")
        headerText += ("Fitted,")
        for k in range(len(funcName)):
            headerText += (funcName[k]+",")
        headerText = headerText.rstrip(',')
        fw.write(headerText+"\n")
        num_text = len(resultList)
        for j in range(fit_result_y.size()):
            text = ""
            for i in range(num_text):
                val=resultList[i][j]
                text += str(val)
                if i != (num_text - 1):
                    text += ","
            fw.write(text+"\n")

    fw.close()

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

def exportCsvFitParamResult(result,filename):
    """
    export Fitting Result, fitting parameter data 
    @param result          (ElementContainerArray)
    @param filename        (str)
    """
    fw = open(filename,'w')

    if type(result) == mm.ElementContainerMatrix:
        fit_result_eca = result.Put(0)
        num_of_Q = fit_result_eca.PutSize()
        hh=fit_result_eca(0).PutHeaderPointer()
        if (hh.CheckKey("FittingFunc")==1):
            func = hh.PutString("FittingFunc")
            paramList = getParamName(func)
            Text = "Q,"
            for textList in paramList:
                Text += textList
                Text += ",,"
            Text = Text.rstrip(",")
            fw.write(Text+"\n")
        for i in range(num_of_Q):
            hh=fit_result_eca(i).PutHeaderPointer()
            Text = ""

            if (hh.CheckKey("XRANGE")==1):
                XRange=hh.PutDoubleVector("XRANGE")
                Q = (XRange[0]+XRange[1])*0.5
            else:
                Q = 0
            Text += str(Q)+","
            flug = True
            if (hh.CheckKey("ChiSq")==1):
                chisq = hh.PutDouble("ChiSq")
                print(chisq,chisq!=chisq)
                if chisq==chisq:
                    pnum = 0
                    while flug:
                        if (hh.CheckKey("FittingParam"+str(pnum))==1):
                            Text += str(hh.PutDouble("FittingParam"+str(pnum)))+","
                            Text += str(hh.PutDouble("FittingParamErr"+str(pnum)))+","
                            pnum += 1
                        if (hh.CheckKey("FittingParam"+str(pnum))==0):
                            Text = Text.rstrip(",")
                            flug = False
                    if hh.PutDouble("FittingParamErr0")!=0.0:
                        fw.write(Text+"\n")
                elif chisq!=chisq:
                    pnum = 0
                    while flug:
                        if (hh.CheckKey("FittingParam"+str(pnum))==1):
                            Text += "0,0,"
                            pnum += 1
                        if (hh.CheckKey("FittingParam"+str(pnum))==0):
                            Text = Text.rstrip(",")
                            flug = False
            #fw.write(Text+"\n")

    if type(result) == mm.ElementContainerArray:
        fit_result_ec = result.Put(0)
        hh=fit_result_ec.PutHeaderPointer()
        if (hh.CheckKey("FittingFunc")==1):
            func = hh.PutStrinng("FittingFunc")
            paramList = getParamName(func)
            Text = "Q,"
            for textList in paramlist:
                Text += textList
                Text += ","
            Text = Text.rstrip(",")
            fw.write(Text+"\n")
        Text = ""
        if (hh.CheckKey("XRANGE")==1):
            XRange=hh.PutDoubleVector("XRANGE")
            Q = (XRange[0]+XRange[1])*0.5
        else:
            Q = 0
        flug = True
        Text += str(Q)
        if (hh.CheckKey("ChiSq")==1):
            chisq = hh.PutDouble("ChiSq")
            if chisq==chisq:
                pnum = 0
                while flug:
                    if (hh.CheckKey("FittingParam"+str(pnum))==1):
                        Text += str(hh.PutDouble("FittingParam"+str(pnum)))
                        Text += str(hh.PutDouble("FittingParamErr"+str(pnum)))
                        pnum += 1
                    if (hh.CheckKey("FittingParam"+str(pnum))==0):
                        Text = Text.rstrip(",")
                        flug = False
                if hh.PutDouble("FittingParamErr0")!=0.0:
                    fw.write(Text+"\n")
            elif chisq!=chisq:
                pnum = 0
                while flug:
                    if (hh.CheckKey("FittingParam"+str(pnum))==1):
                        Text += "0,0,"
                        pnum += 1
                    if (hh.CheckKey("FittingParam"+str(pnum))==0):
                        Text = Text.rstrip(",")
                        flug = False
        #fw.write(Text+"\n")
    fw.close()

##########################################
def getFunctionName(function):
    """
    Fitting関数の省略形表記の結合の入力文字列から､複数回関数が選択されている場合関数名にその数字を付けたListとして返す。
    また、一回のみの選択でも1を付けて入力文字列から関数名＋数字のListを返す
    @param function          (string)
    """
    function=replacePlusStr(function)
    h=function.split()
    funclist =[]
    funclist.append(["lc","lorentzConv"])
    funclist.append(["gc","gaussConv"])
    funclist.append(["dc","deltaConv"])
    funclist.append(["pv1c","pseudoVoigt1Conv"])
    funclist.append(["pv2c","pseudoVoigt2Conv"])
    funclist.append(["dhoc","dampedHarmonicOscillatorConv"])
    funclist.append(["alc","augmentedLorentzianConv"])
    funclist.append(["cc","constantConv"])
    funclist.append(["p1c","polynomial1Conv"])
    funclist.append(["p2c","polynomial2Conv"])
    funclist.append(["p3c","polynomial3Conv"])
    funclist.append(["l","lorentz"])
    funclist.append(["g","gauss"])
    funclist.append(["pv1","pseudoVoigt1"])
    funclist.append(["pv2","pseudoVoigt2"])
    funclist.append(["dho","dampedHarmonicOscillator"])
    funclist.append(["al","augmentedLorentzian"])
    funclist.append(["c","constant"])
    funclist.append(["p1","polynomial1"])
    funclist.append(["p2","polynomial2"])
    funclist.append(["p3","polynomial3"])

    h_list = []
    outputText = ""
    output = []
    for i in range(len(h)):
        h_list.append(h[i])
        numTag = h_list.count(h[i])
        funcName = h[i]
        for j in range(len(funclist)):
            if h[i]==funclist[j][0]:
                funcName = funclist[j][1]
        output.append(funcName+str(numTag))

    return output

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

def getParamName(function):
    """
    Fitting関数の省略形表記の結合の入力文字列から､その関数に対応するパラメータ名を結合した関数名のListを返す。関数名_パラメータ名
    @param function          (string)
    """
    function=replacePlusStr(function)
    h=function.split()
    funclist =[]
    funclist.append(["lc","lorentzConv",["Area","Position","HWHM"]])
    funclist.append(["gc","gaussConv",["Area","Position","HWHM"]])
    funclist.append(["dc","deltaConv",["Area","Position"]])
    funclist.append(["pv1c","pseudoVoigt1Conv",["Area","Position","HWHM","LinearCombinationCoefficient"]])
    funclist.append(["pv2c","pseudoVoigt2Conv",["Area","Position","HWHMofGauss","HWHMofLorentz","LinearCombinationCoefficient"]])
    funclist.append(["dhoc","dampedHarmonicOscillatorConv",["Area","Frequency","FrictionCoefficient"]])
    funclist.append(["alc","augmentedLorentzianConv",["Area","Position","Width","Power"]])
    funclist.append(["cc","constantConv",["Constant"]])
    funclist.append(["p1c","polynomial1Conv",["PolynomialCoefficient"]])
    funclist.append(["p2c","polynomial2Conv",["PolynomialCoefficient"]])
    funclist.append(["p3c","polynomial3Conv",["PolynomialCoefficient"]])
    funclist.append(["l","lorentz",["Area","Position","HWHM"]])
    funclist.append(["g","gauss",["Area","Position","HWHM"]])
    funclist.append(["pv1","pseudoVoigt1",["Area","Position","HWHM","LinearCombinationCoefficient"]])
    funclist.append(["pv2","pseudoVoigt2",["Area","Position","HWHM","LinearCombinationCoefficient"]])
    funclist.append(["dho","dampedHarmonicOscillator",["Area","Frequency","FrictionCoefficient"]])
    funclist.append(["al","augmentedLorentzian",["Area","Position","Width","Power"]])
    funclist.append(["c","constant",["Constant"]])
    funclist.append(["p1","polynomial1",["PolynomialCoefficient"]])
    funclist.append(["p2","polynomial2",["PolynomialCoefficient"]])
    funclist.append(["p3","polynomial3",["PolynomialCoefficient"]])

    h_list = []
    outputText = ""
    output = []
    for i in range(len(h)):
        h_list.append(h[i])
        numTag = h_list.count(h[i])
        funcName = h[i]
        for j in range(len(funclist)):
            if h[i]==funclist[j][0]:
                funcName = funclist[j][1]
                for ll in funclist[j][2]:
                    output.append(funcName+str(numTag)+"_"+ll)

    return output

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

def selectQbin(eca,num):
    """
    入力したECAから指定したECを返す
    @param eca          (ElementContainerArray)
    @param num          (int)
    @retval ec          (ElementContainer)
    """
    if type(eca)==mm.ElementContainer:
        print("input data is ElementContainer")
        return eca
    if type(eca)==mm.ElementContainerArray:
        ecaNum = eca.PutSize()
        if num<0 or num > ecaNum:
            print("input num is out of range")
        else:
            return eca.Put(num)
    if type(eca)==mm.ElementContainerMatrix:
        print("input data is ElementContainerMatrix")
        ec = mm.ElementContainer()
        return ec

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

def chceckZeroYValueForECA(eca):
    """
    ECA内のECの強度0のビンを探しそれを削除する
    @param  eca         (ElementContainerArray)
    @retval ecaNew      (ElementContainerArray)
    """
    ecaNew = mm.ElementContainerArray()
    ecaNew.InputHeader(eca.PutHeader())
    flag = False
    for i in range(eca.PutTableSize()):
        ec = eca.Put(i)
        ecX = ec.PutX()
        ecY = ec.PutY()
        ecE = ec.PutE()

        ecXnewCenter=[]
        ecXnew=[ecX[0]]
        ecYnew=[]
        ecEnew=[]
        for j in range(ecE.size()):
            if ecE[j]!=0.0:
                ecXnewCenter.append((ecX[j]+ecX[j+1])*0.5)
                ecYnew.append(ecY[j])
                ecEnew.append(ecE[j])
        for k in range(len(ecXnewCenter)):
            ecXnewElement= - ecXnew[k] + ecXnewCenter[k]*2
            ecXnew.append(ecXnewElement)

        if len(ecXnew)!=ecX.size():
            #print "eca("+str(i)+") has-zero-event-bin-data"
            #print "eca("+str(i)+"), zero-event-bins were deleted"
            flag=True
        if len(ecYnew)==0:
            ecYnew=[0]*ecY.size()
            ecEnew=[1]*ecE.size()
            ecXnew=ecX
            flag=True
            #print "eca("+str(i)+") has zero-event-bin-data"

        ecNew = mm.ElementContainer()
        #print ecXnew
        #print min(ecXnew),max(ecXnew)
        ecNew.Add("x",ecXnew)
        ecNew.Add("y",ecYnew)
        ecNew.Add("e",ecEnew)
        ecNew.Add("xOrg",ecX)
        ecNew.Add("yOrg",ecY)
        ecNew.Add("eOrg",ecE)
        ecNew.SetKeys("x","y","e")
        ecNew.InputHeader(ec.PutHeader())
        ecaNew.Add(ecNew)

    if flag:
        print("eca has zero-event-data")

    return ecaNew

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

def replacePlusStr(text):
    """
    +文字列を空白文字列にし、連続した空白文字列をひとつの空白文字列にする。
    @param text        (string)
    @retval textOut    (string)
    """
    while 1:
        text = text.replace("+"," ")
        text = text.replace("  "," ")
        if text.find("  ") == -1:
            break
    return text

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

def ElementContainerToXYList(ec):
    """
    入力したElementContainerからx,yの数値データのListを返す
    @param ec        (ElementContainer)
    @retval xylist   (list)
    """
    xbin = ec.PutX()
    ybin = ec.PutY()
    xbinList = []
    ybinList = []
    numYbin = ybin.size()
    for i in range(numYbin):
        xbinList.append((xbin[i]+xbin[i+1])*0.5)
        ybinList.append(ybin[i])
    xyList = [xbinList,ybinList]
    return xyList

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

def ElementContainerToXYEList(ec):
    """
    @param ec        (ElementContainer)
    入力したElementContainerからx,y,eの数値データのListを返す
    @retval xylist   (list)
    """
    xbin = ec.PutX()
    ybin = ec.PutY()
    ebin = ec.PutE()
    xbinList = []
    ybinList = []
    ebinList = []
    numYbin = ybin.size()
    for i in range(numYbin):
        xbinList.append((xbin[i]+xbin[i+1])*0.5)
        ybinList.append(ybin[i])
        ebinList.append(ebin[i])
    xyList = [xbinList,ybinList,ebinList]
    return xyList

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

def ElementContainerArrayToXYList2(eca):
    """
    入力したElementContainerArrayからx,yの数値データのListをそれぞれのECで計算し、それらを満たしたListを返す
    @param eca        (ElementContainerArray)
    @retval xylist   (list)
    """
    numOfEc = eca.PutTableSize()
    xyList2 = []

    for i in range(numOfEc):
        ec = eca.Put(i)
        xyList = ElementContainerToXYList(ec)
        xyList2.append(xyList)

    return xyList2

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

def ElementContainerArrayToXYEList2(eca):
    """
    入力したElementContainerArrayからx,y,eの数値データのListをそれぞれのECで計算し、それらを満たしたListを返す
    @param eca        (ElementContainerArray)
    @retval xylist   (list)
    """
    numOfEc = eca.PutTableSize()
    xyList2 = []

    for i in range(numOfEc):
        ec = eca.Put(i)
        xyList = ElementContainerToXYEList(ec)
        xyList2.append(xyList)

    return xyList2

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

def getNumOfEC(eca):
    """
    ECAに含まれるECの数を返す
    @param eca        (ElementContainerArray)
    @retval val       (int)
    """
    numOfEc = eca.PutTableSize()
    return numOfEc

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

def getUnit(eca):
    """
    ECAに含まれるECのそれぞれの単位をListで返す
    @param eca        (ElementContainerArray)
    @retval val       (list)
    """
    numOfEc = eca.PutTableSize()
    val=[]
    for i in range(numOfEc):
        ec=eca.Put(i)
        val.append([ec.PutUnit(ec.PutXKey()),ec.PutUnit(ec.PutYKey()),ec.PutUnit(ec.PutEKey())])

    return val

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

def getKeyName(eca):
    """
    ECAに含まれるECのそれぞれのKey名をListで返す
    @param eca        (ElementContainerArray)
    @retval val       (list)
    """
    numOfEc = eca.PutTableSize()
    val=[]
    for i in range(numOfEc):
        ec=eca.Put(i)
        val.append([ec.PutXKey(),ec.PutYKey(),ec.PutEKey()])

    return val

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

def getQBoundary(eca):
    """
    ECAに含まれるECのそれぞれのQの境界をListで返す
    @param eca        (ElementContainerArray)
    @retval qlist     (list)
    """
    qlist=[]
    if eca != None:
        numOfEc = eca.PutTableSize()
        for i in range(numOfEc):
            ec=eca.Put(i)
            hh=ec.PutHeader()
            if hh.CheckKey("XRANGE")==0:
                qlist.append(i)
            else:
                xr=hh.PutDoubleVector("XRANGE")
                if i==0:
                    qlist.append(xr[0])
                qlist.append(xr[1])
    return qlist

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

def getQValue(eca):
    """
    入力したECAのECのヘッダーXRANGEから中心値をQとして計算しそのListを返す
    @param result          (ElementContainerMatrix)
    """
    val=[]
    num=eca.PutTableSize()
    for i in range(num):
        hh=eca.Put(i).PutHeader()
        XRange=hh.PutDoubleVector("XRANGE")   #20130124 add-line, start
        CenterVal = (XRange[0]+XRange[1])*0.5
        val.append(CenterVal)
    return val

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

def setConvolutionRange(eca,rangelist):
    """
    入力したECAに対応した畳み込積分範囲のListからECAないのECのヘッダーに情報を書き込む
    @param eca        (ElementContainerArray)
    @param rangelist  (list)
    @retval ecaOut       (ElementContainerArray)
    """
    ecaOut=mm.ElementContainerArray()
    numOfEc = eca.PutTableSize()
    for i in range(numOfEc):
        ec=eca.Put(i)
        hh=ec.PutHeader()
        if (hh.CheckKey("CONVOLRANGE")==0):
            hh.Add("CONVOLRANGE",mm.ListToDoubleVector(rangelist[i]))
        if (hh.CheckKey("CONVOLRANGE")==1):
            hh.OverWrite("CONVOLRANGE",mm.ListToDoubleVector(rangelist[i]))
        ec.InputHeader(hh)
        ecaOut.Add(ec)
    return ecaOut

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

def getBinInformation(eca):
    """
    入力したECAの先頭のECのX軸初期値、最終値、刻み幅のタプルを返す
    @param eca        (ElementContainerArray)
    @retval val       (list)
    """
    if type(eca)==mm.ElementContainerArray:
        ecX = eca.Put(0).PutX()
        return ecX[0],ecX[-1],ecX[1]-ecX[0]
    else:
        return None,None,None

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

def getFittingRawData(eca):
    """
    ECAの数値データを変えす。x,y
    @param eca        (ElementContainerArray)
    @retval xylist   (list)
    """
    if type(eca)==mm.ElementContainerArray:
        xylist = ElementContainerArrayToXYList2(eca)
    else:
        print("filetype is incorrect.")
        print("format is ElementContainerArray")
        xylist=[]
    return xylist

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

def getFittingRawDataWithError(eca):
    """
    ECAの数値データを変えす。x,y,e
    @param eca        (ElementContainerArray)
    @retval xylist   (list)
    """
    if type(eca)==mm.ElementContainerArray:
        xylist = ElementContainerArrayToXYEList2(eca)
    else:
        print("filetype is incorrect.")
        print("format is ElementContainerArray")
        xylist=[]
    return xylist

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

def getFittingResultData(ecm):
    """
    Fitting結果のECMよりFitting結果の関数の数値データを返すx,y
    @param ecm        (ElementContainerMatrix)
    @retval paraxylist   (list)
    """
    paraxylist = []
    if type(ecm)==mm.ElementContainerMatrix:
        eachECM = getFitEachResult(ecm)
        numOfEc = eachECM.PutTableSize()
        for i in range(numOfEc):
            #ecm.Put(1).Put(i).Dump()
            eca = eachECM.Put(i)
            #ecTot = (ecm.Put(0)).Put(i) # from levmar loutine result

            numFunc = eca.PutTableSize()
            ecTot=eca.Put(0)
            if numFunc > 1:
                for i in range(numFunc-1):
                    ecTot = ecTot + eca.Put(i+1) # sum of function from fitting parameter result

            xylist_org = ElementContainerToXYList(ecTot)
            xylist2 = ElementContainerArrayToXYList2(eca)
            xylist = [xylist_org]
            xylist.extend(xylist2)
            paraxylist.append(xylist)
    else:
        print("filetype is incorrect.")
        print("format is ElementContainerMatrix")

    return paraxylist

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

def getResidualDistributionData(ecm):
    """
    Fitting結果のECMより残渣の数値データを返すx,y
    @param ecm        (ElementContainerMatrix)
    @retval xylist   (list)
    """
    if type(ecm)==mm.ElementContainerMatrix and ecm(0).PutTableSize>=3:
        eca = ecm.Put(3)
        xylist = ElementContainerArrayToXYList2(eca)
    else:
        print("filetype is incorrect.")
        print("format is ElementContainerMatrix including with fitting-results")
        xylist=[]
    return xylist

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

def getDeltaFuncResolECA(ecaIn):
    """
    入力したECAのヒストグラムと同じX軸を持ったデルタ関数のECAを返す
    @param ecaIn        (ElementContainerArray)
    @retval ecaOut      (ElementContainerArray)
    """
    ecaOut=mm.ElementContainerArray()
    num_of_eca=ecaIn.PutTableSize()

    for i in range(num_of_eca):
        ecX=ecaIn(i).PutX()
        abs_val=abs(ecX[0])
        zero_bin=0

        for i in range(ecX.size()):
            if abs(ecX[i])<abs_val:
                abs_val=abs(ecX[i])
                zero_bin=i

        ecY=[0]*(ecX.size()-2)
        ecY.insert(zero_bin,1)

        ec=mm.ElementContainer()
        ec.Add("x",ecX)
        ec.Add("y",ecY)
        ec.SetKeys("x","y","y")

        ecaOut.Add(ec)

    return ecaOut

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

def usePastExecuteResult(ecmIn,num,resultlist):
    """
    入力したFitting結果を、指定したECのヘッダーに書き込む
    @param ecmIn        (ElementContainerArray)
    @param num          (int)
    @param resultlist   (list)
    @retval None
    """
    ecmOut=mm.ElementContainerMatrix()
    result_eca=mm.ElementContainerArray()
    residual_eca=mm.ElementContainerArray()
    ecaDet=mm.ElementContainerArray()

    ecaDet_org=ecmIn.Put(1)
    result_eca_org=ecmIn.Put(0)
    residual_eca_org=ecmIn.Put(3)

    param=""
    for p in resultlist[0]:
        if param=="":
            param = str(p)
        else:
            param = param+","+str(p)

    function= ecaDet_org(num).PutHeader().PutString("FittingFunc")

    for i in range(ecmIn.Put(1).PutTableSize()):

        if i!=num:
            result_eca.Add(result_eca_org(i))
            residual_eca.Add(residual_eca_org(i))
            ecaDet.Add(ecaDet_org(i))
        else:
            result_ec = PF.getFittingFunction(function,param,ecaDet_org(num))
            result_ec.SetUnit(result_ec.PutXKey(),'meV')
            result_ec.SetUnit(result_ec.PutYKey(),'')

            hh = ecaDet_org(num).PutHeader()

            for i in range(len(resultlist[0])):
                if (hh.CheckKey("FittingParam"+str(i))==0):
                    hh.Add("FittingParam"+str(i),resultlist[0][i])
                if (hh.CheckKey("FittingParam"+str(i))==1):
                    hh.OverWrite("FittingParam"+str(i),resultlist[0][i])

                if (hh.CheckKey("FittingParamErr"+str(i))==0):
                    hh.Add("FittingParamErr"+str(i),resultlist[1][i])
                if (hh.CheckKey("FittingParamErr"+str(i))==1):
                    hh.OverWrite("FittingParamErr"+str(i),resultlist[1][i])

            result_ec.InputHeader(hh)
            ecDet=ecaDet_org(num)
            ecDet.InputHeader(hh)

            residual_ec = PF.getResidualDistribution(ecaDet_org(num),result_ec)
            residual_ec.SetUnit(residual_ec.PutXKey(),'meV')
            residual_ec.SetUnit(residual_ec.PutYKey(),'')
            result_eca.Add(result_ec)
            residual_eca.Add(residual_ec)
            ecaDet.Add(ecDet)

    ecmOut.Add(result_eca)
    ecmOut.Add(ecaDet)
    ecmOut.Add(ecmIn.Put(2))
    ecmOut.Add(residual_eca)
    ecmOut.Add(ecmIn.Put(4))

    residual_eca = getResidualDistribution(ecmOut)
    ecmOut.EraseElement(4)
    ecmOut.EraseElement(3)
    ecmOut.Add(residual_eca)
    ecmOut.Add(ecmIn.Put(4))

    return ecmOut

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

def importDaveFormat(filepath):
    """
    Dave形式のヒストグラムをElementContainerに変換
    @param filepath          (str)
    @retval eca      (ElementContainerArray)
    """
    return DFB.importDaveFormat(filepath)

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

def exportDaveFormat(eca,filepath):
    """
    ElementContainerをDave形式のヒストグラムに変換
    @param eca           (ElementContainerArray)
    @param filepath          (str)
    @retval None
    """
    return DFB.exportDaveFormat(eca,filepath)

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

def OutputECText(ec,filename):
    """
    ElementContainerをText形式のデータに変換
    @param ec      (ElementContainer)
    @param filename          (string)
    @retval None
    """
    return DFB.OutputECText(ec,filename)

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

def ReadECA(filename):
    """
    c++-boostでシリアライズされたECAを読み込む
    @param filename  (string)
    @retval eca      (ElementContainerArray)
    """
    return DFB.ReadECA(filename)

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

def OutputECA(eca,filepath):
    """
    ECAをc++-boostでシリアライズする
    @param eca           (ElementContainerArray)
    @param filepath      (str)
    @retval None
    """
    return DFB.OutputECA(eca,filepath)

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

def importTextFormat(filepath):
    """
    Text形式のElementContainerArrayデータに変換
    @param filepath      (str)
    @retval eca          (ElementContainerArray)
    """
    return DFB.importTextFormat(filepath)

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

def exportTextFormat(eca,filepath):
    """
    ElementContainerArrayをText形式のデータに変換
    @param eca           (ElementContainerArray)
    @param filepath      (str)
    @retval None
    """
    return DFB.exportTextFormat(eca,filepath)

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

def getResidualDistribution(ecm):

    paraxylist = []
    if type(ecm)==mm.ElementContainerMatrix:
        eachECM = getFitEachResult(ecm)
        numOfEc = eachECM.PutTableSize()
        ecaOut= mm.ElementContainerArray()
        ecaDet=ecm.Put(1)
        for i in range(numOfEc):
            eca = eachECM.Put(i)
            ecDet=ecaDet.Put(i)
            numFunc = eca.PutTableSize()
            ecTot=eca.Put(0)
            if numFunc > 1:
                for i in range(numFunc-1):
                    ecTot = ecTot + eca.Put(i+1)
            #xvec=eraseLastVect(ecTot.PutX())
            #yvec=eraseLastVect(ecTot.PutY())
            #evec=eraseLastVect(ecTot.PutE())
            #ecTot.Add("xnew",xvec)
            #ecTot.Add("ynew",yvec)
            #ecTot.Add("enew",evec)
            #ecTot.SetKeys("xnew","ynew","enew")

            #if "xOrg" in ecDet.PutKeysList():
            #    ecDet.SetKeys("xOrg","yOrg","eOrg")
            #if "x" in ecDet.PutKeysList():
            #    ecDet.SetKeys("x","y","e")

            ecRes=PF.getResidualDistribution(ecDet,ecTot)

            #ecDet.Dump()
            #ecTot.Dump()
            #ecRes.Dump()


            ecaOut.Add(ecRes)
    else:
        print("filetype is incorrect.")
        print("format is ElementContainerMatrix")

    return ecaOut

def eraseLastVect(vec):
    ret=[vec[i] for i in range(vec.size()-1)]
    return ret

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

def getTotalResultDistribution(ecm):

    paraxylist = []
    if type(ecm)==mm.ElementContainerMatrix:
        eachECM = getFitEachResult(ecm)
        numOfEc = eachECM.PutTableSize()
        ecaOut= mm.ElementContainerArray()
        ecaDet=ecm.Put(1)
        ecaResult=ecm.Put(0)
        for i in range(numOfEc):
            eca = eachECM.Put(i)
            ecDet=ecaDet.Put(i)
            ecResultHeader=ecaResult.Put(i).PutHeader()
            numFunc = eca.PutTableSize()
            ecTot=eca.Put(0)
            if numFunc > 1:
                for i in range(numFunc-1):
                    ecTot = ecTot + eca.Put(i+1)

            ecTot.SetUnit(ecTot.PutXKey(),'meV')
            ecTot.SetUnit(ecTot.PutYKey(),'')
            ecTot.InputHeader(ecResultHeader)
            ecaOut.Add(ecTot)
    else:
        print("filetype is incorrect.")
        print("format is ElementContainerMatrix")

    return ecaOut
