/// <summary> /// Lookup value in RatingTable /// </summary> /// <param name="pt"></param> /// <returns></returns> private Point Lookup(Point pt) { if (pt.IsMissing) { return(new Point(pt.DateTime, Point.MissingValueFlag)); } if (pt.Value > MaxXValue()) { return(new Point(pt.DateTime, Point.MissingValueFlag)); } if (pt.Value < MinXValue()) { // if first value in table computes zero, then extrapolate a zero. if (System.Math.Abs(MinYValue()) < 0.01) { return(new Point(pt.DateTime, 0, PointFlag.Edited)); } return(new Point(pt.DateTime, Point.MissingValueFlag)); } double d = Lookup(pt.Value); if (Point.IsMissingValue(d)) { Logger.WriteLine("Rating Table Lookup failed for " + pt.ToString()); return(new Point(pt.DateTime, Point.MissingValueFlag)); } return(new Point(pt.DateTime, d)); }
/// <summary> /// This function returns the RMS error between 2 values. /// </summary> /// <param name="sourceVal"></param> /// <param name="targetVal"></param> /// <returns></returns> private static double getRMS(double sourceVal, double targetVal) { // Assign a ridiculously large value to penalize missing or zeroed data from the source series // this is a hack that prevents the selection of a daily series with no values when there is data // for the monthly series if (sourceVal == 0.0 || Point.IsMissingValue(sourceVal)) { sourceVal = -999999999999999.99; } return(System.Math.Pow(sourceVal - targetVal, 2)); }
public static Series HydrometResidualForecast(Series forecast, Series runoff, Series residual) { var rval = new Series(); rval.TimeInterval = TimeInterval.Daily; if (runoff.Count < 30) { Logger.WriteLine("Missing or not enough runoff data: HydrometResidualForecast()"); return(residual); } if (residual.Count == 0) { residual.Add(runoff[0].DateTime, 0); } double resid = residual[0].Value; for (int i = 0; i < runoff.Count; i++) { var t = runoff[i].DateTime; resid = ResetResidualBasedOnForecast(t, forecast, resid); bool missing = Point.IsMissingValue(resid); if (!missing && !runoff[i].IsMissing && t <= runoff.MaxDateTime) { var quTemp = runoff[t].Value; if (quTemp < 0) { quTemp = 0; } resid = resid - quTemp * 1.98347; if (resid < 0) { resid = 0; } rval.Add(t, resid); } else { rval.AddMissing(t); Console.WriteLine("Missing data: incremental: " + runoff[i].ToString()); missing = true; } } return(rval); }
internal static Series Compare(Series series, double p, Func <double, double, double> f) { Series rval = series.Copy(); for (int i = 0; i < rval.Count; i++) { Point pt = rval[i]; var missing = new Point(pt.DateTime, Point.MissingValueFlag, PointFlag.Missing); if (pt.IsMissing || Point.IsMissingValue(p)) { pt = missing; } else { pt.Value = f(pt.Value, p); } rval[i] = pt; } return(rval); }
/// <summary> /// Lineraly Interpolates y value from a DataTable /// sorted based on DateTime values (in the first column) /// </summary> /// <param name="tbl"></param> /// <param name="t">DateTime t</param> /// <param name="xColumnName">name of column that contains DateTime values</param> /// <param name="yColumnName">name of column that contains y values</param> /// <param name="nearestIndex">index to row nearest to x_value in your DataTable </param> /// <returns></returns> public static double Interpolate(DataTable tbl, DateTime t, string xColumnName, string yColumnName, out int nearestIndex ) { nearestIndex = -1; if (tbl.Rows.Count == 0) { throw new ArgumentException("Interpolate can not work with an empty DataTable"); } DataView rows = tbl.DefaultView; int n = rows.Count; DateTime currentT = Convert.ToDateTime(rows[0][xColumnName]); DateTime previousT = currentT; DateTime maxT = Convert.ToDateTime(rows[n - 1][xColumnName]); if (t == currentT) // first value in table matches. { nearestIndex = 0; return(Convert.ToDouble(tbl.Rows[0][yColumnName])); } if (t > maxT || t < currentT) { string msg = "Cannot interpolate " + xColumnName + "=" + t + " it is out of the range of the input DataTable"; Console.WriteLine(msg); //cbp.Utility.Write(tbl); throw new ArgumentOutOfRangeException(msg); } int x_pos = 0; do { x_pos++; if (x_pos >= n || previousT > currentT) { string msg = "Interpolate failed! is your DataTable sorted on the " + xColumnName + " column"; msg += "\n x_value = " + t + " x_pos = " + x_pos; Logger.WriteLine(msg); throw new InvalidOperationException(msg); } previousT = currentT; currentT = Convert.ToDateTime(rows[x_pos][xColumnName]); }while (t > currentT); if (t == currentT) { nearestIndex = x_pos; return(Convert.ToDouble(rows[x_pos][yColumnName])); } var delta = t - previousT; var diff = currentT - previousT; double percent = delta.Seconds / diff.Seconds; //double percent = (t - previousT) / (currentT - previousT); if (percent >= 0.5) { nearestIndex = x_pos; } else { nearestIndex = x_pos - 1; } double y = Convert.ToDouble(rows[x_pos][yColumnName]); double ym1 = Convert.ToDouble(rows[x_pos - 1][yColumnName]); if (Point.IsMissingValue(y) || Point.IsMissingValue(ym1)) { return(Point.MissingValueFlag); } return((1.0 - percent) * ym1 + percent * y); }