#!/usr/bin/env python3
"""
Basic GISAS 2D fitting example.
The model is in gisas_model1.
Fake experimental data are generated by gisas_fake1.
"""

import os
import numpy as np
import gisas_model1 as model
import bornagain as ba
from bornagain import ba_fitmonitor
from bornagain.numpyutil import Arrayf64Converter as dac

from matplotlib import pyplot as plt


if __name__ == '__main__':
    datadir = os.getenv('BA_DATA_DIR', '')
    if not datadir:
        raise Exception("Environment variable BA_DATA_DIR not set")
    fname = os.path.join(datadir, "scatter2d/faked_gisas1.int")
    data = ba.readData2D(fname, ba.csv2D)

    fit_objective = ba.FitObjective()
    fit_objective.addFitPair(model.get_simulation, data)

    fit_objective.initPrint(10)  # Print on every 10th iteration.
    observer = ba_fitmonitor.PlotterGISAS()
    fit_objective.initPlot(10, observer) # Plot every 10th, slow!

    minimizer = ba.Minimizer()
    minimizer.setMinimizer("Minuit2", "Migrad",
                           "MaxFunctionCalls=0")
    P = model.start_parameters_1()
    result = minimizer.minimize(fit_objective.evaluate, P)

    fit_objective.finalize(result)

    print("Fit completed.")
    print("chi2:", result.minValue())
    for fitPar in result.parameters():
        print(fitPar.name(), fitPar.value, fitPar.error)

    # Save simulation image corresponding to the best fit parameters
    np.savetxt("fit.txt",
               dac.asNpArray(fit_objective.simulationResult().dataArray()))
    plt.show()
