public IndexBoundingBox GetBoundingBox(ITimeSegment t) { Debug.Assert(t.FirstYear != t.LastYear || t.FirstDay <= t.LastDay); int lastDay = t.LastDay; bool isLeapYear = (t.FirstYear == t.LastYear && DateTime.IsLeapYear(t.FirstYear)); var p1 = DaysOfYearConversions.ProjectFirstDay(t.FirstDay, isLeapYear); var p2 = DaysOfYearConversions.ProjectLastDay(t.LastDay, isLeapYear); IndexBoundingBox bb; if (lastDay < t.FirstDay) { bb = new IndexBoundingBox() { first = 0, last = 11 } } ; //new year overlap else { bb = new IndexBoundingBox() { first = (int)Math.Floor(p1), last = (int)Math.Floor(p2 - 1e-2) //the shift is less than "1 day" is needed to handle exact end of the month } }; return(bb); }
public Tuple <double, double> ProjectIntervalToTheAxis(Tuple <DateTime, DateTime> interval) { if (interval == null) { return(null); } int leftYear = interval.Item1.Year; int leftDay = interval.Item1.DayOfYear; double leftYearFraction = DaysOfYearConversions.ProjectFirstDay(leftDay, DateTime.IsLeapYear(leftYear)) / 12.0; int rightYear = interval.Item2.Year; int rightDay = interval.Item2.DayOfYear; if (interval.Item2.DayOfYear == 1 && interval.Item2.TimeOfDay.TotalSeconds < 1.0)//exact new year value. the right bound is previous year { rightYear--; rightDay = DateTime.IsLeapYear(rightYear) ? 366 : 365; } else if (interval.Item2.TimeOfDay.TotalSeconds < 1.0) //exact midnight value. right day is the day before { rightDay--; } double rightYearFraction = DaysOfYearConversions.ProjectLastDay(rightDay, DateTime.IsLeapYear(rightYear)) / 12.0; double leftVal = (leftYear + leftYearFraction - baseYear - baseYearFraction) * 360.0; double rightVal = (rightYear + rightYearFraction - baseYear - baseYearFraction) * 360.0; return(Tuple.Create( Math.Floor(leftVal), Math.Ceiling(rightVal) )); }
public IPs GetTempIPs(ITimeSegment t) { Debug.Assert(t.FirstYear != t.LastYear || t.FirstDay <= t.LastDay); bool isLeap = false; if (t.FirstYear == t.LastYear && DateTime.IsLeapYear(t.FirstYear)) { isLeap = true; } int lastDay = t.LastDay; if (t.LastDay < t.FirstDay) //handling new year overlap { lastDay += 365; } double startProjection = DaysOfYearConversions.ProjectFirstDay(t.FirstDay, isLeap); double endProjection = DaysOfYearConversions.ProjectLastDay(lastDay, isLeap); var r = coverageEvaluator.EvaluateInterval(axis, startProjection, endProjection); Debug.Assert(r != DataCoverageResult.OutOfData); int startIndex, stopIndex; double[] weights = weightsProvider.GetWeights(axis, startProjection, endProjection, out startIndex, out stopIndex); double[] accumulatedWeights = new double[12]; for (int i = startIndex; i <= stopIndex; i++) { accumulatedWeights[i % 12] += weights[i - startIndex]; } List <double> weightsL = new List <double>(12); List <int> indecesL = new List <int>(12); for (int i = 0; i < 12; i++) { if (accumulatedWeights[i] != 0.0) //both number and NAN will cause generation of IP { indecesL.Add(i); weightsL.Add(accumulatedWeights[i]); } } IPs integrationPoints = new IPs { Indices = indecesL.ToArray(), Weights = weightsL.ToArray(), BoundingIndices = new IndexBoundingBox { first = indecesL[0], last = indecesL[indecesL.Count - 1] } }; return(integrationPoints); }
public void TestProjectLastDay() { Assert.AreEqual(1.0, DaysOfYearConversions.ProjectLastDay(31, true));//31 Jenuary Assert.AreEqual(1.0, DaysOfYearConversions.ProjectLastDay(31, false)); Assert.AreEqual(2.0, DaysOfYearConversions.ProjectLastDay(60, true)); //29 February Assert.AreEqual(2.0, DaysOfYearConversions.ProjectLastDay(59, false)); //28 February Assert.AreEqual(3.5, DaysOfYearConversions.ProjectLastDay(106, true)); //15 april (exact end of the first half of april) Assert.AreEqual(3.5, DaysOfYearConversions.ProjectLastDay(105, false)); Assert.AreEqual(12.0, DaysOfYearConversions.ProjectLastDay(365, false)); Assert.AreEqual(12.0, DaysOfYearConversions.ProjectLastDay(366, true)); Assert.AreEqual(15.5, DaysOfYearConversions.ProjectLastDay(470, false)); //overlapped 15 april Assert.AreEqual(23.0, DaysOfYearConversions.ProjectLastDay(699, false)); //overlapped 30 november }
public double GetRTGCV(double latmin, double latmax, double lonmin, double lonmax, int daystart, int daystop, bool isLeap) { if (lonmax > 180.0) { lonmax -= 180.0; lonmin -= 180.0; } Tuple <double, double, double, double> areaStart = null, areaStop = null; foreach (var t in this.Keys) { if (latmin > t.Item1 && latmin < t.Item3 && lonmin > t.Item2 && lonmin < t.Item4) { areaStart = t; } if (latmax > t.Item1 && latmax < t.Item3 && lonmax > t.Item2 && lonmax < t.Item4) { areaStop = t; } } if (areaStart == null || areaStop == null || areaStart != areaStop) { return(unVal); } double sum = 0; var p = new WeightProviders.StepFunctionInterpolation(); double startProj = DaysOfYearConversions.ProjectFirstDay(daystart, isLeap); double stopProj = DaysOfYearConversions.ProjectLastDay(daystop, isLeap); int startIndex, stopIndex; var weights = p.GetWeights(months, startProj, stopProj, out startIndex, out stopIndex); var area = this[areaStart]; for (int i = startIndex; i <= stopIndex; i++) { sum += area[i % 12] * weights[i - startIndex]; } return(sum / (stopIndex - startIndex + 1)); }