Skip to content

Commit

Permalink
feat(extension): Add methods to extend ladybug-radiance studies
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswmackey authored and Chris Mackey committed Jul 22, 2023
1 parent 19b0902 commit 13d302f
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 3 deletions.
6 changes: 6 additions & 0 deletions ladybug_display/_extend_ladybug.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,21 @@
from ladybug_radiance.visualize.skydome import SkyDome
from ladybug_radiance.visualize.radrose import RadiationRose
from ladybug_radiance.visualize.raddome import RadiationDome
from ladybug_radiance.study.directsun import DirectSunStudy
from ladybug_radiance.study.radiation import RadiationStudy

# import the extension functions
from .extension.skydome import sky_dome_to_vis_set
from .extension.radrose import radiation_rose_to_vis_set
from .extension.raddome import radiation_dome_to_vis_set
from .extension.study.directsun import direct_sun_study_to_vis_set
from .extension.study.radiation import radiation_study_to_vis_set

# inject the methods onto the classes
SkyDome.to_vis_set = sky_dome_to_vis_set
RadiationRose.to_vis_set = radiation_rose_to_vis_set
RadiationDome.to_vis_set = radiation_dome_to_vis_set
DirectSunStudy.to_vis_set = direct_sun_study_to_vis_set
RadiationStudy.to_vis_set = radiation_study_to_vis_set
except ImportError:
pass # ladybug-radiance is not installed
2 changes: 1 addition & 1 deletion ladybug_display/extension/raddome.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def radiation_dome_to_vis_set(radiation_dome, show_components=False, include_tit
"""Translate radiation dome geometry into a VisualizationSet.
Args:
radiation_dome: A Ladybug RadiationDome object.
radiation_dome: A Ladybug-Radiance RadiationDome object.
show_components: Boolean to indicate whether only one dome with total radiation
should be displayed (False) or three domes with the solar radiation
components (total, direct, and diffuse) should be shown. (Default: False).
Expand Down
2 changes: 1 addition & 1 deletion ladybug_display/extension/radrose.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def radiation_rose_to_vis_set(
"""Translate radiation rose geometry into a format suitable for Rhino.
Args:
radiation_rose: A Ladybug RadiationRose object.
radiation_rose: A Ladybug-Radiance RadiationRose object.
max_rad: An optional number to set the level of radiation or irradiance
associated with the full radius of the rose. If None, this is
determined by the maximum level of radiation in the input data
Expand Down
2 changes: 1 addition & 1 deletion ladybug_display/extension/skydome.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def sky_dome_to_vis_set(sky_dome, show_components=False, include_title=True):
"""Translate sky dome geometry into a VisualizationSet.
Args:
sky_dome: A Ladybug SkyDome object.
sky_dome: A Ladybug-Radiance SkyDome object.
show_components: Boolean to indicate whether only one dome with total radiation
should be displayed (False) or three domes with the solar radiation
components (total, direct, and diffuse) should be shown. (Default: False).
Expand Down
1 change: 1 addition & 0 deletions ladybug_display/extension/study/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Sub-package with methods to extend ladybug-radiance studies."""
71 changes: 71 additions & 0 deletions ladybug_display/extension/study/directsun.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Method to draw a RadiationDome as a VisualizationSet."""
from ladybug_geometry.bounding import bounding_box
from ladybug.color import Colorset
from ladybug.legend import LegendParameters
from ladybug.graphic import GraphicContainer
from ladybug.datatype.time import Time

from ladybug_display.geometry3d import DisplayText3D
from ladybug_display.visualization import VisualizationSet, AnalysisGeometry, \
VisualizationData, ContextGeometry


def direct_sun_study_to_vis_set(
direct_sun_study, legend_parameters=None, include_title=True):
"""Translate direct sun study into a VisualizationSet.
Args:
direct_sun_study: A Ladybug-Radiance DirectSunStudy object.
legend_parameters: An optional LegendParameter object to change the display
of the direct sun study. If None, default legend parameters will be
used. (Default: None).
include_title: Boolean to note whether the title should be included
in the output visualization. (Default: True).
Returns:
A VisualizationSet with the direct sun study represented as an
AnalysisGeometry. This includes these objects in the following order.
- Title -- A ContextGeometry with text for the title of the study.
This layer will be excluded if include_title is False.
- Direct_Sun_Data -- An AnalysisGeometry for the direct sun data.
"""
# process the legend parameters and override the legend colors
if legend_parameters is not None:
assert isinstance(legend_parameters, LegendParameters), \
'Expected LegendParameters. Got {}.'.format(type(legend_parameters))
l_par = legend_parameters.duplicate()
else:
l_par = LegendParameters()
if l_par.are_colors_default:
l_par.colors = Colorset.ecotect()

# create the visualization set object
vis_set = VisualizationSet('DirectSunStudy', ())
vis_set.display_name = 'Direct Sun Study'
d_type, unit = Time(), 'hr'
sun_data = direct_sun_study.direct_sun_hours

# create the ContextGeometry for the title
if include_title:
all_geo = (direct_sun_study.study_mesh,) + direct_sun_study.context_geometry
min_pt, max_pt = bounding_box(all_geo)
graphic = GraphicContainer(
sun_data, min_pt, max_pt, l_par, d_type, unit)
study_title = DisplayText3D(
'Direct Sun Hours', graphic.lower_title_location,
graphic.legend_parameters.text_height, None,
graphic.legend_parameters.font, 'Left', 'Top')
title_geo = ContextGeometry('Title', [study_title])
vis_set.add_geometry(title_geo)

# create the AnalysisGeometry
vis_data = VisualizationData(sun_data, l_par, d_type, unit)
mesh_geo = AnalysisGeometry(
'Direct_Sun_Data', [direct_sun_study.study_mesh], [vis_data])
mesh_geo.display_name = 'Direct Sun Data'
mesh_geo.display_mode = 'Surface'
vis_set.add_geometry(mesh_geo)

return vis_set
91 changes: 91 additions & 0 deletions ladybug_display/extension/study/radiation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""Method to draw a RadiationDome as a VisualizationSet."""
from ladybug_geometry.bounding import bounding_box
from ladybug.color import Colorset
from ladybug.legend import LegendParameters
from ladybug.graphic import GraphicContainer
from ladybug.datatype.energyintensity import Radiation
from ladybug.datatype.energyflux import Irradiance

from ladybug_display.geometry3d import DisplayText3D
from ladybug_display.visualization import VisualizationSet, AnalysisGeometry, \
VisualizationData, ContextGeometry


def radiation_study_to_vis_set(
radiation_study, legend_parameters=None, plot_irradiance=False,
include_title=True):
"""Translate radiation study into a VisualizationSet.
Args:
radiation_study: A Ladybug-Radiance RadiationStudy object.
legend_parameters: An optional LegendParameter object to change the display
of the radiation study. If None, default legend parameters will be
used. (Default: None).
include_title: Boolean to note whether the title should be included
in the output visualization. (Default: True).
Returns:
A VisualizationSet with the radiation study represented as an
AnalysisGeometry. This includes these objects in the following order.
- Title -- A ContextGeometry with text for the title of the study.
This layer will be excluded if include_title is False.
- Radiation_Data -- An AnalysisGeometry for the radiation data.
"""
# get the radiation data
if plot_irradiance:
d_type, unit, title = Irradiance(), 'W/m2', 'Incident Irradiance'
rad_data = radiation_study.irradiance_values
else:
d_type, unit, title = Radiation(), 'kWh/m2', 'Incident Radiation'
rad_data = radiation_study.radiation_values
if radiation_study.is_benefit:
title = '{} Benefit/Harm'.format(title)

# process the legend parameters and override the legend colors
if legend_parameters is not None:
assert isinstance(legend_parameters, LegendParameters), \
'Expected LegendParameters. Got {}.'.format(type(legend_parameters))
l_par = legend_parameters.duplicate()
else:
l_par = LegendParameters()
if radiation_study.is_benefit:
if l_par.min is None:
l_par.min = min((min(rad_data), -max(rad_data)))
if l_par.max is None:
l_par.max = max((-min(rad_data), max(rad_data)))
if l_par.are_colors_default:
l_par.colors = reversed(Colorset.benefit_harm())
else:
if l_par.min is None:
l_par.min = 0
if l_par.max is None:
l_par.max = max(rad_data)

# create the visualization set object
vis_set = VisualizationSet('RadiationStudy', ())
vis_set.display_name = 'Radiation Study'

# create the ContextGeometry for the title
if include_title:
all_geo = (radiation_study.study_mesh,) + radiation_study.context_geometry
min_pt, max_pt = bounding_box(all_geo)
graphic = GraphicContainer(
rad_data, min_pt, max_pt, l_par, d_type, unit)
study_title = DisplayText3D(
title, graphic.lower_title_location,
graphic.legend_parameters.text_height, None,
graphic.legend_parameters.font, 'Left', 'Top')
title_geo = ContextGeometry('Title', [study_title])
vis_set.add_geometry(title_geo)

# create the AnalysisGeometry
vis_data = VisualizationData(rad_data, l_par, d_type, unit)
mesh_geo = AnalysisGeometry(
'Radiation_Data', [radiation_study.study_mesh], [vis_data])
mesh_geo.display_name = 'Radiation Data'
mesh_geo.display_mode = 'Surface'
vis_set.add_geometry(mesh_geo)

return vis_set

0 comments on commit 13d302f

Please sign in to comment.