// AdditionalPlotTypes.cs created with MonoDevelop
// User: klose at 13:19 15.07.2010
// CVS release: $Id: AdditionalPlotTypes.cs,v 1.5 2011-04-19 13:13:02 klose Exp $
//

using System;
using System.Collections.Generic;

using Hiperscan.SGS.Benchtop;
using Hiperscan.Spectroscopy;
using Hiperscan.Spectroscopy.Math;
using Hiperscan.Unix;


namespace Hiperscan.Extensions.AdditionalPlotTypes
{

    public class ZenithApoIdent2FitQuadratic : Hiperscan.Extensions.PlotTypeInfo
    {
        public ZenithApoIdent2FitQuadratic() : base(Catalog.GetString("Global Fit (Quadratic, ZenithApoIdent)"))
        {
            this.XLabel = Catalog.GetString("Wavelength / nm");
            this.YLabel = Catalog.GetString("Normalised Absorbance / a.u.");
            this.LowerLimit = 0.0;
            this.UpperLimit = 1.5;
            this.StandardMin = 0.5;
            this.StandardMax = 1.1;
            this.NeedAbsorbance = true;
        }

        public override DataSet ComputeDataSet(Spectrum spectrum, DataSet.XConstraints x_constraints)
        {
            if (spectrum.HasAbsorbance == false)
                return null;

            DataSet ds = x_constraints.Apply(spectrum.Absorbance);
            DataSet ref_ds = Finder.GetWavelengthReference(ReferenceWheelVersion.ZenithApoIdent2).Absorbance;
            DataSet fit_ds = ds.Interpolate(ref_ds.X, InterpolationType.NaturalCubic);

            double[] p = LevenbergMarquardt.Fit(new LevenbergMarquardt.Match2DQuadraticQuadraticSlopeFit(fit_ds, ref_ds, 1.0)).Coefficients;

            double[] pwl = new double[3];
            Array.Copy(p, 0, pwl, 0, 3);
            WavelengthCorrection wlc = new WavelengthCorrection(pwl);
            DataSet fit = wlc.CorrectedSpectrum(fit_ds).Interpolate(ref_ds.X);

            List<double> Y = new List<double>();
            for (int ix=0; ix < fit.Count; ++ix)
            {
                Y.Add(p[3] + p[4]*fit.Y[ix] + p[5]*fit.Y[ix]*fit.Y[ix] + p[6]*fit.X[ix]);
            }

            return new DataSet(fit.X, Y);
        }
    }
}