/// <summary> /// Primary input validate method, initiates all validation methods. /// </summary> /// <param name="errorMsg"></param> /// <param name="dataset"></param> /// <param name="input"></param> /// <returns></returns> public static ITimeSeriesInput Validate(out string errorMsg, List <string> dataset, ITimeSeriesInput input) { errorMsg = ""; ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); ITimeSeriesInput validInput = iFactory.Initialize(); List <string> errors = new List <string>(); List <string> errorTemp = new List <string>(); bool validDataset = ValidateDataset(out errorTemp, dataset); errors = errors.Concat(errorTemp).ToList(); errorTemp = new List <string>(); if (errors.Count == 0 && ValidateSource(out errorTemp, dataset, input.Source)) { validInput.Source = input.Source; } errors = errors.Concat(errorTemp).ToList(); errorTemp = new List <string>(); if (errors.Count == 0 && ValidateGeometry(out errorTemp, input.Geometry)) { validInput.Geometry = input.Geometry; } errors = errors.Concat(errorTemp).ToList(); errorTemp = new List <string>(); if (errors.Count == 0 && ValidateDates(out errorTemp, input.DateTimeSpan)) { validInput.DateTimeSpan = input.DateTimeSpan; if (input.DateTimeSpan.DateTimeFormat == null) { validInput.DateTimeSpan.DateTimeFormat = "yyyy-MM-dd HH"; } } errors = errors.Concat(errorTemp).ToList(); errorTemp = new List <string>(); validInput.BaseURL = GetBaseUrl(out errorTemp, input.Source, dataset); errors = errors.Concat(errorTemp).ToList(); errorTemp = new List <string>(); validInput.TemporalResolution = (string.IsNullOrWhiteSpace(input.TemporalResolution)) ? "default" : input.TemporalResolution; validInput.TimeLocalized = (string.IsNullOrWhiteSpace(input.TimeLocalized.ToString())) ? false : true; validInput.Units = (string.IsNullOrWhiteSpace(input.Units)) ? "metric" : input.Units; validInput.OutputFormat = (string.IsNullOrWhiteSpace(input.OutputFormat)) ? "json" : input.OutputFormat; validInput.DataValueFormat = (string.IsNullOrWhiteSpace(input.DataValueFormat)) ? "E3" : input.DataValueFormat; errorMsg = string.Join(", ", errors.ToArray()); return(validInput); }
/// <summary> /// Calls the function in Data.Source.NLDAS that will perform the status check. /// </summary> /// <param name="input"></param> /// <returns></returns> public static Dictionary <string, string> CheckStatus(ITimeSeriesInput input) { return(Data.Source.NLDAS.CheckStatus("SurfaceRunoff", input)); }
public DataTable daymetData(ITimeSeriesInput inpt, ITimeSeriesOutput outpt) { string errorMsg = ""; string data = ""; StringBuilder st = new StringBuilder(); int yearDif = (inpt.DateTimeSpan.EndDate.Year - inpt.DateTimeSpan.StartDate.Year); for (int i = 0; i <= yearDif; i++) { string year = inpt.DateTimeSpan.StartDate.AddYears(i).Year.ToString(); st.Append(year + ","); } st.Remove(st.Length - 1, 1); string url = "https://daymet.ornl.gov/data/send/saveData?" + "lat=" + inpt.Geometry.Point.Latitude + "&lon=" + inpt.Geometry.Point.Longitude + "&measuredParams=" + "tmax,tmin,srad,dayl" + "&years=" + st.ToString(); WebClient myWC = new WebClient(); try { int retries = 5; // Max number of request retries string status = ""; // response status code while (retries > 0 && !status.Contains("OK")) { Thread.Sleep(100); WebRequest wr = WebRequest.Create(url); HttpWebResponse response = (HttpWebResponse)wr.GetResponse(); status = response.StatusCode.ToString(); Stream dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); data = reader.ReadToEnd(); reader.Close(); response.Close(); retries -= 1; } } catch (Exception ex) { errorMsg = "ERROR: Unable to download data from Daymet. " + ex.Message; return(null); } DataTable tab = new DataTable(); tab.Columns.Add("Date"); tab.Columns.Add("Julian_Day"); tab.Columns.Add("TMin_C"); tab.Columns.Add("TMax_C"); tab.Columns.Add("TMean_C"); tab.Columns.Add("SolarRadMean_MJm2day"); string[] splitData = data.Split(new string[] { "year,yday,prcp (mm/day)", "year,yday,tmax (deg c),tmin (deg c)", "year,yday,dayl (s),srad (W/m^2),tmax (deg c),tmin (deg c)" }, StringSplitOptions.RemoveEmptyEntries); string[] lines = splitData[1].Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); Boolean julianflag = false; foreach (string line in lines) { string[] linedata = line.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (Convert.ToInt32(Convert.ToDouble(linedata[1])) >= inpt.DateTimeSpan.StartDate.DayOfYear && (Convert.ToInt32(Convert.ToDouble(linedata[0])) == inpt.DateTimeSpan.StartDate.Year)) { julianflag = true; } if (Convert.ToInt32(Convert.ToDouble(linedata[1])) > inpt.DateTimeSpan.EndDate.DayOfYear && (Convert.ToInt32(Convert.ToDouble(linedata[0])) == inpt.DateTimeSpan.EndDate.Year)) { julianflag = false; break; } if (julianflag) { DataRow tabrow = tab.NewRow(); tabrow["Date"] = (new DateTime(Convert.ToInt32(Convert.ToDouble(linedata[0])), 1, 1).AddDays(Convert.ToInt32(Convert.ToDouble(linedata[1])) - 1)).ToString(inpt.DateTimeSpan.DateTimeFormat); tabrow["Julian_Day"] = Convert.ToInt32(Convert.ToDouble(linedata[1])); tabrow["TMin_C"] = linedata[5]; tabrow["TMax_C"] = linedata[4]; tabrow["TMean_C"] = (Convert.ToDouble(linedata[4]) + Convert.ToDouble(linedata[5])) / 2.0; double srad = Convert.ToDouble(linedata[3]); double dayl = Convert.ToDouble(linedata[2]); tabrow["SolarRadMean_MJm2day"] = Math.Round((srad * dayl) / 1000000, 2); tab.Rows.Add(tabrow); } } return(tab); }
/// <summary> /// Makes the GetData call to the base PRISM class. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns> public ITimeSeriesOutput GetData(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; Data.Source.PRISM prism = new Data.Source.PRISM(); string data = prism.GetData(out errorMsg, "'tmax', 'tmin'", input); if (errorMsg.Contains("ERROR")) { return(null); } ITimeSeriesOutput prismOutput = output; prismOutput = prism.SetDataToOutput(out errorMsg, "Temperature", data, output, input); if (errorMsg.Contains("ERROR")) { return(null); } prismOutput = TemporalAggregation(out errorMsg, output, input); if (errorMsg.Contains("ERROR")) { return(null); } return(prismOutput); }
/// <summary> /// Calls the function in Data.Source.GLDAS that will perform the status check. /// </summary> /// <param name="input"></param> /// <returns></returns> public static Dictionary <string, string> CheckStatus(ITimeSeriesInput input) { return(Data.Source.GLDAS.CheckStatus("Temperature", input)); }
/// <summary> /// Checks for temporal resolution and runs appropriate aggregation function. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns> private ITimeSeriesOutput TemporalAggregation(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; output.Metadata.Add("gldas_temporalresolution", input.TemporalResolution); if (input.Units.Contains("imperial")) { output.Metadata["gldas_unit"] = "F"; } output.Data = (input.Units.Contains("imperial")) ? NLDAS.UnitConversion(out errorMsg, output, input) : output.Data; output.Metadata.Add("column_1", "date"); switch (input.TemporalResolution) { case "daily": case "default": // Combined high/low/average output.Data = NLDAS.DailyValues(out errorMsg, output, input, "all"); output.Metadata.Add("column_2", "Max Temperature"); output.Metadata.Add("column_3", "Min Temperature"); output.Metadata.Add("column_4", "Average Temperature"); return(output); case "daily-avg": output.Data = NLDAS.DailyValues(out errorMsg, output, input, "avg"); output.Metadata.Add("column_2", "Average Temperature"); return(output); case "daily-high": output.Data = NLDAS.DailyValues(out errorMsg, output, input, "high"); output.Metadata.Add("column_2", "Max Temperature"); return(output); case "daily-low": output.Data = NLDAS.DailyValues(out errorMsg, output, input, "low"); output.Metadata.Add("column_2", "Min Temperature"); return(output); case "weekly": // Combined high/low/average output.Data = NLDAS.WeeklyValues(out errorMsg, output, input, "all"); output.Metadata.Add("column_2", "Max Temperature"); output.Metadata.Add("column_3", "Min Temperature"); output.Metadata.Add("column_4", "Average Temperature"); return(output); case "weekly-avg": output.Data = NLDAS.WeeklyValues(out errorMsg, output, input, "avg"); output.Metadata.Add("column_2", "Average Temperature"); return(output); case "weekly-high": output.Data = NLDAS.WeeklyValues(out errorMsg, output, input, "high"); output.Metadata.Add("column_2", "Max Temperature"); return(output); case "weekly-low": output.Data = NLDAS.WeeklyValues(out errorMsg, output, input, "low"); output.Metadata.Add("column_2", "Min Temperature"); return(output); case "monthly": // Combined high/low/average output.Data = NLDAS.MonthlyValues(out errorMsg, output, input, "all"); output.Metadata.Add("column_2", "Max Temperature"); output.Metadata.Add("column_3", "Min Temperature"); output.Metadata.Add("column_4", "Average Temperature"); return(output); case "monthly-avg": output.Data = NLDAS.MonthlyValues(out errorMsg, output, input, "avg"); output.Metadata.Add("column_2", "Average Temperature"); return(output); case "monthly-high": output.Data = NLDAS.MonthlyValues(out errorMsg, output, input, "high"); output.Metadata.Add("column_2", "Max Temperature"); return(output); case "monthly-low": output.Data = NLDAS.MonthlyValues(out errorMsg, output, input, "low"); output.Metadata.Add("column_2", "Min Temperature"); return(output); default: return(output); } }
public ITimeSeriesOutput Compute(ITimeSeriesInput inpt, ITimeSeriesOutput outpt, double lat, double lon, string startDate, string endDate, int timeZoneOffset, out string errorMsg) { errorMsg = ""; //NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); double relHMax = 0; double relHMin = 0.0; double petSW = 0; string strDate; CultureInfo CInfoUS = new CultureInfo("en-US"); //DataTable dt = nldas.getData4(timeZoneOffset, out errorMsg); DataTable dt = new DataTable(); DataTable daymets = new DataTable(); switch (inpt.Source) { case "daymet": daymets = daymetData(inpt, outpt); inpt.Source = "nldas"; NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); dt = nldas.getData4(timeZoneOffset, out errorMsg); for (int i = 0; i < daymets.Rows.Count; i++) { DataRow dr = dt.Rows[i]; dr["TMin_C"] = daymets.Rows[i]["TMin_C"]; dr["TMax_C"] = daymets.Rows[i]["TMax_C"]; dr["TMean_C"] = daymets.Rows[i]["TMean_C"]; dr["SolarRadMean_MJm2day"] = daymets.Rows[i]["SolarRadMean_MJm2day"]; } daymets = null; break; case "custom": CustomData cd = new CustomData(); dt = cd.ParseCustomData(inpt, outpt, inpt.Geometry.GeometryMetadata["userdata"].ToString(), "shuttleworthwallace"); break; case "nldas": case "gldas": default: NLDAS2 nldas2 = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); if (inpt.TemporalResolution == "hourly") { NLDAS2 nldasday = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); DataTable dtd = nldasday.getData4(timeZoneOffset, out errorMsg); dt = nldas2.getDataHourly(timeZoneOffset, false, out errorMsg); dt.Columns["THourly_C"].ColumnName = "TMean_C"; dt.Columns["SolarRad_MJm2day"].ColumnName = "SolarRadMean_MJm2day"; dt.Columns["WindSpeed_m/s"].ColumnName = "WindSpeedMean_m/s"; dt.Columns.Remove("SH_Hourly"); dt.Columns.Add("TMin_C"); dt.Columns.Add("TMax_C"); dt.Columns.Add("SHmin"); dt.Columns.Add("SHmax"); int j = -1; for (int i = 0; i < dt.Rows.Count; i++) { if ((inpt.Source == "nldas" && (i % 24 == 0)) || (inpt.Source == "gldas" && (i % 8 == 0))) { j++; } DataRow dr = dtd.Rows[j]; dt.Rows[i]["TMin_C"] = dr["TMin_C"]; dt.Rows[i]["TMax_C"] = dr["TMax_C"]; dt.Rows[i]["SHmin"] = dr["SHmin"]; dt.Rows[i]["SHmax"] = dr["SHmax"]; } dtd = null; } else { dt = nldas2.getData4(timeZoneOffset, out errorMsg); DataRow dr1 = null; List <Double> tList = new List <double>(); List <Double> sList = new List <double>(); double sol = 0.0; double wind = 0.0; if (inpt.TemporalResolution == "weekly") { DataTable wkly = dt.Clone(); int j = 0; for (int i = 0; i < dt.Rows.Count; i++) { if (j == 0) { dr1 = wkly.NewRow(); dr1["Date"] = dt.Rows[i]["Date"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); tList = new List <double>(); sList = new List <double>(); sol = 0.0; wind = 0.0; } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].ToString())); sol += Convert.ToDouble(dt.Rows[i]["SolarRadMean_MJm2day"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeedMean_m/s"]); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmin"].ToString())); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmax"].ToString())); if (j == 6 || i == dt.Rows.Count - 1) { dr1["TMin_C"] = tList.Min().ToString("F2", CultureInfo.InvariantCulture); dr1["TMax_C"] = tList.Max().ToString("F2", CultureInfo.InvariantCulture); dr1["TMean_C"] = (tList.Min() + tList.Max()) / 2.0; dr1["SolarRadMean_MJm2day"] = Math.Round(sol / (j + 1), 2); dr1["WindSpeedMean_m/s"] = Math.Round(wind / (j + 1), 2); dr1["SHmin"] = sList.Min().ToString(); dr1["SHmax"] = sList.Max().ToString(); wkly.Rows.Add(dr1); j = -1; } j++; } dt = wkly; } else if (inpt.TemporalResolution == "monthly") { DataTable mnly = dt.Clone(); int curmonth = inpt.DateTimeSpan.StartDate.Month; int j = 0; bool newmonth = true; for (int i = 0; i < dt.Rows.Count; i++) { if (newmonth) { dr1 = mnly.NewRow(); dr1["Date"] = dt.Rows[i]["Date"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); tList = new List <double>(); sList = new List <double>(); sol = 0.0; wind = 0.0; newmonth = false; curmonth = Convert.ToDateTime(dt.Rows[i]["Date"]).Month; } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].ToString())); sol += Convert.ToDouble(dt.Rows[i]["SolarRadMean_MJm2day"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeedMean_m/s"]); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmin"].ToString())); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmax"].ToString())); if (i + 1 < dt.Rows.Count && (Convert.ToDateTime(dt.Rows[i + 1]["Date"]).Month != curmonth) || i == dt.Rows.Count - 1) { dr1["TMin_C"] = tList.Min().ToString("F2", CultureInfo.InvariantCulture); dr1["TMax_C"] = tList.Max().ToString("F2", CultureInfo.InvariantCulture); dr1["TMean_C"] = (tList.Min() + tList.Max()) / 2.0; dr1["SolarRadMean_MJm2day"] = Math.Round(sol / (j + 1), 2); dr1["WindSpeedMean_m/s"] = Math.Round(wind / (j + 1), 2); dr1["SHmin"] = sList.Min().ToString(); dr1["SHmax"] = sList.Max().ToString(); mnly.Rows.Add(dr1); j = -1; newmonth = true; } j++; } dt = mnly; } } break; } if (errorMsg != "") { Utilities.ErrorOutput err = new Utilities.ErrorOutput(); return(err.ReturnError(errorMsg)); } dt.Columns.Add("RHmin"); dt.Columns.Add("RHmax"); dt.Columns.Add("ShuttleworthWallacePET_in"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "shuttleworthwallace"; string leafareas = "{ "; foreach (int key in leafAreaIndex.Keys) { leafareas += String.Format("{0}: {1}, ", key, leafAreaIndex[key]); } leafareas += "}"; output.Metadata = new Dictionary <string, string>() { { "elevation", elevation.ToString() }, { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "albedo", albedo.ToString() }, { "stomatal_resistance", resistanceStomatal.ToString() }, { "surface_resistance", resistanceSurfaceSoil.ToString() }, { "ground_roughness_length", groundRoughnessLength.ToString() }, { "leaf_width", widthLeaf.ToString() }, { "vegetation_height", vegetationHeight.ToString() }, { "leaf_area_indices", leafareas }, { "request_time", DateTime.Now.ToString() }, { "column_1", "Date" }, { "column_2", "Julian Day" }, { "column_3", "Minimum Temperature" }, { "column_3.1", "Maximum Temperature" }, { "column_3.2", "Mean Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Mean Wind Speed" }, { "column_6", "Minimum Relative Humidity" }, { "column_7", "Maximum Relative Humidity" }, { "column_8", "Potential Evapotranspiration" } }; if (inpt.TemporalResolution == "hourly") { output.Metadata = new Dictionary <string, string>() { { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "DateHour" }, { "column_2", "Julian Day" }, { "column_3", "Hourly Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Minimum Daily Temperature" }, { "column_6", "Maximum Daily Temperature" }, { "column_6.1", "Mean Wind Speed" }, { "column_7", "Minimum Relative Humidity" }, { "column_8", "Maximum Relative Humidity" }, { "column_9", "Potential Evapotranspiration" } }; } output.Data = new Dictionary <string, List <string> >(); foreach (DataRow dr in dt.Rows) { double tmean = Convert.ToDouble(dr["TMean_C"].ToString()); double tmin = Convert.ToDouble(dr["TMin_C"].ToString()); double tmax = Convert.ToDouble(dr["TMax_C"].ToString()); double shmin = Convert.ToDouble(dr["SHmin"].ToString()); double shmax = Convert.ToDouble(dr["SHmax"].ToString()); if (inpt.TemporalResolution == "hourly") { DateTime days = DateTime.Parse(dr["DateHour"].ToString()); strDate = days.ToString("yyyy-MM-dd"); } else { strDate = dr["Date"].ToString(); } DateTime time1 = DateTime.ParseExact(strDate, "yyyy-MM-dd", CInfoUS); double wind = Convert.ToDouble(dr["WindSpeedMean_m/s"].ToString()); double solarRad = Convert.ToDouble(dr["SolarRadMean_MJm2day"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"].ToString()); ShuttleworthWallaceMethod(tmin, tmax, tmean, jday, time1, shmin, shmax, wind, solarRad, out relHMin, out relHMax, out petSW, out errorMsg); dr["RHmin"] = relHMin.ToString("F2", CultureInfo.InstalledUICulture); dr["RHmax"] = relHMax.ToString("F2", CultureInfo.InstalledUICulture); dr["ShuttleworthWallacePET_in"] = petSW.ToString("F4", CultureInfo.InvariantCulture); } dt.Columns.Remove("SHmin"); dt.Columns.Remove("SHmax"); foreach (DataRow dr in dt.Rows) { List <string> lv = new List <string>(); foreach (Object g in dr.ItemArray.Skip(1)) { lv.Add(g.ToString()); } output.Data.Add(dr[0].ToString(), lv); } return(output); }
private double CalculateCN(out string errorMsg, ITimeSeriesInput input) { dynamic cn = GetNLCDCN(); dynamic conditions = GetCNConditions(); dynamic ndvi = GetNDVI(); List <int> ndviCN = new List <int>() { 41, 42, 43, 52, 71, 81, 82 }; Streamcat sc = new Streamcat(); Catchment catchment = sc.GetCatchmentData(out errorMsg, input.Geometry.ComID); double catchmentCN = 0.0; foreach (int c in catchment.landcover.Keys) { double v = catchment.landcover[c]; var nlcd = cn[c.ToString()]; double n = 0.0; if (ndviCN.Contains(c)) { // TODO: ndviType is currently a placeholder value, but will be determined from modis ndvi data using the ranges found in curvenumber_ndvi.json string ndviType = "GOOD"; switch (catchment.hsg) { case "A": n = conditions[c.ToString()][ndviType].A; break; case "B": n = conditions[c.ToString()][ndviType].B; break; case "C": n = conditions[c.ToString()][ndviType].C; break; case "D": n = conditions[c.ToString()][ndviType].D; break; default: n = conditions[c.ToString()][ndviType].A; break; } } else { switch (catchment.hsg) { case "A": n = nlcd.A; break; case "B": n = nlcd.B; break; case "C": n = nlcd.C; break; case "D": n = nlcd.D; break; default: n = nlcd.A; break; } } if (n == -1) { continue; } catchmentCN += v / 100 * n; } if (catchmentCN < 30) { catchmentCN = 30.0; } return(catchmentCN); }
/// <summary> /// Takes the data recieved from prism and sets the ITimeSeries object values. /// </summary> /// <param name="errorMsg"></param> /// <param name="dataset"></param> /// <param name="component"></param> /// <param name="data"></param> /// <returns></returns> public ITimeSeriesOutput SetDataToOutput(out string errorMsg, string dataset, string data, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; PRISMData.PRISM content = Newtonsoft.Json.JsonConvert.DeserializeObject <PRISMData.PRISM>(data); output.Dataset = dataset; output.DataSource = input.Source; output.Metadata = SetMetadata(out errorMsg, content, input, output); output.Data = SetData(out errorMsg, content, input.DateTimeSpan.DateTimeFormat, input.DataValueFormat); return(output); }
/// <summary> /// Parses data string from prism and sets the metadata for the ITimeSeries object. /// </summary> /// <param name="errorMsg"></param> /// <param name="data"></param> /// <param name="output"></param> /// <returns></returns> private Dictionary <string, string> SetMetadata(out string errorMsg, PRISMData.PRISM content, ITimeSeriesInput input, ITimeSeriesOutput output) { errorMsg = ""; Dictionary <string, string> meta = output.Metadata; foreach (PropertyInfo p in typeof(PRISMData.Metainfo).GetProperties()) { if (!meta.ContainsKey(p.Name) || !meta.ContainsKey("prism_" + p.Name)) { meta.Add("prism_" + p.Name, p.GetValue(content.metainfo, null).ToString()); } } meta.Add("prism_start_date", input.DateTimeSpan.StartDate.ToString()); meta.Add("prism_end_date", input.DateTimeSpan.EndDate.ToString()); meta.Add("prism_point_longitude", input.Geometry.Point.Longitude.ToString()); meta.Add("prism_point_latitude", input.Geometry.Point.Latitude.ToString()); if (output.Dataset == "Precipitation") { meta.Add("prism_unit", "mm"); } else { meta.Add("prism_unit", "degC"); } return(meta); }
public DataTable ParseCustomData(ITimeSeriesInput inpt, ITimeSeriesOutput outpt, string data, string algorithm) { DataTable tab = new DataTable(); tab.Columns.Add("Date"); tab.Columns.Add("Julian_Day"); tab.Columns.Add("TMin_C"); tab.Columns.Add("TMax_C"); tab.Columns.Add("TMean_C"); switch (algorithm) { case "hamon": //temp break; case "priestlytaylor": //temp, solar tab.Columns.Add("SolarRadMean_MJm2day"); break; case "mortoncrae": case "mortoncrwe": //temp, solar, spec tab.Columns.Add("SolarRadMean_MJm2day"); tab.Columns.Add("SHmin"); tab.Columns.Add("SHmax"); break; case "grangergray": case "penpan": case "mcjannett": case "penmanopenwater": case "penmandaily": case "shuttleworthwallace": //temp, solar, spec, wind tab.Columns.Add("SolarRadMean_MJm2day"); tab.Columns.Add("SHmin"); tab.Columns.Add("SHmax"); tab.Columns.Add("WindSpeedMean_m/s"); break; } string[] lines = data.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { string[] linedata = line.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); DataRow tabrow = tab.NewRow(); tabrow["Date"] = linedata[0]; tabrow["Julian_Day"] = Convert.ToInt32(Convert.ToDouble(linedata[1])); tabrow["TMin_C"] = linedata[2]; tabrow["TMax_C"] = linedata[3]; tabrow["TMean_C"] = linedata[4];//(Convert.ToDouble(linedata[2]) + Convert.ToDouble(linedata[3])) / 2.0; switch (algorithm) { case "hamon": //temp break; case "priestlytaylor": //temp, solar tabrow["SolarRadMean_MJm2day"] = linedata[5]; break; case "mortoncrae": case "mortoncrwe": //temp, solar, spec tabrow["SolarRadMean_MJm2day"] = linedata[5]; tabrow["SHmin"] = linedata[6]; tabrow["SHmax"] = linedata[7]; break; case "grangergray": case "penpan": case "mcjannett": case "penmanopenwater": case "penmandaily": case "shuttleworthwallace": //temp, solar, spec, wind tabrow["SolarRadMean_MJm2day"] = linedata[5]; tabrow["SHmin"] = linedata[6]; tabrow["SHmax"] = linedata[7]; tabrow["WindSpeedMean_m/s"] = linedata[8]; break; } tab.Rows.Add(tabrow); } return(tab); }
/// <summary> /// Calls the function in Data.Source.NLDAS that will perform the status check. /// </summary> /// <param name="input"></param> /// <returns></returns> public static Dictionary <string, string> CheckStatus(ITimeSeriesInput input) { return(Data.Source.NLDAS.CheckStatus("Evapotranspiration", input)); }
/// <summary> /// Gets workflow data. /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ITimeSeriesOutput> GetWorkFlowData(WorkFlowCompareInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); input.SourceList = new List <string>() { { "ncdc" }, { "nldas" }, { "gldas" }, { "daymet" } }; ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.DataSource = string.Join(" - ", input.SourceList.ToArray()); if (input.Dataset.Contains("precipitation")) { input.SourceList = new List <string>() { { "nldas" }, { "gldas" }, { "daymet" } }; input.Source = "ncdc"; // Validate precipitation sources. errorMsg = (!Enum.TryParse(input.Source, true, out PrecipSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } List <Precipitation.Precipitation> precipList = new List <Precipitation.Precipitation>(); List <ITimeSeriesOutput> outputList = new List <ITimeSeriesOutput>(); // NCDC Call Precipitation.Precipitation ncdc = new Precipitation.Precipitation(); // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory nFactory = new TimeSeriesInputFactory(); ITimeSeriesInput nInput = nFactory.SetTimeSeriesInput(input, new List <string>() { "precipitation" }, out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Set input to precip object. ncdc.Input = nInput; ncdc.Input.TemporalResolution = "daily"; ncdc.Input.Geometry.GeometryMetadata["token"] = (ncdc.Input.Geometry.GeometryMetadata.ContainsKey("token")) ? ncdc.Input.Geometry.GeometryMetadata["token"] : "RUYNSTvfSvtosAoakBSpgxcHASBxazzP"; ITimeSeriesOutput nResult = ncdc.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } output = nResult; // Construct Precipitation objects for Parallel execution in the preceeding Parallel.ForEach statement. foreach (string source in input.SourceList) { // Precipitation object Precipitation.Precipitation precip = new Precipitation.Precipitation(); PointCoordinate point = new PointCoordinate(); if (output.Metadata.ContainsKey("ncdc_latitude") && output.Metadata.ContainsKey("ncdc_longitude")) { point.Latitude = Convert.ToDouble(output.Metadata["ncdc_latitude"]); point.Longitude = Convert.ToDouble(output.Metadata["ncdc_longitude"]); input.Geometry.Point = point; } else { errorMsg = "ERROR: Coordinate information was not found or is invalid for the specified NCDC station."; } // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); input.Source = source; ITimeSeriesInput sInput = iFactory.SetTimeSeriesInput(input, new List <string>() { "PRECIP" }, out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Set input to precip object. precip.Input = sInput; precip.Input.TemporalResolution = "daily"; precip.Input.DateTimeSpan.EndDate = precip.Input.DateTimeSpan.EndDate.AddDays(1); if (!precip.Input.Geometry.GeometryMetadata.ContainsKey("leapYear")) { precip.Input.Geometry.GeometryMetadata.Add("leapYear", "correction"); } precipList.Add(precip); } List <string> errorList = new List <string>(); object outputListLock = new object(); var options = new ParallelOptions { MaxDegreeOfParallelism = -1 }; Parallel.ForEach(precipList, options, (Precipitation.Precipitation precip) => { // Gets the Precipitation data. string errorM = ""; ITimeSeriesOutput result = precip.GetData(out errorM); lock (outputListLock) { errorList.Add(errorM); outputList.Add(result); } }); if (errorList.FindIndex(errorStr => errorStr.Contains("ERROR")) != -1) { return(err.ReturnError(string.Join(",", errorList.ToArray()))); } foreach (ITimeSeriesOutput result in outputList) { output = Utilities.Merger.MergeTimeSeries(output, result); } output.Metadata.Add("column_1", "date"); output.Metadata.Add("column_2", "ncdc"); output = Utilities.Statistics.GetStatistics(out errorMsg, output); return(output); } else if (input.Dataset.Contains("SurfaceRunoff")) { //TODO: Do runoff source iteration. return(err.ReturnError("ERROR. Workflow has not yet been implemented.")); } else { return(err.ReturnError("ERROR: WorkFlow source not found or is invalid.")); } }
/// <summary> /// Checks temporal resolution and runs appropriate aggregation function. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns> private ITimeSeriesOutput TemporalAggregation(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; output.Metadata.Add("nldas_temporalresolution", input.TemporalResolution); output.Metadata.Add("column_1", "Date"); if (input.Units.Contains("imperial")) { output.Metadata["nldas_unit"] = "in"; } switch (input.TemporalResolution) { case "daily": output.Data = DailyAggregatedSum(out errorMsg, 1.0, output, input); output.Metadata.Add("column_2", "Daily Total"); return(output); case "weekly": output.Data = WeeklyAggregatedSum(out errorMsg, 1.0, output, input); output.Metadata.Add("column_2", "Weekly Total"); return(output); case "monthly": output.Data = MonthlyAggregatedSum(out errorMsg, 1.0, output, input); output.Metadata.Add("column_2", "Monthly Total"); return(output); default: output.Data = (input.Units.Contains("imperial")) ? UnitConversion(out errorMsg, 1.0, output, input) : output.Data; output.Metadata.Add("column_2", "Hourly Total"); return(output); } }
public ITimeSeriesOutput GetData(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; Data.Source.PRISM prism = new Data.Source.PRISM(); string data = prism.GetData(out errorMsg, "ppt", input); ITimeSeriesOutput prismOutput = output; if (errorMsg.Contains("ERROR")) { Utilities.ErrorOutput err = new Utilities.ErrorOutput(); output = err.ReturnError("Precipitation", "PRISM", errorMsg); errorMsg = ""; return(output); } else { prismOutput = prism.SetDataToOutput(out errorMsg, "Precipitation", data, output, input); } string inputObject = Newtonsoft.Json.JsonConvert.SerializeObject(input); string outputObject = Newtonsoft.Json.JsonConvert.SerializeObject(prismOutput); prismOutput = TemporalAggregation(out errorMsg, output, input); if (errorMsg.Contains("ERROR")) { return(null); } return(prismOutput); }
/// <summary> /// Converts metric ldas kg/m**2 (mm) units to imperial inches units. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns> public static Dictionary <string, List <string> > UnitConversion(out string errorMsg, double modifier, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; // Unit conversion coefficient double unit = 0.0393701; Dictionary <string, List <string> > tempData = new Dictionary <string, List <string> >(); for (int i = 0; i < output.Data.Count; i++) { tempData.Add(output.Data.Keys.ElementAt(i).ToString(), new List <string>() { (modifier * unit * Convert.ToDouble(output.Data[output.Data.Keys.ElementAt(i)][0])).ToString(input.DataValueFormat) }); } return(tempData); }
/// <summary> /// TimeSeriesInput setter abstract function /// </summary> /// <param name="input"></param> /// <param name="dataset"></param> /// <param name="errorMsg"></param> /// <returns></returns> public abstract ITimeSeriesInput SetTimeSeriesInput(ITimeSeriesInput input, List <string> dataset, out string errorMsg);
public ITimeSeriesOutput Compute(ITimeSeriesInput inpt, ITimeSeriesOutput outpt, double lat, double lon, string startDate, string endDate, int timeZoneOffset, int model, out double aprecip, out string errorMsg) { errorMsg = ""; //NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); aprecip = 0.0; //nldas.getAnnualPrecipitation(); //AnnualPrecipitation = aprecip; double relHMax = 0; double relHMin = 0.0; double petMCW = 0; string strDate; CultureInfo CInfoUS = new CultureInfo("en-US"); //DataTable dt = nldas.getData3(timeZoneOffset, out errorMsg); DataTable dt = new DataTable(); DataTable data3 = new DataTable(); switch (inpt.Source) { case "daymet": dt = daymetData(inpt, outpt); dt = Utilities.Utility.aggregateData(inpt, dt, "mortoncrwe"); inpt.Source = "nldas"; NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); data3 = nldas.getData3(timeZoneOffset, out errorMsg); dt.Columns.Add("SHmin"); dt.Columns.Add("SHmax"); for (int i = 0; i < dt.Rows.Count; i++) { dt.Rows[i]["SHmin"] = data3.Rows[i]["SHmin"]; dt.Rows[i]["SHmax"] = data3.Rows[i]["SHmin"]; } data3 = null; inpt.Source = "daymet"; break; case "custom": CustomData cd = new CustomData(); dt = cd.ParseCustomData(inpt, outpt, inpt.Geometry.GeometryMetadata["userdata"].ToString(), "mortoncrwe"); break; case "nldas": case "gldas": default: NLDAS2 nldas2 = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); if (inpt.TemporalResolution == "hourly") { NLDAS2 nldasday = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); DataTable dtd = nldasday.getData3(timeZoneOffset, out errorMsg); dt = nldas2.getDataHourly(timeZoneOffset, false, out errorMsg); dt.Columns["THourly_C"].ColumnName = "TMean_C"; dt.Columns["SolarRad_MJm2day"].ColumnName = "SolarRadMean_MJm2day"; dt.Columns.Remove("WindSpeed_m/s"); dt.Columns.Remove("SH_Hourly"); dt.Columns.Add("TMin_C"); dt.Columns.Add("TMax_C"); dt.Columns.Add("SHmin"); dt.Columns.Add("SHmax"); int j = -1; for (int i = 0; i < dt.Rows.Count; i++) { if ((inpt.Source == "nldas" && (i % 24 == 0)) || (inpt.Source == "gldas" && (i % 8 == 0))) { j++; } DataRow dr = dtd.Rows[j]; dt.Rows[i]["TMin_C"] = dr["TMin_C"]; dt.Rows[i]["TMax_C"] = dr["TMax_C"]; dt.Rows[i]["SHmin"] = dr["SHmin"]; dt.Rows[i]["SHmax"] = dr["SHmax"]; } dtd = null; } else { dt = nldas2.getData3(timeZoneOffset, out errorMsg); DataRow dr1 = null; List <Double> tList = new List <double>(); List <Double> sList = new List <double>(); double sol = 0.0; if (inpt.TemporalResolution == "weekly") { DataTable wkly = dt.Clone(); int j = 0; for (int i = 0; i < dt.Rows.Count; i++) { if (j == 0) { dr1 = wkly.NewRow(); dr1["Date"] = dt.Rows[i]["Date"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); tList = new List <double>(); sList = new List <double>(); sol = 0.0; } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].ToString())); sol += Convert.ToDouble(dt.Rows[i]["SolarRadMean_MJm2day"]); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmin"].ToString())); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmax"].ToString())); if (j == 6 || i == dt.Rows.Count - 1) { dr1["TMin_C"] = tList.Min().ToString("F2", CultureInfo.InvariantCulture); dr1["TMax_C"] = tList.Max().ToString("F2", CultureInfo.InvariantCulture); dr1["TMean_C"] = (tList.Min() + tList.Max()) / 2.0; dr1["SolarRadMean_MJm2day"] = Math.Round(sol / (j + 1), 2); dr1["SHmin"] = sList.Min().ToString(); dr1["SHmax"] = sList.Max().ToString(); wkly.Rows.Add(dr1); j = -1; } j++; } dt = wkly; } else if (inpt.TemporalResolution == "monthly") { DataTable mnly = dt.Clone(); int curmonth = inpt.DateTimeSpan.StartDate.Month; int j = 0; bool newmonth = true; for (int i = 0; i < dt.Rows.Count; i++) { if (newmonth) { dr1 = mnly.NewRow(); dr1["Date"] = dt.Rows[i]["Date"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); tList = new List <double>(); sList = new List <double>(); sol = 0.0; newmonth = false; curmonth = Convert.ToDateTime(dt.Rows[i]["Date"]).Month; } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].ToString())); sol += Convert.ToDouble(dt.Rows[i]["SolarRadMean_MJm2day"]); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmin"].ToString())); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmax"].ToString())); if (i + 1 < dt.Rows.Count && (Convert.ToDateTime(dt.Rows[i + 1]["Date"]).Month != curmonth) || i == dt.Rows.Count - 1) { dr1["TMin_C"] = tList.Min().ToString("F2", CultureInfo.InvariantCulture); dr1["TMax_C"] = tList.Max().ToString("F2", CultureInfo.InvariantCulture); dr1["TMean_C"] = (tList.Min() + tList.Max()) / 2.0; dr1["SolarRadMean_MJm2day"] = Math.Round(sol / (j + 1), 2); dr1["SHmin"] = sList.Min().ToString(); dr1["SHmax"] = sList.Max().ToString(); mnly.Rows.Add(dr1); j = -1; newmonth = true; } j++; } dt = mnly; } } aprecip = nldas2.getAnnualPrecipitation(); AnnualPrecipitation = aprecip; break; } if (errorMsg != "") { Utilities.ErrorOutput err = new Utilities.ErrorOutput(); return(err.ReturnError(errorMsg)); } dt.Columns.Add("RHmin"); dt.Columns.Add("RHmax"); dt.Columns.Add("MortonCRWEPET_in"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "mortoncrwe"; output.Metadata = new Dictionary <string, string>() { { "elevation", elevation.ToString() }, { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "albedo", albedo.ToString() }, { "emissivity", emissivity.ToString() }, { "annual_precipitation", annualPrecipitation.ToString() }, { "zenith", azenith.ToString() }, { "model", model.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "Date" }, { "column_2", "Julian Day" }, { "column_3", "Minimum Temperature" }, { "column_4", "Maximum Temperature" }, { "column_5", "Mean Temperature" }, { "column_6", "Mean Solar Radiation" }, { "column_7", "Minimum Relative Humidity" }, { "column_8", "Maximum Relative Humidity" }, { "column_9", "Potential Evapotranspiration" } }; if (inpt.TemporalResolution == "hourly") { output.Metadata = new Dictionary <string, string>() { { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "DateHour" }, { "column_2", "Julian Day" }, { "column_3", "Hourly Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Minimum Daily Temperature" }, { "column_6", "Maximum Daily Temperature" }, { "column_7", "Minimum Relative Humidity" }, { "column_8", "Maximum Relative Humidity" }, { "column_9", "Potential Evapotranspiration" } }; } output.Data = new Dictionary <string, List <string> >(); foreach (DataRow dr in dt.Rows) { double tmean = Convert.ToDouble(dr["TMean_C"].ToString()); double tmin = Convert.ToDouble(dr["TMin_C"].ToString()); double tmax = Convert.ToDouble(dr["TMax_C"].ToString()); double shmin = Convert.ToDouble(dr["SHmin"].ToString()); double shmax = Convert.ToDouble(dr["SHmax"].ToString()); if (inpt.TemporalResolution == "hourly") { DateTime days = DateTime.Parse(dr["DateHour"].ToString()); strDate = days.ToString("yyyy-MM-dd"); } else { strDate = dr["Date"].ToString().Trim(); } DateTime time = DateTime.ParseExact(strDate, "yyyy-MM-dd", CInfoUS); double solarRad = Convert.ToDouble(dr["SolarRadMean_MJm2day"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"].ToString()); MortonCRWEMethod(tmin, tmax, tmean, jday, time, shmin, shmax, solarRad, model, out relHMin, out relHMax, out petMCW, out errorMsg); if (inpt.Source == "daymet") { double vapor = Convert.ToDouble(dr["VaPress"].ToString()); dr["RHmin"] = daymetHumid(tmin, vapor).ToString("F2", CultureInfo.InstalledUICulture); dr["RHmax"] = daymetHumid(tmax, vapor).ToString("F2", CultureInfo.InstalledUICulture); } else { dr["RHmin"] = relHMin.ToString("F2", CultureInfo.InstalledUICulture); dr["RHmax"] = relHMax.ToString("F2", CultureInfo.InstalledUICulture); } dr["MortonCRWEPET_in"] = petMCW.ToString("F4", CultureInfo.InvariantCulture); } if (inpt.Source == "daymet") { dt.Columns.Remove("VaPress"); } dt.Columns.Remove("SHmin"); dt.Columns.Remove("SHmax"); foreach (DataRow dr in dt.Rows) { List <string> lv = new List <string>(); foreach (Object g in dr.ItemArray.Skip(1)) { lv.Add(g.ToString()); } output.Data.Add(dr[0].ToString(), lv); } return(output); }
/// <summary> /// TimeSeriesInputFactory function for validating and setting TimeSeriesInput objects. /// </summary> /// <param name="input"></param> /// <param name="dataset"></param> /// <param name="errorMsg"></param> /// <returns></returns> public override ITimeSeriesInput SetTimeSeriesInput(ITimeSeriesInput input, List <string> dataset, out string errorMsg) { errorMsg = ""; TimeSeriesInput newInput = new TimeSeriesInput(); // Below preforms validation of required parameters when attempting to initialize dataset component inputs. // Validates that the source string is not null or empty. if (String.IsNullOrWhiteSpace(input.Source)) { errorMsg += "ERROR: Required 'Source' parameter was not found or is invalid."; return(newInput); } else { newInput.Source = input.Source; } // Validating Geometry object if (input.Geometry == null) { errorMsg += "ERROR: No geometry values found in the provided parameters."; return(newInput); } else { newInput.Geometry = input.Geometry; } // Validates that the Latitude parameter is not invalid if (!input.Source.Contains("ncdc") && !input.Source.Contains("compare")) { if (input.Geometry.Point == null) { errorMsg += "ERROR: No geometry values found in the provided parameters."; return(newInput); } if (Double.IsNaN(input.Geometry.Point.Latitude)) { errorMsg += "ERROR: Required 'Latitude' parameter was not found or is invalid."; } // Validates that the Longitude parameter is not invalid if (Double.IsNaN(input.Geometry.Point.Longitude)) { errorMsg += "ERROR: Required 'Longitude' parameter was not found or is invalid."; } if (!errorMsg.Contains("Latitude") || !errorMsg.Contains("Longitude")) { if (input.Geometry.Point.Latitude > -90 && input.Geometry.Point.Latitude < 90 && input.Geometry.Point.Longitude > -180 && input.Geometry.Point.Longitude < 180) { IPointCoordinate pC = new PointCoordinate() { Latitude = input.Geometry.Point.Latitude, Longitude = input.Geometry.Point.Longitude }; newInput.Geometry = new TimeSeriesGeometry() { Point = (PointCoordinate)pC }; } else { errorMsg += "ERROR: Latitude or Longitude value is not a valid coordinate."; } } } else { if (!input.Geometry.GeometryMetadata.ContainsKey("stationID")) { errorMsg += "ERROR: " + input.Source + " used as source but no stationID value was found in Geometry.GeometryMetadata."; } IPointCoordinate pC = new PointCoordinate() { Latitude = 0.0, Longitude = 0.0 }; newInput.Geometry = new TimeSeriesGeometry() { Point = (PointCoordinate)pC }; } newInput.Geometry.GeometryMetadata = input.Geometry.GeometryMetadata ?? new Dictionary <string, string>(); newInput.Geometry.Description = input.Geometry.Description ?? ""; // Validates and sets Timezone information if (input.Geometry.Timezone == null) { newInput.Geometry.Timezone = new Timezone() { Name = "", Offset = 0.0, DLS = false }; } else { newInput.Geometry.Timezone = new Timezone() { }; newInput.Geometry.Timezone.Name = (String.IsNullOrWhiteSpace(input.Geometry.Timezone.Name)) ? "TZNotSet" : input.Geometry.Timezone.Name; newInput.Geometry.Timezone.Offset = (Double.IsNaN(input.Geometry.Timezone.Offset)) ? 0.0 : input.Geometry.Timezone.Offset; newInput.Geometry.Timezone.DLS = (input.Geometry.Timezone.DLS == true) ? true : false; } if (input.DateTimeSpan == null) { errorMsg += "ERROR: DateTimeSpan object is null. DateTimeSpan, with a StartDate and EndDate, is required."; return(newInput); } // Validates that the StartDate parameter is not invalid if (input.DateTimeSpan.StartDate.Equals(DateTime.MinValue)) { errorMsg += "ERROR: Required 'StartDate' parameter was not found or is invalid."; } // Validates that the EndDate parameter is not invalid if (input.DateTimeSpan.EndDate.Equals(DateTime.MinValue)) { errorMsg += "ERROR: Required 'EndDate' parameter was not found or is invalid."; } if (!errorMsg.Contains("StartDate") || !errorMsg.Contains("EndDate")) { newInput.DateTimeSpan = new DateTimeSpan() { StartDate = input.DateTimeSpan.StartDate, EndDate = input.DateTimeSpan.EndDate }; } if (!errorMsg.Contains("ERROR")) { if (DateTime.Compare(newInput.DateTimeSpan.StartDate, newInput.DateTimeSpan.EndDate) >= 0) { errorMsg += "ERROR: Start date must be before end date."; } } // Validates DateTime output format newInput.DateTimeSpan.DateTimeFormat = (String.IsNullOrWhiteSpace(input.DateTimeSpan.DateTimeFormat)) ? "yyyy-MM-dd HH": input.DateTimeSpan.DateTimeFormat; // TODO: Add validation of the given datetimeformat. If not valid set to default, TBD // Validates the DataValueFormat parameter newInput.DataValueFormat = (String.IsNullOrWhiteSpace(input.DataValueFormat)) ? "E3" : input.DataValueFormat; // TODO: Add validation of the given datavalueformat. If not valid set to default, TBD // Validates TemporalResolution parameter newInput.TemporalResolution = (String.IsNullOrWhiteSpace(input.TemporalResolution)) ? "default" : input.TemporalResolution; // TODO: Add validation of the provided temporalresolution. If not valid set to default // Validates TimeLocalized parameter newInput.TimeLocalized = (input.TimeLocalized == true) ? true : false; // TODO: Add validation of the provided timelocalized. If not valid set to true // Validates Units parameter newInput.Units = (String.IsNullOrWhiteSpace(input.Units)) ? "metric" : input.Units; // TODO: Add validation of the provided units. If not valid set to "metric" // Validates OutputFormat parameter newInput.OutputFormat = (String.IsNullOrWhiteSpace(input.OutputFormat)) ? "json" : input.OutputFormat; // TODO: Add validation of the provided output. If not valid set to "json" newInput.BaseURL = new List <string>(); foreach (string ds in dataset) { string tempError = ""; newInput.BaseURL.Add(GetBaseURL(input, ds, out tempError)); if (tempError.Contains("ERROR")) { errorMsg += tempError; } } return(newInput); }
/// <summary> /// Makes the GetData call to the base GLDAS class. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns>S public ITimeSeriesOutput GetData(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; Data.Source.GLDAS gldas = new Data.Source.GLDAS(); string data = gldas.GetData(out errorMsg, "Temp", input); if (errorMsg.Contains("ERROR")) { return(null); } ITimeSeriesOutput gldasOutput = output; gldasOutput = gldas.SetDataToOutput(out errorMsg, "Temperature", data, output, input); if (errorMsg.Contains("ERROR")) { return(null); } gldasOutput = TemporalAggregation(out errorMsg, output, input); if (errorMsg.Contains("ERROR")) { return(null); } return(gldasOutput); }
private static string GetBaseURL(ITimeSeriesInput input, string dataset, out string errorMsg) { errorMsg = ""; Dictionary <string, string> urls = new Dictionary <string, string>(); // TODO: Find alternative solution for HttpContext.Current to only load url_info.txt on application startup. HttpContext behavior altered in .Net Core //if (HttpContext.Current == null) //{ urls = Data.Files.FileToDictionary(@".\App_Data\" + "url_info.txt"); //} //else //{ // urls = (Dictionary<string, string>)HttpContext.Current.Application["urlList"]; //} Dictionary <string, string> caselessUrls = new Dictionary <string, string>(urls, StringComparer.OrdinalIgnoreCase); string src = ""; switch (input.Source) { case "nldas": src = "NLDAS"; break; case "gldas": src = "GLDAS"; break; case "daymet": src = "DAYMET"; break; case "ncdc": src = "NCDC"; break; case "wgen": return(""); case "prism": src = "PRISM"; break; default: errorMsg = "ERROR: Provided source is not valid. Unable to construct base url."; return(""); } string url_key = (src == "PRISM") ? src + "_URL": src + "_" + dataset + "_URL"; try { return(caselessUrls[url_key]); } catch { errorMsg = "ERROR: Unable to construct base url from the specified dataset and provided data source."; return(""); } }
public ITimeSeriesOutput Compute(ITimeSeriesInput inpt, ITimeSeriesOutput outpt, double lat, double lon, string startDate, string endDate, int timeZoneOffset, out string errorMsg) { errorMsg = ""; double relHMax = 0; double relHMin = 0.0; double petGG = 0; //NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); DataTable dt = new DataTable(); DataTable daymets = new DataTable(); switch (inpt.Source) { case "daymet": daymets = daymetData(inpt, outpt); inpt.Source = "nldas"; NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); dt = nldas.getData4(timeZoneOffset, out errorMsg); for (int i = 0; i < daymets.Rows.Count; i++) //dt.rows.count { DataRow dr = dt.Rows[i]; //Missing day error fixed? dr["TMin_C"] = daymets.Rows[i]["TMin_C"]; dr["TMax_C"] = daymets.Rows[i]["TMax_C"]; dr["TMean_C"] = daymets.Rows[i]["TMean_C"]; dr["SolarRadMean_MJm2day"] = daymets.Rows[i]["SolarRadMean_MJm2day"]; } daymets = null; break; case "custom": CustomData cd = new CustomData(); dt = cd.ParseCustomData(inpt, outpt, inpt.Geometry.GeometryMetadata["userdata"].ToString(), "grangergray"); break; case "nldas": case "gldas": default: NLDAS2 nldas2 = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); if (inpt.TemporalResolution == "hourly") { NLDAS2 nldasday = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); DataTable dtd = nldasday.getData4(timeZoneOffset, out errorMsg); dt = nldas2.getDataHourly(timeZoneOffset, false, out errorMsg); dt.Columns["THourly_C"].ColumnName = "TMean_C"; dt.Columns["SolarRad_MJm2day"].ColumnName = "SolarRadMean_MJm2day"; dt.Columns["WindSpeed_m/s"].ColumnName = "WindSpeedMean_m/s"; dt.Columns.Remove("SH_Hourly"); //dt.Columns.Remove("WindSpeed_m/s"); dt.Columns.Add("TMin_C"); dt.Columns.Add("TMax_C"); dt.Columns.Add("SHmin"); dt.Columns.Add("SHmax"); int j = -1; for (int i = 0; i < dt.Rows.Count; i++) { if ((inpt.Source == "nldas" && (i % 24 == 0)) || (inpt.Source == "gldas" && (i % 8 == 0))) { j++; } DataRow dr = dtd.Rows[j]; dt.Rows[i]["TMin_C"] = dr["TMin_C"]; dt.Rows[i]["TMax_C"] = dr["TMax_C"]; dt.Rows[i]["SHmin"] = dr["SHmin"]; dt.Rows[i]["SHmax"] = dr["SHmax"]; } dtd = null; } else { dt = nldas2.getData4(timeZoneOffset, out errorMsg); DataRow dr1 = null; List <Double> tList = new List <double>(); List <Double> sList = new List <double>(); double sol = 0.0; double wind = 0.0; if (inpt.TemporalResolution == "weekly") { DataTable wkly = dt.Clone(); int j = 0; for (int i = 0; i < dt.Rows.Count; i++) { if (j == 0) { dr1 = wkly.NewRow(); dr1["Date"] = dt.Rows[i]["Date"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); tList = new List <double>(); sList = new List <double>(); sol = 0.0; wind = 0.0; } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].ToString())); sol += Convert.ToDouble(dt.Rows[i]["SolarRadMean_MJm2day"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeedMean_m/s"]); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmin"].ToString())); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmax"].ToString())); if (j == 6 || i == dt.Rows.Count - 1) { dr1["TMin_C"] = tList.Min().ToString("F2", CultureInfo.InvariantCulture); dr1["TMax_C"] = tList.Max().ToString("F2", CultureInfo.InvariantCulture); dr1["TMean_C"] = (tList.Min() + tList.Max()) / 2.0; dr1["SolarRadMean_MJm2day"] = Math.Round(sol / (j + 1), 2); dr1["WindSpeedMean_m/s"] = Math.Round(wind / (j + 1), 2); dr1["SHmin"] = sList.Min().ToString(); dr1["SHmax"] = sList.Max().ToString(); wkly.Rows.Add(dr1); j = -1; } j++; } dt = wkly; } else if (inpt.TemporalResolution == "monthly") { DataTable mnly = dt.Clone(); int curmonth = inpt.DateTimeSpan.StartDate.Month; int j = 0; bool newmonth = true; for (int i = 0; i < dt.Rows.Count; i++) { if (newmonth) { dr1 = mnly.NewRow(); dr1["Date"] = dt.Rows[i]["Date"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); tList = new List <double>(); sList = new List <double>(); sol = 0.0; wind = 0.0; newmonth = false; curmonth = Convert.ToDateTime(dt.Rows[i]["Date"]).Month; } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].ToString())); sol += Convert.ToDouble(dt.Rows[i]["SolarRadMean_MJm2day"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeedMean_m/s"]); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmin"].ToString())); sList.Add(Convert.ToDouble(dt.Rows[i]["SHmax"].ToString())); if (i + 1 < dt.Rows.Count && (Convert.ToDateTime(dt.Rows[i + 1]["Date"]).Month != curmonth) || i == dt.Rows.Count - 1) { dr1["TMin_C"] = tList.Min().ToString("F2", CultureInfo.InvariantCulture); dr1["TMax_C"] = tList.Max().ToString("F2", CultureInfo.InvariantCulture); dr1["TMean_C"] = (tList.Min() + tList.Max()) / 2.0; dr1["SolarRadMean_MJm2day"] = Math.Round(sol / (j + 1), 2); dr1["WindSpeedMean_m/s"] = Math.Round(wind / (j + 1), 2); dr1["SHmin"] = sList.Min().ToString(); dr1["SHmax"] = sList.Max().ToString(); mnly.Rows.Add(dr1); j = -1; newmonth = true; } j++; } dt = mnly; } } break; } if (errorMsg != "") { Utilities.ErrorOutput err = new Utilities.ErrorOutput(); return(err.ReturnError(errorMsg)); } dt.Columns.Add("RHmin"); dt.Columns.Add("RHmax"); dt.Columns.Add("GrangerGrayPET_In"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "grangergray"; output.Metadata = new Dictionary <string, string>() { { "elevation", elevation.ToString() }, { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "albedo", albedo.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "Date" }, { "column_2", "Julian Day" }, { "column_3", "Minimum Temperature" }, { "column_3.1", "Maximum Temperature" }, { "column_3.2", "Mean Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Mean Wind Speed" }, { "column_6", "Minimum Relative Humidity" }, { "column_7", "Maximum Relative Humidity" }, { "column_8", "Potential Evapotranspiration" } }; if (inpt.TemporalResolution == "hourly") { output.Metadata = new Dictionary <string, string>() { { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "DateHour" }, { "column_2", "Julian Day" }, { "column_3", "Hourly Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Minimum Daily Temperature" }, { "column_6", "Maximum Daily Temperature" }, { "column_6.1", "Mean Wind Speed" }, { "column_7", "Minimum Relative Humidity" }, { "column_8", "Maximum Relative Humidity" }, { "column_9", "Potential Evapotranspiration" } }; } output.Data = new Dictionary <string, List <string> >(); foreach (DataRow dr in dt.Rows) { double tmean = Convert.ToDouble(dr["TMean_C"].ToString()); double tmin = Convert.ToDouble(dr["TMin_C"].ToString()); double tmax = Convert.ToDouble(dr["TMax_C"].ToString()); double shmin = Convert.ToDouble(dr["SHmin"].ToString()); double shmax = Convert.ToDouble(dr["SHmax"].ToString()); double wind = Convert.ToDouble(dr["WindSpeedMean_m/s"].ToString()); double solarRad = Convert.ToDouble(dr["SolarRadMean_MJm2day"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"].ToString()); GrangerGrayMethod(tmin, tmax, tmean, jday, shmin, shmax, wind, solarRad, out relHMin, out relHMax, out petGG, out errorMsg); dr["RHmin"] = relHMin.ToString("F2", CultureInfo.InstalledUICulture); dr["RHmax"] = relHMax.ToString("F2", CultureInfo.InstalledUICulture); dr["GrangerGrayPET_In"] = petGG.ToString("F4", CultureInfo.InvariantCulture); } dt.Columns.Remove("SHmin"); dt.Columns.Remove("SHmax"); foreach (DataRow dr in dt.Rows) { List <string> lv = new List <string>(); foreach (Object g in dr.ItemArray.Skip(1)) { lv.Add(g.ToString()); } output.Data.Add(dr[0].ToString(), lv); } return(output); }
/// <summary> /// Makes the GetData call to the base NLDAS class. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns> public ITimeSeriesOutput GetData(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; Data.Source.NLDAS nldas = new Data.Source.NLDAS(); string data = nldas.GetData(out errorMsg, "Surface_Flow", input); if (errorMsg.Contains("ERROR")) { return(null); } ITimeSeriesOutput nldasOutput = output; nldasOutput = nldas.SetDataToOutput(out errorMsg, "SurfaceRunoff", data, output, input); if (errorMsg.Contains("ERROR")) { return(null); } nldasOutput = TemporalAggregation(out errorMsg, output, input); if (errorMsg.Contains("ERROR")) { return(null); } return(nldasOutput); }
/// <summary> /// Converts Kelvin to Fahrenheit /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <returns></returns> public static Dictionary <string, List <string> > UnitConversion(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; Dictionary <string, List <string> > tempData = new Dictionary <string, List <string> >(); for (int i = 0; i < output.Data.Count; i++) { tempData.Add(output.Data.Keys.ElementAt(i).ToString(), new List <string>() { ((Convert.ToDouble(output.Data[output.Data.Keys.ElementAt(i)][0]) * (9.0 / 5.0)) - 459.67).ToString(input.DataValueFormat) }); } return(tempData); }
/// <summary> /// Monthly aggregated sums for SurfaceRunoff data. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <returns></returns> public static Dictionary <string, List <string> > MonthlyAggregatedSum(out string errorMsg, double modifier, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; DateTime iDate = new DateTime(); double sum = 0.0; // Unit conversion coefficient double unit = (input.Units.Contains("imperial")) ? 0.0393701 : 1.0; string dateString0 = output.Data.Keys.ElementAt(0).ToString().Substring(0, output.Data.Keys.ElementAt(0).ToString().Length - 1) + ":00:00"; DateTime.TryParse(dateString0, out iDate); Dictionary <string, List <string> > tempData = new Dictionary <string, List <string> >(); for (int i = 0; i < output.Data.Count; i++) { DateTime date = new DateTime(); string dateString = output.Data.Keys.ElementAt(i).ToString().Substring(0, output.Data.Keys.ElementAt(i).ToString().Length - 1) + ":00:00"; DateTime.TryParse(dateString, out date); if (date.Month != iDate.Month) { tempData.Add(iDate.ToString(input.DateTimeSpan.DateTimeFormat), new List <string>() { (modifier * unit * sum).ToString(input.DataValueFormat) }); iDate = date; sum = Convert.ToDouble(output.Data[output.Data.Keys.ElementAt(i)][0]); } else { sum += Convert.ToDouble(output.Data[output.Data.Keys.ElementAt(i)][0]); } } return(tempData); }
/// <summary> /// Gets monthly temperature values, calculating and setting to Data average, high and low, depending on request. /// </summary> /// <param name="errorMsg"></param> /// <param name="output"></param> /// <param name="input"></param> /// <param name="type">"all", "avg", "high", "low"</param> /// <returns></returns> public static Dictionary <string, List <string> > MonthlyValues(out string errorMsg, ITimeSeriesOutput output, ITimeSeriesInput input, string type) { errorMsg = ""; DateTime iDate = new DateTime(); string dateString0 = output.Data.Keys.ElementAt(0).ToString().Substring(0, output.Data.Keys.ElementAt(0).ToString().Length - 1) + ":00:00"; DateTime.TryParse(dateString0, out iDate); double sum = 0.0; double high = 0.0; double low = 5000; double allSum = 0.0; double allHigh = 0.0; double allLow = 5000; int dayIndex = 0; Dictionary <string, List <string> > tempData = new Dictionary <string, List <string> >(); for (int i = 0; i < output.Data.Count; i++) { DateTime date = new DateTime(); string dateString = output.Data.Keys.ElementAt(i).ToString().Substring(0, output.Data.Keys.ElementAt(i).ToString().Length - 1) + ":00:00"; DateTime.TryParse(dateString, out date); if (date.Month != iDate.Month) { double average = 0.0; switch (type) { case "all": default: average = sum / dayIndex; tempData.Add(iDate.ToString(input.DateTimeSpan.DateTimeFormat), new List <string>() { (high).ToString(input.DataValueFormat), (low).ToString(input.DataValueFormat), (average).ToString(input.DataValueFormat) } ); break; case "avg": average = sum / dayIndex; tempData.Add(iDate.ToString(input.DateTimeSpan.DateTimeFormat), new List <string>() { (average).ToString(input.DataValueFormat) } ); break; case "high": tempData.Add(iDate.ToString(input.DateTimeSpan.DateTimeFormat), new List <string>() { (high).ToString(input.DataValueFormat) } ); break; case "low": tempData.Add(iDate.ToString(input.DateTimeSpan.DateTimeFormat), new List <string>() { (low).ToString(input.DataValueFormat) } ); break; } double value = Convert.ToDouble(output.Data[output.Data.Keys.ElementAt(i)][0]); sum = high = low = value; allSum += value; iDate = date; dayIndex = 0; } else { double value = Convert.ToDouble(output.Data[output.Data.Keys.ElementAt(i)][0]); high = (value > high) ? value : high; allHigh = (value > allHigh) ? value : allHigh; low = (value < low) ? value : low; allLow = (value < allLow) ? value : allLow; allSum += value; sum += value; dayIndex++; } } tempData.Add("Total Average", new List <string>() { (allSum / output.Data.Count).ToString(input.DataValueFormat) }); tempData.Add("Max Temp", new List <string>() { allHigh.ToString(input.DataValueFormat) }); tempData.Add("Min Temp", new List <string>() { allLow.ToString(input.DataValueFormat) }); return(tempData); }
/// <summary> /// Takes the data recieved from prism and sets the ITimeSeries object values. /// </summary> /// <param name="errorMsg"></param> /// <param name="dataset"></param> /// <param name="component"></param> /// <param name="data"></param> /// <returns></returns> public ITimeSeriesOutput SetDataToOutput(out string errorMsg, string dataset, string data, ITimeSeriesOutput output, ITimeSeriesInput input) { errorMsg = ""; PRISMData.PRISM content; try { content = Newtonsoft.Json.JsonConvert.DeserializeObject <PRISMData.PRISM>(data); } catch (Newtonsoft.Json.JsonException ex) { errorMsg = "PRISM JSON Deserialization Error: " + ex.Message; return(null); } output.Dataset = dataset; output.DataSource = input.Source; output.Metadata = SetMetadata(out errorMsg, content, input, output); output.Data = SetData(out errorMsg, content, input.DateTimeSpan.DateTimeFormat, input.DataValueFormat); return(output); }