protected SeriesList CreateSeriesList(bool getAveragePcode = false) { list = new SeriesList(); for (int i = 0; i < cbttPodes.Count; i++) { var tokens = cbttPodes[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length != 2) { if (cbttPodes[i].IndexOf("_") >= 0) { // QU or other calculation var s = new CalculationSeries(); s.Expression = cbttPodes[i]; s.TimeInterval = TimeInterval.Monthly; s.Parser.VariableResolver = HydrometData.GetVariableResolver(); list.Add(s); } else { throw new FormatException(cbttPodes[i]); } } else { var cbtt = tokens[0].Trim(); var pcode = tokens[1].Trim(); HydrometHost host = HydrometData.s_server; if (getAveragePcode) { // used for snow/precip throw new NotImplementedException("Error. Legacy System retired."); // pcode = HydrometMonthlySeries.LookupAveargePcode(pcode); // host = HydrometHost.PN; } var s = new HydrometMonthlySeries(cbtt, pcode, host); list.Add(s); } } return(list); }
public ForecastResult Evaluate(DateTime t, bool lookAhead, double estimationScaleFactor, bool setupCache = true) { Logger.WriteLine("Evaluate( " + this.Name + ")"); var rval = new ForecastResult(); rval.Equation = this; rval.EstimationFactor = estimationScaleFactor; string msg = t.ToShortDateString() + " Forecast " + this.Name + " " + DateTime.Now.ToShortDateString(); rval.Details.Add(msg); Logger.WriteLine(msg); if (setupCache) { HydrometData.SetupHydrometData(StartYear, EndYear, GetCbttPcodeList().ToArray(), t, true, false); } rval.Forecast = 0.0; //var total = 0; int i = 0; for (i = 0; i < this.XTerms.Count; i++) { var X = XTerms[i]; Logger.WriteLine("Evaluating X" + X.Number); var d = X.Evaluate(t, lookAhead, estimationScaleFactor); rval.Forecast += d * this.coefficients[X.Number - 1];// apply coeficients... rval.Details.AddRange(X.Details()); rval.Details.Add("X" + X.Number + " = " + d.ToString("F2")); rval.Details.Add(""); Logger.WriteLine("X" + X.Number + "= " + rval.Forecast); } rval.Details.Add(""); rval.Forecast += coefficients[coefficients.Length - 1];// k term // Y = C string s = "Coefficients: "; for (i = 0; i < coefficients.Length; i++) { s += " " + coefficients[i].ToString("F4"); } rval.Details.Add(s); //var runoff = YTerm.Evaluate(t, lookAhead,estimationScaleFactor); var runoffToDate = YTerm.RunoffToDate(t); var seasonalRunoff = YTerm.SeasonalRunoff(t); rval.Details.AddRange(YTerm.Details()); var dr = YTerm.MonthNames; rval.Details.Add(""); rval.ForecastPeriod = (t.ToString("MMM") + "-" + dr[dr.Count - 1]).ToUpper(); rval.AverageRunoff = Lookup30YearAverageRunoff(t); string fullPeriod = (dr[0] + "-" + dr[dr.Count - 1]).ToUpper(); rval.Details.Add(fullPeriod + " = " + rval.Forecast.ToString("F2")); if (lookAhead) { // actual runoff rval.Details.Add("++ using look ahead for future data"); rval.Details.Add(dr[0] + " - " + dr[dr.Count - 1] + " runoff : " + seasonalRunoff.ToString("F1")); } else { rval.Details.Add("Runoff to Date : " + runoffToDate.ToString("F1")); // forecast forward var fc = rval.Forecast - runoffToDate; rval.ResidualForecast = fc; rval.Details.Add("Date - " + dr[dr.Count - 1] + " forecast : " + fc.ToString("F1")); } rval.Details.Add("average " + rval.ForecastPeriod + " runoff = " + rval.AverageRunoff.ToString("F2")); return(rval); }
/// <summary> /// Uses forecast equation for each historical year. /// </summary> /// <param name="year1"></param> /// <param name="year2"></param> /// <returns>a table comparing acutal to forecasted values</returns> public DataTable RunHistoricalForecasts(int year1, int year2, bool lookAhead, int forecastMonth, double[] estimationFactors, int forecastDay = 1) { DataTable tbl = new DataTable(Name); //Logger.EnableLogger(); tbl.Columns.Add("Notes"); tbl.Columns.Add("Year"); tbl.Columns.Add("Actual Forecast Period Volume", typeof(double)); tbl.Columns.Add("Forecasted Period Volume", typeof(double)); tbl.Columns.Add("Difference", typeof(double)); tbl.Columns.Add("Error", typeof(double)); tbl.Columns.Add("Actual Residual Volume", typeof(double)); tbl.Columns.Add("Forecasted Residual Volume", typeof(double)); tbl.Columns.Add("Difference2", typeof(double)); tbl.Columns.Add("Error2", typeof(double)); // [JR] Hacks to write the inputs to the MLR process foreach (var item in this.YTerm.MonthNames) { tbl.Columns.Add("Y-Runoff-" + item.ToUpper(), typeof(double)); } for (int i = 0; i < this.XTerms.Count(); i++) { var ithTerm = this.XTerms[i]; var termName = "X" + ithTerm.Number + "-" + ithTerm.ForecastTermType; foreach (var item in ithTerm.MonthNames) { tbl.Columns.Add(termName + "-" + item.ToUpper(), typeof(double)); } } for (int i = 1; i < estimationFactors.Length; i++) { tbl.Columns.Add("Forecast " + estimationFactors[i], typeof(double)); //tbl.Columns.Add("Difference " + estimationFactors[i], typeof(double)); //tbl.Columns.Add("Error " + estimationFactors[i], typeof(double)); } HydrometData.SetupHydrometData(StartYear, EndYear, GetCbttPcodeList().ToArray(), DateTime.MaxValue, true, true); // date is ignored when reading all years string forecastPeriod = ""; for (int year = year1; year <= year2; year++) { var row = tbl.NewRow(); row["Year"] = year; Logger.WriteLine(year.ToString(), "ui"); DateTime t = new DateTime(year, forecastMonth, forecastDay); try { var fcResult = Evaluate(t, lookAhead, estimationFactors[0], false); var actual = YTerm.SeasonalRunoff(t); row["Actual Forecast Period Volume"] = actual; row["Forecasted Period Volume"] = fcResult.Forecast; var diff = fcResult.Forecast - actual; // convention of FORTRAN row["Difference"] = diff; row["Error"] = (diff / actual) * 100.0; var actualResid = actual - YTerm.RunoffToDate(t); //var forecastResid = fcResult.GetForecastForSummary(lookAhead); var forecastResid = fcResult.Forecast - YTerm.RunoffToDate(t); row["Actual Residual Volume"] = actualResid; row["Forecasted Residual Volume"] = forecastResid; row["Difference2"] = forecastResid - actualResid; row["Error2"] = (forecastResid - actualResid) / actualResid * 100.0; for (int i = 1; i < estimationFactors.Length; i++) { var s = " " + estimationFactors[i]; fcResult = Evaluate(t, lookAhead, estimationFactors[i], false); row["Forecasted Period Volume" + s] = fcResult.Forecast; diff = actual - fcResult.Forecast; // convention of FORTRAN //row["Difference"+s] = diff; //row["Error"+s] = (diff / actual) * 100.0; } forecastPeriod = fcResult.ForecastPeriod; // [JR] Hacks to write the inputs to the MLR process #region var sTEMP = this.YTerm.yData; for (int ithMon = 0; ithMon < sTEMP.Count(); ithMon++) { row["Y-Runoff-" + sTEMP[ithMon].DateTime.ToString("MMM").ToUpper()] = sTEMP[ithMon].Value; } foreach (var term in this.XTerms) { if (term.xData.Count() > 0) { var termName = "X" + term.Number + "-" + term.ForecastTermType; var sList = term.xData; var sSum = new Reclamation.TimeSeries.Series(); for (int i = 0; i < sList.Count; i++) { foreach (var point in sList[i]) { if (i == 0) { sSum.Add(point.DateTime, 0.0); } sSum[point.DateTime] = new Reclamation.TimeSeries.Point(point.DateTime, sSum[point.DateTime].Value + point.Value); } } foreach (var point in sSum) { try { row[termName + "-" + point.DateTime.ToString("MMM").ToUpper()] = point.Value; } catch { } } } } #endregion } catch (Exception ex) { row["Notes"] = ex.Message; for (int i = 2; i < row.ItemArray.Count(); i++) { row[i] = Double.NaN; } } tbl.Rows.Add(row); } // add some notes if (tbl.Rows.Count >= 5) { tbl.Rows[0]["Notes"] = this.Name; tbl.Rows[1]["Notes"] = "Current Forecast Month: " + forecastMonth; tbl.Rows[2]["Notes"] = "Current Forecast Day: " + forecastDay; tbl.Rows[3]["Notes"] = "Current Forecast Period: " + forecastPeriod; tbl.Rows[4]["Notes"] = "Full Forecast Period: " + this.YTerm.MonthNames[0].ToString().ToUpper() + "-" + this.YTerm.MonthNames[this.YTerm.MonthNames.Count() - 1].ToString().ToUpper(); } var summaryRow = tbl.NewRow(); summaryRow["Year"] = "Average"; //summaryRow["Actual Forecast Period Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Actual Forecast Period Volume")); //summaryRow["Forecasted Period Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Forecasted Period Volume")); //summaryRow["Difference"] = tbl.AsEnumerable().Average(x => x.Field<double>("Difference")); //summaryRow["Error"] = tbl.AsEnumerable().Average(x => x.Field<double>("Error")); //summaryRow["Actual Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Actual Residual Volume")); //summaryRow["Forecasted Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Forecasted Residual Volume")); //summaryRow["Difference2"] = tbl.AsEnumerable().Average(x => x.Field<double>("Difference2")); //summaryRow["Error2"] = tbl.AsEnumerable().Average(x => x.Field<double>("Error2")); for (int i = 2; i < tbl.Columns.Count; i++) { var colName = tbl.Columns[i].ColumnName; try { var colAvg = tbl.AsEnumerable().Select(x => x.Field <double>(colName)).Where(s => s.ToString() != Double.NaN.ToString()).Average(); summaryRow[colName] = colAvg; } catch { } } // Get percent of average for MLR inputs for (int i = 10; i < tbl.Columns.Count; i++) { var colName = tbl.Columns[i].ColumnName; try { DataColumn ithColumn = tbl.Columns[colName]; foreach (DataRow row in tbl.Rows) { double oldVal = row.Field <double>(ithColumn); row.SetField(ithColumn, oldVal / Convert.ToDouble(summaryRow[colName].ToString())); } } catch { } } tbl.Rows.Add(summaryRow); return(tbl); }
/// <summary> /// Uses forecast equation for each historical year. /// </summary> /// <param name="year1"></param> /// <param name="year2"></param> /// <returns>a table comparing acutal to forecasted values</returns> public DataTable RunHistoricalForecasts(int year1, int year2, bool lookAhead, int forecastMonth, double[] estimationFactors, int forecastDay = 1) { DataTable tbl = new DataTable(Name); //Logger.EnableLogger(); tbl.Columns.Add("Notes"); tbl.Columns.Add("Year"); tbl.Columns.Add("Actual Forecast Period Volume", typeof(double)); tbl.Columns.Add("Forecasted Period Volume", typeof(double)); tbl.Columns.Add("Difference", typeof(double)); tbl.Columns.Add("Error", typeof(double)); tbl.Columns.Add("Actual Residual Volume", typeof(double)); tbl.Columns.Add("Forecasted Residual Volume", typeof(double)); tbl.Columns.Add("Difference2", typeof(double)); tbl.Columns.Add("Error2", typeof(double)); for (int i = 1; i < estimationFactors.Length; i++) { tbl.Columns.Add("Forecast " + estimationFactors[i], typeof(double)); //tbl.Columns.Add("Difference " + estimationFactors[i], typeof(double)); //tbl.Columns.Add("Error " + estimationFactors[i], typeof(double)); } HydrometData.SetupHydrometData(StartYear, EndYear, GetCbttPcodeList().ToArray(), DateTime.MaxValue, true, true); // date is ignored when reading all years for (int year = year1; year <= year2; year++) { var row = tbl.NewRow(); row["Year"] = year; Logger.WriteLine(year.ToString(), "ui"); DateTime t = new DateTime(year, forecastMonth, forecastDay); try { var fcResult = Evaluate(t, lookAhead, estimationFactors[0], false); var actual = YTerm.SeasonalRunoff(t); row["Actual Forecast Period Volume"] = actual; row["Forecasted Period Volume"] = fcResult.Forecast; var diff = fcResult.Forecast - actual; // convention of FORTRAN row["Difference"] = diff; row["Error"] = (diff / actual) * 100.0; var actualResid = actual - YTerm.RunoffToDate(t); var forecastResid = fcResult.GetForecastForSummary(lookAhead); row["Actual Residual Volume"] = actualResid; row["Forecasted Residual Volume"] = forecastResid; row["Difference2"] = forecastResid - actualResid; row["Error2"] = (forecastResid - actualResid) / actualResid * 100.0; for (int i = 1; i < estimationFactors.Length; i++) { var s = " " + estimationFactors[i]; fcResult = Evaluate(t, lookAhead, estimationFactors[i], false); row["Forecasted Period Volume" + s] = fcResult.Forecast; diff = actual - fcResult.Forecast; // convention of FORTRAN //row["Difference"+s] = diff; //row["Error"+s] = (diff / actual) * 100.0; } } catch (Exception ex) { row["Notes"] = ex.Message; } tbl.Rows.Add(row); } // add some notes if (tbl.Rows.Count >= 3) { tbl.Rows[0]["Notes"] = this.Name; tbl.Rows[1]["Notes"] = "forecast Month " + forecastMonth; tbl.Rows[2]["Notes"] = "forecast Day " + forecastDay; } var summaryRow = tbl.NewRow(); summaryRow["Year"] = "Average"; summaryRow["Actual Forecast Period Volume"] = tbl.AsEnumerable().Average(x => x.Field <double>("Actual Forecast Period Volume")); summaryRow["Forecasted Period Volume"] = tbl.AsEnumerable().Average(x => x.Field <double>("Forecasted Period Volume")); summaryRow["Difference"] = tbl.AsEnumerable().Average(x => x.Field <double>("Difference")); summaryRow["Error"] = tbl.AsEnumerable().Average(x => x.Field <double>("Error")); summaryRow["Actual Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field <double>("Actual Residual Volume")); summaryRow["Forecasted Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field <double>("Forecasted Residual Volume")); summaryRow["Difference2"] = tbl.AsEnumerable().Average(x => x.Field <double>("Difference2")); summaryRow["Error2"] = tbl.AsEnumerable().Average(x => x.Field <double>("Error2")); tbl.Rows.Add(summaryRow); return(tbl); }