public static void RecalibrateImpl(SilacType silacType, int nranges, int[] iranges, int[][] chargePairs,
                                           SilacCluster[] silacClusters, ref double[,] mzCalibrationParams,
                                           ref double[,] intensityCalibrationParams, double massErrorNormalization,
                                           IsotopeCluster[] isotopeCluster, IPeakList peakList, float[] intensities)
        {
            double[] x   = new double[chargePairs.Length];
            double[] y   = new double[chargePairs.Length];
            double[] sig = new double[chargePairs.Length];
            for (int i = 0; i < chargePairs.Length; i++)
            {
                x[i] = i;
                int          ind1 = chargePairs[i][0];
                int          ind2 = chargePairs[i][1];
                SilacCluster sc1  = silacClusters[ind1];
                SilacCluster sc2  = silacClusters[ind2];
                sig[i] = Math.Sqrt(sc1.GetMassError(massErrorNormalization) * sc1.GetMassError(massErrorNormalization) +
                                   sc2.GetMassError(massErrorNormalization) * sc2.GetMassError(massErrorNormalization));
            }
            intensityCalibrationParams = new double[nranges, nparamsIntensityFit];
            double[,] icp = intensityCalibrationParams;
            Funcs2 f = delegate(double x1, double[] aa) {
                int ind  = (int)Math.Round(x1);
                int ind1 = chargePairs[ind][0];
                int ind2 = chargePairs[ind][1];
                double[,] mzAa = new double[nranges, nparamsMzFit];
                int c = 0;
                for (int j = 0; j < iranges.Length; j++)
                {
                    for (int i = 0; i < nparamsMzFit; i++)
                    {
                        mzAa[iranges[j], i] = aa[c++];
                    }
                }
                double y1 = GetCalibratedSilacMassStat(silacClusters[ind1], mzAa, icp, silacType, isotopeCluster, peakList,
                                                       intensities);
                double y2 = GetCalibratedSilacMassStat(silacClusters[ind2], mzAa, icp, silacType, isotopeCluster, peakList,
                                                       intensities);
                double yy = y1 - y2;
                return(yy);
            };
            double chisq;

            double[] a      = new double[nparamsMzFit * iranges.Length];
            int      county = 0;

            for (int j = 0; j < iranges.Length; j++)
            {
                for (int i = 0; i < nparamsMzFit; i++)
                {
                    a[county++] = startValsMzFit[i];
                }
            }
            NumUtil.FitNonlin(x, y, sig, a, out chisq, f);
            mzCalibrationParams = new double[nranges, nparamsMzFit];
            int s = 0;

            for (int j = 0; j < iranges.Length; j++)
            {
                for (int i = 0; i < nparamsMzFit; i++)
                {
                    mzCalibrationParams[iranges[j], i] = a[s++];
                }
            }
            double[,] mcp = mzCalibrationParams;
            f             = delegate(double x1, double[] aa) {
                int ind  = (int)Math.Round(x1);
                int ind1 = chargePairs[ind][0];
                int ind2 = chargePairs[ind][1];
                double[,] intensityAa = new double[nranges, nparamsIntensityFit];
                int c = 0;
                for (int j = 0; j < iranges.Length; j++)
                {
                    for (int i = 0; i < nparamsIntensityFit; i++)
                    {
                        intensityAa[iranges[j], i] = aa[c++];
                    }
                }
                double y1 = GetCalibratedSilacMassStat(silacClusters[ind1], mcp, intensityAa, silacType, isotopeCluster, peakList,
                                                       intensities);
                double y2 = GetCalibratedSilacMassStat(silacClusters[ind2], mcp, intensityAa, silacType, isotopeCluster, peakList,
                                                       intensities);
                double yy = y1 - y2;
                return(yy);
            };
            a = new double[nparamsIntensityFit * iranges.Length];
            NumUtil.FitNonlin(x, y, sig, a, out chisq, f);
            s = 0;
            for (int j = 0; j < iranges.Length; j++)
            {
                for (int i = 0; i < nparamsIntensityFit; i++)
                {
                    intensityCalibrationParams[iranges[j], i] = a[s++];
                }
            }
            icp = intensityCalibrationParams;
            f   = delegate(double x1, double[] aa) {
                int ind  = (int)Math.Round(x1);
                int ind1 = chargePairs[ind][0];
                int ind2 = chargePairs[ind][1];
                double[,] mzAa = new double[nranges, nparamsMzFit];
                int c = 0;
                for (int j = 0; j < iranges.Length; j++)
                {
                    for (int i = 0; i < nparamsMzFit; i++)
                    {
                        mzAa[iranges[j], i] = aa[c++];
                    }
                }
                double y1 = GetCalibratedSilacMassStat(silacClusters[ind1], mzAa, icp, silacType, isotopeCluster, peakList,
                                                       intensities);
                double y2 = GetCalibratedSilacMassStat(silacClusters[ind2], mzAa, icp, silacType, isotopeCluster, peakList,
                                                       intensities);
                double yy = y1 - y2;
                return(yy);
            };
            a      = new double[nparamsMzFit * iranges.Length];
            county = 0;
            for (int j = 0; j < iranges.Length; j++)
            {
                for (int i = 0; i < nparamsMzFit; i++)
                {
                    a[county++] = mzCalibrationParams[iranges[j], i];
                }
            }
            NumUtil.FitNonlin(x, y, sig, a, out chisq, f);
            s = 0;
            for (int j = 0; j < iranges.Length; j++)
            {
                for (int i = 0; i < nparamsMzFit; i++)
                {
                    mzCalibrationParams[iranges[j], i] = a[s++];
                }
            }
        }