From 0bfb45c4f660216e4ccf3d309e7648321e059147 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Mon, 8 Jul 2024 16:22:41 +0100 Subject: [PATCH 01/31] save point for many files, added method for getting meta data from wind, collection and sunpaths, and added a bit of interop c# side --- .../AdapterActions/Execute.cs | 21 +++++ .../Convert/MetaData/PlotInformation.cs | 93 +++++++++++++++++++ .../bhom/wrapped/plot/diurnal.py | 2 +- .../bhom/wrapped/plot/sunpath.py | 1 - .../bhom/wrapped/plot/windrose.py | 14 ++- .../ladybug_extension/datacollection.py | 6 ++ .../ladybug_extension/sunpath.py | 47 ++++++++++ .../Python/src/ladybugtools_toolkit/wind.py | 21 +++++ LadybugTools_oM/MetaData/CollectionData.cs | 27 ++++++ LadybugTools_oM/MetaData/ISimulationData.cs | 11 +++ LadybugTools_oM/MetaData/PlotInformation.cs | 14 +++ LadybugTools_oM/MetaData/WindroseData.cs | 27 ++++++ 12 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs create mode 100644 LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py create mode 100644 LadybugTools_oM/MetaData/CollectionData.cs create mode 100644 LadybugTools_oM/MetaData/ISimulationData.cs create mode 100644 LadybugTools_oM/MetaData/PlotInformation.cs create mode 100644 LadybugTools_oM/MetaData/WindroseData.cs diff --git a/LadybugTools_Adapter/AdapterActions/Execute.cs b/LadybugTools_Adapter/AdapterActions/Execute.cs index 9c2fed03..9b69c6bf 100644 --- a/LadybugTools_Adapter/AdapterActions/Execute.cs +++ b/LadybugTools_Adapter/AdapterActions/Execute.cs @@ -355,6 +355,27 @@ private List RunCommand(WindroseCommand command, ActionConfig actionConf string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -ap \"{command.AnalysisPeriod.FromBHoM().Replace("\"", "\\\"")}\" -cmap \"{colourMap}\" -bins \"{command.NumberOfDirectionBins}\" -p \"{command.OutputLocation}\""; string result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); + CustomObject data = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(result); + + object image = ""; + + if (!data.CustomData.TryGetValue("figure", out image)) + { + BH.Engine.Base.Compute.RecordError("An error occurred during generation of the plot."); + return new List(); + } + + PlotInformation info = new PlotInformation() + { + Image = (string)image, + OtherData = new WindroseData() + { + Description = (data.CustomData["description"] as List).Select(x => x.ToString()).ToList(), + MaxSpeed = + } + }; + + m_executeSuccess = true; return new List { result }; } diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs new file mode 100644 index 00000000..8f051849 --- /dev/null +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -0,0 +1,93 @@ +using BH.oM.Base; +using BH.oM.LadybugTools; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BH.Adapter.LadybugTools +{ + public static partial class Convert + { + public static ISimulationData IToSimulationData(this CustomObject oldObject, ISimulationData toUpdate) + { + return ToSimulationData(oldObject.CustomData, toUpdate as dynamic); + } + + private static CollectionData ToSimulationData(this Dictionary oldData, CollectionData toUpdate) + { + try + { + toUpdate.Description = (oldData["description"] as List).Select(x => x.ToString()).ToList(); + } + catch { } + + double.TryParse(oldData["highest_value"].ToString(), out double result); + toUpdate.HighestValue = result; + + double.TryParse(oldData["lowest_value"].ToString(), out result); + toUpdate.LowestValue = result; + + DateTime.TryParse(oldData["highest_time"].ToString(), out DateTime date); + toUpdate.HighestTime = date; + + DateTime.TryParse(oldData["lowest_time"].ToString(), out date); + toUpdate.LowestTime = date; + + double.TryParse(oldData["highest_average_month_value"].ToString(), out result); + toUpdate.HighestAverageMonthValue = result; + + int.TryParse(oldData["highest_average_month"].ToString(), out int month); + toUpdate.HighestAverageMonth = month; + + double.TryParse(oldData["lowest_average_month_value"].ToString(), out result); + toUpdate.LowestAverageMonthValue = result; + + int.TryParse(oldData["lowest_average_month"].ToString(), out month); + toUpdate.LowestAverageMonth = month; + + return toUpdate; + } + + private static WindroseData ToSimulationData(this Dictionary oldData, WindroseData toUpdate) + { + try + { + toUpdate.Description = (oldData["description"] as List).Select(x => x.ToString()).ToList(); + } + catch { } + + double.TryParse(oldData["prevailing_direction"].ToString(), out double result); + toUpdate.PrevailingDirection = result; + + double.TryParse(oldData["prevailing_speed"].ToString(), out result); + toUpdate.PrevailingSpeed = result; + + + DateTime.TryParse(oldData["prevailing_time"].ToString(), out DateTime date); + toUpdate.PrevailingTime = date; + + double.TryParse(oldData["max_speed"].ToString(), out result); + toUpdate.MaxSpeed = result; + + double.TryParse(oldData["max_speed_direction"].ToString(), out result); + toUpdate.MaxSpeedDirection = result; + + DateTime.TryParse(oldData["max_speed_time"].ToString(), out date); + toUpdate.MaxSpeedTime = date; + + double.TryParse(oldData["calm_count"].ToString(), out result); + toUpdate.NumberOfCalmHours = result; + + double.TryParse(oldData["calm_percent"].ToString(), out result); + toUpdate.PercentageOfCalmHours = result; + + return toUpdate; + } + + private static SunPathData ToSimulationData(this Dictionary oldData, SunPathData toUpdate) + { + return toUpdate; + } + } +} \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py index bce5a5e9..fc29f63f 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py @@ -12,7 +12,7 @@ def diurnal(epw_file, data_type_key="Dry Bulb Temperature", color="#000000", tit from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt - + epw = EPW(epw_file) data_type_key = data_type_key.replace("_"," ") coll = HourlyContinuousCollection.from_dict([a for a in epw.to_dict()["data_collections"] if a["header"]["data_type"]["name"] == data_type_key][0]) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py index 8e2e9b24..868ff852 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py @@ -16,7 +16,6 @@ def sun_path(epw_file, analysis_period, size, save_path): analysis_period = AnalysisPeriod.from_dict(json.loads(analysis_period)) epw = EPW(epw_file) - collection = epw.global_horizontal_radiation fig = sunpath( location=epw.location, analysis_period=analysis_period, diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py index da0ac818..dc821ab4 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py @@ -24,15 +24,23 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, sa w_epw = Wind.from_epw(epw_file) fig, ax = plt.subplots(1, 1, figsize=(6, 6), subplot_kw={"projection": "polar"}) + + wind_filtered = w_epw.filter_by_analysis_period(analysis_period=analysis_period) + w_epw.filter_by_analysis_period(analysis_period=analysis_period).plot_windrose(ax=ax, directions=bins, ylim=(0, 3.6/bins), colors=colour_map) + description = wind_filtered.summarise() + + output_dict = {"figure": "", "description": description} + plt.tight_layout() if save_path == None or save_path == "": - base64 = figure_to_base64(fig,html=False) - print(base64) + output_dict["figure"] = figure_to_base64(fig,html=False) + print(json.dumps(output_dict)) else: fig.savefig(save_path, dpi=150, transparent=True) - print(save_path) + output_dict["figure"] = save_path + print(output_dict) except Exception as e: print(e) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py index 7dd513b5..bf9ddb07 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py @@ -1,6 +1,7 @@ """Methods for manipulating Ladybug data collections.""" # pylint: disable=E0401 +from gc import collect import warnings from datetime import datetime, timedelta from pathlib import Path @@ -353,6 +354,11 @@ def summarise_collection( return descriptions +def collection_metadata(collection: BaseCollection) -> dict: + series = collection_to_series(collection) + series.min() + + @bhom_analytics() def average( collections: list[BaseCollection], weights: list[float] = None diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py new file mode 100644 index 00000000..fcf76bcd --- /dev/null +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -0,0 +1,47 @@ +from ladybug.sunpath import Sunpath +from ladybug.location import Location + +import pandas as pd +from datetime import datetime + +def sunpath_metadata(location: Location) -> dict: + """Return a dictionary containing equinox and solstice altitudes at sunrise, noon and sunset for the given location + + Args: + location (Location): + A Ladybug location object. + + Returns: + dict: + A dictionary containing the altitudes in the following structure: + + { + 'december_solstice': {'sunrise': , 'noon': altitude, 'sunset': altitude}, + 'march_equinox': {...}, + 'june_solstice': {...}, + 'september_equinox': {...} + } + """ + sunpath = Sunpath.from_location(location) + + december_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 12, 22)) + march_equinox_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 3, 20)) + june_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 6, 21)) + september_equinox_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 9, 22)) + + december_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in december_solstice_times.items() } + + march_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in march_equinox_times.items() } + + june_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in june_solstice_times.items() } + + september_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in september_equinox_times.items() } + + return { + "december_solstice": december_solstice, + "march_equinox": march_equinox, + "june_solstice": june_solstice, + "september_equinox": september_equinox + } + + diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py index 08bfd234..f6d5a4a6 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py @@ -1506,6 +1506,27 @@ def summarise(self, directions: int = 36) -> list[str]: ) return return_strings # pylint: enable=line-too-long + + def wind_metadata(self) -> dict: + + prevailing_direction = self.prevailing()[0] + + _, bins = self.process_direction_data() + + direction_bin = [d_bin for d_bin in bins if d_bin[0] <= prevailing_direction and d_bin[1] < prevailing_direction][0] + + prevailing_wind_speeds = self.ws.loc[self.bin_data()["Wind Direction (degrees)"] == direction_bin] + + wind_dict = { + "95percentile": self.percentile(0.95), + "50percentile": self.percentile(0.50), + "calm_percent": self.calm(), + "prevailing_direction": self.prevailing()[0], + "prevailing_95percentile": prevailing_wind_speeds.quantile(0.95), + "prevailing_50percentile": prevailing_wind_speeds.quantile(0.5) + } + return wind_dict + def weibull_pdf(self) -> tuple[float]: """Calculate the parameters of an exponentiated Weibull continuous random variable. diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs new file mode 100644 index 00000000..458c0e12 --- /dev/null +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public class CollectionData : ISimulationData + { + public virtual List Description { get; set; } = new List(); + + public virtual double HighestValue { get; set; } = double.NaN; + + public virtual double LowestValue { get; set; } = double.NaN; + + public virtual DateTime HighestTime { get; set; } = DateTime.MinValue; + + public virtual DateTime LowestTime { get; set; } = DateTime.MinValue; + + public virtual double HighestAverageMonthValue { get; set; } = double.NaN; + + public virtual double LowestAverageMonthValue { get; set; } = double.NaN; + + public virtual int HighestAverageMonth { get; set; } = 0; + + public virtual int LowestAverageMonth { get; set; } = 0; + } +} diff --git a/LadybugTools_oM/MetaData/ISimulationData.cs b/LadybugTools_oM/MetaData/ISimulationData.cs new file mode 100644 index 00000000..967e3c07 --- /dev/null +++ b/LadybugTools_oM/MetaData/ISimulationData.cs @@ -0,0 +1,11 @@ +using BH.oM.Base; +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public interface ISimulationData : IObject + { + } +} diff --git a/LadybugTools_oM/MetaData/PlotInformation.cs b/LadybugTools_oM/MetaData/PlotInformation.cs new file mode 100644 index 00000000..4ffbb4b6 --- /dev/null +++ b/LadybugTools_oM/MetaData/PlotInformation.cs @@ -0,0 +1,14 @@ +using BH.oM.Base; +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public class PlotInformation : BHoMObject + { + public virtual string Image { get; set; } = ""; + + public virtual ISimulationData OtherData { get; set; } + } +} diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs new file mode 100644 index 00000000..f2f2fa7b --- /dev/null +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public class WindroseData : ISimulationData + { + public virtual List Description { get; set; } = new List(); + + public virtual double PrevailingDirection { get; set; } = double.NaN; + + public virtual double PrevailingSpeed { get; set; } = 0; + + public virtual DateTime PrevailingTime { get; set; } = DateTime.MinValue; + + public virtual double MaxSpeed { get; set; } = 0; + + public virtual double MaxSpeedDirection { get; set; } = double.NaN; + + public virtual DateTime MaxSpeedTime { get; set; } = DateTime.MinValue; + + public virtual double NumberOfCalmHours { get; set; } = 0; + + public virtual double PercentageOfCalmHours { get; set; } = 0; + } +} From 01b8a20651456b49c2444a43bc8889b4fc193187 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Tue, 9 Jul 2024 10:45:42 +0100 Subject: [PATCH 02/31] added data collection metadata method --- .../ladybug_extension/datacollection.py | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py index bf9ddb07..ae52e252 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py @@ -355,9 +355,63 @@ def summarise_collection( def collection_metadata(collection: BaseCollection) -> dict: + """Returns a dictionary containing useful metadata about the series. + + Args: + collection (BaseCollection): + ladybug data collection object + + Returns: + dict: + A dictionary containing metadata about the collection, structured: + { + "lowest": lowest, + "lowest_index": lowest_index, + "highest": highest, + "highest_index": highest_index, + "median": median, + "mean": mean, + "month_means": [month_means], + "month_diurnal_ranges": [month_diurnal_ranges], + } + where month_means is a list of means indexed by month, and month_ranges is a list of diurnal month ranges as tuples: (min, max). + """ + series = collection_to_series(collection) - series.min() - + lowest = series.min() + highest = series.max() + lowest_index = series.idxmin() + highest_index = series.idxmax() + median = series.quantile(0.5) + mean = series.mean() + + series_diurnal_mean = series.groupby([series.index.month, series.index.hour]).mean() + series_diurnal_max = series_diurnal_mean.groupby( + series_diurnal_mean.index.get_level_values(0) + ).max() + series_diurnal_min = series_diurnal_mean.groupby( + series_diurnal_mean.index.get_level_values(0) + ).min() + + month_means = [] + month_ranges = [] + for month in range(1, 13): + month_series = series[series.index.month == month] + month_means.append(month_series.mean()) + month_ranges.add((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) + + return { + "lowest": lowest, + "lowest_index": lowest_index, + "highest": highest, + "highest_index": highest_index, + "median": median, + "mean": mean, + "month_means": month_means, + "month_diurnal_ranges": month_ranges, + } + + @bhom_analytics() def average( From c201cca6c62ba2bffaff0cb30637ed145bd0900b Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 09:47:23 +0100 Subject: [PATCH 03/31] serialisation/deserialisation now works for heatmaps --- .../AdapterActions/Execute.cs | 37 +-- .../Convert/MetaData/PlotInformation.cs | 300 +++++++++++++++--- .../bhom/wrapped/plot/heatmap.py | 28 +- .../external_comfort/utci.py | 60 ++++ .../ladybug_extension/datacollection.py | 6 +- LadybugTools_oM/MetaData/CollectionData.cs | 15 +- LadybugTools_oM/MetaData/SunData.cs | 21 ++ LadybugTools_oM/MetaData/SunPathData.cs | 17 + LadybugTools_oM/MetaData/UTCIData.cs | 21 ++ LadybugTools_oM/MetaData/WindroseData.cs | 16 +- 10 files changed, 433 insertions(+), 88 deletions(-) create mode 100644 LadybugTools_oM/MetaData/SunData.cs create mode 100644 LadybugTools_oM/MetaData/SunPathData.cs create mode 100644 LadybugTools_oM/MetaData/UTCIData.cs diff --git a/LadybugTools_Adapter/AdapterActions/Execute.cs b/LadybugTools_Adapter/AdapterActions/Execute.cs index 9b69c6bf..d0034d95 100644 --- a/LadybugTools_Adapter/AdapterActions/Execute.cs +++ b/LadybugTools_Adapter/AdapterActions/Execute.cs @@ -312,12 +312,24 @@ private List RunCommand(HeatPlotCommand command, ActionConfig actionConf if (colourMap.ColourMapValidity()) colourMap = colourMap.ToColourMap().FromColourMap(); + string returnFile = Path.GetTempFileName(); + // run the process - string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -dtk \"{command.EPWKey.ToText()}\" -cmap \"{colourMap}\" -p \"{command.OutputLocation}\""; + string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -dtk \"{command.EPWKey.ToText()}\" -cmap \"{colourMap}\" -r \"{returnFile.Replace('\\', '/')}\" -p \"{command.OutputLocation}\""; string result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); + if (!File.Exists(result)) + { + BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + return new List(); + } + + CustomObject obj = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(System.IO.File.ReadAllText(returnFile)); + File.Delete(returnFile); + PlotInformation info = Convert.ToPlotInformation(obj, new CollectionData()); + m_executeSuccess = true; - return new List() { result }; + return new List() { info }; } /**************************************************/ @@ -355,27 +367,6 @@ private List RunCommand(WindroseCommand command, ActionConfig actionConf string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -ap \"{command.AnalysisPeriod.FromBHoM().Replace("\"", "\\\"")}\" -cmap \"{colourMap}\" -bins \"{command.NumberOfDirectionBins}\" -p \"{command.OutputLocation}\""; string result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); - CustomObject data = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(result); - - object image = ""; - - if (!data.CustomData.TryGetValue("figure", out image)) - { - BH.Engine.Base.Compute.RecordError("An error occurred during generation of the plot."); - return new List(); - } - - PlotInformation info = new PlotInformation() - { - Image = (string)image, - OtherData = new WindroseData() - { - Description = (data.CustomData["description"] as List).Select(x => x.ToString()).ToList(), - MaxSpeed = - } - }; - - m_executeSuccess = true; return new List { result }; } diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs index 8f051849..906fc4ed 100644 --- a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -3,90 +3,314 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Principal; using System.Text; namespace BH.Adapter.LadybugTools { public static partial class Convert { - public static ISimulationData IToSimulationData(this CustomObject oldObject, ISimulationData toUpdate) + + public static PlotInformation ToPlotInformation(this CustomObject oldObject, ISimulationData toUpdate) + { + PlotInformation plotInformation = new PlotInformation(); + + plotInformation.Image = oldObject.CustomData["figure"].ToString(); + + plotInformation.OtherData = IToSimulationData((oldObject.CustomData["data"] as CustomObject).CustomData, toUpdate); + + return plotInformation; + + } + + private static ISimulationData IToSimulationData(Dictionary oldObject, ISimulationData toUpdate) { - return ToSimulationData(oldObject.CustomData, toUpdate as dynamic); + return ToSimulationData(oldObject, toUpdate as dynamic); } private static CollectionData ToSimulationData(this Dictionary oldData, CollectionData toUpdate) { + + if (!double.TryParse(oldData["highest"].ToString(), out double result)) + result = double.NaN; + + toUpdate.HighestValue = result; + + if (!double.TryParse(oldData["lowest"].ToString(), out result)) + result = double.NaN; + + toUpdate.LowestValue = result; + + if (!DateTime.TryParse(oldData["highest_index"].ToString(), out DateTime date)) + date = DateTime.MinValue; + + toUpdate.HighestIndex = date; + + if (!DateTime.TryParse(oldData["lowest_index"].ToString(), out date)) + date = DateTime.MinValue; + + toUpdate.LowestIndex = date; + + if (!double.TryParse(oldData["median"].ToString(), out result)) + result = double.NaN; + + toUpdate.MedianValue = result; + + if (!double.TryParse(oldData["mean"].ToString(), out result)) + result = double.NaN; + + toUpdate.MeanValue = result; + + try + { + List means = oldData["month_means"] as List; + + int monthIndex = 0; + + foreach (object mean in means) + { + if (!double.TryParse(mean.ToString(), out double value)) + value = double.NaN; + + toUpdate.MonthlyMeans[monthIndex] = value; + monthIndex++; + } + } + catch { } + try { - toUpdate.Description = (oldData["description"] as List).Select(x => x.ToString()).ToList(); + List> ranges = oldData["month_diurnal_ranges"] as List>; + List> monthlyRanges = new List>(); + + int monthIndex = 0; + + foreach (List range in ranges) + { + List values = new List(); + + foreach (object value in range) + { + if (!double.TryParse(value.ToString(), out result)) + result = double.NaN; + + values.Add(result); + } + + toUpdate.MonthlyDiurnalRanges[monthIndex] = values; + monthIndex++; + } } catch { } - double.TryParse(oldData["highest_value"].ToString(), out double result); - toUpdate.HighestValue = result; - double.TryParse(oldData["lowest_value"].ToString(), out result); - toUpdate.LowestValue = result; + return toUpdate; + } - DateTime.TryParse(oldData["highest_time"].ToString(), out DateTime date); - toUpdate.HighestTime = date; + private static WindroseData ToSimulationData(this Dictionary oldData, WindroseData toUpdate) + { + if (!double.TryParse(oldData["prevailing_direction"].ToString(), out double result)) + result = double.NaN; + toUpdate.PrevailingDirection = result; - DateTime.TryParse(oldData["lowest_time"].ToString(), out date); - toUpdate.LowestTime = date; + if (!double.TryParse(oldData["prevailing_95percentile"].ToString(), out result)) + result = double.NaN; + toUpdate.PrevailingPercentile95 = result; - double.TryParse(oldData["highest_average_month_value"].ToString(), out result); - toUpdate.HighestAverageMonthValue = result; + if (!double.TryParse(oldData["prevailing_50percentile"].ToString(), out result)) + result = double.NaN; + toUpdate.PrevailingPercentile50 = result; - int.TryParse(oldData["highest_average_month"].ToString(), out int month); - toUpdate.HighestAverageMonth = month; + if (!double.TryParse(oldData["95percentile"].ToString(), out result)) + result = double.NaN; + toUpdate.Percentile95 = result; - double.TryParse(oldData["lowest_average_month_value"].ToString(), out result); - toUpdate.LowestAverageMonthValue = result; + if (!double.TryParse(oldData["50percentile"].ToString(), out result)) + result = double.NaN; + toUpdate.Percentile50 = result; - int.TryParse(oldData["lowest_average_month"].ToString(), out month); - toUpdate.LowestAverageMonth = month; + if (!double.TryParse(oldData["calm_percent"].ToString(), out result)) + result = double.NaN; + toUpdate.PercentageOfCalmHours = result; return toUpdate; } - private static WindroseData ToSimulationData(this Dictionary oldData, WindroseData toUpdate) + private static SunPathData ToSimulationData(this Dictionary oldData, SunPathData toUpdate) { try { - toUpdate.Description = (oldData["description"] as List).Select(x => x.ToString()).ToList(); + Dictionary december_object = (oldData["december_solstice"] as CustomObject).CustomData; + + Dictionary sunset = (december_object["sunset"] as CustomObject).CustomData; + + if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) + result = double.NaN; + toUpdate.DecemberSolstice.SunsetAzimuth = result; + + if (!DateTime.TryParse(sunset["time"].ToString(), out DateTime date)) + date = DateTime.MinValue; + toUpdate.DecemberSolstice.SunsetTime = date; + + Dictionary sunrise = (december_object["sunrise"] as CustomObject).CustomData; + + if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) + result = double.NaN; + toUpdate.DecemberSolstice.SunriseAzimuth = result; + + if (!DateTime.TryParse(sunrise["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.DecemberSolstice.SunriseTime = date; + + Dictionary noon = (december_object["noon"] as CustomObject).CustomData; + + if (!double.TryParse(noon["altitude"].ToString(), out result)) + result = double.NaN; + toUpdate.DecemberSolstice.NoonAltitude = result; + + if (!DateTime.TryParse(noon["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.DecemberSolstice.NoonTime = date; + } + catch { } + + try + { + Dictionary march_object = (oldData["march_equinox"] as CustomObject).CustomData; + + Dictionary sunset = (march_object["sunset"] as CustomObject).CustomData; + + if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) + result = double.NaN; + toUpdate.MarchEquinox.SunsetAzimuth = result; + + if (!DateTime.TryParse(sunset["time"].ToString(), out DateTime date)) + date = DateTime.MinValue; + toUpdate.MarchEquinox.SunsetTime = date; + + Dictionary sunrise = (march_object["sunrise"] as CustomObject).CustomData; + + if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) + result = double.NaN; + toUpdate.MarchEquinox.SunriseAzimuth = result; + + if (!DateTime.TryParse(sunrise["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.MarchEquinox.SunriseTime = date; + + Dictionary noon = (march_object["noon"] as CustomObject).CustomData; + + if (!double.TryParse(noon["altitude"].ToString(), out result)) + result = double.NaN; + toUpdate.MarchEquinox.NoonAltitude = result; + + if (!DateTime.TryParse(noon["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.MarchEquinox.NoonTime = date; } catch { } - double.TryParse(oldData["prevailing_direction"].ToString(), out double result); - toUpdate.PrevailingDirection = result; + try + { + Dictionary june_object = (oldData["june_solstice"] as CustomObject).CustomData; - double.TryParse(oldData["prevailing_speed"].ToString(), out result); - toUpdate.PrevailingSpeed = result; + Dictionary sunset = (june_object["sunset"] as CustomObject).CustomData; + if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) + result = double.NaN; + toUpdate.JuneSolstice.SunsetAzimuth = result; - DateTime.TryParse(oldData["prevailing_time"].ToString(), out DateTime date); - toUpdate.PrevailingTime = date; + if (!DateTime.TryParse(sunset["time"].ToString(), out DateTime date)) + date = DateTime.MinValue; + toUpdate.JuneSolstice.SunsetTime = date; - double.TryParse(oldData["max_speed"].ToString(), out result); - toUpdate.MaxSpeed = result; + Dictionary sunrise = (june_object["sunrise"] as CustomObject).CustomData; - double.TryParse(oldData["max_speed_direction"].ToString(), out result); - toUpdate.MaxSpeedDirection = result; + if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) + result = double.NaN; + toUpdate.JuneSolstice.SunriseAzimuth = result; - DateTime.TryParse(oldData["max_speed_time"].ToString(), out date); - toUpdate.MaxSpeedTime = date; + if (!DateTime.TryParse(sunrise["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.JuneSolstice.SunriseTime = date; - double.TryParse(oldData["calm_count"].ToString(), out result); - toUpdate.NumberOfCalmHours = result; + Dictionary noon = (june_object["noon"] as CustomObject).CustomData; - double.TryParse(oldData["calm_percent"].ToString(), out result); - toUpdate.PercentageOfCalmHours = result; + if (!double.TryParse(noon["altitude"].ToString(), out result)) + result = double.NaN; + toUpdate.JuneSolstice.NoonAltitude = result; + + if (!DateTime.TryParse(noon["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.JuneSolstice.NoonTime = date; + } + catch { } + + try + { + Dictionary september_object = (oldData["september_equinox"] as CustomObject).CustomData; + + Dictionary sunset = (september_object["sunset"] as CustomObject).CustomData; + + if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) + result = double.NaN; + toUpdate.SeptemberEquinox.SunsetAzimuth = result; + + if (!DateTime.TryParse(sunset["time"].ToString(), out DateTime date)) + date = DateTime.MinValue; + toUpdate.SeptemberEquinox.SunsetTime = date; + + Dictionary sunrise = (september_object["sunrise"] as CustomObject).CustomData; + + if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) + result = double.NaN; + toUpdate.SeptemberEquinox.SunriseAzimuth = result; + + if (!DateTime.TryParse(sunrise["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.SeptemberEquinox.SunriseTime = date; + + Dictionary noon = (september_object["noon"] as CustomObject).CustomData; + + if (!double.TryParse(noon["altitude"].ToString(), out result)) + result = double.NaN; + toUpdate.SeptemberEquinox.NoonAltitude = result; + + if (!DateTime.TryParse(noon["time"].ToString(), out date)) + date = DateTime.MinValue; + toUpdate.SeptemberEquinox.NoonTime = date; + } + catch { } return toUpdate; } - private static SunPathData ToSimulationData(this Dictionary oldData, SunPathData toUpdate) + private static UTCIData ToSimulationData(this Dictionary oldData, UTCIData toUpdate) { + if (!double.TryParse(oldData["comfortable_ratio"].ToString(), out double result)) + result = double.NaN; + toUpdate.ComfortableRatio = result; + + if (!double.TryParse(oldData["hot_ratio"].ToString(), out result)) + result = double.NaN; + toUpdate.HotRatio = result; + + if (!double.TryParse(oldData["cold_ratio"].ToString(), out result)) + result = double.NaN; + toUpdate.HotRatio = result; + + if (!double.TryParse(oldData["daytime_comfortable"].ToString(), out result)) + result = double.NaN; + toUpdate.DaytimeComfortableRatio = result; + + if (!double.TryParse(oldData["daytime_hot"].ToString(), out result)) + result = double.NaN; + toUpdate.DaytimeHotRatio = result; + + if (!double.TryParse(oldData["daytime_cold"].ToString(), out result)) + result = double.NaN; + toUpdate.DaytimeColdRatio = result; + return toUpdate; } } diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py index a8055ed4..ec5cd4b9 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py @@ -3,15 +3,16 @@ import argparse import traceback from pathlib import Path +import json -def heatmap(epw_file: str, data_type_key: str, colour_map: str, save_path:str = None) -> None: +def heatmap(epw_file: str, data_type_key: str, colour_map: str, return_file: str, save_path:str = None) -> None: """Create a CSV file version of an EPW.""" try: from ladybug.epw import EPW from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot._heatmap import heatmap - from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series + from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series, collection_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt @@ -21,12 +22,22 @@ def heatmap(epw_file: str, data_type_key: str, colour_map: str, save_path:str = epw = EPW(epw_file) coll = HourlyContinuousCollection.from_dict([a for a in epw.to_dict()["data_collections"] if a["header"]["data_type"]["name"] == data_type_key][0]) fig = heatmap(collection_to_series(coll), cmap=colour_map).get_figure() + + return_dict = {} + if save_path == None or save_path == "": base64 = figure_to_base64(fig,html=False) - print(base64) + return_dict["figure"] = base64 else: fig.savefig(save_path, dpi=150, transparent=True) - print(save_path) + return_dict["figure"] = save_path + + return_dict["data"] = collection_metadata(coll) + + with open(return_file, "w") as rtn: + rtn.write(json.dumps(return_dict, default=str)) + + print(return_file) except Exception as e: @@ -61,6 +72,13 @@ def heatmap(epw_file: str, data_type_key: str, colour_map: str, save_path:str = type=str, required=True, ) + parser.add_argument( + "-r", + "--return_file", + help="json file to write return data to.", + type=str, + required=True, + ) parser.add_argument( "-p", "--save_path", @@ -70,4 +88,4 @@ def heatmap(epw_file: str, data_type_key: str, colour_map: str, save_path:str = ) args = parser.parse_args() - heatmap(args.epw_file, args.data_type_key, args.colour_map, args.save_path) + heatmap(args.epw_file, args.data_type_key, args.colour_map, args.return_file, args.save_path) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py index f724497c..f5df26b5 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py @@ -2,6 +2,7 @@ # pylint: disable=C0302 # pylint: disable=E0401 +from datetime import datetime import warnings from calendar import month_abbr from concurrent.futures import ProcessPoolExecutor @@ -707,6 +708,65 @@ def _utci_ndarray( return utci_approx +def utci_metadata(utci_collection: HourlyContinuousCollection, comfort_lower: float = 9, comfort_higher: float = 26, use_start_hour: int=7, use_end_hour: int=23) -> dict: + """Returns a dictionary of useful metadata for the given collection dependant on the given comfortable range. + + Args: + utci_collection (HourlyContinuousCollection): + utci headered ladybug hourly collection + + comfort_lower (float): + lower value for the comfortable temperature range, where temperatures exclusively below this are too cold. + + comfort_higher (float): + higher value for the comfortable temperature range, where temperatures above and equal to this are too hot. + + use_start_hour (int): + start hour to filter usage time, inclusive + + use_end_hour (int): + end hour to filter usage time, exclusive + + Returns: + dict: + dictionary containing comfortable, hot and cold ratios, structured as follows: + { + 'comfortable_ratio': ratio_of_comfortable_hours, + 'hot_ratio': ratio_of_hot_hours, + 'cold_ratio': ratio_of_cold_hours, + 'daytime_comfortable': daytime_comfortable_ratio, + 'daytime_hot': daytime_hot_ratio, + 'daytime_cold': daytime_cold_ratio + } + """ + if not isinstance(utci_collection.header.data_type, LB_UniversalThermalClimateIndex): + raise ValueError("Input collection is not a UTCI collection.") + + if not comfort_lower < comfort_higher: + raise ValueError(f"The lower comfort temperature {comfort_lower}, must be less than the higher comfort temperature {comfort_higher}.") + + series = collection_to_series(utci_collection) + + daytime = series.loc[(series.index.hour >= use_start_hour) & (series.index.hour < use_end_hour)] + + comfortable_ratio = ((series >= comfort_lower) & (series < comfort_higher)).sum() / len(series) + hot_ratio = (series >= comfort_higher).sum() / len(series) + cold_ratio = (series < comfort_lower).sum() / len(series) + + day_comfortable = ((daytime >= comfort_lower) & (daytime < comfort_higher)).sum() / len(daytime) + day_hot = (daytime >= comfort_higher).sum() / len(daytime) + day_cold = (daytime < comfort_lower).sum() / len(daytime) + + return { + "comfortable_ratio": comfortable_ratio, + "hot_ratio": hot_ratio, + "cold_ratio": cold_ratio, + "daytime_comfortable": day_comfortable, + "daytime_hot": day_hot, + "daytime_cold": day_cold + } + + def _utci_collection( air_temperature: HourlyContinuousCollection, mean_radiant_temperature: HourlyContinuousCollection, diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py index ae52e252..7b4c44e2 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py @@ -395,10 +395,10 @@ def collection_metadata(collection: BaseCollection) -> dict: month_means = [] month_ranges = [] - for month in range(1, 13): - month_series = series[series.index.month == month] + for month in range(12): + month_series = series[series.index.month == month + 1] month_means.append(month_series.mean()) - month_ranges.add((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) + month_ranges.append((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) return { "lowest": lowest, diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs index 458c0e12..217e0eb1 100644 --- a/LadybugTools_oM/MetaData/CollectionData.cs +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -1,27 +1,26 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace BH.oM.LadybugTools { public class CollectionData : ISimulationData { - public virtual List Description { get; set; } = new List(); - public virtual double HighestValue { get; set; } = double.NaN; public virtual double LowestValue { get; set; } = double.NaN; - public virtual DateTime HighestTime { get; set; } = DateTime.MinValue; + public virtual DateTime HighestIndex { get; set; } = DateTime.MinValue; - public virtual DateTime LowestTime { get; set; } = DateTime.MinValue; + public virtual DateTime LowestIndex { get; set; } = DateTime.MinValue; - public virtual double HighestAverageMonthValue { get; set; } = double.NaN; + public virtual double MedianValue { get; set; } = double.NaN; - public virtual double LowestAverageMonthValue { get; set; } = double.NaN; + public virtual double MeanValue { get; set; } = double.NaN; - public virtual int HighestAverageMonth { get; set; } = 0; + public virtual List MonthlyMeans { get; set; } = Enumerable.Repeat(double.NaN, 12).ToList(); - public virtual int LowestAverageMonth { get; set; } = 0; + public virtual List> MonthlyDiurnalRanges { get; set; } = Enumerable.Repeat>(new List { double.NaN, double.NaN }, 12).ToList(); } } diff --git a/LadybugTools_oM/MetaData/SunData.cs b/LadybugTools_oM/MetaData/SunData.cs new file mode 100644 index 00000000..9fbfe6fc --- /dev/null +++ b/LadybugTools_oM/MetaData/SunData.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public class SunData + { + public virtual double SunriseAzimuth { get; set; } = double.NaN; + + public virtual DateTime SunriseTime { get; set; } = DateTime.MinValue; + + public virtual double NoonAltitude { get; set; } = double.NaN; + + public virtual DateTime NoonTime { get; set; } = DateTime.MinValue; + + public virtual double SunsetAzimuth { get; set; } = double.NaN; + + public virtual DateTime SunsetTime { get; set; } = DateTime.MinValue; + } +} diff --git a/LadybugTools_oM/MetaData/SunPathData.cs b/LadybugTools_oM/MetaData/SunPathData.cs new file mode 100644 index 00000000..5006eb46 --- /dev/null +++ b/LadybugTools_oM/MetaData/SunPathData.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public class SunPathData : ISimulationData + { + public virtual SunData DecemberSolstice { get; set; } = new SunData(); + + public virtual SunData MarchEquinox { get; set; } = new SunData(); + + public virtual SunData JuneSolstice { get; set; } = new SunData(); + + public virtual SunData SeptemberEquinox { get; set; } = new SunData(); + } +} diff --git a/LadybugTools_oM/MetaData/UTCIData.cs b/LadybugTools_oM/MetaData/UTCIData.cs new file mode 100644 index 00000000..839ff1b4 --- /dev/null +++ b/LadybugTools_oM/MetaData/UTCIData.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BH.oM.LadybugTools +{ + public class UTCIData : ISimulationData + { + public virtual double ComfortableRatio { get; set; } = double.NaN; + + public virtual double HotRatio { get; set; } = double.NaN; + + public virtual double ColdRatio { get; set; } = double.NaN; + + public virtual double DaytimeComfortableRatio { get; set; } = double.NaN; + + public virtual double DaytimeHotRatio { get; set; } = double.NaN; + + public virtual double DaytimeColdRatio { get; set; } = double.NaN; + } +} diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs index f2f2fa7b..566cdc76 100644 --- a/LadybugTools_oM/MetaData/WindroseData.cs +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -6,22 +6,16 @@ namespace BH.oM.LadybugTools { public class WindroseData : ISimulationData { - public virtual List Description { get; set; } = new List(); - public virtual double PrevailingDirection { get; set; } = double.NaN; - public virtual double PrevailingSpeed { get; set; } = 0; - - public virtual DateTime PrevailingTime { get; set; } = DateTime.MinValue; - - public virtual double MaxSpeed { get; set; } = 0; + public virtual double PrevailingPercentile95 { get; set; } = double.NaN; - public virtual double MaxSpeedDirection { get; set; } = double.NaN; + public virtual double PrevailingPercentile50 { get; set; } = double.NaN; - public virtual DateTime MaxSpeedTime { get; set; } = DateTime.MinValue; + public virtual double Percentile95 { get; set; } = double.NaN; - public virtual double NumberOfCalmHours { get; set; } = 0; + public virtual double Percentile50 { get; set; } = double.NaN; - public virtual double PercentageOfCalmHours { get; set; } = 0; + public virtual double PercentageOfCalmHours { get; set; } = double.NaN; } } From 639bc9b1f35f6e46e9678448a3fe97f1a3e4cbd5 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 13:01:35 +0100 Subject: [PATCH 04/31] fixed prevailing direction issue by ignoring calm hours, and implemented windrose and utci plot information --- .../AdapterActions/Execute.cs | 46 +++++++++++++------ .../Convert/MetaData/PlotInformation.cs | 24 +++++++--- .../bhom/wrapped/plot/utci_heatmap.py | 27 +++++++++-- .../bhom/wrapped/plot/windrose.py | 22 ++++++--- .../Python/src/ladybugtools_toolkit/wind.py | 32 ++++++++----- LadybugTools_oM/MetaData/WindroseData.cs | 3 +- 6 files changed, 112 insertions(+), 42 deletions(-) diff --git a/LadybugTools_Adapter/AdapterActions/Execute.cs b/LadybugTools_Adapter/AdapterActions/Execute.cs index d0034d95..5df9c325 100644 --- a/LadybugTools_Adapter/AdapterActions/Execute.cs +++ b/LadybugTools_Adapter/AdapterActions/Execute.cs @@ -321,6 +321,7 @@ private List RunCommand(HeatPlotCommand command, ActionConfig actionConf if (!File.Exists(result)) { BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + File.Delete(returnFile); return new List(); } @@ -363,12 +364,25 @@ private List RunCommand(WindroseCommand command, ActionConfig actionConf if (colourMap.ColourMapValidity()) colourMap = colourMap.ToColourMap().FromColourMap(); + string returnFile = Path.GetTempFileName(); + // run the process - string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -ap \"{command.AnalysisPeriod.FromBHoM().Replace("\"", "\\\"")}\" -cmap \"{colourMap}\" -bins \"{command.NumberOfDirectionBins}\" -p \"{command.OutputLocation}\""; + string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -ap \"{command.AnalysisPeriod.FromBHoM().Replace("\"", "\\\"")}\" -cmap \"{colourMap}\" -bins \"{command.NumberOfDirectionBins}\" -r \"{returnFile.Replace('\\', '/')}\" -p \"{command.OutputLocation}\""; string result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); + if (!File.Exists(result)) + { + BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + File.Delete(returnFile); + return new List(); + } + + CustomObject obj = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(System.IO.File.ReadAllText(returnFile)); + File.Delete(returnFile); + PlotInformation info = Convert.ToPlotInformation(obj, new WindroseData()); + m_executeSuccess = true; - return new List { result }; + return new List { info }; } /**************************************************/ @@ -430,25 +444,29 @@ private List RunCommand(UTCIHeatPlotCommand command, ActionConfig action string script = Path.Combine(Engine.LadybugTools.Query.PythonCodeDirectory(), "LadybugTools_Toolkit\\src\\ladybugtools_toolkit\\bhom\\wrapped\\plot", "utci_heatmap.py"); + string returnFile = Path.GetTempFileName(); + // run the process - string cmdCommand = $"{m_environment.Executable} \"{script}\" -e \"{epwFile}\" -in \"{argFile}\" -ws \"{command.WindSpeedMultiplier}\" -sp \"{command.OutputLocation}\""; - string result = ""; + string cmdCommand = $"{m_environment.Executable} \"{script}\" -e \"{epwFile}\" -in \"{argFile}\" -ws \"{command.WindSpeedMultiplier}\" -r \"{returnFile.Replace('\\', '/')}\" -sp \"{command.OutputLocation}\""; + string result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); - try - { - result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); - } - catch (Exception ex) - { - BH.Engine.Base.Compute.RecordError(ex, "An error occurred while running some python."); - } - finally + string resultFile = result.Split('\n').Last(); + + if (!File.Exists(resultFile)) { + BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + File.Delete(returnFile); File.Delete(argFile); + return new List(); } + CustomObject obj = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(System.IO.File.ReadAllText(returnFile)); + File.Delete(returnFile); + File.Delete(argFile); + PlotInformation info = Convert.ToPlotInformation(obj, new UTCIData()); + m_executeSuccess = true; - return new List { result.Split('\n').Last() }; + return new List { info }; } /**************************************************/ diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs index 906fc4ed..f48dd98c 100644 --- a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -109,14 +109,26 @@ private static CollectionData ToSimulationData(this Dictionary o private static WindroseData ToSimulationData(this Dictionary oldData, WindroseData toUpdate) { - if (!double.TryParse(oldData["prevailing_direction"].ToString(), out double result)) - result = double.NaN; - toUpdate.PrevailingDirection = result; - - if (!double.TryParse(oldData["prevailing_95percentile"].ToString(), out result)) + if (!double.TryParse(oldData["prevailing_95percentile"].ToString(), out double result)) result = double.NaN; toUpdate.PrevailingPercentile95 = result; + try + { + List tuple = oldData["prevailing_direction"] as List; + int index = 0; + + foreach (object value in tuple) + { + if (!double.TryParse(value.ToString(), out result)) + result = double.NaN; + + toUpdate.PrevailingDirection[index] = result; + index++; + } + } + catch { } + if (!double.TryParse(oldData["prevailing_50percentile"].ToString(), out result)) result = double.NaN; toUpdate.PrevailingPercentile50 = result; @@ -297,7 +309,7 @@ private static UTCIData ToSimulationData(this Dictionary oldData if (!double.TryParse(oldData["cold_ratio"].ToString(), out result)) result = double.NaN; - toUpdate.HotRatio = result; + toUpdate.ColdRatio = result; if (!double.TryParse(oldData["daytime_comfortable"].ToString(), out result)) result = double.NaN; diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py index 9fdf871f..0c18d6e5 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py @@ -8,6 +8,7 @@ def utci_heatmap(epw_file:str, json_file:str, + return_file: str, wind_speed_multiplier:float = 1, save_path = None) -> None: from ladybugtools_toolkit.external_comfort.material import Materials @@ -15,6 +16,7 @@ def utci_heatmap(epw_file:str, from ladybugtools_toolkit.external_comfort._typologybase import Typology from ladybugtools_toolkit.external_comfort.simulate import SimulationResult from ladybugtools_toolkit.external_comfort.externalcomfort import ExternalComfort + from ladybugtools_toolkit.external_comfort.utci import utci_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 from ladybugtools_toolkit.categorical.categories import Categorical, UTCI_DEFAULT_CATEGORIES from honeybee_energy.dictutil import dict_to_material @@ -50,14 +52,24 @@ def utci_heatmap(epw_file:str, fig, ax = plt.subplots(1, 1, figsize=(10, 4)) ec.plot_utci_heatmap(utci_categories = custom_bins) + utci_collection = ec.universal_thermal_climate_index + + return_dict = {"data": utci_metadata(utci_collection)} + plt.tight_layout() + if save_path == None or save_path == "": base64 = figure_to_base64(fig,html=False) - print(base64) + return_dict["figure"] = base64 else: fig.savefig(save_path, dpi=150, transparent=True) - print(save_path) - plt.close(fig) + return_dict["figure"] = base64 + + with open(return_file, "w") as rtn: + rtn.write(json.dumps(return_dict, default=str)) + + print(return_file) + if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -86,6 +98,13 @@ def utci_heatmap(epw_file:str, type=float, required=False, ) + parser.add_argument( + "-r", + "--return_file", + help="json file to write return data to.", + type=str, + required=True, + ) parser.add_argument( "-sp", "--save_path", @@ -96,4 +115,4 @@ def utci_heatmap(epw_file:str, args = parser.parse_args() - utci_heatmap(args.epw_path, args.json_args, args.wind_speed_multiplier, args.save_path) \ No newline at end of file + utci_heatmap(args.epw_path, args.json_args, args.return_file, args.wind_speed_multiplier, args.save_path) \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py index dc821ab4..909fa702 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py @@ -5,7 +5,7 @@ from pathlib import Path -def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, save_path: str = None) -> None: +def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, return_file: str, save_path: str = None) -> None: """Method to wrap for creating wind roses from epw files.""" try: from ladybug.epw import EPW, AnalysisPeriod @@ -29,18 +29,21 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, sa w_epw.filter_by_analysis_period(analysis_period=analysis_period).plot_windrose(ax=ax, directions=bins, ylim=(0, 3.6/bins), colors=colour_map) - description = wind_filtered.summarise() + description = wind_filtered.wind_metadata(bins) - output_dict = {"figure": "", "description": description} + output_dict = {"data": description} plt.tight_layout() if save_path == None or save_path == "": output_dict["figure"] = figure_to_base64(fig,html=False) - print(json.dumps(output_dict)) else: fig.savefig(save_path, dpi=150, transparent=True) output_dict["figure"] = save_path - print(output_dict) + + with open(return_file, "w") as rtn: + rtn.write(json.dumps(output_dict, default=str)) + + print(return_file) except Exception as e: print(e) @@ -81,6 +84,13 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, sa type=int, required=True, ) + parser.add_argument( + "-r", + "--return_file", + help="json file to write return data to.", + type=str, + required=True, + ) parser.add_argument( "-p", "--save_path", @@ -90,4 +100,4 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, sa ) args = parser.parse_args() - windrose(args.epw_file, args.analysis_period, args.colour_map, args.bins, args.save_path) \ No newline at end of file + windrose(args.epw_file, args.analysis_period, args.colour_map, args.bins, args.return_file, args.save_path) \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py index f6d5a4a6..f1a37b61 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py @@ -1201,6 +1201,8 @@ def prevailing( directions: int = 36, n: int = 1, as_cardinal: bool = False, + ignore_calm: bool = True, + threshold: float = 1e-10, ) -> list[float] | list[str]: """Calculate the prevailing wind direction/s for this object. @@ -1218,6 +1220,10 @@ def prevailing( """ binned = self.bin_data(directions=directions) + + if ignore_calm: + binned = binned.loc[self.ws > threshold] + prevailing_angles = binned.iloc[:, 0].value_counts().index[:n] if as_cardinal: @@ -1507,25 +1513,29 @@ def summarise(self, directions: int = 36) -> list[str]: return return_strings # pylint: enable=line-too-long - def wind_metadata(self) -> dict: - - prevailing_direction = self.prevailing()[0] + def wind_metadata(self, directions: int=36, ignore_calm: bool=True, threshold: float = 1e-10) -> dict: + prevailing_direction = self.prevailing(directions=directions, ignore_calm=ignore_calm, threshold=threshold)[0] - _, bins = self.process_direction_data() + _, bins = self.process_direction_data(directions=directions) - direction_bin = [d_bin for d_bin in bins if d_bin[0] <= prevailing_direction and d_bin[1] < prevailing_direction][0] + direction_bin = [d_bin for d_bin in bins if d_bin == prevailing_direction][0] - prevailing_wind_speeds = self.ws.loc[self.bin_data()["Wind Direction (degrees)"] == direction_bin] + prevailing_wind_speeds = self.ws.loc[self.bin_data(directions=directions)["Wind Direction (degrees)"] == direction_bin] - wind_dict = { - "95percentile": self.percentile(0.95), - "50percentile": self.percentile(0.50), + ws = self.ws + + if ignore_calm: + prevailing_wind_speeds = prevailing_wind_speeds.loc[prevailing_wind_speeds > threshold] + ws = self.ws.loc[self.ws > threshold] + + return { + "95percentile": ws.quantile(0.95), + "50percentile": ws.quantile(0.50), "calm_percent": self.calm(), - "prevailing_direction": self.prevailing()[0], + "prevailing_direction": prevailing_direction, "prevailing_95percentile": prevailing_wind_speeds.quantile(0.95), "prevailing_50percentile": prevailing_wind_speeds.quantile(0.5) } - return wind_dict def weibull_pdf(self) -> tuple[float]: diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs index 566cdc76..458c3a2a 100644 --- a/LadybugTools_oM/MetaData/WindroseData.cs +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace BH.oM.LadybugTools { public class WindroseData : ISimulationData { - public virtual double PrevailingDirection { get; set; } = double.NaN; + public virtual List PrevailingDirection { get; set; } = Enumerable.Repeat(double.NaN, 2).ToList(); public virtual double PrevailingPercentile95 { get; set; } = double.NaN; From 04b5ed5f0fe54cb53a4f928205a78fd25e756b2e Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 13:12:17 +0100 Subject: [PATCH 05/31] fixed incorrect namespace --- LadybugTools_Engine/Convert/HexCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index c79db3b3..166e7981 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -30,7 +30,7 @@ using System.ComponentModel; using BH.oM.Base.Attributes; -namespace BH.Engine.LadyBugTools +namespace BH.Engine.LadybugTools { public static partial class Convert { From 3ca05b24cb0992df227c64eb77d229f1b1a5cb92 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 13:28:24 +0100 Subject: [PATCH 06/31] updated to return plotinfo for diurnal and sunpath --- .../AdapterActions/Execute.cs | 39 ++++++++++++++++--- .../bhom/wrapped/plot/diurnal.py | 28 ++++++++++--- .../bhom/wrapped/plot/sunpath.py | 24 ++++++++++-- 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/LadybugTools_Adapter/AdapterActions/Execute.cs b/LadybugTools_Adapter/AdapterActions/Execute.cs index 5df9c325..6b3d9d65 100644 --- a/LadybugTools_Adapter/AdapterActions/Execute.cs +++ b/LadybugTools_Adapter/AdapterActions/Execute.cs @@ -37,7 +37,6 @@ using BH.Engine.Base; using System.Drawing; using BH.Engine.Serialiser; -using BH.Engine.LadyBugTools; using System.Reflection; namespace BH.Adapter.LadybugTools @@ -503,12 +502,27 @@ private List RunCommand(DiurnalPlotCommand command, ActionConfig actionC string script = Path.Combine(Engine.LadybugTools.Query.PythonCodeDirectory(), "LadybugTools_Toolkit\\src\\ladybugtools_toolkit\\bhom\\wrapped\\plot", "diurnal.py"); + string returnFile = Path.GetTempFileName(); + // run the process - string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -dtk \"{command.EPWKey.ToText()}\" -c \"{command.Colour.ToHexCode()}\" -t \"{command.Title}\" -ap \"{command.Period.ToString().ToLower()}\" -p \"{command.OutputLocation}\""; + string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -dtk \"{command.EPWKey.ToText()}\" -c \"{command.Colour.ToHexCode()}\" -t \"{command.Title}\" -ap \"{command.Period.ToString().ToLower()}\" -r \"{returnFile.Replace('\\', '/')}\" -p \"{command.OutputLocation}\""; string result = Engine.Python.Compute.RunCommandStdout(command: cmdCommand, hideWindows: true); + string resultFile = result.Split('\n').Last(); + + if (!File.Exists(resultFile)) + { + BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + File.Delete(returnFile); + return new List(); + } + + CustomObject obj = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(System.IO.File.ReadAllText(returnFile)); + File.Delete(returnFile); + PlotInformation info = Convert.ToPlotInformation(obj, new CollectionData()); + m_executeSuccess = true; - return new List() { result.Split('\n').Last() }; + return new List() { info }; } /**************************************************/ @@ -543,12 +557,27 @@ private List RunCommand(SunPathPlotCommand command, ActionConfig actionC string script = Path.Combine(Engine.LadybugTools.Query.PythonCodeDirectory(), "LadybugTools_Toolkit\\src\\ladybugtools_toolkit\\bhom\\wrapped\\plot", "sunpath.py"); + string returnFile = Path.GetTempFileName(); + //run the process - string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -s {command.SunSize} -ap \"{command.AnalysisPeriod.FromBHoM().Replace("\"", "\\\"")}\" -p \"{command.OutputLocation}\""; + string cmdCommand = $"{m_environment.Executable} {script} -e \"{epwFile}\" -s {command.SunSize} -ap \"{command.AnalysisPeriod.FromBHoM().Replace("\"", "\\\"")}\" -r \"{returnFile.Replace('\\', '/')}\" -p \"{command.OutputLocation}\""; string result = Engine.Python.Compute.RunCommandStdout(cmdCommand, hideWindows: true); + string resultFile = result.Split('\n').Last(); + + if (!File.Exists(resultFile)) + { + BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + File.Delete(returnFile); + return new List(); + } + + CustomObject obj = (CustomObject)BH.Engine.Serialiser.Convert.FromJson(System.IO.File.ReadAllText(returnFile)); + File.Delete(returnFile); + PlotInformation info = Convert.ToPlotInformation(obj, new SunPathData()); + m_executeSuccess = true; - return new List() { result.Split('\n').Last() }; + return new List() { info }; } /**************************************************/ diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py index fc29f63f..548b3575 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py @@ -1,13 +1,14 @@ """Method to wrap creation of diurnal plots""" # pylint: disable=C0415,E0401,W0703 import argparse +import json import traceback from pathlib import Path -def diurnal(epw_file, data_type_key="Dry Bulb Temperature", color="#000000", title=None, period="monthly", save_path = None): +def diurnal(epw_file, return_file: str, data_type_key="Dry Bulb Temperature", color="#000000", title=None, period="monthly", save_path = None): try: from ladybug.epw import EPW, AnalysisPeriod - from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series + from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series, collection_metadata from ladybugtools_toolkit.plot._diurnal import diurnal from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot.utilities import figure_to_base64 @@ -17,12 +18,22 @@ def diurnal(epw_file, data_type_key="Dry Bulb Temperature", color="#000000", tit data_type_key = data_type_key.replace("_"," ") coll = HourlyContinuousCollection.from_dict([a for a in epw.to_dict()["data_collections"] if a["header"]["data_type"]["name"] == data_type_key][0]) fig = diurnal(collection_to_series(coll),title=title, period=period, color=color).get_figure() + + + return_dict = {"data": collection_metadata(coll)} + if save_path == None or save_path == "": base64 = figure_to_base64(fig, html=False) - print(base64) + return_dict["figure"] = base64 else: fig.savefig(save_path, dpi=150, transparent=True) - print(save_path) + return_dict["figure"] = save_path + + with open(return_file, "w") as rtn: + rtn.write(json.dumps(return_dict, default=str)) + + print(return_file) + except Exception as e: print(traceback.format_exc()) @@ -67,6 +78,13 @@ def diurnal(epw_file, data_type_key="Dry Bulb Temperature", color="#000000", tit type=str, required=True, ) + parser.add_argument( + "-r", + "--return_file", + help="json file to write return data to.", + type=str, + required=True, + ) parser.add_argument( "-p", "--save_path", @@ -76,4 +94,4 @@ def diurnal(epw_file, data_type_key="Dry Bulb Temperature", color="#000000", tit ) args = parser.parse_args() - diurnal(args.epw_file, args.data_type_key, args.colour, args.title, args.period, args.save_path) + diurnal(args.epw_file, args.return_file, args.data_type_key, args.colour, args.title, args.period, args.save_path) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py index 868ff852..a38b050a 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py @@ -4,11 +4,12 @@ import traceback from pathlib import Path -def sun_path(epw_file, analysis_period, size, save_path): +def sun_path(epw_file, analysis_period, size, return_file: str, save_path): try: from ladybugtools_toolkit.plot._sunpath import sunpath from ladybug.epw import EPW, AnalysisPeriod from ladybug.datacollection import HourlyContinuousCollection + from ladybugtools_toolkit.ladybug_extension.sunpath import sunpath_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt from pathlib import Path @@ -22,12 +23,20 @@ def sun_path(epw_file, analysis_period, size, save_path): sun_size=size, ).get_figure() + return_dict = {"data": sunpath_metadata(epw.location)} + if save_path is None or save_path == "": base64 = figure_to_base64(fig, html=False) - print(base64) + return_dict["figure"] = base64 else: fig.savefig(save_path, dpi=150, transparent=True) - print(save_path) + return_dict["figure"] = save_path + + with open(return_file, "w") as rtn: + rtn.write(json.dumps(return_dict, default=str)) + + print(return_file) + except Exception as e: print(e) @@ -58,6 +67,13 @@ def sun_path(epw_file, analysis_period, size, save_path): type=str, required=True, ) + parser.add_argument( + "-r", + "--return_file", + help="json file to write return data to.", + type=str, + required=True, + ) parser.add_argument( "-p", "--save_path", @@ -67,4 +83,4 @@ def sun_path(epw_file, analysis_period, size, save_path): ) args = parser.parse_args() - sun_path(args.epw_file, args.analysis_period, args.size, args.save_path) \ No newline at end of file + sun_path(args.epw_file, args.analysis_period, args.size, args.return_file, args.save_path) \ No newline at end of file From f9f152b4a930bcdfddc1940e9c66206dd2b7cbbd Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 13:37:41 +0100 Subject: [PATCH 07/31] fixed incorrect sunpath method name --- .../src/ladybugtools_toolkit/ladybug_extension/sunpath.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py index fcf76bcd..94ba4c1a 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -29,13 +29,13 @@ def sunpath_metadata(location: Location) -> dict: june_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 6, 21)) september_equinox_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 9, 22)) - december_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in december_solstice_times.items() } + december_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in december_solstice_times.items() } - march_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in march_equinox_times.items() } + march_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in march_equinox_times.items() } - june_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in june_solstice_times.items() } + june_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in june_solstice_times.items() } - september_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_datetime(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_datetime(v).altitude} for k, v in september_equinox_times.items() } + september_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in september_equinox_times.items() } return { "december_solstice": december_solstice, From 642d7341d9f5d3b9d00f3642f787c34fb3d2ae36 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 13:45:09 +0100 Subject: [PATCH 08/31] added bhom analytics to metadata methods --- .../src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py | 3 ++- .../src/ladybugtools_toolkit/external_comfort/utci.py | 1 + .../ladybug_extension/datacollection.py | 1 + .../src/ladybugtools_toolkit/ladybug_extension/sunpath.py | 6 +++--- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py index a38b050a..d0330c21 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py @@ -9,6 +9,7 @@ def sun_path(epw_file, analysis_period, size, return_file: str, save_path): from ladybugtools_toolkit.plot._sunpath import sunpath from ladybug.epw import EPW, AnalysisPeriod from ladybug.datacollection import HourlyContinuousCollection + from ladybug.sunpath import Sunpath from ladybugtools_toolkit.ladybug_extension.sunpath import sunpath_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt @@ -23,7 +24,7 @@ def sun_path(epw_file, analysis_period, size, return_file: str, save_path): sun_size=size, ).get_figure() - return_dict = {"data": sunpath_metadata(epw.location)} + return_dict = {"data": sunpath_metadata(Sunpath.from_location(epw.location))} if save_path is None or save_path == "": base64 = figure_to_base64(fig, html=False) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py index f5df26b5..1b984d30 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py @@ -708,6 +708,7 @@ def _utci_ndarray( return utci_approx +@bhom_analytics() def utci_metadata(utci_collection: HourlyContinuousCollection, comfort_lower: float = 9, comfort_higher: float = 26, use_start_hour: int=7, use_end_hour: int=23) -> dict: """Returns a dictionary of useful metadata for the given collection dependant on the given comfortable range. diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py index 7b4c44e2..c1465595 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py @@ -354,6 +354,7 @@ def summarise_collection( return descriptions +@bhom_analytics() def collection_metadata(collection: BaseCollection) -> dict: """Returns a dictionary containing useful metadata about the series. diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py index 94ba4c1a..aa6cbc33 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -1,10 +1,12 @@ from ladybug.sunpath import Sunpath from ladybug.location import Location +from ..bhom.analytics import bhom_analytics import pandas as pd from datetime import datetime -def sunpath_metadata(location: Location) -> dict: +@bhom_analytics() +def sunpath_metadata(sunpath: Sunpath) -> dict: """Return a dictionary containing equinox and solstice altitudes at sunrise, noon and sunset for the given location Args: @@ -22,8 +24,6 @@ def sunpath_metadata(location: Location) -> dict: 'september_equinox': {...} } """ - sunpath = Sunpath.from_location(location) - december_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 12, 22)) march_equinox_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 3, 20)) june_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 6, 21)) From 0ebabfc60448b57b1218f108eb3c81b6175eeaa2 Mon Sep 17 00:00:00 2001 From: BHoMBot Date: Wed, 10 Jul 2024 14:44:41 +0100 Subject: [PATCH 09/31] Resolve copyright compliance --- .../Convert/MetaData/PlotInformation.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/CollectionData.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/ISimulationData.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/PlotInformation.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/SunData.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/SunPathData.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/UTCIData.cs | 24 ++++++++++++++++++- LadybugTools_oM/MetaData/WindroseData.cs | 24 ++++++++++++++++++- 8 files changed, 184 insertions(+), 8 deletions(-) diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs index f48dd98c..88a6986b 100644 --- a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -1,4 +1,26 @@ -using BH.oM.Base; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base; using BH.oM.LadybugTools; using System; using System.Collections.Generic; diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs index 217e0eb1..23a8bcaa 100644 --- a/LadybugTools_oM/MetaData/CollectionData.cs +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -1,4 +1,26 @@ -using System; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/LadybugTools_oM/MetaData/ISimulationData.cs b/LadybugTools_oM/MetaData/ISimulationData.cs index 967e3c07..e2fef973 100644 --- a/LadybugTools_oM/MetaData/ISimulationData.cs +++ b/LadybugTools_oM/MetaData/ISimulationData.cs @@ -1,4 +1,26 @@ -using BH.oM.Base; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base; using System; using System.Collections.Generic; using System.Text; diff --git a/LadybugTools_oM/MetaData/PlotInformation.cs b/LadybugTools_oM/MetaData/PlotInformation.cs index 4ffbb4b6..063b8f2c 100644 --- a/LadybugTools_oM/MetaData/PlotInformation.cs +++ b/LadybugTools_oM/MetaData/PlotInformation.cs @@ -1,4 +1,26 @@ -using BH.oM.Base; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base; using System; using System.Collections.Generic; using System.Text; diff --git a/LadybugTools_oM/MetaData/SunData.cs b/LadybugTools_oM/MetaData/SunData.cs index 9fbfe6fc..76d5b25b 100644 --- a/LadybugTools_oM/MetaData/SunData.cs +++ b/LadybugTools_oM/MetaData/SunData.cs @@ -1,4 +1,26 @@ -using System; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; using System.Collections.Generic; using System.Text; diff --git a/LadybugTools_oM/MetaData/SunPathData.cs b/LadybugTools_oM/MetaData/SunPathData.cs index 5006eb46..dd3bcf05 100644 --- a/LadybugTools_oM/MetaData/SunPathData.cs +++ b/LadybugTools_oM/MetaData/SunPathData.cs @@ -1,4 +1,26 @@ -using System; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; using System.Collections.Generic; using System.Text; diff --git a/LadybugTools_oM/MetaData/UTCIData.cs b/LadybugTools_oM/MetaData/UTCIData.cs index 839ff1b4..e31317e3 100644 --- a/LadybugTools_oM/MetaData/UTCIData.cs +++ b/LadybugTools_oM/MetaData/UTCIData.cs @@ -1,4 +1,26 @@ -using System; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; using System.Collections.Generic; using System.Text; diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs index 458c3a2a..b3739565 100644 --- a/LadybugTools_oM/MetaData/WindroseData.cs +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -1,4 +1,26 @@ -using System; +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2024, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; using System.Collections.Generic; using System.Linq; using System.Text; From 42fa73be4975f53a7add1f786401cee78d59d1d1 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 15:00:13 +0100 Subject: [PATCH 10/31] fixed versioning --- LadybugTools_Engine/Versioning_73.json | 7 +++++++ LadybugTools_oM/MetaData/CollectionData.cs | 2 ++ LadybugTools_oM/MetaData/PlotInformation.cs | 2 ++ LadybugTools_oM/MetaData/SunData.cs | 2 ++ LadybugTools_oM/MetaData/SunPathData.cs | 2 ++ LadybugTools_oM/MetaData/WindroseData.cs | 2 ++ 6 files changed, 17 insertions(+) create mode 100644 LadybugTools_Engine/Versioning_73.json diff --git a/LadybugTools_Engine/Versioning_73.json b/LadybugTools_Engine/Versioning_73.json new file mode 100644 index 00000000..3e95d7dc --- /dev/null +++ b/LadybugTools_Engine/Versioning_73.json @@ -0,0 +1,7 @@ +{ + "Namespace": { + "ToNew": { + "BH.Engine.LadyBugTools": "BH.Engine.LadybugTools" + } + } +} \ No newline at end of file diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs index 23a8bcaa..d2ec2033 100644 --- a/LadybugTools_oM/MetaData/CollectionData.cs +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -20,6 +20,7 @@ * along with this code. If not, see . */ +using BH.oM.Base.Attributes; using System; using System.Collections.Generic; using System.Linq; @@ -27,6 +28,7 @@ namespace BH.oM.LadybugTools { + [NoAutoConstructor] public class CollectionData : ISimulationData { public virtual double HighestValue { get; set; } = double.NaN; diff --git a/LadybugTools_oM/MetaData/PlotInformation.cs b/LadybugTools_oM/MetaData/PlotInformation.cs index 063b8f2c..a610acf0 100644 --- a/LadybugTools_oM/MetaData/PlotInformation.cs +++ b/LadybugTools_oM/MetaData/PlotInformation.cs @@ -21,12 +21,14 @@ */ using BH.oM.Base; +using BH.oM.Base.Attributes; using System; using System.Collections.Generic; using System.Text; namespace BH.oM.LadybugTools { + [NoAutoConstructor] public class PlotInformation : BHoMObject { public virtual string Image { get; set; } = ""; diff --git a/LadybugTools_oM/MetaData/SunData.cs b/LadybugTools_oM/MetaData/SunData.cs index 76d5b25b..81d2da87 100644 --- a/LadybugTools_oM/MetaData/SunData.cs +++ b/LadybugTools_oM/MetaData/SunData.cs @@ -20,12 +20,14 @@ * along with this code. If not, see . */ +using BH.oM.Base.Attributes; using System; using System.Collections.Generic; using System.Text; namespace BH.oM.LadybugTools { + [NoAutoConstructor] public class SunData { public virtual double SunriseAzimuth { get; set; } = double.NaN; diff --git a/LadybugTools_oM/MetaData/SunPathData.cs b/LadybugTools_oM/MetaData/SunPathData.cs index dd3bcf05..77e8eb08 100644 --- a/LadybugTools_oM/MetaData/SunPathData.cs +++ b/LadybugTools_oM/MetaData/SunPathData.cs @@ -20,12 +20,14 @@ * along with this code. If not, see . */ +using BH.oM.Base.Attributes; using System; using System.Collections.Generic; using System.Text; namespace BH.oM.LadybugTools { + [NoAutoConstructor] public class SunPathData : ISimulationData { public virtual SunData DecemberSolstice { get; set; } = new SunData(); diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs index b3739565..44e649a9 100644 --- a/LadybugTools_oM/MetaData/WindroseData.cs +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -20,6 +20,7 @@ * along with this code. If not, see . */ +using BH.oM.Base.Attributes; using System; using System.Collections.Generic; using System.Linq; @@ -27,6 +28,7 @@ namespace BH.oM.LadybugTools { + [NoAutoConstructor] public class WindroseData : ISimulationData { public virtual List PrevailingDirection { get; set; } = Enumerable.Repeat(double.NaN, 2).ToList(); From 20d4f212ae1fc682e604bfcdd653376616ed74c4 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 15:25:11 +0100 Subject: [PATCH 11/31] fix versioning better --- LadybugTools_Engine/Versioning_73.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/LadybugTools_Engine/Versioning_73.json b/LadybugTools_Engine/Versioning_73.json index 3e95d7dc..5e3afabc 100644 --- a/LadybugTools_Engine/Versioning_73.json +++ b/LadybugTools_Engine/Versioning_73.json @@ -1,7 +1,13 @@ { - "Namespace": { + "Method": { "ToNew": { - "BH.Engine.LadyBugTools": "BH.Engine.LadybugTools" + "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)": "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)", + "BH.Engine.LadyBugTools.FromHexCode(System.String)": "BH.Engine.LadybugTools.FromHexCode(System.String)" + }, + "ToOld": { + "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)": "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)", + "BH.Engine.LadybugTools.FromHexCode(System.String)": "BH.Engine.LadyBugTools.FromHexCode(System.String)" } + } } \ No newline at end of file From f018a37dfeeb6934ae17c9d8cb1070563b9f9c3f Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 15:47:14 +0100 Subject: [PATCH 12/31] versioning --- LadybugTools_Engine/Versioning_73.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LadybugTools_Engine/Versioning_73.json b/LadybugTools_Engine/Versioning_73.json index 5e3afabc..ee390653 100644 --- a/LadybugTools_Engine/Versioning_73.json +++ b/LadybugTools_Engine/Versioning_73.json @@ -1,13 +1,13 @@ { + "Namespace": { + "ToNew": { + "BH.Engine.LadyBugTools": "BH.Engine.LadybugTools" + } + }, "Method": { "ToNew": { "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)": "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)", - "BH.Engine.LadyBugTools.FromHexCode(System.String)": "BH.Engine.LadybugTools.FromHexCode(System.String)" - }, - "ToOld": { - "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)": "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)", - "BH.Engine.LadybugTools.FromHexCode(System.String)": "BH.Engine.LadyBugTools.FromHexCode(System.String)" + "BH.Engine.LadyBugTools.FromHexCode(System.String)": "BH.Engine.LadybugTools.FromHexCode(System.String)" } - } } \ No newline at end of file From 7dec7269f32cf38e25849bf8a1470670b1a37d65 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 16:20:30 +0100 Subject: [PATCH 13/31] try versioning again --- LadybugTools_Engine/Convert/HexCode.cs | 2 ++ LadybugTools_Engine/Versioning_73.json | 13 ------------- 2 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 LadybugTools_Engine/Versioning_73.json diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index 166e7981..d950bed8 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -37,6 +37,7 @@ public static partial class Convert [Description("Converts a colour to its respective RGB hexadecimal code (eg. white => #ffffff).")] [Input("colour", "The colour to convert into a hex code.")] [Output("hex", "The corresponding hex code.")] + [PreviousVersion("7.3", "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)")] public static string ToHexCode(this Color colour) { return $"#{colour.R.ToString("X2")}{colour.G.ToString("X2")}{colour.B.ToString("X2")}"; @@ -47,6 +48,7 @@ public static string ToHexCode(this Color colour) [Description("Converts a string that is in the RGB hexadecimal format into a colour. (eg. #ffffff => white).")] [Input("hex", "The hexadecimal representation of a colour.")] [Output("colour", "The corresponding colour.")] + [PreviousVersion("7.3", "BH.Engine.LadybugTools.FromHexCode(System.String)")] public static Color? FromHexCode(this string hex) { if (hex.IsNullOrEmpty()) diff --git a/LadybugTools_Engine/Versioning_73.json b/LadybugTools_Engine/Versioning_73.json deleted file mode 100644 index ee390653..00000000 --- a/LadybugTools_Engine/Versioning_73.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Namespace": { - "ToNew": { - "BH.Engine.LadyBugTools": "BH.Engine.LadybugTools" - } - }, - "Method": { - "ToNew": { - "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)": "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)", - "BH.Engine.LadyBugTools.FromHexCode(System.String)": "BH.Engine.LadybugTools.FromHexCode(System.String)" - } - } -} \ No newline at end of file From f1bb964a22a1c21b4914c90e529542a1181bbd26 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 10 Jul 2024 16:44:08 +0100 Subject: [PATCH 14/31] versioning morer --- LadybugTools_Engine/Convert/HexCode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index d950bed8..e9e9b4e3 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -37,7 +37,7 @@ public static partial class Convert [Description("Converts a colour to its respective RGB hexadecimal code (eg. white => #ffffff).")] [Input("colour", "The colour to convert into a hex code.")] [Output("hex", "The corresponding hex code.")] - [PreviousVersion("7.3", "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)")] + [PreviousVersion("7.2", "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)")] public static string ToHexCode(this Color colour) { return $"#{colour.R.ToString("X2")}{colour.G.ToString("X2")}{colour.B.ToString("X2")}"; @@ -48,7 +48,7 @@ public static string ToHexCode(this Color colour) [Description("Converts a string that is in the RGB hexadecimal format into a colour. (eg. #ffffff => white).")] [Input("hex", "The hexadecimal representation of a colour.")] [Output("colour", "The corresponding colour.")] - [PreviousVersion("7.3", "BH.Engine.LadybugTools.FromHexCode(System.String)")] + [PreviousVersion("7.2", "BH.Engine.LadybugTools.FromHexCode(System.String)")] public static Color? FromHexCode(this string hex) { if (hex.IsNullOrEmpty()) From d4a6a0067f3b23fb74e127587291fc1347c65f6d Mon Sep 17 00:00:00 2001 From: Fraser Greenroyd Date: Wed, 10 Jul 2024 19:05:48 +0100 Subject: [PATCH 15/31] Update LadybugTools_Engine/Convert/HexCode.cs --- LadybugTools_Engine/Convert/HexCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index e9e9b4e3..5f7cc4d0 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -37,7 +37,7 @@ public static partial class Convert [Description("Converts a colour to its respective RGB hexadecimal code (eg. white => #ffffff).")] [Input("colour", "The colour to convert into a hex code.")] [Output("hex", "The corresponding hex code.")] - [PreviousVersion("7.2", "BH.Engine.LadyBugTools.ToHexCode(System.Drawing.Color)")] + [PreviousVersion("7.2", "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)")] public static string ToHexCode(this Color colour) { return $"#{colour.R.ToString("X2")}{colour.G.ToString("X2")}{colour.B.ToString("X2")}"; From e7a4b1b8db7e06f6c54dd59e1ff7df0d7a1593fc Mon Sep 17 00:00:00 2001 From: Fraser Greenroyd Date: Wed, 10 Jul 2024 19:06:55 +0100 Subject: [PATCH 16/31] Update LadybugTools_Engine/Convert/HexCode.cs --- LadybugTools_Engine/Convert/HexCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index 5f7cc4d0..c4cc5538 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -37,7 +37,7 @@ public static partial class Convert [Description("Converts a colour to its respective RGB hexadecimal code (eg. white => #ffffff).")] [Input("colour", "The colour to convert into a hex code.")] [Output("hex", "The corresponding hex code.")] - [PreviousVersion("7.2", "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)")] + [PreviousVersion("7.3", "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)")] public static string ToHexCode(this Color colour) { return $"#{colour.R.ToString("X2")}{colour.G.ToString("X2")}{colour.B.ToString("X2")}"; From f301bd8dcaaa0287a6e896a43f7f50514520fea2 Mon Sep 17 00:00:00 2001 From: Fraser Greenroyd Date: Wed, 10 Jul 2024 19:07:02 +0100 Subject: [PATCH 17/31] Update LadybugTools_Engine/Convert/HexCode.cs --- LadybugTools_Engine/Convert/HexCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index c4cc5538..80de4342 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -48,7 +48,7 @@ public static string ToHexCode(this Color colour) [Description("Converts a string that is in the RGB hexadecimal format into a colour. (eg. #ffffff => white).")] [Input("hex", "The hexadecimal representation of a colour.")] [Output("colour", "The corresponding colour.")] - [PreviousVersion("7.2", "BH.Engine.LadybugTools.FromHexCode(System.String)")] + [PreviousVersion("7.3", "BH.Engine.LadybugTools.FromHexCode(System.String)")] public static Color? FromHexCode(this string hex) { if (hex.IsNullOrEmpty()) From f93ef1df1a61b258f73923e75df9eba15b4bd1ff Mon Sep 17 00:00:00 2001 From: Fraser Greenroyd Date: Wed, 10 Jul 2024 19:19:39 +0100 Subject: [PATCH 18/31] Update LadybugTools_Engine/Convert/HexCode.cs --- LadybugTools_Engine/Convert/HexCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index 80de4342..4dfabbb9 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -37,7 +37,7 @@ public static partial class Convert [Description("Converts a colour to its respective RGB hexadecimal code (eg. white => #ffffff).")] [Input("colour", "The colour to convert into a hex code.")] [Output("hex", "The corresponding hex code.")] - [PreviousVersion("7.3", "BH.Engine.LadybugTools.ToHexCode(System.Drawing.Color)")] + [PreviousVersion("7.3", "BH.Engine.LadybugTools.Convert.ToHexCode(System.Drawing.Color)")] public static string ToHexCode(this Color colour) { return $"#{colour.R.ToString("X2")}{colour.G.ToString("X2")}{colour.B.ToString("X2")}"; From d4780d3bfdd6b71f8d1623bda05bb9b25d10f3a4 Mon Sep 17 00:00:00 2001 From: Fraser Greenroyd Date: Wed, 10 Jul 2024 19:19:45 +0100 Subject: [PATCH 19/31] Update LadybugTools_Engine/Convert/HexCode.cs --- LadybugTools_Engine/Convert/HexCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index 4dfabbb9..50388657 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -48,7 +48,7 @@ public static string ToHexCode(this Color colour) [Description("Converts a string that is in the RGB hexadecimal format into a colour. (eg. #ffffff => white).")] [Input("hex", "The hexadecimal representation of a colour.")] [Output("colour", "The corresponding colour.")] - [PreviousVersion("7.3", "BH.Engine.LadybugTools.FromHexCode(System.String)")] + [PreviousVersion("7.3", "BH.Engine.LadybugTools.Convert.FromHexCode(System.String)")] public static Color? FromHexCode(this string hex) { if (hex.IsNullOrEmpty()) From f46d01ba80a98ab6b8998357af389474950891a9 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Thu, 11 Jul 2024 14:04:02 +0100 Subject: [PATCH 20/31] final try on versioning before going over to versioning toolkit --- LadybugTools_Engine/Convert/HexCode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LadybugTools_Engine/Convert/HexCode.cs b/LadybugTools_Engine/Convert/HexCode.cs index 50388657..f2b65e0c 100644 --- a/LadybugTools_Engine/Convert/HexCode.cs +++ b/LadybugTools_Engine/Convert/HexCode.cs @@ -37,7 +37,7 @@ public static partial class Convert [Description("Converts a colour to its respective RGB hexadecimal code (eg. white => #ffffff).")] [Input("colour", "The colour to convert into a hex code.")] [Output("hex", "The corresponding hex code.")] - [PreviousVersion("7.3", "BH.Engine.LadybugTools.Convert.ToHexCode(System.Drawing.Color)")] + [PreviousVersion("7.3", "BH.Engine.LadyBugTools.Convert.ToHexCode(System.Drawing.Color)")] public static string ToHexCode(this Color colour) { return $"#{colour.R.ToString("X2")}{colour.G.ToString("X2")}{colour.B.ToString("X2")}"; @@ -48,7 +48,7 @@ public static string ToHexCode(this Color colour) [Description("Converts a string that is in the RGB hexadecimal format into a colour. (eg. #ffffff => white).")] [Input("hex", "The hexadecimal representation of a colour.")] [Output("colour", "The corresponding colour.")] - [PreviousVersion("7.3", "BH.Engine.LadybugTools.Convert.FromHexCode(System.String)")] + [PreviousVersion("7.3", "BH.Engine.LadyBugTools.Convert.FromHexCode(System.String)")] public static Color? FromHexCode(this string hex) { if (hex.IsNullOrEmpty()) From ec77fdb92194c78cff42d658a75df0bd669597ed Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Mon, 15 Jul 2024 10:32:43 +0100 Subject: [PATCH 21/31] added noautoconstructor to UTCIData, and updated docstrings for added python methods --- .../ladybug_extension/sunpath.py | 10 ++++---- .../Python/src/ladybugtools_toolkit/wind.py | 23 +++++++++++++++++++ LadybugTools_oM/MetaData/UTCIData.cs | 2 ++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py index aa6cbc33..8de13bd3 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -7,18 +7,18 @@ @bhom_analytics() def sunpath_metadata(sunpath: Sunpath) -> dict: - """Return a dictionary containing equinox and solstice altitudes at sunrise, noon and sunset for the given location + """Return a dictionary containing equinox and solstice altitudes at sunrise, noon and sunset for the given sunpath. Args: - location (Location): - A Ladybug location object. + sunpath (Sunpath): + A Ladybug sunpath object. Returns: dict: - A dictionary containing the altitudes in the following structure: + A dictionary containing the azimuths and altitudes in the following structure: { - 'december_solstice': {'sunrise': , 'noon': altitude, 'sunset': altitude}, + 'december_solstice': {'sunrise': azimuth, 'noon': altitude, 'sunset': azimuth}, 'march_equinox': {...}, 'june_solstice': {...}, 'september_equinox': {...} diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py index f1a37b61..95fec9fc 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py @@ -1514,6 +1514,29 @@ def summarise(self, directions: int = 36) -> list[str]: # pylint: enable=line-too-long def wind_metadata(self, directions: int=36, ignore_calm: bool=True, threshold: float = 1e-10) -> dict: + """Provides a dictionary containing metadata of this wind object. + + Args: + directions (int, optional): + The number of directions to use. Defaults to 36. + ignore_calm (bool, optional): + Whether or not to ignore wind speed values before the threshold, allowing a more accurate prevailing direction and quantile wind speeds. Defaults to True + threshold (float, optional): + The threshold to use for calm wind speeds. Defaults to 1e-10. + + Returns: + dict: + The resultant metadata dictionary, which has the following structure: + { + "95percentile": 95 percentile wind speed, + "50percentile": 50 percentile wind speed, + "calm_percent": the proportion of calm hours (not affected by ignore_calm bool), + "prevailing_direction": direction of prevailing wind, + "prevailing_95percentile": prevailing 95 percentile wind speed, + "prevailing_50percentile": prevailing 50 percentile wind speed + } + + """ prevailing_direction = self.prevailing(directions=directions, ignore_calm=ignore_calm, threshold=threshold)[0] _, bins = self.process_direction_data(directions=directions) diff --git a/LadybugTools_oM/MetaData/UTCIData.cs b/LadybugTools_oM/MetaData/UTCIData.cs index e31317e3..1b2d9098 100644 --- a/LadybugTools_oM/MetaData/UTCIData.cs +++ b/LadybugTools_oM/MetaData/UTCIData.cs @@ -20,12 +20,14 @@ * along with this code. If not, see . */ +using BH.oM.Base.Attributes; using System; using System.Collections.Generic; using System.Text; namespace BH.oM.LadybugTools { + [NoAutoConstructor] public class UTCIData : ISimulationData { public virtual double ComfortableRatio { get; set; } = double.NaN; From 19ae9c626d20ea69b1288947263c9624d4049cf2 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 17 Jul 2024 11:16:24 +0100 Subject: [PATCH 22/31] moved collection_metadata to bhom/wrapped, and added method that gets montly diurnal ranges --- .../bhom/wrapped/collection.py | 59 +++++++++++++++++++ .../bhom/wrapped/plot/diurnal.py | 5 +- .../ladybug_extension/datacollection.py | 55 ++++------------- 3 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/collection.py diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/collection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/collection.py new file mode 100644 index 00000000..9a923e20 --- /dev/null +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/collection.py @@ -0,0 +1,59 @@ +from ladybug.datacollection import BaseCollection +from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series + +def collection_metadata(collection: BaseCollection) -> dict: + """Returns a dictionary containing useful metadata about the series. + + Args: + collection (BaseCollection): + ladybug data collection object + + Returns: + dict: + A dictionary containing metadata about the collection, structured: + { + "lowest": lowest, + "lowest_index": lowest_index, + "highest": highest, + "highest_index": highest_index, + "median": median, + "mean": mean, + "month_means": [month_means], + "month_diurnal_ranges": [month_diurnal_ranges], + } + where month_means is a list of means indexed by month, and month_ranges is a list of diurnal month ranges as tuples: (min, max). + """ + + series = collection_to_series(collection) + lowest = series.min() + highest = series.max() + lowest_index = series.idxmin() + highest_index = series.idxmax() + median = series.quantile(0.5) + mean = series.mean() + + series_diurnal_mean = series.groupby([series.index.month, series.index.hour]).mean() + series_diurnal_max = series_diurnal_mean.groupby( + series_diurnal_mean.index.get_level_values(0) + ).max() + series_diurnal_min = series_diurnal_mean.groupby( + series_diurnal_mean.index.get_level_values(0) + ).min() + + month_means = [] + month_ranges = [] + for month in range(12): + month_series = series[series.index.month == month + 1] + month_means.append(month_series.mean()) + month_ranges.append((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) + + return { + "lowest": lowest, + "lowest_index": lowest_index, + "highest": highest, + "highest_index": highest_index, + "median": median, + "mean": mean, + "month_means": month_means, + "month_diurnal_ranges": month_ranges, + } \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py index 548b3575..7bea87d5 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py @@ -8,16 +8,17 @@ def diurnal(epw_file, return_file: str, data_type_key="Dry Bulb Temperature", color="#000000", title=None, period="monthly", save_path = None): try: from ladybug.epw import EPW, AnalysisPeriod - from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series, collection_metadata + from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series from ladybugtools_toolkit.plot._diurnal import diurnal from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot.utilities import figure_to_base64 + from ladybugtools_toolkit.bhom.wrapped.collection import collection_metadata import matplotlib.pyplot as plt epw = EPW(epw_file) data_type_key = data_type_key.replace("_"," ") coll = HourlyContinuousCollection.from_dict([a for a in epw.to_dict()["data_collections"] if a["header"]["data_type"]["name"] == data_type_key][0]) - fig = diurnal(collection_to_series(coll),title=title, period=period, color=color).get_figure() + fig = diurnal(collection_to_series(coll), title=title, period=period, color=color).get_figure() return_dict = {"data": collection_metadata(coll)} diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py index c1465595..ed543a9a 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py @@ -355,64 +355,29 @@ def summarise_collection( @bhom_analytics() -def collection_metadata(collection: BaseCollection) -> dict: - """Returns a dictionary containing useful metadata about the series. +def monthly_diurnal_ranges(collection: BaseCollection) -> list[(float, float)]: + """Returns a list of diurnal ranges for each month Args: collection (BaseCollection): ladybug data collection object - + Returns: - dict: - A dictionary containing metadata about the collection, structured: - { - "lowest": lowest, - "lowest_index": lowest_index, - "highest": highest, - "highest_index": highest_index, - "median": median, - "mean": mean, - "month_means": [month_means], - "month_diurnal_ranges": [month_diurnal_ranges], - } - where month_means is a list of means indexed by month, and month_ranges is a list of diurnal month ranges as tuples: (min, max). + list[(float, float)]: + a list of diurnal ranges for each month as tuples (min, max) """ series = collection_to_series(collection) - lowest = series.min() - highest = series.max() - lowest_index = series.idxmin() - highest_index = series.idxmax() - median = series.quantile(0.5) - mean = series.mean() - series_diurnal_mean = series.groupby([series.index.month, series.index.hour]).mean() - series_diurnal_max = series_diurnal_mean.groupby( - series_diurnal_mean.index.get_level_values(0) - ).max() - series_diurnal_min = series_diurnal_mean.groupby( - series_diurnal_mean.index.get_level_values(0) - ).min() - - month_means = [] + series_diurnal_min = series_diurnal_mean.groupby(series_diurnal_mean.index.get_level_values(0)).min() + series_diurnal_max = series_diurnal_mean.groupby(series_diurnal_mean.index.get_level_values(0)).max() month_ranges = [] + for month in range(12): - month_series = series[series.index.month == month + 1] - month_means.append(month_series.mean()) month_ranges.append((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) - return { - "lowest": lowest, - "lowest_index": lowest_index, - "highest": highest, - "highest_index": highest_index, - "median": median, - "mean": mean, - "month_means": month_means, - "month_diurnal_ranges": month_ranges, - } - - + return month_ranges + @bhom_analytics() def average( From 0c19bcbbaa192c31e84022d4b1635cc0cb3555f8 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 17 Jul 2024 12:23:12 +0100 Subject: [PATCH 23/31] moved wind metadata to bhom/wrapped and added method that gets the prevailing directions and wind speeds --- .../bhom/wrapped/plot/windrose.py | 5 +- .../bhom/wrapped/wind_metadata.py | 41 ++++++++++++ .../Python/src/ladybugtools_toolkit/wind.py | 62 +++++++------------ 3 files changed, 64 insertions(+), 44 deletions(-) create mode 100644 LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/wind_metadata.py diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py index 909fa702..44232790 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py @@ -11,6 +11,7 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, re from ladybug.epw import EPW, AnalysisPeriod from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.wind import Wind + from ladybugtools_toolkit.bhom.wrapped.wind_metadata import wind_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt from pathlib import Path @@ -29,9 +30,7 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, re w_epw.filter_by_analysis_period(analysis_period=analysis_period).plot_windrose(ax=ax, directions=bins, ylim=(0, 3.6/bins), colors=colour_map) - description = wind_filtered.wind_metadata(bins) - - output_dict = {"data": description} + output_dict = {"data": wind_metadata(wind_filtered, directions=bins)} plt.tight_layout() if save_path == None or save_path == "": diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/wind_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/wind_metadata.py new file mode 100644 index 00000000..e94121dd --- /dev/null +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/wind_metadata.py @@ -0,0 +1,41 @@ +from ladybugtools_toolkit.wind import Wind + +def wind_metadata(wind_object: Wind, directions: int=36, ignore_calm: bool=True, threshold: float = 1e-10) -> dict: + """Provides a dictionary containing metadata of this wind object. + + Args: + directions (int, optional): + The number of directions to use. Defaults to 36. + ignore_calm (bool, optional): + Whether or not to ignore wind speed values before the threshold, allowing a more accurate prevailing direction and quantile wind speeds. Defaults to True + threshold (float, optional): + The threshold to use for calm wind speeds. Defaults to 1e-10. + + Returns: + dict: + The resultant metadata dictionary, which has the following structure: + { + "95percentile": 95 percentile wind speed, + "50percentile": 50 percentile wind speed, + "calm_percent": the proportion of calm hours (not affected by ignore_calm bool), + "prevailing_direction": direction of prevailing wind, + "prevailing_95percentile": prevailing 95 percentile wind speed, + "prevailing_50percentile": prevailing 50 percentile wind speed + } + + """ + ws = wind_object.ws + + prevailing_wind_speeds, prevailing_directions = wind_object.prevailing_wind_speeds(n=1, directions=directions, ignore_calm=ignore_calm, threshold=threshold) + + prevailing_wind_speed = prevailing_wind_speeds[0] + prevailing_direction = prevailing_directions[0] + + return { + "95percentile": ws.quantile(0.95), + "50percentile": ws.quantile(0.50), + "calm_percent": wind_object.calm(), + "prevailing_direction": prevailing_direction, + "prevailing_95percentile": prevailing_wind_speeds.quantile(0.95), + "prevailing_50percentile": prevailing_wind_speeds.quantile(0.5) + } \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py index 95fec9fc..4dd30125 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/wind.py @@ -1513,52 +1513,32 @@ def summarise(self, directions: int = 36) -> list[str]: return return_strings # pylint: enable=line-too-long - def wind_metadata(self, directions: int=36, ignore_calm: bool=True, threshold: float = 1e-10) -> dict: - """Provides a dictionary containing metadata of this wind object. - + def prevailing_wind_speeds(self, n: int=1, directions: int=36, ignore_calm: bool=True, threshold: float=1e-10) -> tuple[list[pd.Series], list[tuple[float, float]]]: + """Gets the wind speeds for the prevailing directions + Args: - directions (int, optional): - The number of directions to use. Defaults to 36. - ignore_calm (bool, optional): - Whether or not to ignore wind speed values before the threshold, allowing a more accurate prevailing direction and quantile wind speeds. Defaults to True - threshold (float, optional): - The threshold to use for calm wind speeds. Defaults to 1e-10. - - Returns: - dict: - The resultant metadata dictionary, which has the following structure: - { - "95percentile": 95 percentile wind speed, - "50percentile": 50 percentile wind speed, - "calm_percent": the proportion of calm hours (not affected by ignore_calm bool), - "prevailing_direction": direction of prevailing wind, - "prevailing_95percentile": prevailing 95 percentile wind speed, - "prevailing_50percentile": prevailing 50 percentile wind speed - } + n (int): + Number of prevailing directions to return. Defaults to 1 + + directions (int): + Number of direction bins to use when calculating the prevailing directions. Defaults to 36 + + ignore_calm (bool): + Whether to ignore calm hours when getting the prevailing directions. Defaults to True - """ - prevailing_direction = self.prevailing(directions=directions, ignore_calm=ignore_calm, threshold=threshold)[0] + threshold (float): + The threshold for calm hours. Defaults to 1e-10 - _, bins = self.process_direction_data(directions=directions) - - direction_bin = [d_bin for d_bin in bins if d_bin == prevailing_direction][0] - - prevailing_wind_speeds = self.ws.loc[self.bin_data(directions=directions)["Wind Direction (degrees)"] == direction_bin] + Returns: + (list[pandas.Series], list[(float, float)]): + Tuple containing a list of time-indexed series containing wind speed data for each prevailing direction, from most to least prevailing, + and a list of wind directions corresponding to the serieses. + """ + prevailing_directions = self.prevailing(n=n, directions=directions, ignore_calm=ignore_calm, threshold=threshold) - ws = self.ws + prevailing_wind_speeds = [self.ws.loc[self.bin_data(directions=directions)["Wind Direction (degrees)"] == direction] for direction in prevailing_directions] - if ignore_calm: - prevailing_wind_speeds = prevailing_wind_speeds.loc[prevailing_wind_speeds > threshold] - ws = self.ws.loc[self.ws > threshold] - - return { - "95percentile": ws.quantile(0.95), - "50percentile": ws.quantile(0.50), - "calm_percent": self.calm(), - "prevailing_direction": prevailing_direction, - "prevailing_95percentile": prevailing_wind_speeds.quantile(0.95), - "prevailing_50percentile": prevailing_wind_speeds.quantile(0.5) - } + return (prevailing_wind_speeds, prevailing_directions) def weibull_pdf(self) -> tuple[float]: From ca70a3df81463c3e9b8239e8c149f2a22aa3051f Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 17 Jul 2024 13:21:52 +0100 Subject: [PATCH 24/31] moved metadata for all other plots to bhom/wrapped and changed sunpath method to get the sunrise, sunset and noon times, azimuths and altitudes --- .../bhom/wrapped/plot/heatmap.py | 3 +- .../bhom/wrapped/plot/sunpath.py | 2 +- .../bhom/wrapped/plot/utci_heatmap.py | 2 +- .../bhom/wrapped/plot/windrose.py | 1 - .../bhom/wrapped/sunpath_metadata.py | 34 ++++++++++ .../bhom/wrapped/utci_metadata.py | 63 +++++++++++++++++++ .../external_comfort/utci.py | 60 ------------------ .../ladybug_extension/sunpath.py | 50 ++++++--------- 8 files changed, 121 insertions(+), 94 deletions(-) create mode 100644 LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/sunpath_metadata.py create mode 100644 LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/utci_metadata.py diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py index ec5cd4b9..254ac2ed 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py @@ -12,7 +12,8 @@ def heatmap(epw_file: str, data_type_key: str, colour_map: str, return_file: str from ladybug.epw import EPW from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot._heatmap import heatmap - from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series, collection_metadata + from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series + from ladybugtools_toolkit.bhom.wrapped.collection import collection_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py index d0330c21..c8ed81b8 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py @@ -10,7 +10,7 @@ def sun_path(epw_file, analysis_period, size, return_file: str, save_path): from ladybug.epw import EPW, AnalysisPeriod from ladybug.datacollection import HourlyContinuousCollection from ladybug.sunpath import Sunpath - from ladybugtools_toolkit.ladybug_extension.sunpath import sunpath_metadata + from ladybugtools_toolkit.bhom.wrapped.sunpath_metadata import sunpath_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt from pathlib import Path diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py index 0c18d6e5..4177a8bd 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py @@ -16,7 +16,7 @@ def utci_heatmap(epw_file:str, from ladybugtools_toolkit.external_comfort._typologybase import Typology from ladybugtools_toolkit.external_comfort.simulate import SimulationResult from ladybugtools_toolkit.external_comfort.externalcomfort import ExternalComfort - from ladybugtools_toolkit.external_comfort.utci import utci_metadata + from ladybugtools_toolkit.bhom.wrapped.utci_metadata import utci_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 from ladybugtools_toolkit.categorical.categories import Categorical, UTCI_DEFAULT_CATEGORIES from honeybee_energy.dictutil import dict_to_material diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py index 44232790..fa22d4fa 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py @@ -48,7 +48,6 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, re print(e) - if __name__ == "__main__": parser = argparse.ArgumentParser( description=( diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/sunpath_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/sunpath_metadata.py new file mode 100644 index 00000000..a44a7c9a --- /dev/null +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/sunpath_metadata.py @@ -0,0 +1,34 @@ +from ladybug.sunpath import Sunpath +from ladybugtools_toolkit.ladybug_extension.sunpath import sunrise_sunset_azimuths +from datetime import datetime + +def sunpath_metadata(sunpath: Sunpath) -> dict: + """Return a dictionary containing equinox and solstice azimuths and altitudes at sunrise, noon and sunset for the given sunpath. + + Args: + sunpath (Sunpath): + A Ladybug sunpath object. + + Returns: + dict: + A dictionary containing the azimuths and altitudes in the following structure: + + { + 'december_solstice': {'sunrise': azimuth, 'noon': altitude, 'sunset': azimuth}, + 'march_equinox': {...}, + 'june_solstice': {...}, + 'september_equinox': {...} + } + """ + + december_solstice = sunrise_sunset_azimuths(sunpath, 2023, 12, 22) + march_equinox = sunrise_sunset_azimuths(sunpath, 2023, 3, 20) + june_solstice = sunrise_sunset_azimuths(sunpath, 2023, 6, 21) + september_equinox = sunrise_sunset_azimuths(sunpath, 2023, 9, 22) + + return { + "december_solstice": december_solstice, + "march_equinox": march_equinox, + "june_solstice": june_solstice, + "september_equinox": september_equinox + } \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/utci_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/utci_metadata.py new file mode 100644 index 00000000..a537e56b --- /dev/null +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/utci_metadata.py @@ -0,0 +1,63 @@ +from ladybug.datacollection import HourlyContinuousCollection +from ladybug.datatype.temperature import ( + UniversalThermalClimateIndex as LB_UniversalThermalClimateIndex, +) +from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series + +def utci_metadata(utci_collection: HourlyContinuousCollection, comfort_lower: float = 9, comfort_higher: float = 26, use_start_hour: int=7, use_end_hour: int=23) -> dict: + """Returns a dictionary of useful metadata for the given collection dependant on the given comfortable range. + + Args: + utci_collection (HourlyContinuousCollection): + utci headered ladybug hourly collection + + comfort_lower (float): + lower value for the comfortable temperature range, where temperatures exclusively below this are too cold. + + comfort_higher (float): + higher value for the comfortable temperature range, where temperatures above and equal to this are too hot. + + use_start_hour (int): + start hour to filter usage time, inclusive + + use_end_hour (int): + end hour to filter usage time, exclusive + + Returns: + dict: + dictionary containing comfortable, hot and cold ratios, structured as follows: + { + 'comfortable_ratio': ratio_of_comfortable_hours, + 'hot_ratio': ratio_of_hot_hours, + 'cold_ratio': ratio_of_cold_hours, + 'daytime_comfortable': daytime_comfortable_ratio, + 'daytime_hot': daytime_hot_ratio, + 'daytime_cold': daytime_cold_ratio + } + """ + if not isinstance(utci_collection.header.data_type, LB_UniversalThermalClimateIndex): + raise ValueError("Input collection is not a UTCI collection.") + + if not comfort_lower < comfort_higher: + raise ValueError(f"The lower comfort temperature {comfort_lower}, must be less than the higher comfort temperature {comfort_higher}.") + + series = collection_to_series(utci_collection) + + daytime = series.loc[(series.index.hour >= use_start_hour) & (series.index.hour < use_end_hour)] + + comfortable_ratio = ((series >= comfort_lower) & (series < comfort_higher)).sum() / len(series) + hot_ratio = (series >= comfort_higher).sum() / len(series) + cold_ratio = (series < comfort_lower).sum() / len(series) + + day_comfortable = ((daytime >= comfort_lower) & (daytime < comfort_higher)).sum() / len(daytime) + day_hot = (daytime >= comfort_higher).sum() / len(daytime) + day_cold = (daytime < comfort_lower).sum() / len(daytime) + + return { + "comfortable_ratio": comfortable_ratio, + "hot_ratio": hot_ratio, + "cold_ratio": cold_ratio, + "daytime_comfortable": day_comfortable, + "daytime_hot": day_hot, + "daytime_cold": day_cold + } \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py index 1b984d30..cb1132d5 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py @@ -708,66 +708,6 @@ def _utci_ndarray( return utci_approx -@bhom_analytics() -def utci_metadata(utci_collection: HourlyContinuousCollection, comfort_lower: float = 9, comfort_higher: float = 26, use_start_hour: int=7, use_end_hour: int=23) -> dict: - """Returns a dictionary of useful metadata for the given collection dependant on the given comfortable range. - - Args: - utci_collection (HourlyContinuousCollection): - utci headered ladybug hourly collection - - comfort_lower (float): - lower value for the comfortable temperature range, where temperatures exclusively below this are too cold. - - comfort_higher (float): - higher value for the comfortable temperature range, where temperatures above and equal to this are too hot. - - use_start_hour (int): - start hour to filter usage time, inclusive - - use_end_hour (int): - end hour to filter usage time, exclusive - - Returns: - dict: - dictionary containing comfortable, hot and cold ratios, structured as follows: - { - 'comfortable_ratio': ratio_of_comfortable_hours, - 'hot_ratio': ratio_of_hot_hours, - 'cold_ratio': ratio_of_cold_hours, - 'daytime_comfortable': daytime_comfortable_ratio, - 'daytime_hot': daytime_hot_ratio, - 'daytime_cold': daytime_cold_ratio - } - """ - if not isinstance(utci_collection.header.data_type, LB_UniversalThermalClimateIndex): - raise ValueError("Input collection is not a UTCI collection.") - - if not comfort_lower < comfort_higher: - raise ValueError(f"The lower comfort temperature {comfort_lower}, must be less than the higher comfort temperature {comfort_higher}.") - - series = collection_to_series(utci_collection) - - daytime = series.loc[(series.index.hour >= use_start_hour) & (series.index.hour < use_end_hour)] - - comfortable_ratio = ((series >= comfort_lower) & (series < comfort_higher)).sum() / len(series) - hot_ratio = (series >= comfort_higher).sum() / len(series) - cold_ratio = (series < comfort_lower).sum() / len(series) - - day_comfortable = ((daytime >= comfort_lower) & (daytime < comfort_higher)).sum() / len(daytime) - day_hot = (daytime >= comfort_higher).sum() / len(daytime) - day_cold = (daytime < comfort_lower).sum() / len(daytime) - - return { - "comfortable_ratio": comfortable_ratio, - "hot_ratio": hot_ratio, - "cold_ratio": cold_ratio, - "daytime_comfortable": day_comfortable, - "daytime_hot": day_hot, - "daytime_cold": day_cold - } - - def _utci_collection( air_temperature: HourlyContinuousCollection, mean_radiant_temperature: HourlyContinuousCollection, diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py index 8de13bd3..327d0e92 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -5,43 +5,33 @@ import pandas as pd from datetime import datetime -@bhom_analytics() -def sunpath_metadata(sunpath: Sunpath) -> dict: - """Return a dictionary containing equinox and solstice altitudes at sunrise, noon and sunset for the given sunpath. - +@bhom_analytics +def sunrise_sunset_azimuths(sunpath: Sunpath, year: int, month: int, day: int) -> dict: + """Return a dictionary containing azimuths at sunrise and sunset, and altitude at solar noon + Args: sunpath (Sunpath): - A Ladybug sunpath object. - + a ladybug sunpath object + + month (int): + month as an int, starting at 1 and ending at 12 + + day (int): + day as an int, starting at 1, and ending at 28 through 31 depending on the month + Returns: dict: - A dictionary containing the azimuths and altitudes in the following structure: - + A dictionary containing the azimuths and altitude in the following structure: { - 'december_solstice': {'sunrise': azimuth, 'noon': altitude, 'sunset': azimuth}, - 'march_equinox': {...}, - 'june_solstice': {...}, - 'september_equinox': {...} + "sunrise": {"time": sunrise time, "azimuth": azimuth at sunrise }, + "noon": {"time": noon time, "altitude" altitude at noon }, + "sunset": {"time": sunset time, "azimuth": azimuth at sunset }, } - """ - december_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 12, 22)) - march_equinox_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 3, 20)) - june_solstice_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 6, 21)) - september_equinox_times = sunpath.calculate_sunrise_sunset_from_datetime(datetime(2023, 9, 22)) - december_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in december_solstice_times.items() } - - march_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in march_equinox_times.items() } + """ - june_solstice = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in june_solstice_times.items() } + sunrise_sunset = sunpath.calculate_sunrise_sunset_from_datetime(datetime(year=year, month=month, day=day)) - september_equinox = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in september_equinox_times.items() } + azimuths_altitude = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in sunrise_sunset.items() } - return { - "december_solstice": december_solstice, - "march_equinox": march_equinox, - "june_solstice": june_solstice, - "september_equinox": september_equinox - } - - + return azimuths_altitude \ No newline at end of file From 57a8d5010ad0e53f7424a6abf52d4e74dd651873 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Tue, 23 Jul 2024 16:29:42 +0100 Subject: [PATCH 25/31] moved metadata methods to separate folder --- .../bhom/wrapped/{ => metadata}/sunpath_metadata.py | 0 .../bhom/wrapped/{ => metadata}/utci_metadata.py | 0 .../bhom/wrapped/{ => metadata}/wind_metadata.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/{ => metadata}/sunpath_metadata.py (100%) rename LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/{ => metadata}/utci_metadata.py (100%) rename LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/{ => metadata}/wind_metadata.py (100%) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/sunpath_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/sunpath_metadata.py similarity index 100% rename from LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/sunpath_metadata.py rename to LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/sunpath_metadata.py diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/utci_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/utci_metadata.py similarity index 100% rename from LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/utci_metadata.py rename to LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/utci_metadata.py diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/wind_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/wind_metadata.py similarity index 100% rename from LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/wind_metadata.py rename to LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/wind_metadata.py From 1febd75e8646c4ac3a89bde12576cb0b300a5efa Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Mon, 29 Jul 2024 10:53:34 +0100 Subject: [PATCH 26/31] fix for #228 and update import paths --- LadybugTools_Adapter/AdapterActions/Execute.cs | 3 ++- .../bhom/wrapped/{ => metadata}/collection.py | 0 .../src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py | 2 +- .../src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py | 2 +- .../src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py | 2 +- .../src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py | 3 +-- .../src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py | 2 +- LadybugTools_Engine/Python/src/ladybugtools_toolkit/helpers.py | 2 +- .../ladybug_extension/groundtemperature.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) rename LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/{ => metadata}/collection.py (100%) diff --git a/LadybugTools_Adapter/AdapterActions/Execute.cs b/LadybugTools_Adapter/AdapterActions/Execute.cs index 6b3d9d65..fb152160 100644 --- a/LadybugTools_Adapter/AdapterActions/Execute.cs +++ b/LadybugTools_Adapter/AdapterActions/Execute.cs @@ -422,6 +422,7 @@ private List RunCommand(UTCIHeatPlotCommand command, ActionConfig action BH.Engine.Base.Compute.RecordError($"When overriding bin colours 10 colours must be provided, but {command.BinColours.Count} colours were provided instead."); return null; } + List colours = command.BinColours.Select(x => x.ToHexCode()).ToList(); string hexColours = $"[\"{string.Join("\",\"", colours)}\"]"; @@ -453,7 +454,7 @@ private List RunCommand(UTCIHeatPlotCommand command, ActionConfig action if (!File.Exists(resultFile)) { - BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + BH.Engine.Base.Compute.RecordError($"An error occurred while running the command: {result}"); File.Delete(returnFile); File.Delete(argFile); return new List(); diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/collection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/collection.py similarity index 100% rename from LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/collection.py rename to LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/collection.py diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py index 7bea87d5..4409a3c0 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/diurnal.py @@ -12,7 +12,7 @@ def diurnal(epw_file, return_file: str, data_type_key="Dry Bulb Temperature", co from ladybugtools_toolkit.plot._diurnal import diurnal from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot.utilities import figure_to_base64 - from ladybugtools_toolkit.bhom.wrapped.collection import collection_metadata + from ladybugtools_toolkit.bhom.wrapped.metadata.collection import collection_metadata import matplotlib.pyplot as plt epw = EPW(epw_file) diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py index 254ac2ed..adf74e40 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/heatmap.py @@ -13,7 +13,7 @@ def heatmap(epw_file: str, data_type_key: str, colour_map: str, return_file: str from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.plot._heatmap import heatmap from ladybugtools_toolkit.ladybug_extension.datacollection import collection_to_series - from ladybugtools_toolkit.bhom.wrapped.collection import collection_metadata + from ladybugtools_toolkit.bhom.wrapped.metadata.collection import collection_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py index c8ed81b8..43b79361 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/sunpath.py @@ -10,7 +10,7 @@ def sun_path(epw_file, analysis_period, size, return_file: str, save_path): from ladybug.epw import EPW, AnalysisPeriod from ladybug.datacollection import HourlyContinuousCollection from ladybug.sunpath import Sunpath - from ladybugtools_toolkit.bhom.wrapped.sunpath_metadata import sunpath_metadata + from ladybugtools_toolkit.bhom.wrapped.metadata.sunpath_metadata import sunpath_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt from pathlib import Path diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py index 4177a8bd..fccbc49b 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/utci_heatmap.py @@ -16,7 +16,7 @@ def utci_heatmap(epw_file:str, from ladybugtools_toolkit.external_comfort._typologybase import Typology from ladybugtools_toolkit.external_comfort.simulate import SimulationResult from ladybugtools_toolkit.external_comfort.externalcomfort import ExternalComfort - from ladybugtools_toolkit.bhom.wrapped.utci_metadata import utci_metadata + from ladybugtools_toolkit.bhom.wrapped.metadata.utci_metadata import utci_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 from ladybugtools_toolkit.categorical.categories import Categorical, UTCI_DEFAULT_CATEGORIES from honeybee_energy.dictutil import dict_to_material @@ -41,7 +41,6 @@ def utci_heatmap(epw_file:str, custom_bins = UTCI_DEFAULT_CATEGORIES bin_colours = json.loads(argsDict["bin_colours"]) - [print(a) for a in bin_colours] if len(bin_colours) == 10: custom_bins = Categorical( diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py index fa22d4fa..9834b925 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/plot/windrose.py @@ -11,7 +11,7 @@ def windrose(epw_file: str, analysis_period: str, colour_map: str, bins: int, re from ladybug.epw import EPW, AnalysisPeriod from ladybug.datacollection import HourlyContinuousCollection from ladybugtools_toolkit.wind import Wind - from ladybugtools_toolkit.bhom.wrapped.wind_metadata import wind_metadata + from ladybugtools_toolkit.bhom.wrapped.metadata.wind_metadata import wind_metadata from ladybugtools_toolkit.plot.utilities import figure_to_base64 import matplotlib.pyplot as plt from pathlib import Path diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/helpers.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/helpers.py index 430b37bb..774942f2 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/helpers.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/helpers.py @@ -350,7 +350,7 @@ def scrape_weather( df.interpolate(limit=4, inplace=True) if resample: - df = df.resample("30T").mean() + df = df.resample("30min").mean() return df diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/groundtemperature.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/groundtemperature.py index 99d1edd9..ca9e1e6b 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/groundtemperature.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/groundtemperature.py @@ -203,7 +203,7 @@ def ground_temperature_at_depth( ], index=dbt.resample("D").min().index, ) - .resample("60T") + .resample("60min") .mean() .interpolate() .values From 7935a993c55350841bb4b29111b9942f1ce28d40 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Tue, 30 Jul 2024 08:22:35 +0100 Subject: [PATCH 27/31] added python output to error message --- LadybugTools_Adapter/AdapterActions/Execute.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LadybugTools_Adapter/AdapterActions/Execute.cs b/LadybugTools_Adapter/AdapterActions/Execute.cs index fb152160..2b86a36c 100644 --- a/LadybugTools_Adapter/AdapterActions/Execute.cs +++ b/LadybugTools_Adapter/AdapterActions/Execute.cs @@ -319,7 +319,7 @@ private List RunCommand(HeatPlotCommand command, ActionConfig actionConf if (!File.Exists(result)) { - BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + BH.Engine.Base.Compute.RecordError($"An error occurred while running the command: {result}"); File.Delete(returnFile); return new List(); } @@ -371,7 +371,7 @@ private List RunCommand(WindroseCommand command, ActionConfig actionConf if (!File.Exists(result)) { - BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + BH.Engine.Base.Compute.RecordError($"An error occurred while running the command: {result}"); File.Delete(returnFile); return new List(); } @@ -513,7 +513,7 @@ private List RunCommand(DiurnalPlotCommand command, ActionConfig actionC if (!File.Exists(resultFile)) { - BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + BH.Engine.Base.Compute.RecordError($"An error occurred while running the command: {result}"); File.Delete(returnFile); return new List(); } @@ -568,7 +568,7 @@ private List RunCommand(SunPathPlotCommand command, ActionConfig actionC if (!File.Exists(resultFile)) { - BH.Engine.Base.Compute.RecordError("An error occurred while running the command."); + BH.Engine.Base.Compute.RecordError($"An error occurred while running the command: {result}"); File.Delete(returnFile); return new List(); } From 9804f9fe9bc24cb8656418f82f2a63da526b0de2 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 31 Jul 2024 10:59:25 +0100 Subject: [PATCH 28/31] added method separators and fallback for ToSimulationData --- .../Convert/MetaData/PlotInformation.cs | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs index 88a6986b..5ee7be92 100644 --- a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -33,22 +33,25 @@ namespace BH.Adapter.LadybugTools public static partial class Convert { + /**************************************************/ + /**** Public Methods: Interface ****/ + /**************************************************/ + public static PlotInformation ToPlotInformation(this CustomObject oldObject, ISimulationData toUpdate) { PlotInformation plotInformation = new PlotInformation(); plotInformation.Image = oldObject.CustomData["figure"].ToString(); - plotInformation.OtherData = IToSimulationData((oldObject.CustomData["data"] as CustomObject).CustomData, toUpdate); + plotInformation.OtherData = ToSimulationData((oldObject.CustomData["data"] as CustomObject).CustomData, toUpdate as dynamic); return plotInformation; } - private static ISimulationData IToSimulationData(Dictionary oldObject, ISimulationData toUpdate) - { - return ToSimulationData(oldObject, toUpdate as dynamic); - } + /**************************************************/ + /**** Private Methods: Deserialise ****/ + /**************************************************/ private static CollectionData ToSimulationData(this Dictionary oldData, CollectionData toUpdate) { @@ -129,6 +132,8 @@ private static CollectionData ToSimulationData(this Dictionary o return toUpdate; } + /**************************************************/ + private static WindroseData ToSimulationData(this Dictionary oldData, WindroseData toUpdate) { if (!double.TryParse(oldData["prevailing_95percentile"].ToString(), out double result)) @@ -170,6 +175,8 @@ private static WindroseData ToSimulationData(this Dictionary old return toUpdate; } + /**************************************************/ + private static SunPathData ToSimulationData(this Dictionary oldData, SunPathData toUpdate) { try @@ -319,6 +326,8 @@ private static SunPathData ToSimulationData(this Dictionary oldD return toUpdate; } + /**************************************************/ + private static UTCIData ToSimulationData(this Dictionary oldData, UTCIData toUpdate) { if (!double.TryParse(oldData["comfortable_ratio"].ToString(), out double result)) @@ -347,5 +356,15 @@ private static UTCIData ToSimulationData(this Dictionary oldData return toUpdate; } + + /**************************************************/ + /**** Private Methods: Fallback ****/ + /**************************************************/ + + private static ISimulationData ToSimulationData(Dictionary oldObject, ISimulationData toUpdate) + { + BH.Engine.Base.Compute.RecordError($"The simulation data type {toUpdate.GetType().FullName} is not supported with the LadybugToolsAdapter. No simulation data has been returned with this action."); + return null; + } } } \ No newline at end of file From bdf754560c837ebced7034848e03dc26d89aecc9 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 31 Jul 2024 11:16:25 +0100 Subject: [PATCH 29/31] added descriptions to ISimulationData objects. --- LadybugTools_oM/MetaData/CollectionData.cs | 9 +++++++++ LadybugTools_oM/MetaData/PlotInformation.cs | 3 +++ LadybugTools_oM/MetaData/SunData.cs | 7 +++++++ LadybugTools_oM/MetaData/SunPathData.cs | 5 +++++ LadybugTools_oM/MetaData/UTCIData.cs | 7 +++++++ LadybugTools_oM/MetaData/WindroseData.cs | 9 ++++++++- 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs index d2ec2033..ec5c3594 100644 --- a/LadybugTools_oM/MetaData/CollectionData.cs +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -23,6 +23,7 @@ using BH.oM.Base.Attributes; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; @@ -31,20 +32,28 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class CollectionData : ISimulationData { + [Description("The maximum value in the collection.")] public virtual double HighestValue { get; set; } = double.NaN; + [Description("The minimum value in the collection")] public virtual double LowestValue { get; set; } = double.NaN; + [Description("The date and time for when the maximum value occurs.")] public virtual DateTime HighestIndex { get; set; } = DateTime.MinValue; + [Description("The date and time for when the minimum value occurs.")] public virtual DateTime LowestIndex { get; set; } = DateTime.MinValue; + [Description("The median (50 percentile) value in the collection.")] public virtual double MedianValue { get; set; } = double.NaN; + [Description("The mean value of the collection.")] public virtual double MeanValue { get; set; } = double.NaN; + [Description("The mean values for each month.")] public virtual List MonthlyMeans { get; set; } = Enumerable.Repeat(double.NaN, 12).ToList(); + [Description("The diurnal ranges for each month as a list of tuples: (lowest, highest).")] public virtual List> MonthlyDiurnalRanges { get; set; } = Enumerable.Repeat>(new List { double.NaN, double.NaN }, 12).ToList(); } } diff --git a/LadybugTools_oM/MetaData/PlotInformation.cs b/LadybugTools_oM/MetaData/PlotInformation.cs index a610acf0..b8a078c8 100644 --- a/LadybugTools_oM/MetaData/PlotInformation.cs +++ b/LadybugTools_oM/MetaData/PlotInformation.cs @@ -24,6 +24,7 @@ using BH.oM.Base.Attributes; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Text; namespace BH.oM.LadybugTools @@ -31,8 +32,10 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class PlotInformation : BHoMObject { + [Description("The image produced.")] public virtual string Image { get; set; } = ""; + [Description("Metadata about the data used to produce the image.")] public virtual ISimulationData OtherData { get; set; } } } diff --git a/LadybugTools_oM/MetaData/SunData.cs b/LadybugTools_oM/MetaData/SunData.cs index 81d2da87..ae554b82 100644 --- a/LadybugTools_oM/MetaData/SunData.cs +++ b/LadybugTools_oM/MetaData/SunData.cs @@ -23,6 +23,7 @@ using BH.oM.Base.Attributes; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Text; namespace BH.oM.LadybugTools @@ -30,16 +31,22 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class SunData { + [Description("The azimuth angle at sunrise.")] public virtual double SunriseAzimuth { get; set; } = double.NaN; + [Description("The time that sunrise happens.")] public virtual DateTime SunriseTime { get; set; } = DateTime.MinValue; + [Description("The altitude angle at solar noon (when the sun is at its highest point).")] public virtual double NoonAltitude { get; set; } = double.NaN; + [Description("The time that the altitude is highest.")] public virtual DateTime NoonTime { get; set; } = DateTime.MinValue; + [Description("The azimuth angle at sunset.")] public virtual double SunsetAzimuth { get; set; } = double.NaN; + [Description("The time that sunset happens.")] public virtual DateTime SunsetTime { get; set; } = DateTime.MinValue; } } diff --git a/LadybugTools_oM/MetaData/SunPathData.cs b/LadybugTools_oM/MetaData/SunPathData.cs index 77e8eb08..f2bfdac0 100644 --- a/LadybugTools_oM/MetaData/SunPathData.cs +++ b/LadybugTools_oM/MetaData/SunPathData.cs @@ -23,6 +23,7 @@ using BH.oM.Base.Attributes; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Text; namespace BH.oM.LadybugTools @@ -30,12 +31,16 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class SunPathData : ISimulationData { + [Description("Data for the december (winter) solstice.")] public virtual SunData DecemberSolstice { get; set; } = new SunData(); + [Description("Data for the march (spring) equinox.")] public virtual SunData MarchEquinox { get; set; } = new SunData(); + [Description("Data for the june (summer) solstice.")] public virtual SunData JuneSolstice { get; set; } = new SunData(); + [Description("Data for the september (autumn) equinox.")] public virtual SunData SeptemberEquinox { get; set; } = new SunData(); } } diff --git a/LadybugTools_oM/MetaData/UTCIData.cs b/LadybugTools_oM/MetaData/UTCIData.cs index 1b2d9098..2a371a7e 100644 --- a/LadybugTools_oM/MetaData/UTCIData.cs +++ b/LadybugTools_oM/MetaData/UTCIData.cs @@ -23,6 +23,7 @@ using BH.oM.Base.Attributes; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Text; namespace BH.oM.LadybugTools @@ -30,16 +31,22 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class UTCIData : ISimulationData { + [Description("The ratio of comfortable hours / total hours.")] public virtual double ComfortableRatio { get; set; } = double.NaN; + [Description("The ratio of heat stress hours / total hours.")] public virtual double HotRatio { get; set; } = double.NaN; + [Description("The ratio of cold stress hours / total hours.")] public virtual double ColdRatio { get; set; } = double.NaN; + [Description("The ratio of daytime active comfortable hours / daytime active hours.")] public virtual double DaytimeComfortableRatio { get; set; } = double.NaN; + [Description("The ratio of daytime active heat stress hours / daytime active hours.")] public virtual double DaytimeHotRatio { get; set; } = double.NaN; + [Description("The ratio of daytime active cold stress hours / daytime active hours.")] public virtual double DaytimeColdRatio { get; set; } = double.NaN; } } diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs index 44e649a9..d471273e 100644 --- a/LadybugTools_oM/MetaData/WindroseData.cs +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -23,6 +23,7 @@ using BH.oM.Base.Attributes; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; @@ -31,16 +32,22 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class WindroseData : ISimulationData { + [Description("The direction that the prevailing wind is coming from between two angles as a tuple, where 0 degrees is north.")] public virtual List PrevailingDirection { get; set; } = Enumerable.Repeat(double.NaN, 2).ToList(); + [Description("The 95 percentile wind speed value in the prevailing direction.")] public virtual double PrevailingPercentile95 { get; set; } = double.NaN; + [Description("The median (50 percentile) wind speed value in the prevailing direction.")] public virtual double PrevailingPercentile50 { get; set; } = double.NaN; - public virtual double Percentile95 { get; set; } = double.NaN; + [Description("The 95 percentile wind speed value.")] + public virtual double Percentile95 { get; set; } = double.NaN; + [Description("The median (50 percentile) wind speed value.")] public virtual double Percentile50 { get; set; } = double.NaN; + [Description("The percentage of calm hours / total hours.")] public virtual double PercentageOfCalmHours { get; set; } = double.NaN; } } From 7df2c7bac165bd9a2a100c1fae066f74bbab0da1 Mon Sep 17 00:00:00 2001 From: Thomas Edward Kingstone Date: Wed, 31 Jul 2024 14:33:24 +0100 Subject: [PATCH 30/31] fixes from review --- .../Convert/MetaData/PlotInformation.cs | 26 ------------------- .../bhom/wrapped/metadata/collection.py | 12 --------- .../bhom/wrapped/metadata/wind_metadata.py | 4 +-- .../ladybug_extension/sunpath.py | 4 +-- LadybugTools_oM/MetaData/CollectionData.cs | 3 --- 5 files changed, 4 insertions(+), 45 deletions(-) diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs index 5ee7be92..e9346b49 100644 --- a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -103,32 +103,6 @@ private static CollectionData ToSimulationData(this Dictionary o } catch { } - try - { - List> ranges = oldData["month_diurnal_ranges"] as List>; - List> monthlyRanges = new List>(); - - int monthIndex = 0; - - foreach (List range in ranges) - { - List values = new List(); - - foreach (object value in range) - { - if (!double.TryParse(value.ToString(), out result)) - result = double.NaN; - - values.Add(result); - } - - toUpdate.MonthlyDiurnalRanges[monthIndex] = values; - monthIndex++; - } - } - catch { } - - return toUpdate; } diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/collection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/collection.py index 9a923e20..ce9a498b 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/collection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/collection.py @@ -19,7 +19,6 @@ def collection_metadata(collection: BaseCollection) -> dict: "median": median, "mean": mean, "month_means": [month_means], - "month_diurnal_ranges": [month_diurnal_ranges], } where month_means is a list of means indexed by month, and month_ranges is a list of diurnal month ranges as tuples: (min, max). """ @@ -31,21 +30,11 @@ def collection_metadata(collection: BaseCollection) -> dict: highest_index = series.idxmax() median = series.quantile(0.5) mean = series.mean() - - series_diurnal_mean = series.groupby([series.index.month, series.index.hour]).mean() - series_diurnal_max = series_diurnal_mean.groupby( - series_diurnal_mean.index.get_level_values(0) - ).max() - series_diurnal_min = series_diurnal_mean.groupby( - series_diurnal_mean.index.get_level_values(0) - ).min() month_means = [] - month_ranges = [] for month in range(12): month_series = series[series.index.month == month + 1] month_means.append(month_series.mean()) - month_ranges.append((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) return { "lowest": lowest, @@ -55,5 +44,4 @@ def collection_metadata(collection: BaseCollection) -> dict: "median": median, "mean": mean, "month_means": month_means, - "month_diurnal_ranges": month_ranges, } \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/wind_metadata.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/wind_metadata.py index e94121dd..25b9000a 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/wind_metadata.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/bhom/wrapped/metadata/wind_metadata.py @@ -36,6 +36,6 @@ def wind_metadata(wind_object: Wind, directions: int=36, ignore_calm: bool=True, "50percentile": ws.quantile(0.50), "calm_percent": wind_object.calm(), "prevailing_direction": prevailing_direction, - "prevailing_95percentile": prevailing_wind_speeds.quantile(0.95), - "prevailing_50percentile": prevailing_wind_speeds.quantile(0.5) + "prevailing_95percentile": prevailing_wind_speed.quantile(0.95), + "prevailing_50percentile": prevailing_wind_speed.quantile(0.5) } \ No newline at end of file diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py index 327d0e92..29ea5f04 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -5,7 +5,7 @@ import pandas as pd from datetime import datetime -@bhom_analytics +@bhom_analytics() def sunrise_sunset_azimuths(sunpath: Sunpath, year: int, month: int, day: int) -> dict: """Return a dictionary containing azimuths at sunrise and sunset, and altitude at solar noon @@ -32,6 +32,6 @@ def sunrise_sunset_azimuths(sunpath: Sunpath, year: int, month: int, day: int) - sunrise_sunset = sunpath.calculate_sunrise_sunset_from_datetime(datetime(year=year, month=month, day=day)) - azimuths_altitude = {k:{"time": v, "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": v, "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in sunrise_sunset.items() } + azimuths_altitude = {k:{"time": datetime(year, v.month, v.day, v.hour, v.minute), "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": datetime(year, v.month, v.day, v.hour, v.minute), "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in sunrise_sunset.items() } return azimuths_altitude \ No newline at end of file diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs index ec5c3594..0a564d79 100644 --- a/LadybugTools_oM/MetaData/CollectionData.cs +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -52,8 +52,5 @@ public class CollectionData : ISimulationData [Description("The mean values for each month.")] public virtual List MonthlyMeans { get; set; } = Enumerable.Repeat(double.NaN, 12).ToList(); - - [Description("The diurnal ranges for each month as a list of tuples: (lowest, highest).")] - public virtual List> MonthlyDiurnalRanges { get; set; } = Enumerable.Repeat>(new List { double.NaN, double.NaN }, 12).ToList(); } } From 8cbd05240b4b945b7d0252526f07770ea15f57d1 Mon Sep 17 00:00:00 2001 From: James Ramsden Date: Thu, 1 Aug 2024 13:36:14 +0100 Subject: [PATCH 31/31] Additional changes --- .../Convert/MetaData/PlotInformation.cs | 72 ++++++++++++------- .../external_comfort/utci.py | 1 - .../ladybug_extension/datacollection.py | 26 ------- .../ladybug_extension/sunpath.py | 10 +-- LadybugTools_oM/MetaData/CollectionData.cs | 6 +- LadybugTools_oM/MetaData/PlotInformation.cs | 2 +- LadybugTools_oM/MetaData/SunData.cs | 10 +-- LadybugTools_oM/MetaData/SunPathData.cs | 8 +-- LadybugTools_oM/MetaData/UTCIData.cs | 20 +++--- LadybugTools_oM/MetaData/WindroseData.cs | 14 ++-- 10 files changed, 81 insertions(+), 88 deletions(-) diff --git a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs index e9346b49..e6569a44 100644 --- a/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs +++ b/LadybugTools_Adapter/Convert/MetaData/PlotInformation.cs @@ -101,7 +101,10 @@ private static CollectionData ToSimulationData(this Dictionary o monthIndex++; } } - catch { } + catch (Exception ex) + { + BH.Engine.Base.Compute.RecordError(ex, "An error occurred while deserialising the monthly means:"); + } return toUpdate; } @@ -128,7 +131,10 @@ private static WindroseData ToSimulationData(this Dictionary old index++; } } - catch { } + catch (Exception ex) + { + BH.Engine.Base.Compute.RecordError(ex, "An error occurred while deserialising the prevailing wind direction:"); + } if (!double.TryParse(oldData["prevailing_50percentile"].ToString(), out result)) result = double.NaN; @@ -144,7 +150,7 @@ private static WindroseData ToSimulationData(this Dictionary old if (!double.TryParse(oldData["calm_percent"].ToString(), out result)) result = double.NaN; - toUpdate.PercentageOfCalmHours = result; + toUpdate.RatioOfCalmHours = result; return toUpdate; } @@ -155,9 +161,9 @@ private static SunPathData ToSimulationData(this Dictionary oldD { try { - Dictionary december_object = (oldData["december_solstice"] as CustomObject).CustomData; + Dictionary decemberObject = (oldData["december_solstice"] as CustomObject).CustomData; - Dictionary sunset = (december_object["sunset"] as CustomObject).CustomData; + Dictionary sunset = (decemberObject["sunset"] as CustomObject).CustomData; if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) result = double.NaN; @@ -167,7 +173,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.DecemberSolstice.SunsetTime = date; - Dictionary sunrise = (december_object["sunrise"] as CustomObject).CustomData; + Dictionary sunrise = (decemberObject["sunrise"] as CustomObject).CustomData; if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) result = double.NaN; @@ -177,7 +183,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.DecemberSolstice.SunriseTime = date; - Dictionary noon = (december_object["noon"] as CustomObject).CustomData; + Dictionary noon = (decemberObject["noon"] as CustomObject).CustomData; if (!double.TryParse(noon["altitude"].ToString(), out result)) result = double.NaN; @@ -187,13 +193,16 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.DecemberSolstice.NoonTime = date; } - catch { } + catch (Exception ex) + { + BH.Engine.Base.Compute.RecordError(ex, "An error occurred while deserialising the December solstice:"); + } try { - Dictionary march_object = (oldData["march_equinox"] as CustomObject).CustomData; + Dictionary marchObject = (oldData["march_equinox"] as CustomObject).CustomData; - Dictionary sunset = (march_object["sunset"] as CustomObject).CustomData; + Dictionary sunset = (marchObject["sunset"] as CustomObject).CustomData; if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) result = double.NaN; @@ -203,7 +212,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.MarchEquinox.SunsetTime = date; - Dictionary sunrise = (march_object["sunrise"] as CustomObject).CustomData; + Dictionary sunrise = (marchObject["sunrise"] as CustomObject).CustomData; if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) result = double.NaN; @@ -213,7 +222,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.MarchEquinox.SunriseTime = date; - Dictionary noon = (march_object["noon"] as CustomObject).CustomData; + Dictionary noon = (marchObject["noon"] as CustomObject).CustomData; if (!double.TryParse(noon["altitude"].ToString(), out result)) result = double.NaN; @@ -223,13 +232,16 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.MarchEquinox.NoonTime = date; } - catch { } + catch (Exception ex) + { + BH.Engine.Base.Compute.RecordError(ex, "An error occurred while deserialising the March equinox:"); + } try { - Dictionary june_object = (oldData["june_solstice"] as CustomObject).CustomData; + Dictionary juneObject = (oldData["june_solstice"] as CustomObject).CustomData; - Dictionary sunset = (june_object["sunset"] as CustomObject).CustomData; + Dictionary sunset = (juneObject["sunset"] as CustomObject).CustomData; if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) result = double.NaN; @@ -239,7 +251,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.JuneSolstice.SunsetTime = date; - Dictionary sunrise = (june_object["sunrise"] as CustomObject).CustomData; + Dictionary sunrise = (juneObject["sunrise"] as CustomObject).CustomData; if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) result = double.NaN; @@ -249,7 +261,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.JuneSolstice.SunriseTime = date; - Dictionary noon = (june_object["noon"] as CustomObject).CustomData; + Dictionary noon = (juneObject["noon"] as CustomObject).CustomData; if (!double.TryParse(noon["altitude"].ToString(), out result)) result = double.NaN; @@ -259,13 +271,16 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.JuneSolstice.NoonTime = date; } - catch { } + catch (Exception ex) + { + BH.Engine.Base.Compute.RecordError(ex, "An error occurred while deserialising the June solstice:"); + } try { - Dictionary september_object = (oldData["september_equinox"] as CustomObject).CustomData; + Dictionary septemberObject = (oldData["september_equinox"] as CustomObject).CustomData; - Dictionary sunset = (september_object["sunset"] as CustomObject).CustomData; + Dictionary sunset = (septemberObject["sunset"] as CustomObject).CustomData; if (!double.TryParse(sunset["azimuth"].ToString(), out double result)) result = double.NaN; @@ -275,7 +290,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.SeptemberEquinox.SunsetTime = date; - Dictionary sunrise = (september_object["sunrise"] as CustomObject).CustomData; + Dictionary sunrise = (septemberObject["sunrise"] as CustomObject).CustomData; if (!double.TryParse(sunrise["azimuth"].ToString(), out result)) result = double.NaN; @@ -285,7 +300,7 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.SeptemberEquinox.SunriseTime = date; - Dictionary noon = (september_object["noon"] as CustomObject).CustomData; + Dictionary noon = (septemberObject["noon"] as CustomObject).CustomData; if (!double.TryParse(noon["altitude"].ToString(), out result)) result = double.NaN; @@ -295,7 +310,10 @@ private static SunPathData ToSimulationData(this Dictionary oldD date = DateTime.MinValue; toUpdate.SeptemberEquinox.NoonTime = date; } - catch { } + catch (Exception ex) + { + BH.Engine.Base.Compute.RecordError(ex, "An error occurred while deserialising the September equinox:"); + } return toUpdate; } @@ -310,11 +328,11 @@ private static UTCIData ToSimulationData(this Dictionary oldData if (!double.TryParse(oldData["hot_ratio"].ToString(), out result)) result = double.NaN; - toUpdate.HotRatio = result; + toUpdate.HeatStressRatio = result; if (!double.TryParse(oldData["cold_ratio"].ToString(), out result)) result = double.NaN; - toUpdate.ColdRatio = result; + toUpdate.ColdStressRatio = result; if (!double.TryParse(oldData["daytime_comfortable"].ToString(), out result)) result = double.NaN; @@ -322,11 +340,11 @@ private static UTCIData ToSimulationData(this Dictionary oldData if (!double.TryParse(oldData["daytime_hot"].ToString(), out result)) result = double.NaN; - toUpdate.DaytimeHotRatio = result; + toUpdate.DaytimeHeatStressRatio = result; if (!double.TryParse(oldData["daytime_cold"].ToString(), out result)) result = double.NaN; - toUpdate.DaytimeColdRatio = result; + toUpdate.DaytimeColdStressRatio = result; return toUpdate; } diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py index cb1132d5..f724497c 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/external_comfort/utci.py @@ -2,7 +2,6 @@ # pylint: disable=C0302 # pylint: disable=E0401 -from datetime import datetime import warnings from calendar import month_abbr from concurrent.futures import ProcessPoolExecutor diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py index ed543a9a..7dd513b5 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/datacollection.py @@ -1,7 +1,6 @@ """Methods for manipulating Ladybug data collections.""" # pylint: disable=E0401 -from gc import collect import warnings from datetime import datetime, timedelta from pathlib import Path @@ -354,31 +353,6 @@ def summarise_collection( return descriptions -@bhom_analytics() -def monthly_diurnal_ranges(collection: BaseCollection) -> list[(float, float)]: - """Returns a list of diurnal ranges for each month - - Args: - collection (BaseCollection): - ladybug data collection object - - Returns: - list[(float, float)]: - a list of diurnal ranges for each month as tuples (min, max) - """ - - series = collection_to_series(collection) - series_diurnal_mean = series.groupby([series.index.month, series.index.hour]).mean() - series_diurnal_min = series_diurnal_mean.groupby(series_diurnal_mean.index.get_level_values(0)).min() - series_diurnal_max = series_diurnal_mean.groupby(series_diurnal_mean.index.get_level_values(0)).max() - month_ranges = [] - - for month in range(12): - month_ranges.append((series_diurnal_min.iloc[month], series_diurnal_max.iloc[month])) - - return month_ranges - - @bhom_analytics() def average( collections: list[BaseCollection], weights: list[float] = None diff --git a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py index 29ea5f04..6bb8b025 100644 --- a/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py +++ b/LadybugTools_Engine/Python/src/ladybugtools_toolkit/ladybug_extension/sunpath.py @@ -7,17 +7,17 @@ @bhom_analytics() def sunrise_sunset_azimuths(sunpath: Sunpath, year: int, month: int, day: int) -> dict: - """Return a dictionary containing azimuths at sunrise and sunset, and altitude at solar noon + """Return a dictionary containing azimuths at sunrise and sunset, and altitude at solar noon. Sunrise and sunset are defined as actual sunrise/sunset, which is the point at which the full height of the sun has passed the horizon. Args: sunpath (Sunpath): - a ladybug sunpath object + a ladybug Sunpath object month (int): month as an int, starting at 1 and ending at 12 day (int): - day as an int, starting at 1, and ending at 28 through 31 depending on the month + day as an int starting at 1, and ending between 28 and 31 depending on the month Returns: dict: @@ -32,6 +32,8 @@ def sunrise_sunset_azimuths(sunpath: Sunpath, year: int, month: int, day: int) - sunrise_sunset = sunpath.calculate_sunrise_sunset_from_datetime(datetime(year=year, month=month, day=day)) - azimuths_altitude = {k:{"time": datetime(year, v.month, v.day, v.hour, v.minute), "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": datetime(year, v.month, v.day, v.hour, v.minute), "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in sunrise_sunset.items() } + azimuths_altitude = { + k: {"time": datetime(year, v.month, v.day, v.hour, v.minute), "azimuth": sunpath.calculate_sun_from_date_time(v).azimuth} if k in ["sunrise", "sunset"] else {"time": datetime(year, v.month, v.day, v.hour, v.minute), "altitude": sunpath.calculate_sun_from_date_time(v).altitude} for k, v in sunrise_sunset.items() + } return azimuths_altitude \ No newline at end of file diff --git a/LadybugTools_oM/MetaData/CollectionData.cs b/LadybugTools_oM/MetaData/CollectionData.cs index 0a564d79..edd15238 100644 --- a/LadybugTools_oM/MetaData/CollectionData.cs +++ b/LadybugTools_oM/MetaData/CollectionData.cs @@ -35,13 +35,13 @@ public class CollectionData : ISimulationData [Description("The maximum value in the collection.")] public virtual double HighestValue { get; set; } = double.NaN; - [Description("The minimum value in the collection")] + [Description("The minimum value in the collection.")] public virtual double LowestValue { get; set; } = double.NaN; - [Description("The date and time for when the maximum value occurs.")] + [Description("The date and time at which the maximum value occurs.")] public virtual DateTime HighestIndex { get; set; } = DateTime.MinValue; - [Description("The date and time for when the minimum value occurs.")] + [Description("The date and time at which the minimum value occurs.")] public virtual DateTime LowestIndex { get; set; } = DateTime.MinValue; [Description("The median (50 percentile) value in the collection.")] diff --git a/LadybugTools_oM/MetaData/PlotInformation.cs b/LadybugTools_oM/MetaData/PlotInformation.cs index b8a078c8..79791bc8 100644 --- a/LadybugTools_oM/MetaData/PlotInformation.cs +++ b/LadybugTools_oM/MetaData/PlotInformation.cs @@ -32,7 +32,7 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class PlotInformation : BHoMObject { - [Description("The image produced.")] + [Description("The image produced, either as a filepath to the file created, or as a base64 string representation of the image.")] public virtual string Image { get; set; } = ""; [Description("Metadata about the data used to produce the image.")] diff --git a/LadybugTools_oM/MetaData/SunData.cs b/LadybugTools_oM/MetaData/SunData.cs index ae554b82..c15abb4f 100644 --- a/LadybugTools_oM/MetaData/SunData.cs +++ b/LadybugTools_oM/MetaData/SunData.cs @@ -31,22 +31,22 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class SunData { - [Description("The azimuth angle at sunrise.")] + [Description("The azimuth angle at sunrise in degrees. Sunrise is defined as the time at which the sun is first visible above the horizon, ignoring atmospheric effects.")] public virtual double SunriseAzimuth { get; set; } = double.NaN; - [Description("The time that sunrise happens.")] + [Description("The time of actual sunrise, defined as the time at which the sun is first visible above the horizon, ignoring atmospheric effects.")] public virtual DateTime SunriseTime { get; set; } = DateTime.MinValue; - [Description("The altitude angle at solar noon (when the sun is at its highest point).")] + [Description("The altitude angle at solar noon (when the sun is at its highest point) in degrees.")] public virtual double NoonAltitude { get; set; } = double.NaN; [Description("The time that the altitude is highest.")] public virtual DateTime NoonTime { get; set; } = DateTime.MinValue; - [Description("The azimuth angle at sunset.")] + [Description("The azimuth angle at sunset in degrees. Sunset is defined as the time at which the sun has just finished passing the horizon, ignoring atmospheric effects.")] public virtual double SunsetAzimuth { get; set; } = double.NaN; - [Description("The time that sunset happens.")] + [Description("The time of actual sunset, defined as the time at which the sun has just finished passing the horizon, ignoring atmospheric effects.")] public virtual DateTime SunsetTime { get; set; } = DateTime.MinValue; } } diff --git a/LadybugTools_oM/MetaData/SunPathData.cs b/LadybugTools_oM/MetaData/SunPathData.cs index f2bfdac0..0a466e46 100644 --- a/LadybugTools_oM/MetaData/SunPathData.cs +++ b/LadybugTools_oM/MetaData/SunPathData.cs @@ -31,16 +31,16 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class SunPathData : ISimulationData { - [Description("Data for the december (winter) solstice.")] + [Description("Data describing the December (winter) solstice.")] public virtual SunData DecemberSolstice { get; set; } = new SunData(); - [Description("Data for the march (spring) equinox.")] + [Description("Data describing the March (spring) equinox.")] public virtual SunData MarchEquinox { get; set; } = new SunData(); - [Description("Data for the june (summer) solstice.")] + [Description("Data describing the June (summer) solstice.")] public virtual SunData JuneSolstice { get; set; } = new SunData(); - [Description("Data for the september (autumn) equinox.")] + [Description("Data describing the September (autumn) equinox.")] public virtual SunData SeptemberEquinox { get; set; } = new SunData(); } } diff --git a/LadybugTools_oM/MetaData/UTCIData.cs b/LadybugTools_oM/MetaData/UTCIData.cs index 2a371a7e..a6f6afb7 100644 --- a/LadybugTools_oM/MetaData/UTCIData.cs +++ b/LadybugTools_oM/MetaData/UTCIData.cs @@ -31,22 +31,22 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class UTCIData : ISimulationData { - [Description("The ratio of comfortable hours / total hours.")] + [Description("The ratio of comfortable hours to total hours. Comfortable hours are hours between 9 and 26°C.")] public virtual double ComfortableRatio { get; set; } = double.NaN; - [Description("The ratio of heat stress hours / total hours.")] - public virtual double HotRatio { get; set; } = double.NaN; + [Description("The ratio of heat stress hours to total hours. Heat stress hours are hours greater than 26°C.")] + public virtual double HeatStressRatio { get; set; } = double.NaN; - [Description("The ratio of cold stress hours / total hours.")] - public virtual double ColdRatio { get; set; } = double.NaN; + [Description("The ratio of cold stress hours to total hours. Cold stress hours are hours less than 9°C.")] + public virtual double ColdStressRatio { get; set; } = double.NaN; - [Description("The ratio of daytime active comfortable hours / daytime active hours.")] + [Description("The ratio of daytime comfortable hours to daytime hours. Daytime comfortable hours are hours between 9 and 26°C and between 07:00-22:59.")] public virtual double DaytimeComfortableRatio { get; set; } = double.NaN; - [Description("The ratio of daytime active heat stress hours / daytime active hours.")] - public virtual double DaytimeHotRatio { get; set; } = double.NaN; + [Description("The ratio of daytime heat stress hours to daytime hours. Daytime heat stress hours are hours greater than 26°C and between 07:00-22:59.")] + public virtual double DaytimeHeatStressRatio { get; set; } = double.NaN; - [Description("The ratio of daytime active cold stress hours / daytime active hours.")] - public virtual double DaytimeColdRatio { get; set; } = double.NaN; + [Description("The ratio of daytime cold stress hours to daytime hours. Daytime cold stress hours are hours less than 9°C and between 07:00-22:59.")] + public virtual double DaytimeColdStressRatio { get; set; } = double.NaN; } } diff --git a/LadybugTools_oM/MetaData/WindroseData.cs b/LadybugTools_oM/MetaData/WindroseData.cs index d471273e..f520749e 100644 --- a/LadybugTools_oM/MetaData/WindroseData.cs +++ b/LadybugTools_oM/MetaData/WindroseData.cs @@ -32,22 +32,22 @@ namespace BH.oM.LadybugTools [NoAutoConstructor] public class WindroseData : ISimulationData { - [Description("The direction that the prevailing wind is coming from between two angles as a tuple, where 0 degrees is north.")] + [Description("The direction bin of the prevailing wind, defined as two values (in degrees) for the lower and upper values for the bin, where 0 degrees is north.")] public virtual List PrevailingDirection { get; set; } = Enumerable.Repeat(double.NaN, 2).ToList(); - [Description("The 95 percentile wind speed value in the prevailing direction.")] + [Description("The 95th percentile wind speed value in the prevailing direction.")] public virtual double PrevailingPercentile95 { get; set; } = double.NaN; - [Description("The median (50 percentile) wind speed value in the prevailing direction.")] + [Description("The median (50th percentile) wind speed value in the prevailing direction.")] public virtual double PrevailingPercentile50 { get; set; } = double.NaN; - [Description("The 95 percentile wind speed value.")] + [Description("The 95th percentile wind speed value.")] public virtual double Percentile95 { get; set; } = double.NaN; - [Description("The median (50 percentile) wind speed value.")] + [Description("The median (50th percentile) wind speed value.")] public virtual double Percentile50 { get; set; } = double.NaN; - [Description("The percentage of calm hours / total hours.")] - public virtual double PercentageOfCalmHours { get; set; } = double.NaN; + [Description("The ratio of calm hours to total hours. Calm hours are hours with a wind speed of 1e-10 or less.")] + public virtual double RatioOfCalmHours { get; set; } = double.NaN; } }