# -----------------------------------------------------------------------
#  Diana process modelling, simulation and analysis software
#  Copyright (c) 2006, Sergiy Gogolenko
#  e-mail: gogolenk@mpi-magdeburg.mpg.de
#  All rights reserved.
# -----------------------------------------------------------------------
#  $Id: HafkeReactor.py Fri Aug 11 13:22:08 2006 gogolenk $
# -----------------------------------------------------------------------
#  Written under: i586-suse-linux 
# -----------------------------------------------------------------------
#  Last update: Fri Aug 11 13:22:08 2006 
# -----------------------------------------------------------------------
#  Description:
#   Simple example of using DIANA for solving parameter fitting problems 
#  with deterministic optimizer (in this case LBFGS-solver).

import diana, sys, os

modelPath = "Substrateuptake.so"
observedParams = ["c_x", "c_s"]
fileMesData = "./data/observations.dat"
integratorName = "ida" # "odessa"
optimizerName = "direct" # "nmsimplex"

# initialize Diana main class
dmain=diana.GetDianaMain(sys.argv)

# create NMSimplex-optimizer
sfactory = dmain.GetSolverFactory()
solverPE = sfactory.CreateSolver(diana.CAPE_NLP, None, optimizerName)

# create model
mmanager=dmain.GetModelManager()
model = mmanager.CreateModel(diana.CAPE_CONTINUOUS, modelPath)
model.Initialize()

# load measured data (state values and time points) from specified file
md = diana.DianaMeasuredData(model, observedParams)
md.load(fileMesData)

# Describe estimated parameters
sps = [
    diana.DianaNLPRealParameterSpec("k_s",  # name
                                    "",     # description
                                    1.0,    # default value
                                    1.0,    # lower bound
                                    3.0,    # upper bound
                                    0.0001),# precision
    diana.DianaNLPRealParameterSpec("mu_max", "",  4.0, 4.0, 6.0, 0.0001)
    ]

# create paramerter fitting task
taskPE = diana.ParameterFittingTask(dmain, integratorName,
                                    model, md, sps)
taskPE.Initialize()

print "Parameter fitting task for %s is initialized" \
      % model.GetComponentName()

# create report
report = dmain.CreateReportingInterface(optimizerName)
# set parameters for reporting
pars_solverPErep = report.GetParameters()
pars_solverPErep["Author"].SetValue("SG")
pars_solverPErep["OutputFolder"].SetValue("./parfit")
pars_solverPErep["ConsoleOutput"].SetValue(True)
pars_solverPErep["Samples"].SetValue(True)
report.Initialize()
print "Report initialized"

# set prepared task and report to solver
solverPE.SetReportingInterface(report);
solverPE.SetNLPTask(taskPE);
solverPE.Initialize();
print "Optimizer %s initialized" % solverPE.GetComponentName()

# start optimization
print "Parameter fitting for %s..." % model.GetComponentName()
try:
    solverPE.Solve()
except:
    print "Best solution: ", solverPE.GetSolution()
    raise
print "Solution: ", solverPE.GetSolution()
print "Parameter values:"
print taskPE.GetSoughtParameters()
