honeybee-radiance 1.66.190__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of honeybee-radiance might be problematic. Click here for more details.
- honeybee_radiance/__init__.py +11 -0
- honeybee_radiance/__main__.py +4 -0
- honeybee_radiance/_extend_honeybee.py +93 -0
- honeybee_radiance/cli/__init__.py +88 -0
- honeybee_radiance/cli/dc.py +400 -0
- honeybee_radiance/cli/edit.py +529 -0
- honeybee_radiance/cli/glare.py +118 -0
- honeybee_radiance/cli/grid.py +859 -0
- honeybee_radiance/cli/lib.py +458 -0
- honeybee_radiance/cli/modifier.py +133 -0
- honeybee_radiance/cli/mtx.py +226 -0
- honeybee_radiance/cli/multiphase.py +1034 -0
- honeybee_radiance/cli/octree.py +640 -0
- honeybee_radiance/cli/postprocess.py +1186 -0
- honeybee_radiance/cli/raytrace.py +219 -0
- honeybee_radiance/cli/rpict.py +125 -0
- honeybee_radiance/cli/schedule.py +56 -0
- honeybee_radiance/cli/setconfig.py +63 -0
- honeybee_radiance/cli/sky.py +545 -0
- honeybee_radiance/cli/study.py +66 -0
- honeybee_radiance/cli/sunpath.py +331 -0
- honeybee_radiance/cli/threephase.py +255 -0
- honeybee_radiance/cli/translate.py +400 -0
- honeybee_radiance/cli/util.py +121 -0
- honeybee_radiance/cli/view.py +261 -0
- honeybee_radiance/cli/viewfactor.py +347 -0
- honeybee_radiance/config.json +6 -0
- honeybee_radiance/config.py +427 -0
- honeybee_radiance/dictutil.py +50 -0
- honeybee_radiance/dynamic/__init__.py +5 -0
- honeybee_radiance/dynamic/group.py +479 -0
- honeybee_radiance/dynamic/multiphase.py +557 -0
- honeybee_radiance/dynamic/state.py +718 -0
- honeybee_radiance/dynamic/stategeo.py +352 -0
- honeybee_radiance/geometry/__init__.py +13 -0
- honeybee_radiance/geometry/bubble.py +42 -0
- honeybee_radiance/geometry/cone.py +215 -0
- honeybee_radiance/geometry/cup.py +54 -0
- honeybee_radiance/geometry/cylinder.py +197 -0
- honeybee_radiance/geometry/geometrybase.py +37 -0
- honeybee_radiance/geometry/instance.py +40 -0
- honeybee_radiance/geometry/mesh.py +38 -0
- honeybee_radiance/geometry/polygon.py +174 -0
- honeybee_radiance/geometry/ring.py +214 -0
- honeybee_radiance/geometry/source.py +182 -0
- honeybee_radiance/geometry/sphere.py +178 -0
- honeybee_radiance/geometry/tube.py +46 -0
- honeybee_radiance/lib/__init__.py +1 -0
- honeybee_radiance/lib/_loadmodifiers.py +72 -0
- honeybee_radiance/lib/_loadmodifiersets.py +69 -0
- honeybee_radiance/lib/modifiers.py +58 -0
- honeybee_radiance/lib/modifiersets.py +63 -0
- honeybee_radiance/lightpath.py +204 -0
- honeybee_radiance/lightsource/__init__.py +1 -0
- honeybee_radiance/lightsource/_gendaylit.py +479 -0
- honeybee_radiance/lightsource/dictutil.py +49 -0
- honeybee_radiance/lightsource/ground.py +160 -0
- honeybee_radiance/lightsource/sky/__init__.py +7 -0
- honeybee_radiance/lightsource/sky/_skybase.py +177 -0
- honeybee_radiance/lightsource/sky/certainirradiance.py +232 -0
- honeybee_radiance/lightsource/sky/cie.py +378 -0
- honeybee_radiance/lightsource/sky/climatebased.py +501 -0
- honeybee_radiance/lightsource/sky/hemisphere.py +160 -0
- honeybee_radiance/lightsource/sky/skydome.py +113 -0
- honeybee_radiance/lightsource/sky/skymatrix.py +163 -0
- honeybee_radiance/lightsource/sky/strutil.py +34 -0
- honeybee_radiance/lightsource/sky/sunmatrix.py +212 -0
- honeybee_radiance/lightsource/sunpath.py +247 -0
- honeybee_radiance/modifier/__init__.py +3 -0
- honeybee_radiance/modifier/material/__init__.py +30 -0
- honeybee_radiance/modifier/material/absdf.py +477 -0
- honeybee_radiance/modifier/material/antimatter.py +54 -0
- honeybee_radiance/modifier/material/ashik2.py +51 -0
- honeybee_radiance/modifier/material/brtdfunc.py +81 -0
- honeybee_radiance/modifier/material/bsdf.py +292 -0
- honeybee_radiance/modifier/material/dielectric.py +53 -0
- honeybee_radiance/modifier/material/glass.py +431 -0
- honeybee_radiance/modifier/material/glow.py +246 -0
- honeybee_radiance/modifier/material/illum.py +51 -0
- honeybee_radiance/modifier/material/interface.py +49 -0
- honeybee_radiance/modifier/material/light.py +206 -0
- honeybee_radiance/modifier/material/materialbase.py +36 -0
- honeybee_radiance/modifier/material/metal.py +167 -0
- honeybee_radiance/modifier/material/metal2.py +41 -0
- honeybee_radiance/modifier/material/metdata.py +41 -0
- honeybee_radiance/modifier/material/metfunc.py +41 -0
- honeybee_radiance/modifier/material/mirror.py +340 -0
- honeybee_radiance/modifier/material/mist.py +86 -0
- honeybee_radiance/modifier/material/plasdata.py +58 -0
- honeybee_radiance/modifier/material/plasfunc.py +59 -0
- honeybee_radiance/modifier/material/plastic.py +354 -0
- honeybee_radiance/modifier/material/plastic2.py +58 -0
- honeybee_radiance/modifier/material/prism1.py +57 -0
- honeybee_radiance/modifier/material/prism2.py +48 -0
- honeybee_radiance/modifier/material/spotlight.py +50 -0
- honeybee_radiance/modifier/material/trans.py +518 -0
- honeybee_radiance/modifier/material/trans2.py +49 -0
- honeybee_radiance/modifier/material/transdata.py +50 -0
- honeybee_radiance/modifier/material/transfunc.py +53 -0
- honeybee_radiance/modifier/mixture/__init__.py +6 -0
- honeybee_radiance/modifier/mixture/mixdata.py +49 -0
- honeybee_radiance/modifier/mixture/mixfunc.py +54 -0
- honeybee_radiance/modifier/mixture/mixpict.py +52 -0
- honeybee_radiance/modifier/mixture/mixtext.py +66 -0
- honeybee_radiance/modifier/mixture/mixturebase.py +28 -0
- honeybee_radiance/modifier/modifierbase.py +40 -0
- honeybee_radiance/modifier/pattern/__init__.py +9 -0
- honeybee_radiance/modifier/pattern/brightdata.py +49 -0
- honeybee_radiance/modifier/pattern/brightfunc.py +47 -0
- honeybee_radiance/modifier/pattern/brighttext.py +81 -0
- honeybee_radiance/modifier/pattern/colordata.py +56 -0
- honeybee_radiance/modifier/pattern/colorfunc.py +47 -0
- honeybee_radiance/modifier/pattern/colorpict.py +54 -0
- honeybee_radiance/modifier/pattern/colortext.py +73 -0
- honeybee_radiance/modifier/pattern/patternbase.py +34 -0
- honeybee_radiance/modifier/texture/__init__.py +4 -0
- honeybee_radiance/modifier/texture/texdata.py +29 -0
- honeybee_radiance/modifier/texture/texfunc.py +26 -0
- honeybee_radiance/modifier/texture/texturebase.py +27 -0
- honeybee_radiance/modifierset.py +1091 -0
- honeybee_radiance/mutil.py +60 -0
- honeybee_radiance/postprocess/__init__.py +1 -0
- honeybee_radiance/postprocess/annual.py +108 -0
- honeybee_radiance/postprocess/annualdaylight.py +425 -0
- honeybee_radiance/postprocess/annualglare.py +201 -0
- honeybee_radiance/postprocess/annualirradiance.py +187 -0
- honeybee_radiance/postprocess/electriclight.py +119 -0
- honeybee_radiance/postprocess/en17037.py +261 -0
- honeybee_radiance/postprocess/leed.py +304 -0
- honeybee_radiance/postprocess/solartracking.py +90 -0
- honeybee_radiance/primitive.py +554 -0
- honeybee_radiance/properties/__init__.py +1 -0
- honeybee_radiance/properties/_base.py +390 -0
- honeybee_radiance/properties/aperture.py +197 -0
- honeybee_radiance/properties/door.py +198 -0
- honeybee_radiance/properties/face.py +123 -0
- honeybee_radiance/properties/model.py +1291 -0
- honeybee_radiance/properties/room.py +490 -0
- honeybee_radiance/properties/shade.py +186 -0
- honeybee_radiance/properties/shademesh.py +116 -0
- honeybee_radiance/putil.py +44 -0
- honeybee_radiance/reader.py +214 -0
- honeybee_radiance/sensor.py +166 -0
- honeybee_radiance/sensorgrid.py +1008 -0
- honeybee_radiance/view.py +1101 -0
- honeybee_radiance/writer.py +951 -0
- honeybee_radiance-1.66.190.dist-info/METADATA +89 -0
- honeybee_radiance-1.66.190.dist-info/RECORD +152 -0
- honeybee_radiance-1.66.190.dist-info/WHEEL +5 -0
- honeybee_radiance-1.66.190.dist-info/entry_points.txt +2 -0
- honeybee_radiance-1.66.190.dist-info/licenses/LICENSE +661 -0
- honeybee_radiance-1.66.190.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Virtual skydome for daylight coefficient studies with constant radiance."""
|
|
2
|
+
|
|
3
|
+
from ._skybase import _SkyDome
|
|
4
|
+
import honeybee.typing as typing
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SkyDome(_SkyDome):
|
|
8
|
+
"""Virtual skydome for daylight coefficient studies with constant radiance.
|
|
9
|
+
|
|
10
|
+
Use this sky to calculate daylight matrix.
|
|
11
|
+
|
|
12
|
+
.. code-block:: shell
|
|
13
|
+
|
|
14
|
+
#@rfluxmtx h=u u=Y
|
|
15
|
+
void glow ground_glow
|
|
16
|
+
0
|
|
17
|
+
0
|
|
18
|
+
4 0.2 0.2 0.2 0
|
|
19
|
+
|
|
20
|
+
ground_glow source ground
|
|
21
|
+
0
|
|
22
|
+
0
|
|
23
|
+
4 0 0 -1 180
|
|
24
|
+
|
|
25
|
+
#@rfluxmtx h=r1 u=Y
|
|
26
|
+
void glow sky_glow
|
|
27
|
+
0
|
|
28
|
+
0
|
|
29
|
+
4 1 1 1 0
|
|
30
|
+
|
|
31
|
+
sky_glow source sky
|
|
32
|
+
0
|
|
33
|
+
0
|
|
34
|
+
4 0 0 1 180
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
density: Sky patch subdivision density. This values is similar to -m option
|
|
38
|
+
in gendaymtx command. Default is 1 which means 145 sky patches and 1
|
|
39
|
+
patch for the ground.
|
|
40
|
+
|
|
41
|
+
One can add to the resolution typically by factors of two (2, 4, 8, ...)
|
|
42
|
+
which yields a higher resolution sky using the Reinhart patch subdivision
|
|
43
|
+
For example, setting density to 4 yields a sky with 2305 patches plus one
|
|
44
|
+
patch for the ground.
|
|
45
|
+
ground_emittance: Ground emittance value between 0.0 and 1.0 - Default: 0.2
|
|
46
|
+
"""
|
|
47
|
+
__slots__ = ('_sky_density', '_ground_emittance')
|
|
48
|
+
|
|
49
|
+
def __init__(self, sky_density=1, ground_emittance=0.2):
|
|
50
|
+
_SkyDome.__init__(self, modifier='void')
|
|
51
|
+
self.sky_density = sky_density
|
|
52
|
+
self.ground_hemisphere.r_emittance = ground_emittance
|
|
53
|
+
self.ground_hemisphere.g_emittance = ground_emittance
|
|
54
|
+
self.ground_hemisphere.b_emittance = ground_emittance
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def sky_density(self):
|
|
58
|
+
"""Set and get sky subdivision density."""
|
|
59
|
+
return self._sky_density
|
|
60
|
+
|
|
61
|
+
@sky_density.setter
|
|
62
|
+
def sky_density(self, v):
|
|
63
|
+
density = typing.int_in_range(v, 1, input_name='Sky subdivision density')
|
|
64
|
+
self._sky_density = density
|
|
65
|
+
|
|
66
|
+
def to_radiance(self):
|
|
67
|
+
"""Radiance definition for SkyDome."""
|
|
68
|
+
|
|
69
|
+
return '#@rfluxmtx h=u u=Y\n%s\n\n#@rfluxmtx h=r%d u=Y\n%s\n' % (
|
|
70
|
+
self.ground_hemisphere, self.sky_density, self.sky_hemisphere
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class UniformSky(_SkyDome):
|
|
75
|
+
"""Uniform sky is similar to a SkyDome but with no rfluxmtx header.
|
|
76
|
+
|
|
77
|
+
.. code-block:: shell
|
|
78
|
+
|
|
79
|
+
void glow sky_glow
|
|
80
|
+
0
|
|
81
|
+
0
|
|
82
|
+
4 1 1 1 0
|
|
83
|
+
|
|
84
|
+
sky_glow source sky
|
|
85
|
+
0
|
|
86
|
+
0
|
|
87
|
+
4 0 0 1 180
|
|
88
|
+
|
|
89
|
+
void glow ground_glow
|
|
90
|
+
0
|
|
91
|
+
0
|
|
92
|
+
4 0.2 0.2 0.2 0
|
|
93
|
+
|
|
94
|
+
ground_glow source ground
|
|
95
|
+
0
|
|
96
|
+
0
|
|
97
|
+
4 0 0 -1 180
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
ground_emittance: Ground emittance value between 0.0 and 1.0 - Default: 0.2
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
__slots__ = ('_ground_emittance',)
|
|
104
|
+
|
|
105
|
+
def __init__(self, ground_emittance=0.2):
|
|
106
|
+
_SkyDome.__init__(self, modifier='void')
|
|
107
|
+
self.ground_hemisphere.r_emittance = ground_emittance
|
|
108
|
+
self.ground_hemisphere.g_emittance = ground_emittance
|
|
109
|
+
self.ground_hemisphere.b_emittance = ground_emittance
|
|
110
|
+
|
|
111
|
+
def to_radiance(self):
|
|
112
|
+
"""Radiance definition for uniform sky."""
|
|
113
|
+
return '%s\n\n%s\n' % (self.sky_hemisphere, self.ground_hemisphere)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""Generate a point-in-time climate-based sky."""
|
|
2
|
+
from __future__ import division
|
|
3
|
+
|
|
4
|
+
from .sunmatrix import SunMatrix
|
|
5
|
+
import honeybee.typing as typing
|
|
6
|
+
from ladybug.wea import Wea
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SkyMatrix(SunMatrix):
|
|
10
|
+
"""Annual Climate-based Sky matrix.
|
|
11
|
+
|
|
12
|
+
The output of SkyMatrix is similar to using command Radiance's gendaymtx command with
|
|
13
|
+
default options. For more information see gendaymtx documentation.
|
|
14
|
+
|
|
15
|
+
https://www.radiance-online.org/learning/documentation/manual-pages/pdfs/gendaymtx.pdf
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
wea: A Ladybug wea object.
|
|
19
|
+
north: A number between -360 and 360 for the counterclockwise difference between
|
|
20
|
+
the North and the positive Y-axis in degrees. 90 is West and 270 is East
|
|
21
|
+
(Default: 0)
|
|
22
|
+
density: Sky patch subdivision density. This values is similar to -m option
|
|
23
|
+
in gendaymtx command. Default is 1 which means 145 sky patches and 1
|
|
24
|
+
patch for the ground.
|
|
25
|
+
|
|
26
|
+
One can add to the resolution typically by factors of two (2, 4, 8, ...)
|
|
27
|
+
which yields a higher resolution sky using the Reinhart patch subdivision
|
|
28
|
+
For example, setting density to 4 yields a sky with 2305 patches plus one
|
|
29
|
+
patch for the ground.
|
|
30
|
+
|
|
31
|
+
Properties:
|
|
32
|
+
* wea
|
|
33
|
+
* location
|
|
34
|
+
* north
|
|
35
|
+
* is_point_in_time
|
|
36
|
+
* is_climate_based
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
__slots__ = ('_density',)
|
|
40
|
+
|
|
41
|
+
def __init__(self, wea, north=0, density=1):
|
|
42
|
+
"""Create a climate-based sky matrix."""
|
|
43
|
+
SunMatrix.__init__(self, wea, north)
|
|
44
|
+
self.density = density
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def density(self):
|
|
48
|
+
"""Set and get sky patch subdivision density.
|
|
49
|
+
|
|
50
|
+
This values is similar to -m option in gendaymtx command. Default is 1 which
|
|
51
|
+
means 145 sky patches and 1 patch for the ground.
|
|
52
|
+
|
|
53
|
+
One can add to the resolution typically by factors of two (2, 4, 8, ...) which
|
|
54
|
+
yields a higher resolution sky using the Reinhart patch subdivision. For example,
|
|
55
|
+
setting density to 4 yields a sky with 2305 patches plus one patch for the
|
|
56
|
+
ground.
|
|
57
|
+
"""
|
|
58
|
+
return self._density
|
|
59
|
+
|
|
60
|
+
@density.setter
|
|
61
|
+
def density(self, value):
|
|
62
|
+
typing.int_in_range(value, 1, input_name='SkyMatrix subdivision density')
|
|
63
|
+
self._density = value
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def from_dict(cls, input_dict):
|
|
67
|
+
"""Create the sky from a dictionary.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
input_dict: A python dictionary in the following format
|
|
71
|
+
|
|
72
|
+
.. code-block:: python
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
'type': 'SkyMatrix',
|
|
76
|
+
'wea': {},
|
|
77
|
+
'north': 0.0 # optional
|
|
78
|
+
'density': 1 # optional
|
|
79
|
+
}
|
|
80
|
+
"""
|
|
81
|
+
if 'type' not in input_dict or input_dict['type'] != 'SkyMatrix':
|
|
82
|
+
raise ValueError('Input dict "type" must be "SkyMatrix".')
|
|
83
|
+
if 'north' in input_dict:
|
|
84
|
+
north = input_dict['north']
|
|
85
|
+
else:
|
|
86
|
+
north = 0
|
|
87
|
+
if 'density' in input_dict:
|
|
88
|
+
density = input_dict['density']
|
|
89
|
+
else:
|
|
90
|
+
density = 1
|
|
91
|
+
|
|
92
|
+
sky = cls(Wea.from_dict(input_dict['wea']), north, density)
|
|
93
|
+
|
|
94
|
+
return sky
|
|
95
|
+
|
|
96
|
+
# TODO: add support for additional parameters
|
|
97
|
+
# TODO: add gendaymtx to radiance-command and use it for validating inputs
|
|
98
|
+
def to_radiance(
|
|
99
|
+
self, output_type=0, wea_file=None, output_name=None, cumulative=False,
|
|
100
|
+
components=0):
|
|
101
|
+
"""Return Radiance command to generate the sky.
|
|
102
|
+
|
|
103
|
+
Note that you need to write the wea to a file (in.wea) before running this
|
|
104
|
+
command.
|
|
105
|
+
|
|
106
|
+
Alternatively you can use write method which will write the wea data to a file.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
output_type: An integer between 0 to 1 for output type.
|
|
110
|
+
* 0 = output in W/m2/sr visible (default)
|
|
111
|
+
* 1 = output in W/m2/sr solar
|
|
112
|
+
wea_file: Path to wea file (default: in.wea).
|
|
113
|
+
output_name: A name for output files (default: sky_mtx).
|
|
114
|
+
cumulative: A boolean to generate cumulative sky. This option is only
|
|
115
|
+
available in Radiance 5.3 and higher versions (default: False).
|
|
116
|
+
components: An integer between 0-2 to note the distribution of which
|
|
117
|
+
components should be included. 0 might be used to include both sun and
|
|
118
|
+
sky contribution. 1 may be used to produce a sun-only matrix, with no sky
|
|
119
|
+
contributions. Alternatively, 2 may be used to exclude any sun component
|
|
120
|
+
from the output. If there is a sun in the description, gendaymtx will
|
|
121
|
+
include its contribution in the four nearest sky patches, distributing
|
|
122
|
+
energy according to centroid proximity (default: 0).
|
|
123
|
+
"""
|
|
124
|
+
output_type = typing.int_in_range(output_type, 0, 1, 'SkyMatrix output type')
|
|
125
|
+
wea_file = wea_file or 'in.wea'
|
|
126
|
+
output_name = output_name or 'sky'
|
|
127
|
+
|
|
128
|
+
options = ['-O{}'.format(output_type)]
|
|
129
|
+
if self.density != 1:
|
|
130
|
+
options.append('-m %d' % self.density)
|
|
131
|
+
if self.north != 0:
|
|
132
|
+
options.append('-r {}'.format(self.north))
|
|
133
|
+
if cumulative:
|
|
134
|
+
options.append('-A')
|
|
135
|
+
if components == 1:
|
|
136
|
+
# sun-only
|
|
137
|
+
options.append('-d')
|
|
138
|
+
elif components == 2:
|
|
139
|
+
# sky only
|
|
140
|
+
options.append('-s')
|
|
141
|
+
options.append(wea_file)
|
|
142
|
+
# add all the other options here
|
|
143
|
+
command = 'gendaymtx {0} > {1}.mtx'.format(' '.join(options), output_name)
|
|
144
|
+
|
|
145
|
+
return command
|
|
146
|
+
|
|
147
|
+
def to_dict(self):
|
|
148
|
+
"""Translate this matrix to a dictionary."""
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
'type': 'SkyMatrix',
|
|
152
|
+
'wea': self.wea.to_dict(),
|
|
153
|
+
'north': self.north,
|
|
154
|
+
'density': self.density
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
def __eq__(self, value):
|
|
158
|
+
if type(value) != type(self) \
|
|
159
|
+
or value.wea != self.wea \
|
|
160
|
+
or value.north != self.north \
|
|
161
|
+
or value.density != self.density:
|
|
162
|
+
return False
|
|
163
|
+
return True
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Utilities to convert sky strings to Python objects."""
|
|
3
|
+
from honeybee_radiance.lightsource.sky.certainirradiance import CertainIrradiance
|
|
4
|
+
from honeybee_radiance.lightsource.sky.cie import CIE
|
|
5
|
+
from honeybee_radiance.lightsource.sky.climatebased import ClimateBased
|
|
6
|
+
|
|
7
|
+
SKY_TYPES = {
|
|
8
|
+
'irradiance': CertainIrradiance,
|
|
9
|
+
'illuminance': CertainIrradiance,
|
|
10
|
+
'cie': CIE,
|
|
11
|
+
'climate-based': ClimateBased
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def string_to_sky(sky_string, raise_exception=True):
|
|
16
|
+
"""Get a Python object of any sky from a string representation.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
sky_string: A text string representing a CIE, ClimateBased, or CertainIrradiance
|
|
20
|
+
sky. This can be a minimal representation of the sky (eg.
|
|
21
|
+
"cie -alt 71.6 -az 185.2 -type 0"). Or it can be a detailed specification of
|
|
22
|
+
time and location (eg. "cie 21 Jun 12:00 -lat 41.78 -lon -87.75 -type 0").
|
|
23
|
+
raise_exception: Boolean to note whether an exception should be raised
|
|
24
|
+
if the object is not identified as a sky. Default: True.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
A Python object derived from the input sky_string.
|
|
28
|
+
"""
|
|
29
|
+
sky_type = sky_string.lower().split(' ')[0].strip()
|
|
30
|
+
try:
|
|
31
|
+
return SKY_TYPES[sky_type].from_string(sky_string)
|
|
32
|
+
except KeyError:
|
|
33
|
+
if raise_exception:
|
|
34
|
+
raise ValueError('{} is not a recognized radiance Sky type'.format(sky_type))
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""Generate a point-in-time climate-based sky."""
|
|
2
|
+
from __future__ import division
|
|
3
|
+
import honeybee.typing as typing
|
|
4
|
+
import ladybug.futil as futil
|
|
5
|
+
from ladybug.wea import Wea
|
|
6
|
+
from ladybug_geometry.geometry2d.pointvector import Vector2D
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import math
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SunMatrix(object):
|
|
13
|
+
"""Annual Climate-based Sun matrix.
|
|
14
|
+
|
|
15
|
+
The output of SkyMatrix is similar to using command Radiance's gendaymtx command with
|
|
16
|
+
``-n -D`` options. The options are available in Radiance 5.3 and after that. For more
|
|
17
|
+
information see gendaymtx documentation.
|
|
18
|
+
|
|
19
|
+
https://www.radiance-online.org/learning/documentation/manual-pages/pdfs/gendaymtx.pdf
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
wea: A Ladybug wea object.
|
|
23
|
+
north: A number between -360 and 360 for the counterclockwise difference between
|
|
24
|
+
the North and the positive Y-axis in degrees. 90 is West and 270 is East
|
|
25
|
+
(Default: 0)
|
|
26
|
+
|
|
27
|
+
Properties:
|
|
28
|
+
* wea
|
|
29
|
+
* location
|
|
30
|
+
* north
|
|
31
|
+
* is_point_in_time
|
|
32
|
+
* is_climate_based
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
__slots__ = ('_wea', '_north')
|
|
36
|
+
|
|
37
|
+
def __init__(self, wea, north=0):
|
|
38
|
+
"""Create a climate-based sun matrix."""
|
|
39
|
+
self.wea = wea
|
|
40
|
+
self.north = north
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def wea(self):
|
|
44
|
+
"""Get and set wea."""
|
|
45
|
+
return self._wea
|
|
46
|
+
|
|
47
|
+
@wea.setter
|
|
48
|
+
def wea(self, value):
|
|
49
|
+
assert isinstance(value, Wea), \
|
|
50
|
+
'wea must be from type Wea not {}'.format(type(value))
|
|
51
|
+
self._wea = value
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def north(self):
|
|
55
|
+
"""Get and set north direction.
|
|
56
|
+
|
|
57
|
+
A number between -360 and 360 for the counterclockwise difference between
|
|
58
|
+
the North and the positive Y-axis in degrees. 90 is West and 270 is East.
|
|
59
|
+
"""
|
|
60
|
+
return self._north
|
|
61
|
+
|
|
62
|
+
@north.setter
|
|
63
|
+
def north(self, value):
|
|
64
|
+
value = typing.float_in_range(value, -360, +360, 'Skymatrix north')
|
|
65
|
+
self._north = value
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def is_climate_based(self):
|
|
69
|
+
"""Return True if the sky is created based on values from weather data."""
|
|
70
|
+
return True
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def is_point_in_time(self):
|
|
74
|
+
"""Return True if the sky is generated for a single point in time."""
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def location(self):
|
|
79
|
+
"""Location information for sky matrix."""
|
|
80
|
+
return self.wea.location
|
|
81
|
+
|
|
82
|
+
def north_from_vector(self, north_vector):
|
|
83
|
+
"""Automatically set the north property using a Vector2D.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
north_vector: A ladybug_geometry Vector2D for the north direction
|
|
87
|
+
"""
|
|
88
|
+
self._north = math.degrees(north_vector.angle_clockwise(Vector2D(0, 1)))
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def from_dict(cls, input_dict):
|
|
92
|
+
"""Create the sky from a dictionary.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
input_dict: A python dictionary in the following format
|
|
96
|
+
|
|
97
|
+
.. code-block:: python
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
'type': 'SunMatrix',
|
|
101
|
+
'wea': {},
|
|
102
|
+
'north': 0.0 # optional
|
|
103
|
+
}
|
|
104
|
+
"""
|
|
105
|
+
if 'type' not in input_dict or input_dict['type'] != 'SunMatrix':
|
|
106
|
+
raise ValueError('Input dict "type" must be "SunMatrix".')
|
|
107
|
+
if 'north' in input_dict:
|
|
108
|
+
sky = cls(Wea.from_dict(input_dict['wea']), input_dict['north'])
|
|
109
|
+
else:
|
|
110
|
+
sky = cls(input_dict['wea'])
|
|
111
|
+
|
|
112
|
+
return sky
|
|
113
|
+
|
|
114
|
+
# TODO: add support for additional parameters
|
|
115
|
+
# TODO: add gendaymtx to radiance-command and use it for validating inputs
|
|
116
|
+
def to_radiance(self, output_type=1, wea_file=None, output_name=None):
|
|
117
|
+
"""Return Radiance command to generate the sky.
|
|
118
|
+
|
|
119
|
+
Note that you need to write the wea to a file (in.wea) before running this
|
|
120
|
+
command.
|
|
121
|
+
|
|
122
|
+
Alternatively you can use write method which will write the wea data to a file.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
output_type: An integer between 0 to 1 for output type.
|
|
126
|
+
* 0 = output in W/m2/sr visible
|
|
127
|
+
* 1 = output in W/m2/sr solar (default)
|
|
128
|
+
wea_file: Path to wea file (default: in.wea).
|
|
129
|
+
output_name: A name for output files (default: suns).
|
|
130
|
+
"""
|
|
131
|
+
output_type = typing.int_in_range(output_type, 0, 1, 'SunMatrix output type')
|
|
132
|
+
wea_file = wea_file or 'in.wea'
|
|
133
|
+
output_name = output_name or 'suns'
|
|
134
|
+
if self.north == 0:
|
|
135
|
+
command = 'gendaymtx -n -D {0}.mtx -M {0}.mod -O{1} {2}'.format(
|
|
136
|
+
output_name, output_type, wea_file
|
|
137
|
+
)
|
|
138
|
+
else:
|
|
139
|
+
command = 'gendaymtx -n -D {0}.mtx -M {0}.mod -O{1} -r {3} {2}'.format(
|
|
140
|
+
output_name, output_type, wea_file, self.north
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return command
|
|
144
|
+
|
|
145
|
+
def to_dict(self):
|
|
146
|
+
"""Translate this matrix to a dictionary."""
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
'type': 'SunMatrix',
|
|
150
|
+
'wea': self.wea.to_dict(),
|
|
151
|
+
'north': self.north
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
def write_wea(self, folder='.', name=None, hoys=None):
|
|
155
|
+
"""Write wea to a file.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
folder: Path to target folder (Default: '.').
|
|
159
|
+
name: Optional name for the wea file (Default: in.wea)
|
|
160
|
+
hoys: Optional list of hoys to filter the hours of the wea. If None,
|
|
161
|
+
this object's wea will be used as-is. Note that you may not want
|
|
162
|
+
to use this input if this object's wea is not annual since an
|
|
163
|
+
exception will be raised if a given hoy is not found in the
|
|
164
|
+
wea. (Default: None).
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Path to wea file.
|
|
168
|
+
"""
|
|
169
|
+
name = name or 'in.wea'
|
|
170
|
+
file_path = os.path.join(folder, name)
|
|
171
|
+
wea_obj = self.wea if hoys is None else self.wea.filter_by_hoys(hoys)
|
|
172
|
+
return wea_obj.write(file_path=file_path)
|
|
173
|
+
|
|
174
|
+
def to_file(self, folder, name=None, hoys=None, mkdir=False):
|
|
175
|
+
"""Write matrix to a Radiance file.
|
|
176
|
+
|
|
177
|
+
This method also writes the wea information to a .wea file.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
folder: Target folder.
|
|
181
|
+
name: File name.
|
|
182
|
+
hoys: Optional list of hoys to filter the hours of the wea. If None,
|
|
183
|
+
this object's wea will be used as-is. Note that you may not want
|
|
184
|
+
to use this input if this object's wea is not annual since an
|
|
185
|
+
exception will be raised if a given hoy is not found in the
|
|
186
|
+
wea. (Default: None).
|
|
187
|
+
mkdir: A boolean to note if the directory should be created if doesn't
|
|
188
|
+
exist (default: False).
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Full path to the newly created file.
|
|
192
|
+
"""
|
|
193
|
+
name = typing.valid_string(name) if name \
|
|
194
|
+
else '%s.rad' % self.__class__.__name__.lower()
|
|
195
|
+
# write wea file first
|
|
196
|
+
wea_file = self.write_wea(folder, hoys=hoys)
|
|
197
|
+
content = self.to_radiance(wea_file=os.path.split(wea_file)[-1])
|
|
198
|
+
return futil.write_to_file_by_name(folder, name, '!' + content, mkdir)
|
|
199
|
+
|
|
200
|
+
def __eq__(self, value):
|
|
201
|
+
if not isinstance(value, self.__class__) \
|
|
202
|
+
or value.wea != self.wea \
|
|
203
|
+
or value.north != self.north:
|
|
204
|
+
return False
|
|
205
|
+
return True
|
|
206
|
+
|
|
207
|
+
def __ne__(self, value):
|
|
208
|
+
return not self.__eq__(value)
|
|
209
|
+
|
|
210
|
+
def __repr__(self):
|
|
211
|
+
"""Matrix representation."""
|
|
212
|
+
return '%s: %s' % (self.__class__.__name__, self.wea.location.city)
|