public void Normalize()
{
// Find the best bandwidth without chrY
double[] gcsNoChrY = withoutChrY.Select(i => gcs[i]).ToArray();
double[] countsNoChrY = withoutChrY.Select(i => counts[i]).ToArray();
double bestBandwidth = findBestBandwith(0.3, 0.75, gcsNoChrY, countsNoChrY);
// Fit LOESS
double medianY = Utilities.Median(counts);
int minGC = (int)gcs.Min();
int maxGC = (int)gcs.Max();
LoessInterpolator loess = new LoessInterpolator(bestBandwidth, 0);
var model = loess.Train(gcs, counts, 1, computeFitted: false);
double[] fittedByGC = model.Predict(Enumerable.Range(minGC, maxGC).Select(i => (double)i));
// Smooth
foreach (GenomicBin bin in bins)
{
int i = Math.Min(fittedByGC.Length - 1, Math.Max(0, bin.GC - minGC));
double smoothed = countTransformer(bin.Count) - fittedByGC[i] + medianY;
bin.Count = invCountTransformer(smoothed);
}
}