/// <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); output.Metadata.Add("column_1", "Date"); if (input.Units.Contains("imperial")) { output.Metadata["gldas_unit"] = "in"; } // NLDAS static methods used for aggregation as GLDAS is identical in function. Modifier refers to the 3hr difference to nldas's hourly resolution. switch (input.TemporalResolution) { case "daily": output.Data = NLDAS.DailyAggregatedSum(out errorMsg, 3.0, output, input); output.Metadata.Add("column_2", "Daily Total"); return(output); case "weekly": output.Data = NLDAS.WeeklyAggregatedSum(out errorMsg, 3.0, output, input); output.Metadata.Add("column_2", "Weekly Total"); return(output); case "monthly": output.Data = NLDAS.MonthlyAggregatedSum(out errorMsg, 3.0, output, input); output.Metadata.Add("column_2", "Monthly Total"); return(output); default: output.Data = (input.Units.Contains("imperial")) ? NLDAS.UnitConversion(out errorMsg, 3.0, output, input) : output.Data; output.Metadata.Add("column_2", "Hourly Average"); return(output); } }
// -------------- Evapotranspiration Functions -------------- // /// <summary> /// Get Evapotranspiration data function. /// </summary> /// <param name="errorMsg"></param> /// <returns></returns> public ITimeSeriesOutput GetData(out string errorMsg) { errorMsg = ""; // If the timezone information is not provided, the tz details are retrieved and set to the geometry.timezone varaible. if (this.Input.Geometry.Timezone.Offset == 0) { Utilities.Time tz = new Utilities.Time(); this.Input.Geometry.Timezone = tz.GetTimezone(out errorMsg, this.Input.Geometry.Point) as Timezone; if (errorMsg.Contains("ERROR")) { return(null); } } //TODO: Check Source and run specific subcomponent class for source ITimeSeriesOutputFactory iFactory = new TimeSeriesOutputFactory(); this.Output = iFactory.Initialize(); switch (this.Input.Source) { case "nldas": // NLDAS Evapotranspiration Data call NLDAS nldas = new NLDAS(); this.Output = nldas.GetData(out errorMsg, this.Output, this.Input); if (errorMsg.Contains("ERROR")) { return(null); } break; case "gldas": // GLDAS Evapotranspiration Data call GLDAS gldas = new GLDAS(); this.Output = gldas.GetData(out errorMsg, this.Output, this.Input); if (errorMsg.Contains("ERROR")) { return(null); } break; default: errorMsg = "ERROR: 'Source' for evapotranspiration was not found among available sources or is invalid."; break; } ; // Adds Geometry metadata to the output metadata. NOT WORKING this.Output.Metadata.Concat(this.Input.Geometry.GeometryMetadata); // Adds Timezone info to metadata this.Output.Metadata.Add(this.Input.Source + "_timeZone", this.Input.Geometry.Timezone.Name); this.Output.Metadata.Add(this.Input.Source + "_tz_offset", this.Input.Geometry.Timezone.Offset.ToString()); //TODO: Add output format control return(this.Output); }
/// <summary> /// Check evapotranspiration data endpoints. /// </summary> /// <returns></returns> public Dictionary <string, string> CheckEndpointStatus() { switch (this.Input.Source) { case "nldas": return(NLDAS.CheckStatus(this.Input)); case "gldas": return(GLDAS.CheckStatus(this.Input)); default: return(new Dictionary <string, string>() { { "status", "invalid source" } }); } }
// -------------- Evapotranspiration Functions -------------- // /// <summary> /// Get Evapotranspiration data function. /// </summary> /// <param name="errorMsg"></param> /// <returns></returns> public ITimeSeriesOutput GetData(out string errorMsg) { errorMsg = ""; // If the timezone information is not provided, the tz details are retrieved and set to the geometry.timezone varaible. if (this.Input.Geometry.Timezone.Offset == 0 && !this.Input.Source.Contains("ncdc")) //if (this.Input.Geometry.Timezone.Offset == 0) { Utilities.Time tz = new Utilities.Time(); this.Input.Geometry.Timezone = tz.GetTimezone(out errorMsg, this.Input.Geometry.Point) as Timezone; if (errorMsg.Contains("ERROR")) { return(null); } } //TODO: Check Source and run specific subcomponent class for source ITimeSeriesOutputFactory iFactory = new TimeSeriesOutputFactory(); this.Output = iFactory.Initialize(); Elevation elev = new Elevation(this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude); Utilities.Time offsets = new Utilities.Time(); //this.Algorithm = (this.Input.Source != null) ? this.Input.Source : this.Algorithm; //Error checking and data validation if (this.Input.Source != "gldas" && this.Algorithm == "gldas") { errorMsg = "ERROR: GLDAS algorithm requires GLDAS data source."; return(null); } if (this.Input.Source != "nldas" && this.Algorithm == "nldas") { errorMsg = "ERROR: NLDAS algorithm requires NLDAS data source."; return(null); } if (this.Input.Source == "daymet" && this.Algorithm != "hamon" && this.Algorithm != "mortoncrae" && this.Algorithm != "mortoncrwe" && this.Algorithm != "priestlytaylor") { errorMsg = "ERROR: Algorithm is incompatible with Daymet data source."; return(null); } if (this.Input.Source == "ncdc" && this.Algorithm != "hamon") { errorMsg = "ERROR: Algorithm is incompatible with NCDC data source."; return(null); } if ((this.Algorithm != "hamon" || this.Algorithm != "gldas") && this.Input.Source == "gldas" && (this.Input.DateTimeSpan.StartDate.Year > 2010 || this.Input.DateTimeSpan.EndDate.Year > 2010)) { errorMsg = "ERROR: No data available for the requested Source/Algorithm/Date range."; return(null); } if (this.Input.Source == "custom") { if (this.Algorithm == "penmanhourly" || this.Algorithm == "hspf") { errorMsg = "ERROR: Hourly algorithms do not yet support custom data."; return(null); } this.Input.Geometry.GeometryMetadata["userdata"] = UserData; } switch (this.Algorithm) { case "nldas": // NLDAS Evapotranspiration Data call NLDAS nldas = new NLDAS(); this.Output = nldas.GetData(out errorMsg, this.Output, this.Input); if (errorMsg.Contains("ERROR")) { return(null); } break; case "gldas": // GLDAS Evapotranspiration Data call GLDAS gldas = new GLDAS(); this.Output = gldas.GetData(out errorMsg, this.Output, this.Input); if (errorMsg.Contains("ERROR")) { return(null); } break; case "hamon": // Hamon Evapotranspiration Data call Hamon hamon = new Hamon(); hamon.Latitude = this.Input.Geometry.Point.Latitude; hamon.Longitude = this.Input.Geometry.Point.Longitude; this.Output = hamon.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "priestlytaylor": // Priestly Taylor Evapotranspiration Data call PriestleyTaylor priestleyTaylor = new PriestleyTaylor(); priestleyTaylor.Latitude = this.Input.Geometry.Point.Latitude; priestleyTaylor.Longitude = this.Input.Geometry.Point.Longitude; priestleyTaylor.Albedo = this.Albedo; priestleyTaylor.Elevation = elev.getElevation(out errorMsg); this.Output = priestleyTaylor.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "grangergray": // Granger Gray Evapotranspiration Data call var test = this.Input; GrangerGray grangerGray = new GrangerGray(); grangerGray.Latitude = this.Input.Geometry.Point.Latitude; grangerGray.Longitude = this.Input.Geometry.Point.Longitude; grangerGray.Albedo = this.Albedo; grangerGray.Elevation = elev.getElevation(out errorMsg); this.Output = grangerGray.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "penpan": // Penpan Evapotranspiration Data call Penpan penpan = new Penpan(); penpan.Latitude = this.Input.Geometry.Point.Latitude; penpan.Longitude = this.Input.Geometry.Point.Longitude; penpan.Albedo = this.Albedo; penpan.Elevation = elev.getElevation(out errorMsg); this.Output = penpan.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "mcjannett": // McJannett Evapotranspiration Data call McJannett mcjannett = new McJannett(); mcjannett.Latitude = this.Input.Geometry.Point.Latitude; mcjannett.Longitude = this.Input.Geometry.Point.Longitude; mcjannett.Albedo = this.Albedo; mcjannett.Elevation = elev.getElevation(out errorMsg); mcjannett.SurfaceArea = this.LakeSurfaceArea; mcjannett.LakeDepth = this.LakeDepth; mcjannett.airToWaterTempFactor[1] = Convert.ToDouble(this.AirTemperature["1"]); mcjannett.airToWaterTempFactor[2] = Convert.ToDouble(this.AirTemperature["2"]); mcjannett.airToWaterTempFactor[3] = Convert.ToDouble(this.AirTemperature["3"]); mcjannett.airToWaterTempFactor[4] = Convert.ToDouble(this.AirTemperature["4"]); mcjannett.airToWaterTempFactor[5] = Convert.ToDouble(this.AirTemperature["5"]); mcjannett.airToWaterTempFactor[6] = Convert.ToDouble(this.AirTemperature["6"]); mcjannett.airToWaterTempFactor[7] = Convert.ToDouble(this.AirTemperature["7"]); mcjannett.airToWaterTempFactor[8] = Convert.ToDouble(this.AirTemperature["8"]); mcjannett.airToWaterTempFactor[9] = Convert.ToDouble(this.AirTemperature["9"]); mcjannett.airToWaterTempFactor[10] = Convert.ToDouble(this.AirTemperature["10"]); mcjannett.airToWaterTempFactor[11] = Convert.ToDouble(this.AirTemperature["11"]); mcjannett.airToWaterTempFactor[12] = Convert.ToDouble(this.AirTemperature["12"]); this.Output = mcjannett.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "penmanopenwater": // Penman Open Water Evapotranspiration Data call PenmanOpenWater penmanOpenWater = new PenmanOpenWater(); penmanOpenWater.Latitude = this.Input.Geometry.Point.Latitude; penmanOpenWater.Longitude = this.Input.Geometry.Point.Longitude; penmanOpenWater.Albedo = this.Albedo; penmanOpenWater.Elevation = elev.getElevation(out errorMsg); this.Output = penmanOpenWater.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "penmandaily": // Penman Daily Evapotranspiration Data call PenmanDaily penmanDaily = new PenmanDaily(); penmanDaily.Latitude = this.Input.Geometry.Point.Latitude; penmanDaily.Longitude = this.Input.Geometry.Point.Longitude; penmanDaily.Albedo = this.Albedo; penmanDaily.Elevation = elev.getElevation(out errorMsg); this.Output = penmanDaily.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "penmanhourly": // Penman Hourly Evapotranspiration Data call PenmanHourly penmanHourly = new PenmanHourly(); penmanHourly.Latitude = this.Input.Geometry.Point.Latitude; penmanHourly.Longitude = this.Input.Geometry.Point.Longitude; penmanHourly.Albedo = this.Albedo; penmanHourly.Elevation = elev.getElevation(out errorMsg); penmanHourly.TimeZoneCentralLongitude = this.CentralLongitude; penmanHourly.SunAngle = this.SunAngle; this.Output = penmanHourly.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "mortoncrae": // Morton CRAE Evapotranspiration Data call MortonCRAE mortonCRAE = new MortonCRAE(); mortonCRAE.Latitude = this.Input.Geometry.Point.Latitude; mortonCRAE.Longitude = this.Input.Geometry.Point.Longitude; mortonCRAE.Albedo = this.Albedo; mortonCRAE.Elevation = elev.getElevation(out errorMsg); mortonCRAE.Emissivity = this.Emissivity; int model = Utilities.Utility.CalculateMortonMethod(this.Model); double aprecip = 0.0; mortonCRAE.AnnualPrecipitation = aprecip; this.Output = mortonCRAE.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, model, out aprecip, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "mortoncrwe": // Morton CRWE Evapotranspiration Data call MortonCRWE mortonCRWE = new MortonCRWE(); mortonCRWE.Latitude = this.Input.Geometry.Point.Latitude; mortonCRWE.Longitude = this.Input.Geometry.Point.Longitude; mortonCRWE.Albedo = this.Albedo; mortonCRWE.Elevation = elev.getElevation(out errorMsg); mortonCRWE.Emissivity = this.Emissivity; mortonCRWE.Azenith = this.Zenith; int model2 = Utilities.Utility.CalculateMortonMethod(this.Model); double aprecip2 = 0.0; mortonCRWE.AnnualPrecipitation = aprecip2; this.Output = mortonCRWE.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, model2, out aprecip2, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "shuttleworthwallace": // Shuttleworth Wallace Evapotranspiration Data call ShuttleworthWallace shuttleworthWallace = new ShuttleworthWallace(); shuttleworthWallace.Latitude = this.Input.Geometry.Point.Latitude; shuttleworthWallace.Longitude = this.Input.Geometry.Point.Longitude; shuttleworthWallace.Albedo = this.Albedo; shuttleworthWallace.Elevation = elev.getElevation(out errorMsg); shuttleworthWallace.ResistanceSurfaceSoil = this.SubsurfaceResistance; shuttleworthWallace.ResistanceStomatal = this.StomatalResistance; shuttleworthWallace.WidthLeaf = this.LeafWidth; shuttleworthWallace.GroundRoughnessLength = this.RoughnessLength; shuttleworthWallace.VegetationHeight = this.VegetationHeight; shuttleworthWallace.leafAreaIndex[1] = Convert.ToDouble(this.LeafAreaIndices["1"]); shuttleworthWallace.leafAreaIndex[2] = Convert.ToDouble(this.LeafAreaIndices["2"]); shuttleworthWallace.leafAreaIndex[3] = Convert.ToDouble(this.LeafAreaIndices["3"]); shuttleworthWallace.leafAreaIndex[4] = Convert.ToDouble(this.LeafAreaIndices["4"]); shuttleworthWallace.leafAreaIndex[5] = Convert.ToDouble(this.LeafAreaIndices["5"]); shuttleworthWallace.leafAreaIndex[6] = Convert.ToDouble(this.LeafAreaIndices["6"]); shuttleworthWallace.leafAreaIndex[7] = Convert.ToDouble(this.LeafAreaIndices["7"]); shuttleworthWallace.leafAreaIndex[8] = Convert.ToDouble(this.LeafAreaIndices["8"]); shuttleworthWallace.leafAreaIndex[9] = Convert.ToDouble(this.LeafAreaIndices["9"]); shuttleworthWallace.leafAreaIndex[10] = Convert.ToDouble(this.LeafAreaIndices["10"]); shuttleworthWallace.leafAreaIndex[11] = Convert.ToDouble(this.LeafAreaIndices["11"]); shuttleworthWallace.leafAreaIndex[12] = Convert.ToDouble(this.LeafAreaIndices["12"]); this.Output = shuttleworthWallace.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; case "hspf": // HSPF Evapotranspiration Data call HSPF hspf = new HSPF(); hspf.Latitude = this.Input.Geometry.Point.Latitude; hspf.Longitude = this.Input.Geometry.Point.Longitude; hspf.Albedo = this.Albedo; hspf.Elevation = elev.getElevation(out errorMsg); hspf.TimeZoneCentralLongitude = this.CentralLongitude; hspf.SunAngle = this.SunAngle; this.Output = hspf.Compute(this.Input, this.Output, this.Input.Geometry.Point.Latitude, this.Input.Geometry.Point.Longitude, this.Input.DateTimeSpan.StartDate.ToString(), this.Input.DateTimeSpan.EndDate.ToString(), (int)this.Input.Geometry.Timezone.Offset, out errorMsg); if (errorMsg.Contains("ERROR")) { return(null); } break; default: errorMsg = "ERROR: 'Algorithm' for evapotranspiration was not found among available sources or is invalid."; break; } ; // Adds Geometry metadata to the output metadata. NOT WORKING this.Output.Metadata.Concat(this.Input.Geometry.GeometryMetadata); // Adds Timezone info to metadata this.Output.Metadata.Add(this.Algorithm + "_timeZone", this.Input.Geometry.Timezone.Name); this.Output.Metadata.Add(this.Algorithm + "_tz_offset", this.Input.Geometry.Timezone.Offset.ToString()); //TODO: Add output format control return(this.Output); }