/// <summary> /// Returns a set of linear weights along with timeSegmint for with dataIndeces in linear weights are valid /// </summary> /// <param name="context"></param> /// <param name="computationalContext"></param> /// <param name="cells"></param> /// <returns></returns> protected IEnumerable <Tuple <ITimeSegment, LinearWeight[]> > CalcLinearWeights(ComputationalContext computationalContext, IEnumerable <GeoCellTuple> cells) { if (!computationalContext.ContainsKey("observations")) { throw new InvalidOperationException("Call SaveObservationsAndDalanayDiagsForCells prior calling CompleteAggregateCellsBatch"); } ISpatPointsLinearInterpolator2D spli2d = (ISpatPointsLinearInterpolator2D)spatialIntegrator; Dictionary <ITimeSegment, IObservationsInformation> observations = (Dictionary <ITimeSegment, IObservationsInformation>)computationalContext["observations"]; Dictionary <ITimeSegment, object> delanays = (Dictionary <ITimeSegment, object>)computationalContext["dalanays"]; var sw1 = System.Diagnostics.Stopwatch.StartNew(); TraceVerbose("Computing field values"); //WARNING: can't be paralleled as dalanays are not thread safe foreach (var cell in cells) { var timeSegment = cell.Time; var observation = observations[timeSegment].Observations; object delanay = delanays[timeSegment]; double latmax = cell.LatMax, latmin = cell.LatMin, lonmax = cell.LonMax, lonmin = cell.LonMin; if (latmax == latmin && lonmax == lonmin) { yield return(Tuple.Create(timeSegment, spli2d.GetLinearWeigths(latmin, lonmin, delanay))); } else { var sizeSqrt = (int)Math.Sqrt(cellAveragingGridSize); LinearWeight[][] toFlatten = new LinearWeight[sizeSqrt * sizeSqrt][]; double latStep = (latmax - latmin) / (sizeSqrt - 1); double lonStep = (lonmax - lonmin) / (sizeSqrt - 1); for (int i = 0; i < sizeSqrt; i++) { for (int j = 0; j < sizeSqrt; j++) { var w = spli2d.GetLinearWeigths(latmin + latStep * i, lonmin + lonStep * j, delanay); toFlatten[sizeSqrt * i + j] = w; } } var devisor = sizeSqrt * sizeSqrt; var flattenedWeights = toFlatten.SelectMany(weights => weights).GroupBy(w => w.DataIndex).Select(g => new LinearWeight(g.Key, g.Select(g1 => g1.Weight).Sum() / devisor)).ToArray(); yield return(Tuple.Create(timeSegment, flattenedWeights)); } } TraceVerbose("Computing field values finished in {0}", sw1.Elapsed); }