// Created with MonoDevelop
//
//    Copyright (C) 2013 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

using Hiperscan.Spectroscopy;
using Hiperscan.Spectroscopy.IO;
using Hiperscan.Spectroscopy.Math;


namespace Hiperscan.SGS.Benchtop.FinderSetup
{

    public static class ProbeErrorCharacteristic
    {        
        private static DataSet error_characteristic = null;

        public static DataSet FitFunc(DataSet error_characteristic, List<double> X, double p1, double p2, double p3)        
        {
            DataSet fit = error_characteristic.Interpolate(X);

            var yl = new List<double>();
            for (int ix = 0; ix < fit.Count; ++ix)
            {
                yl.Add(fit.X[ix] * p2 + p3);
            }
            DataSet ds_l = new DataSet(fit.X, yl);

            return fit * p1 + ds_l;
        }

        public static DataSet GetCorrection(DataSet ds)
        {
            if (error_characteristic == null)
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                CultureInfo culture = new CultureInfo("en-US");

                // that is how the filtered characteristic was created (500 dim filter is expensive and a little bit problematic...)
                //              error_characteristic = CSV.ReadDataSet(assembly.GetManifestResourceStream("SGS.Benchtop.Characteristics.probe_error_characteristic.csv"), culture);
                //              error_characteristic = error_characteristic.Filter(3, 500);
                //              CSV.Write(error_characteristic, "/tmp/filtered_probe_error_characteristic.csv", culture);
                error_characteristic = CSV.ReadDataSet(assembly.GetManifestResourceStream("SGS.Benchtop.Characteristics.filtered_probe_error_characteristic.csv"), culture);
            }

            var lmfit = new LevenbergMarquardt.ProbeErrorCharacteristicFit(ds, error_characteristic, 1.0);
            double[] p = LevenbergMarquardt.Fit(lmfit).Coefficients;

            return FitFunc(error_characteristic, ds.X, p[0], p[1], p[2]);
        }
        
        public static DataSet CorrectDataSet(DataSet ds)
        {
            return (ds - ProbeErrorCharacteristic.GetCorrection(ds)).SNV();
        }
    }
}