/// <summary>
/// Based on Donavan Cheng's R script (loessnormalize_dev_v2.R)
/// </summary>
/// <param name="bandwidth"></param>
/// <param name="gc">GC content</param>
/// <param name="coverage">coverage after variance stabilization. Assumed to be normally distributed</param>
/// <returns></returns>
private static double objective(double bandwidth, double[] gcs, double[] counts)
{
double medianY = Utilities.Median(counts);
int minGC = (int)gcs.Min();
int maxGC = (int)gcs.Max();
LoessInterpolator loess = new LoessInterpolator(bandwidth, 0);
// LOESS
double[] normalized = new double[counts.Length];
{
var model = loess.Train(gcs, counts, 1, computeFitted: false);
double[] fittedByGC = model.Predict(Enumerable.Range(minGC, maxGC).Select(i => (double)i));
for (int i = 0; i < normalized.Length; i++)
{
int gc = (int)gcs[i];
normalized[i] = counts[i] - fittedByGC[gc - minGC] + medianY;
}
}
// another LOESS
double[] fitted = new double[counts.Length];
{
var model = loess.Train(gcs, normalized, 1, computeFitted: false);
double[] fittedByGC = model.Predict(Enumerable.Range(minGC, maxGC).Select(i => (double)i));
for (int i = 0; i < fitted.Length; i++)
{
int gc = (int)gcs[i];
fitted[i] = fittedByGC[gc - minGC];
}
}
return(Utilities.StandardDeviation(fitted));
}