import logging
import sys
import time
import select
import optparse
import OptionSelector
import random

import Manyo
import MultiDataPeakFit as Adv

#import PlotNorm
#import PeakFilter
#import FuncModelGen
#import LowerAndUpperBoundGen

def displace(param):
    #if not isinstance(param, DoubleVector):
    #if not isinstance(param, VectorDouble):
    if not isinstance(param, Manyo.VecDouble):
        raise TypeError("randamize: unsupported type")

    for i in range(len(param)):
        param[i]=param[i]*(0.5 + random.random())
        print "displace: i=", i, "value=", param[i]

########        command line operations        ########
parser=optparse.OptionParser()
parser.add_option("-i", "--input", action="store", type="string", dest="inputFile", help="input file name", metavar="FILE")
options, args = parser.parse_args()
print "options=", options
print "args   =", args
#if len(args) == 0:
#    parser.error("no argument")
if not options.inputFile:
    parser.error("no input file specified.")

########        read original data        ########
io=Manyo.NeXusFileIO()
src = io.ReadElementContainerArray(options.inputFile)
print "container size: ", src.PutSize()

#exprList=Manyo.VectorTool.MakeVectorString()
exprList=[]
for i in range(src.PutSize()):
    ec = src.Put(i)
    exprList.append(ec.PutHeader().PutString("source functions"))
    print exprList[i]

cppToPython=Manyo.CppToPython()
vecString = cppToPython.ListToStringVector(exprList)
param = src.Put(0).PutHeader().PutDoubleVector("source parameters")

op = Adv.MultiDataPeakFit()
op.setSource(src)
op.setMethod(Adv.MULTIDATA_LEVMAR)
op.setDefaultParam()
displace(param)
print "param", param

op.setParam(Adv.LevmarConsts.CONSTRAIN,          Adv.LevmarConsts.NO_CONSTRAIN)
op.setParam(Adv.LevmarConsts.USE_NUMERICAL_DIFF, Adv.LevmarConsts.DEFAULT_USE_NUMERICAL_DIFF)
op.setParam(Adv.LevmarConsts.DIFF_METHOD,        Adv.LevmarConsts.DEFAULT_DIFF_METHOD)
op.setParam(Adv.LevmarConsts.USE_DATA_WEIGHTS,   Adv.LevmarConsts.DEFAULT_USE_DATA_WEIGHTS)

op.setParam(Adv.LevmarConsts.FUNCTIONS,        vecString)
op.setParam(Adv.LevmarConsts.PARAMETER_VALUES, param)
op.getParam().dump()

#plotNorm=PlotNorm()

if op.checkParam():
    #op.execute()
    op.fit()
    while op.isFitting():
        p=op.getLatestConvergenceStat()
        #plotNorm.add(p)
        #plotNorm.plot()
        waitTime=p.getInt4(Adv.LevmarConsts.ITERATION_TIME)/1000000.0
        #print waitTime
        tmpList=select.select([sys.stdin], [], [], waitTime)
        #print tmpList
        if not tmpList==([], [], []):
            c=raw_input()
            if c=="q":
                drv.stopFit()
                break
    while op.isFitting(): # sleep while fitting
        pass
    #plotNorm.addNorm(drv.getLatestConvergenceStat())
    #plotNorm.plot()
    op.eval()

    result=op.getResult()
    result.PutHeader().dump()
    for i in range(src.PutSize()):
        result.Put(i).PutHeader().Dump()
    resultComponents=op.getResultComponents()

    output = Manyo.NeXusFileIO()
    output.Write(result, "fittedArray.data", "tanimori")
