/// <summary> /// Gets evapotranspiration data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ITimeSeriesOutput> GetEvapotranspiration(EvapotranspirationInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // Validate evapotranspiration sources. errorMsg = (!Enum.TryParse(input.Source, true, out EvapoSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Evapotranspiration object Evapotranspiration.Evapotranspiration evapo = new Evapotranspiration.Evapotranspiration() { Algorithm = input.Algorithm, Albedo = input.Albedo, CentralLongitude = input.CentralLongitude, SunAngle = input.SunAngle, Emissivity = input.Emissivity, Model = input.Model, Zenith = input.Zenith, LakeSurfaceArea = input.LakeSurfaceArea, LakeDepth = input.LakeDepth, SubsurfaceResistance = input.SubsurfaceResistance, StomatalResistance = input.StomatalResistance, LeafWidth = input.LeafWidth, RoughnessLength = input.RoughnessLength, VegetationHeight = input.VegetationHeight, LeafAreaIndices = input.LeafAreaIndices, AirTemperature = input.AirTemperature, UserData = input.UserData }; // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); evapo.Input = iFactory.SetTimeSeriesInput(input, new List <string>() { "evapotranspiration" }, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Gets the Evapotranspiration data. ITimeSeriesOutput result = evapo.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
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); } prismOutput = TemporalAggregation(out errorMsg, output, input); if (errorMsg.Contains("ERROR")) { return(null); } return(prismOutput); }
/// <summary> /// Gets SoilMoisture data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input"></param> /// <returns></returns> public ITimeSeriesOutput GetSoilMoisture(SoilMoistureInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // Validate SoilMoisture sources. errorMsg = (!Enum.TryParse(input.Source, true, out SoilMSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // SoilMoisture object SoilMoisture.SoilMoisture soilM = new SoilMoisture.SoilMoisture() { Layers = input.Layers }; // Assigning dataset values, used to determine base url List <string> dataset = new List <string>(); foreach (string layer in soilM.Layers) { string l = layer.Replace('-', '_'); dataset.Add(l + "_SOILM"); } // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); soilM.Input = iFactory.SetTimeSeriesInput(input, dataset, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Gets the SoilMoisture data. ITimeSeriesOutput result = soilM.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
public async Task <IActionResult> POSTSolarCalculator([FromBody] SolarCalculatorInput i) { WSSolar solar = new WSSolar(); Utilities.ErrorOutput error = new Utilities.ErrorOutput(); ITimeSeriesOutput result; if (i is null) { result = error.ReturnError("Input Error: No inputs found in the request or inputs contain invalid formatting."); } else { result = await solar.RunSolarCalculator(i); } return(new ObjectResult(result)); }
/// <summary> /// Gets precipitation data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input">ITimeSeriesInput</param> /// <returns></returns> public ITimeSeriesOutput GetPrecipitation(ITimeSeriesInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // 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)); } // Precipitation object Precipitation.Precipitation precip = new Precipitation.Precipitation(); // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); precip.Input = iFactory.SetTimeSeriesInput(input, new List <string>() { "PRECIP" }, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } if (precip.Input.Source.Contains("ncdc")) { precip.Input.Geometry.GeometryMetadata["token"] = (precip.Input.Geometry.GeometryMetadata.ContainsKey("token")) ? precip.Input.Geometry.GeometryMetadata["token"] : "RUYNSTvfSvtosAoakBSpgxcHASBxazzP"; } // Gets the Precipitation data. ITimeSeriesOutput result = precip.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
/// <summary> /// Gets evapotranspiration data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input"></param> /// <returns></returns> public ITimeSeriesOutput GetEvapotranspiration(ITimeSeriesInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // Validate evapotranspiration sources. errorMsg = (!Enum.TryParse(input.Source, true, out EvapoSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Evapotranspiration object Evapotranspiration.Evapotranspiration evapo = new Evapotranspiration.Evapotranspiration(); // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); evapo.Input = iFactory.SetTimeSeriesInput(input, new List <string>() { "EVAPOT" }, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Gets the Evapotranspiration data. ITimeSeriesOutput result = evapo.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
/// <summary> /// Gets subsurfaceflow data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ITimeSeriesOutput> GetSubSurfaceFlow(ITimeSeriesInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // Validate subsurfaceflow sources. errorMsg = (!Enum.TryParse(input.Source, true, out SSFlowSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // SubSurfaceFlow object SubSurfaceFlow.SubSurfaceFlow evapo = new SubSurfaceFlow.SubSurfaceFlow(); // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); evapo.Input = iFactory.SetTimeSeriesInput(input, new List <string>() { "subsurfaceflow" }, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Gets the SubSurfaceFlow data. ITimeSeriesOutput result = evapo.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
/// <summary> /// Gets SurfaceRunoff data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input"></param> /// <returns></returns> public ITimeSeriesOutput GetSurfaceRunoff(ITimeSeriesInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // Validate SurfaceRunoff sources. errorMsg = (!Enum.TryParse(input.Source, true, out RunoffSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // SurfaceRunoff object SurfaceRunoff.SurfaceRunoff runoff = new SurfaceRunoff.SurfaceRunoff(); // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); runoff.Input = iFactory.SetTimeSeriesInput(input, new List <string>() { "SURFFLOW" }, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Gets the SurfaceRunoff data. ITimeSeriesOutput result = runoff.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
/// <summary> /// Gets temperature data using the given TimeSeriesInput parameters. /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ITimeSeriesOutput> GetTemperature(ITimeSeriesInput input) { string errorMsg = ""; // Constructs default error output object containing error message. Utilities.ErrorOutput err = new Utilities.ErrorOutput(); // Validate evapotranspiration sources. errorMsg = (!Enum.TryParse(input.Source, true, out TempSources pSource)) ? "ERROR: 'Source' was not found or is invalid. Source provided: " + input.Source : ""; if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Temperature object Temperature.Temperature temp = new Temperature.Temperature(); // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object. ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory(); temp.Input = iFactory.SetTimeSeriesInput(input, new List <string>() { "temperature" }, out errorMsg); // If error occurs in input validation and setup, errorMsg is added to metadata of an empty object. if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } // Gets the Temperature data. ITimeSeriesOutput result = temp.GetData(out errorMsg); if (errorMsg.Contains("ERROR")) { return(err.ReturnError(errorMsg)); } return(result); }
/// <summary> /// Model for accessing NOAA Solar Calculator /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ITimeSeriesOutput> RunSolarCalculator(SolarCalculatorInput input) { Solar.SolarCalculator soCal = new SolarCalculator(); soCal.Input = input; soCal.Model = input.Model.ToLower(); Utilities.ErrorOutput error = new Utilities.ErrorOutput(); //Validate unique solar calculator inputs if (String.IsNullOrWhiteSpace(input.DateTimeSpan.StartDate.ToString()) || input.DateTimeSpan.StartDate == DateTime.MinValue) { return(error.ReturnError("DateTimeSpan has no StartDate. StartDate is a required parameter.")); } if (string.IsNullOrWhiteSpace(input.DateTimeSpan.EndDate.ToString()) || input.DateTimeSpan.EndDate == DateTime.MinValue) { soCal.Input.DateTimeSpan.EndDate = soCal.Input.DateTimeSpan.StartDate.AddYears(1); } if (String.IsNullOrWhiteSpace(input.Model)) { return(error.ReturnError("Model parameter not defined in request.")); } if (String.IsNullOrWhiteSpace(input.LocalTime) && input.Model.ToLower().Equals("year")) { soCal.LocalTime = "12:00:00"; } else if (input.Model.ToLower().Equals("year")) { try { DateTime testDate = DateTime.ParseExact(input.LocalTime, "hh:mm:ss", CultureInfo.InvariantCulture); } catch (FormatException fe) { return(error.ReturnError("LocalTime parameter provided is a not a valid hour time. LocalTime format must be hh:mm:ss")); } soCal.LocalTime = input.LocalTime; } soCal.GetCalculatorData(); return(soCal.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); }
/// <summary> /// Gets workflow data. /// </summary> /// <param name="input"></param> /// <returns></returns> public 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>() { "PRECIP" }, 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(); if (output.Metadata.ContainsKey("ncdc_latitude") && output.Metadata.ContainsKey("ncdc_longitude")) { input.Geometry.Point = new PointCoordinate { Latitude = Convert.ToDouble(output.Metadata["ncdc_latitude"]), Longitude = Convert.ToDouble(output.Metadata["ncdc_longitude"]) }; } 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>(); Parallel.ForEach(precipList, (Precipitation.Precipitation precip) => { // Gets the Precipitation data. string errorM = ""; ITimeSeriesOutput result = precip.GetData(out errorM); errorList.Add(errorM); outputList.Add(result); }); 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.")); } }
public ITimeSeriesOutput Compute(ITimeSeriesInput inpt, ITimeSeriesOutput outpt, double lat, double lon, string startDate, string endDate, int timeZoneOffset, out string errorMsg) { errorMsg = ""; double petHamon = 0; double sunshineHours = 0; DataTable dt = new DataTable(); switch (inpt.Source) { case "ncdc": NCDC ncd = new NCDC(); dt = ncd.DownloadData(outpt, inpt); if (dt == null) { errorMsg = "ERROR: Unable to download data. "; } else { dt = ncd.Aggregate(inpt, dt); } break; case "daymet": dt = daymetData(inpt, outpt); dt = Utilities.Utility.aggregateData(inpt, dt, "hamon"); break; case "custom": CustomData cd = new CustomData(); dt = cd.ParseCustomData(inpt, outpt, inpt.Geometry.GeometryMetadata["userdata"].ToString(), "hamon"); break; case "nldas": case "gldas": default: NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); if (inpt.TemporalResolution == "hourly") { dt = nldas.getDataHourly(timeZoneOffset, false, out errorMsg); dt.Columns["THourly_C"].ColumnName = "TMean_C"; dt.Columns.Remove("SolarRad_MJm2day"); dt.Columns.Remove("SH_Hourly"); dt.Columns.Remove("WindSpeed_m/s"); } else { dt = nldas.getData1(timeZoneOffset, out errorMsg); DataRow dr1 = null; List <Double> tList = new List <double>(); 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>(); } tList.Add(Convert.ToDouble(dt.Rows[i]["TMin_C"].ToString())); tList.Add(Convert.ToDouble(dt.Rows[i]["TMax_C"].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; 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>(); 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())); 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; 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("Sunshine_Hours"); dt.Columns.Add("HamonPET_in"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "hamon"; output.Metadata = new Dictionary <string, string>() { { "latitude", latitude.ToString() }, { "longitude", longitude.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", "Sunshine Hours" }, { "column_7", "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", "Sunshine Hours" }, { "column_5", "Potential Evapotranspiration" } }; } output.Data = new Dictionary <string, List <string> >(); foreach (DataRow dr in dt.Rows) { double tmean = Convert.ToDouble(dr["TMean_C"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"]); HamonMethod(tmean, jday, out petHamon, out sunshineHours, out errorMsg); dr["Sunshine_Hours"] = sunshineHours.ToString("F2", CultureInfo.InvariantCulture); dr["HamonPET_in"] = petHamon.ToString("F4", CultureInfo.InvariantCulture); 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); }
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 petPMH = 0; double relHumidityHr = 0.0; string strDate; CultureInfo CInfoUS = new CultureInfo("en-US"); bool flagHSPF = false; //DataTable dt = nldas.getDataHourly(timeZoneOffset, flagHSPF, out errorMsg); DataTable dt = new DataTable(); DataTable daymets = new DataTable(); if (inpt.Source == "daymet") { daymets = daymetData(inpt, outpt); inpt.Source = "nldas"; NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); dt = nldas.getDataHourly(timeZoneOffset, flagHSPF, out errorMsg); int remaindermax = 24; int remaindermin = 23; int remainder = 0; int dayind = 0; for (int i = 0; i < dt.Rows.Count; i++) { DataRow dr = dt.Rows[i]; Math.DivRem(i, remaindermax, out remainder); //dr["TMin_C"] = daymets.Rows[i]["TMin_C"]; //dr["TMax_C"] = daymets.Rows[i]["TMax_C"]; dr["THourly_C"] = daymets.Rows[dayind]["TMean_C"];//dr["TMean_C"] = daymets.Rows[i]["TMean_C"]; dr["SolarRad_MJm2day"] = daymets.Rows[dayind]["SolarRadMean_MJm2day"]; if (remainder == remaindermin) { dayind++; } } daymets = null; } else { /*NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); * dt = nldas.getDataHourly(timeZoneOffset, flagHSPF, out errorMsg);*/ NLDAS2 nldas2 = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); dt = nldas2.getDataHourly(timeZoneOffset, flagHSPF, out errorMsg); DataRow dr1 = null; double sol = 0.0; double wind = 0.0; double temp = 0; double spec = 0; if (inpt.TemporalResolution == "daily") { DataTable daily = dt.Clone(); List <Double> list = new List <double>(); int j = 0; for (int i = 0; i < dt.Rows.Count; i++) { if (j == 0) { dr1 = daily.NewRow(); dr1["DateHour"] = dt.Rows[i]["DateHour"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); temp = 0; spec = 0; wind = 0; sol = 0; } temp += Convert.ToDouble(dt.Rows[i]["THourly_C"]); spec += Convert.ToDouble(dt.Rows[i]["SH_Hourly"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeed_m/s"]); sol += Convert.ToDouble(dt.Rows[i]["SolarRad_MJm2day"]); if (inpt.Source == "nldas" && j == 23) { dr1["THourly_C"] = Math.Round(temp / 24, 2); dr1["SH_Hourly"] = Math.Round(spec / 24, 4); dr1["WindSpeed_m/s"] = Math.Round(wind / 24, 2); dr1["SolarRad_MJm2day"] = Math.Round(sol / 24, 2); daily.Rows.Add(dr1); j = -1; } else if (inpt.Source == "gldas" && j == 7) { dr1["THourly_C"] = Math.Round(temp / 8, 2); dr1["SH_Hourly"] = Math.Round(spec / 8, 4); dr1["WindSpeed_m/s"] = Math.Round(wind / 8, 2); dr1["SolarRad_MJm2day"] = Math.Round(sol / 8, 2); daily.Rows.Add(dr1); j = -1; } j++; } dt = daily; } else 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["DateHour"] = dt.Rows[i]["DateHour"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); temp = 0.0; spec = 0.0; wind = 0.0; sol = 0.0; } temp += Convert.ToDouble(dt.Rows[i]["THourly_C"]); sol += Convert.ToDouble(dt.Rows[i]["SolarRad_MJm2day"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeed_m/s"]); spec += Convert.ToDouble(dt.Rows[i]["SH_Hourly"]); if (inpt.Source == "nldas" && j == 167) { dr1["THourly_C"] = Math.Round(temp / 168, 2); dr1["SH_Hourly"] = Math.Round(spec / 168, 4); dr1["WindSpeed_m/s"] = Math.Round(wind / 168, 2); dr1["SolarRad_MJm2day"] = Math.Round(sol / 168, 2); wkly.Rows.Add(dr1); j = -1; } else if (inpt.Source == "gldas" && j == 55) { dr1["THourly_C"] = Math.Round(temp / 56, 2); dr1["SH_Hourly"] = Math.Round(spec / 56, 4); dr1["WindSpeed_m/s"] = Math.Round(wind / 56, 2); dr1["SolarRad_MJm2day"] = Math.Round(sol / 56, 2); 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["DateHour"] = dt.Rows[i]["DateHour"].ToString(); dr1["Julian_Day"] = dt.Rows[i]["Julian_Day"].ToString(); temp = 0.0; spec = 0.0; wind = 0.0; sol = 0.0; newmonth = false; curmonth = Convert.ToDateTime(dt.Rows[i]["DateHour"]).Month; } temp += Convert.ToDouble(dt.Rows[i]["THourly_C"]); sol += Convert.ToDouble(dt.Rows[i]["SolarRad_MJm2day"]); wind += Convert.ToDouble(dt.Rows[i]["WindSpeed_m/s"]); spec += Convert.ToDouble(dt.Rows[i]["SH_Hourly"]); if (i + 1 < dt.Rows.Count && (Convert.ToDateTime(dt.Rows[i + 1]["DateHour"]).Month != curmonth) || i == dt.Rows.Count - 1) { if (inpt.Source == "nldas") { dr1["THourly_C"] = Math.Round(temp / (j + 1), 2); dr1["SH_Hourly"] = Math.Round(spec / (j + 1), 4); dr1["WindSpeed_m/s"] = Math.Round(wind / (j + 1), 2); dr1["SolarRad_MJm2day"] = Math.Round(sol / (j + 1), 2); } else if (inpt.Source == "gldas") { dr1["THourly_C"] = Math.Round(temp / (j + 1), 2); dr1["SH_Hourly"] = Math.Round(spec / (j + 1), 4); dr1["WindSpeed_m/s"] = Math.Round(wind / (j + 1), 2); dr1["SolarRad_MJm2day"] = Math.Round(sol / (j + 1), 2); } mnly.Rows.Add(dr1); j = -1; newmonth = true; } j++; } dt = mnly; } } if (errorMsg != "") { Utilities.ErrorOutput err = new Utilities.ErrorOutput(); return(err.ReturnError(errorMsg)); } dt.Columns.Add("RH_Hourly"); dt.Columns.Add("PenmanHourlyPET_in"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "penmanhourly"; output.Metadata = new Dictionary <string, string>() { { "elevation", elevation.ToString() }, { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "albedo", albedo.ToString() }, { "sun_angle", sunAngle.ToString() }, { "central_longitude", timeZoneCentralLongitude.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "Date" }, { "column_2", "Julian Day" }, { "column_3", "Hourly Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Mean Wind Speed" }, { "column_6", "Hourly Relative Humidity" }, { "column_7", "Potential Evapotranspiration" } }; if (inpt.TemporalResolution != "hourly" || inpt.TemporalResolution != "default") { output.Metadata = new Dictionary <string, string>() { { "elevation", elevation.ToString() }, { "latitude", latitude.ToString() }, { "longitude", longitude.ToString() }, { "albedo", albedo.ToString() }, { "sun_angle", sunAngle.ToString() }, { "central_longitude", timeZoneCentralLongitude.ToString() }, { "request_time", DateTime.Now.ToString() }, { "column_1", "Date" }, { "column_2", "Julian Day" }, { "column_3", "Hourly Temperature" }, { "column_4", "Mean Solar Radiation" }, { "column_5", "Mean Wind Speed" }, { "column_6", "Hourly Relative Humidity" }, { "column_7", "Potential Evapotranspiration" } }; } output.Data = new Dictionary <string, List <string> >(); foreach (DataRow dr in dt.Rows) { double thour = Convert.ToDouble(dr["THourly_C"].ToString()); strDate = dr["DateHour"].ToString(); DateTime time = DateTime.ParseExact(strDate, "yyyy-MM-dd HH:00", CInfoUS); double shhour = Convert.ToDouble(dr["SH_Hourly"].ToString()); double wind = Convert.ToDouble(dr["WindSpeed_m/s"].ToString()); double solarRad = Convert.ToDouble(dr["SolarRad_MJm2day"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"].ToString()); PenmanHourlyMethod(thour, jday, time, shhour, wind, solarRad, out relHumidityHr, out petPMH, out errorMsg); dr["RH_Hourly"] = relHumidityHr.ToString("F2", CultureInfo.InvariantCulture); dr["PenmanHourlyPET_in"] = petPMH.ToString("F4", CultureInfo.InvariantCulture); } dt.Columns.Remove("SH_Hourly"); 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); }
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; //AnnualPrecipitation = aprecip; double relHMax = 0; double relHMin = 0.0; double petMC = 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, "mortoncrae"); 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(), "mortoncrae"); 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["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.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; } } //dt = nldas2.getData3(timeZoneOffset, out errorMsg); 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("MortonCRAEPET_in"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "mortoncrae"; 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() }, { "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 time1 = DateTime.ParseExact(strDate, "yyyy-MM-dd", CInfoUS); double solarRad = Convert.ToDouble(dr["SolarRadMean_MJm2day"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"].ToString()); MortonCRAEMethod(tmin, tmax, tmean, jday, time1, shmin, shmax, solarRad, model, out relHMin, out relHMax, out petMC, 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["MortonCRAEPET_in"] = petMC.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> /// Default function for retrieving Total Flow data /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ITimeSeriesOutput> GetTotalFlowData(TotalFlowInput input) { //TODO: Extract the geometry percentage from following code and place in Utility class, for possible use by all controllers. // Steps: // 1 - determine geometry // type case ID: is equal to "huc", "commid", or "catchmentid" // type case ID action: send request to HMS-GIS /rest/catchment?source=SOURCE%type=TYPE%id=ID for geometry // type case geojson: is equal to "catchment", or "flowline" // type case geojson action: send request to HMS-GIS /rest/catchment/geojson/ (geojson in body) OR // : send request to HMS-GIS /rest/catchment/flowlines/ (flowline geojson in body) // type case points: is equal to "points" // type case points action: if request is one point - send request to EPA waters for watershed geometry, if request is two points // 2 - retrieve catchments-points table // 3 - collect all points catchment table (this resolves issue of possible duplicate calls on catchment edge) // 4 - retrieve data for all points in catchment table [Parallel] // 5 - iterate through catchments and assign data to appropriate catchment // 6 - aggregate the data for each catchment based upon how much area that cell has in the catchment [Parallel] // 7 - return aggregated data as a timeseries in the form of { datetime : [ catchment1, catchment2, catchment3, ... ]} // 8 - set metadata (request inputs, catchment data, aggregation data, output structure) // 9 - return output string error = ""; Utilities.ErrorOutput err = new Utilities.ErrorOutput(); GeometryResponse geo = new GeometryResponse(); string requestUrl = this.baseUrl + "/hms/rest/api/v2/hms/gis/percentage/"; if (input.GeometryInputs != null) { if (input.GeometryInputs.ContainsKey("huc8") && input.GeometryInputs.ContainsKey("commid")) { Dictionary <string, string> taskID; string queryUrl = requestUrl + "?huc_8_num=" + input.GeometryInputs["huc8"] + "&com_id_num=" + input.GeometryInputs["commid"]; using (var httpClientHandler = new HttpClientHandler()) { httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return(true); }; using (var client = new HttpClient(httpClientHandler)) { taskID = JsonConvert.DeserializeObject <Dictionary <string, string> >(client.GetStringAsync(queryUrl).Result); } geo = this.RequestData(taskID["job_id"], out error); } } else { return(err.ReturnError("Input error - GeometryInputs provided is invalid.")); } } else { switch (input.GeometryType.ToLower()) { case "huc": // use case 1 // use case 2 string hucID = input.GeometryInput; using (var client = new HttpClient()) { string queryUrl = baseUrl + "?huc_8_id=" + hucID; client.Timeout = TimeSpan.FromMinutes(10); geo = JsonConvert.DeserializeObject <GeometryResponse>(client.GetStringAsync(queryUrl).Result); } //goto default; break; case "commid": // use case 3 //string commid = input.GeometryInput; //using (var client = new HttpClient()) //{ // string queryUrl = baseUrl + "?com_id=" + commid; // client.Timeout = TimeSpan.FromMinutes(10); // geo = JsonConvert.DeserializeObject<GeometryResponse>(client.GetStringAsync(queryUrl).Result); //} goto default; break; case "catchmentid": // use case 3 // string catchmentID = input.GeometryInput; //using (var client = new HttpClient()) //{ // geo = JsonConvert.DeserializeObject<GeometryResponse>(client.GetStringAsync(baseUrl + "/api/GridCell/catchmentid/" + catchmentID).Result); //} goto default; break; case "catchment": // use case 4 // Use POST call with geometry goto default; break; case "flowline": // use case 5 // Use POST call with geometry goto default; break; case "points": // use case 6 // use case 7 // GET call with points, hms-gis will get geometries goto default; break; case "test": string testGeometry = "{\"geometry\":{\"9311911\": { \"points\": [ { \"cellArea\": 0.015624999999992895, \"containedArea\": 4.178630503273804e-05, \"longitude\": -71.43749999999996, \"latitude\": 44.18749999999999, \"percentArea\": 0.26743235220964506 }, { \"cellArea\": 0.015624999999996447, \"containedArea\": 0.005083393397351494, \"longitude\": -71.31249999999997, \"latitude\": 44.18750000000001, \"percentArea\": 32.53371774305696 }, { \"cellArea\": 0.015624999999996447, \"containedArea\": 0.0002419268603100419, \"longitude\": -71.31249999999997, \"latitude\": 44.31249999999997, \"percentArea\": 1.5483319059846201 } ] } }, \"metadata\": { \"execution time\": 86.99717831611633, \"nldas source\": \"https://ldas.gsfc.nasa.gov/nldas/gis/NLDAS_Grid_Reference.zip\", \"number of points\": 3, \"request date\": \"Thu, 22 Mar 2018 11:46:44 GMT\", \"shapefile source\": \"ftp://newftp.epa.gov/exposure/BasinsData/NHDPlus21/NHDPlus01060002.zip\" } }"; //string testGeometry = "{\"Geometry\": {\"02080107\": [{\"Latitude\": 37.437499999999972,\"Longitude\": -76.687499999999972,\"CellArea\": 0.0156250000000036,\"ContainedArea\": 0.00559514073505796,\"PercentArea\": 35.8089007043628},{\"Latitude\": 37.437499999999972,\"Longitude\": -76.5625,\"CellArea\": 0.0156250000000053,\"ContainedArea\": 0.0100796700330301,\"PercentArea\": 64.5098882113707},{\"Latitude\": 37.437499999999972,\"Longitude\": -76.437499999999972,\"CellArea\": 0.0156250000000142,\"ContainedArea\": 0.00780989236262298,\"PercentArea\": 49.9833111207416},{\"Latitude\": 37.437499999999972,\"Longitude\": -76.312499999999957,\"CellArea\": 0.0156250000000036,\"ContainedArea\": 0.0012605882348706,\"PercentArea\": 8.06776470316997}]},\"Metadata\": {}}"; geo = JsonConvert.DeserializeObject <GeometryResponse>(testGeometry); break; default: return(err.ReturnError("Input error - GeometryType provided is invalid. Provided value = " + input.GeometryType)); } } // Check for any errors if (!String.IsNullOrWhiteSpace(error) || !geo.status.Equals("SUCCESS")) { return(err.ReturnError(error)); } // Collect all unique points in Catchment List <GeometryPoint> points = new List <GeometryPoint>(); List <string> pointsSTR = new List <string>(); foreach (KeyValuePair <string, Catchment> k in geo.data.geometry) { foreach (Point cp in k.Value.points) { GeometryPoint p = new GeometryPoint(); p.Latitude = cp.latitude; p.Longitude = cp.longitude; if (!points.Contains(p)) { points.Add(p); pointsSTR.Add("[" + p.Latitude.ToString() + ", " + p.Longitude.ToString() + "]"); } } } ITimeSeriesInputFactory inputFactory = new TimeSeriesInputFactory(); List <string> errorMessages = new List <string>(); string errorMsg = ""; // Initialize all surface and subsurface points Dictionary <string, SurfaceRunoff.SurfaceRunoff> surfaceFlow = new Dictionary <string, SurfaceRunoff.SurfaceRunoff>(); Dictionary <string, SubSurfaceFlow.SubSurfaceFlow> subsurfaceFlow = new Dictionary <string, SubSurfaceFlow.SubSurfaceFlow>(); foreach (GeometryPoint point in points) { string key = point.Latitude.ToString() + "," + point.Longitude.ToString(); TimeSeriesGeometry tsGeometry = new TimeSeriesGeometry(); tsGeometry.Point = new PointCoordinate() { Latitude = point.Latitude, Longitude = point.Longitude }; // Initialize surfaceFlow catchment point object errorMsg = ""; TimeSeriesInput surfaceTempInput = new TimeSeriesInput(); surfaceTempInput = input; surfaceTempInput.Geometry = tsGeometry; SurfaceRunoff.SurfaceRunoff sFlow = new SurfaceRunoff.SurfaceRunoff(); sFlow.Input = inputFactory.SetTimeSeriesInput(surfaceTempInput, new List <string>() { "surfacerunoff" }, out errorMsg); surfaceFlow.Add(key, sFlow); errorMessages.Add(errorMsg); // Initialize subsurfaceFlow catchment point object errorMsg = ""; TimeSeriesInput subSurfaceTempInput = new TimeSeriesInput(); subSurfaceTempInput = input; subSurfaceTempInput.Geometry = tsGeometry; SubSurfaceFlow.SubSurfaceFlow subFlow = new SubSurfaceFlow.SubSurfaceFlow(); subFlow.Input = inputFactory.SetTimeSeriesInput(subSurfaceTempInput, new List <string>() { "subsurfaceflow" }, out errorMsg); subsurfaceFlow.Add(key, subFlow); errorMessages.Add(errorMsg); } // TODO: merge parallelized calls to surfaceRunoff and subsurfaceFlow // Parallelized surfaceRunoff object outputListLock = new object(); List <string> surfaceError = new List <string>(); var options = new ParallelOptions { MaxDegreeOfParallelism = -1 }; Parallel.ForEach(surfaceFlow, options, (KeyValuePair <string, SurfaceRunoff.SurfaceRunoff> surF) => { string errorM = ""; surF.Value.GetData(out errorM); lock (outputListLock) { surfaceError.Add(errorM); } }); // Parallelized subsurfaceFlow List <string> subsurfaceError = new List <string>(); Parallel.ForEach(subsurfaceFlow, options, (KeyValuePair <string, SubSurfaceFlow.SubSurfaceFlow> subF) => { string errorM = ""; subF.Value.GetData(out errorM); lock (outputListLock) { subsurfaceError.Add(errorM); } }); ITimeSeriesOutputFactory outputFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = outputFactory.Initialize(); // Aggregate catchments List <ITimeSeriesOutput> catchmentFlow = new List <ITimeSeriesOutput>(); ITimeSeriesOutput iOutput = outputFactory.Initialize(); var options2 = new ParallelOptions { MaxDegreeOfParallelism = 1 }; Dictionary <string, string> catchmentMeta = new Dictionary <string, string>(); Parallel.ForEach(geo.data.geometry, options2, (KeyValuePair <string, Catchment> catchments) => { string catchmentID = catchments.Key; List <ITimeSeriesOutput> catchmentPoints = new List <ITimeSeriesOutput>(); foreach (Point cp in catchments.Value.points) { IPointCoordinate point = new PointCoordinate() { Latitude = cp.latitude, Longitude = cp.longitude }; string key = point.Latitude.ToString() + "," + point.Longitude.ToString(); ITimeSeriesOutput output1 = Utilities.Merger.ModifyTimeSeries(surfaceFlow[key].Output, cp.percentArea / 100); ITimeSeriesOutput output2 = Utilities.Merger.ModifyTimeSeries(subsurfaceFlow[key].Output, cp.percentArea / 100); if (iOutput.Data.Count == 0) { iOutput = output1; iOutput = Utilities.Merger.MergeTimeSeries(iOutput, output2); } else { iOutput = Utilities.Merger.MergeTimeSeries(iOutput, output1); iOutput = Utilities.Merger.MergeTimeSeries(iOutput, output2); } catchmentPoints.Add(Utilities.Merger.AddTimeSeries(output1, output2, "TotalFlow")); } output.Data = (Utilities.Merger.MergeTimeSeries(catchmentPoints).Data); int currentCatchment = catchmentMeta.Count + 1; catchmentMeta.Add("catchment_column_" + currentCatchment.ToString() + "_ID", catchments.Key); }); // Testing // output.Data = iOutput.Data; output.DataSource = input.Source; output.Dataset = "Total Flow"; output.Metadata = surfaceFlow.First().Value.Output.Metadata; output.Metadata.Remove(input.Source + "_lat"); output.Metadata.Remove(input.Source + "_lon"); output.Metadata.Remove(input.Source + "_prod_name"); output.Metadata.Remove(input.Source + "_param_short_name"); output.Metadata.Remove(input.Source + "_param_name"); output.Metadata[input.Source + "_points"] = string.Join(", ", pointsSTR); // Adding geometry metadata to output metadata foreach (KeyValuePair <string, string> kv in geo.data.metadata) { if (!output.Metadata.ContainsKey(kv.Key)) { output.Metadata.Add(kv.Key, kv.Value); } } // Cleaning up output metadata Dictionary <string, string> cleanedMetaData = new Dictionary <string, string>(); foreach (KeyValuePair <string, string> kv in output.Metadata) { if (!kv.Key.Contains("column")) { cleanedMetaData.Add(kv.Key, kv.Value); } } output.Metadata = cleanedMetaData; // Add catchments metadata to output metadata foreach (KeyValuePair <string, string> kv in catchmentMeta) { output.Metadata.Add(kv.Key, kv.Value); } return(output); }
public ITimeSeriesOutput Compute(ITimeSeriesInput inpt, ITimeSeriesOutput outpt, double lat, double lon, string startDate, string endDate, int timeZoneOffset, out string errorMsg) { errorMsg = ""; double petPT = 0; //NLDAS2 nldas = new NLDAS2(inpt.Source, lat, lon, startDate, endDate); DataTable dt = new DataTable(); switch (inpt.Source) { case "daymet": dt = daymetData(inpt, outpt); dt = Utilities.Utility.aggregateData(inpt, dt, "priestlytaylor"); break; case "custom": CustomData cd = new CustomData(); dt = cd.ParseCustomData(inpt, outpt, inpt.Geometry.GeometryMetadata["userdata"].ToString(), "priestlytaylor"); break; case "nldas": case "gldas": default: NLDAS2 nldas = 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.getData2(timeZoneOffset, out errorMsg); dt = nldas.getDataHourly(timeZoneOffset, false, out errorMsg); dt.Columns["THourly_C"].ColumnName = "TMean_C"; dt.Columns["SolarRad_MJm2day"].ColumnName = "SolarRadMean_MJm2day"; dt.Columns.Remove("SH_Hourly"); dt.Columns.Remove("WindSpeed_m/s"); dt.Columns.Add("TMin_C"); dt.Columns.Add("TMax_C"); 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"]; } dtd = null; } else { dt = nldas.getData2(timeZoneOffset, out errorMsg); DataRow dr1 = null; List <Double> tList = 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>(); 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"]); 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); 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>(); 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"]); 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); mnly.Rows.Add(dr1); j = -1; newmonth = true; } j++; } dt = mnly; } } break; } //dt = nldas.getData2(timeZoneOffset, out errorMsg); if (errorMsg != "") { Utilities.ErrorOutput err = new Utilities.ErrorOutput(); return(err.ReturnError(errorMsg)); } dt.Columns.Add("PriestleyTaylorPET_in"); ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory(); ITimeSeriesOutput output = oFactory.Initialize(); output.Dataset = "Evapotranspiration"; output.DataSource = "priestlytaylor"; 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_4", "Maximum Temperature" }, { "column_5", "Mean Temperature" }, { "column_6", "Mean Solar Radiation" }, { "column_7", "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", "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 solarRad = Convert.ToDouble(dr["SolarRadMean_MJm2day"].ToString()); int jday = Convert.ToInt32(dr["Julian_Day"].ToString()); PriestlyTaylorMethod(tmin, tmax, tmean, solarRad, jday, out petPT, out errorMsg); dr["PriestleyTaylorPET_in"] = petPT.ToString("F4", CultureInfo.InvariantCulture); 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); }