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,479 @@
|
|
|
1
|
+
"""Calculate irradiance values based on Radiance's gendaylit.
|
|
2
|
+
|
|
3
|
+
This code is parts of gendaylit.c which is copyrighted by:
|
|
4
|
+
Copyright (c) 1994,2006 *Fraunhofer Institut for Solar Energy Systems
|
|
5
|
+
Heidenhofstr. 2, D-79110 Freiburg, Germany
|
|
6
|
+
Agence de l'Environnement et de la Maitrise de l'Energie
|
|
7
|
+
Centre de Valbonne, 500 route des Lucioles, 06565 Sophia Antipolis Cedex, France
|
|
8
|
+
*BOUYGUES
|
|
9
|
+
1 Avenue Eugene Freyssinet, Saint-Quentin-Yvelines, France
|
|
10
|
+
|
|
11
|
+
You can check the source code at:
|
|
12
|
+
https://github.com/NREL/Radiance/blob/53485a7fb48727293d62f98d7bac830aa34ccba4/src/gen/gendaylit.c
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import division
|
|
16
|
+
import math
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
import sys
|
|
19
|
+
if (sys.version_info >= (3, 0)):
|
|
20
|
+
xrange = range
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def gendaylit(altitude, hoy, directirradiance, diffuseirradiance,
|
|
24
|
+
output_type=0, is_leap_year=False):
|
|
25
|
+
"""Get solar irradiance.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
altitude: Sun altitude in degrees.
|
|
29
|
+
hoy: Day of the year starting from 1.
|
|
30
|
+
directirradiance: Direct irradiance value.
|
|
31
|
+
diffuseirradiance: Diffuse irradiance value.
|
|
32
|
+
output_type: An integer between 0-2. 0=output in W/m^2/sr visible,
|
|
33
|
+
1=output in W/m^2/sr solar, 2=output in candela/m^2 (default: 0).
|
|
34
|
+
Returns:
|
|
35
|
+
solarradiance -- solar irradiance.
|
|
36
|
+
"""
|
|
37
|
+
#
|
|
38
|
+
coeff_perez = [
|
|
39
|
+
1.3525, -0.2576, -0.2690, -1.4366, -0.7670, 0.0007, 1.2734, -0.1233, 2.8000,
|
|
40
|
+
0.6004, 1.2375, 1.000, 1.8734, 0.6297, 0.9738, 0.2809, 0.0356, -0.1246,
|
|
41
|
+
-0.5718, 0.9938, -1.2219, -0.7730, 1.4148, 1.1016, -0.2054, 0.0367, -3.9128,
|
|
42
|
+
0.9156, 6.9750, 0.1774, 6.4477, -0.1239, -1.5798, -0.5081, -1.7812, 0.1080,
|
|
43
|
+
0.2624, 0.0672, -0.2190, -0.4285, -1.1000, -0.2515, 0.8952, 0.0156, 0.2782,
|
|
44
|
+
-0.1812, -4.5000, 1.1766, 24.7219, -13.0812, -37.7000, 34.8438, -5.0000, 1.5218,
|
|
45
|
+
3.9229, -2.6204, -0.0156, 0.1597, 0.4199, -0.5562, -0.5484, -0.6654, -0.2672,
|
|
46
|
+
0.7117, 0.7234, -0.6219, -5.6812, 2.6297, 33.3389, -18.3000, -62.2500, 52.0781,
|
|
47
|
+
-3.5000, 0.0016, 1.1477, 0.1062, 0.4659, -0.3296, -0.0876, -0.0329, -0.6000,
|
|
48
|
+
-0.3566, -2.5000, 2.3250, 0.2937, 0.0496, -5.6812, 1.8415, 21.0000, -4.7656,
|
|
49
|
+
-21.5906, 7.2492, -3.5000, -0.1554, 1.4062, 0.3988, 0.0032, 0.0766, -0.0656,
|
|
50
|
+
-0.1294, -1.0156, -0.3670, 1.0078, 1.4051, 0.2875, -0.5328, -3.8500, 3.3750,
|
|
51
|
+
14.0000, -0.9999, -7.1406, 7.5469, -3.4000, -0.1078, -1.0750, 1.5702, -0.0672,
|
|
52
|
+
0.4016, 0.3017, -0.4844, -1.0000, 0.0211, 0.5025, -0.5119, -0.3000, 0.1922,
|
|
53
|
+
0.7023, -1.6317, 19.0000, -5.0000, 1.2438, -1.9094, -4.0000, 0.0250, 0.3844,
|
|
54
|
+
0.2656, 1.0468, -0.3788, -2.4517, 1.4656, -1.0500, 0.0289, 0.4260, 0.3590,
|
|
55
|
+
-0.3250, 0.1156, 0.7781, 0.0025, 31.0625, -14.5000, -46.1148, 55.3750, -7.2312,
|
|
56
|
+
0.4050, 13.3500, 0.6234, 1.5000, -0.6426, 1.8564, 0.5636]
|
|
57
|
+
|
|
58
|
+
defangle_theta = [
|
|
59
|
+
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
|
|
60
|
+
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
|
61
|
+
72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
|
62
|
+
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
|
63
|
+
60, 60, 60, 60, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
|
64
|
+
48, 48, 48, 48, 48, 48, 48, 48, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
|
|
65
|
+
36, 36, 36, 36, 36, 36, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 12, 12,
|
|
66
|
+
12, 12, 12, 12, 0]
|
|
67
|
+
|
|
68
|
+
defangle_phi = [
|
|
69
|
+
0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204,
|
|
70
|
+
216, 228, 240, 252, 264, 276, 288, 300, 312, 324, 336, 348, 0, 12, 24, 36, 48,
|
|
71
|
+
60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, 252,
|
|
72
|
+
264, 276, 288, 300, 312, 324, 336, 348, 0, 15, 30, 45, 60, 75, 90, 105, 120, 135,
|
|
73
|
+
150, 165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 315, 330, 345, 0, 15, 30,
|
|
74
|
+
45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, 285,
|
|
75
|
+
300, 315, 330, 345, 0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240,
|
|
76
|
+
260, 280, 300, 320, 340, 0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330,
|
|
77
|
+
0, 60, 120, 180, 240, 300, 0]
|
|
78
|
+
|
|
79
|
+
WHTEFFICACY = 179.0 # luminous efficacy of uniform white light
|
|
80
|
+
|
|
81
|
+
# calculate solar direction
|
|
82
|
+
# daynumber = datetime(2017, month, day, int(hour)).timetuple().tm_yday
|
|
83
|
+
|
|
84
|
+
# print '# Solar altitude and azimuth: %.2f %.2f' % (sun.altitude, sun.azimuth - 180)
|
|
85
|
+
# print '# Day number: %d' % daynumber
|
|
86
|
+
# print -1 * sun.sun_vector
|
|
87
|
+
daynumber = int(hoy / 24) + 1
|
|
88
|
+
total_days = 365 if not is_leap_year else 365 + 24
|
|
89
|
+
day_angle = 2 * math.pi * (daynumber - 1) / total_days
|
|
90
|
+
|
|
91
|
+
# altitude correction if too close to zenith
|
|
92
|
+
if altitude > 87.0:
|
|
93
|
+
print("warning - sun too close to zenith, reducing altitude to 87 degrees.")
|
|
94
|
+
altitude = 87.0
|
|
95
|
+
|
|
96
|
+
sunzenith = 90 - altitude
|
|
97
|
+
|
|
98
|
+
# print '#Zenith: %f' % sunzenith
|
|
99
|
+
if directirradiance + diffuseirradiance == 0 or altitude <= 0:
|
|
100
|
+
return 0
|
|
101
|
+
|
|
102
|
+
directirradiance, diffuseirradiance = \
|
|
103
|
+
check_input_values(directirradiance, diffuseirradiance, altitude)
|
|
104
|
+
|
|
105
|
+
skybrightness = sky_brightness(diffuseirradiance, sunzenith, day_angle)
|
|
106
|
+
skyclearness = sky_clearness(diffuseirradiance, directirradiance, sunzenith)
|
|
107
|
+
|
|
108
|
+
skyclearness, skybrightness = check_parametrization(skyclearness, skybrightness)
|
|
109
|
+
|
|
110
|
+
# print '# clearness: %f, brighness: %f' % (skyclearness, skybrightness)
|
|
111
|
+
|
|
112
|
+
# diffuse horizontal illuminance
|
|
113
|
+
diffuseilluminance = diffuseirradiance * \
|
|
114
|
+
glob_h_diffuse_effi_perez(skyclearness, skybrightness, sunzenith)
|
|
115
|
+
|
|
116
|
+
directilluminance = directirradiance * \
|
|
117
|
+
direct_n_effi_perez(skyclearness, skybrightness, sunzenith)
|
|
118
|
+
|
|
119
|
+
directilluminance, diffuseilluminance = \
|
|
120
|
+
check_input_values(directilluminance, diffuseilluminance, altitude)
|
|
121
|
+
|
|
122
|
+
# print '# Illuminance direct %f, diffuse %f' \
|
|
123
|
+
# % (directilluminance, diffuseilluminance)
|
|
124
|
+
|
|
125
|
+
# calculate sky
|
|
126
|
+
# read the angles * \
|
|
127
|
+
half_sun_angle = 0.2665
|
|
128
|
+
theta_o = defangle_theta
|
|
129
|
+
phi_o = defangle_phi
|
|
130
|
+
lv_mod = [] # 145 illuminance values
|
|
131
|
+
|
|
132
|
+
# parameters for the perez model * \
|
|
133
|
+
skybrightness = \
|
|
134
|
+
coeff_lum_perez(radians(sunzenith), skyclearness, skybrightness, coeff_perez)
|
|
135
|
+
|
|
136
|
+
# calculation of the modelled luminance * \
|
|
137
|
+
for j in xrange(145):
|
|
138
|
+
dzeta, gamma = theta_phi_to_dzeta_gamma(
|
|
139
|
+
radians(theta_o[j]), radians(phi_o[j]), radians(sunzenith)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
v = calc_rel_lum_perez(
|
|
143
|
+
dzeta, gamma, radians(sunzenith), skyclearness, skybrightness, coeff_perez
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
lv_mod.append(v)
|
|
147
|
+
# print "theta, phi, lv_mod %f\t %f\t %f\n" % (theta_o[j], phi_o[j], lv_mod[j])
|
|
148
|
+
|
|
149
|
+
# integration of luminance for the normalization factor, diffuse part of the sky
|
|
150
|
+
diffnormalization = integ_lv(lv_mod, theta_o)
|
|
151
|
+
|
|
152
|
+
# normalization coefficient in lumen or in watt * \
|
|
153
|
+
if output_type == 0:
|
|
154
|
+
diffnormalization = diffuseilluminance / diffnormalization / WHTEFFICACY
|
|
155
|
+
elif output_type == 1:
|
|
156
|
+
diffnormalization = diffuseirradiance / diffnormalization
|
|
157
|
+
elif output_type == 2:
|
|
158
|
+
diffnormalization = diffuseilluminance / diffnormalization
|
|
159
|
+
|
|
160
|
+
# calculation for the solar source * \
|
|
161
|
+
if output_type == 0:
|
|
162
|
+
solarradiance = directilluminance / \
|
|
163
|
+
(2 * math.pi * (1 - math.cos(half_sun_angle * math.pi / 180))) / WHTEFFICACY
|
|
164
|
+
|
|
165
|
+
elif output_type == 1:
|
|
166
|
+
solarradiance = directirradiance / \
|
|
167
|
+
(2 * math.pi * (1 - math.cos(half_sun_angle * math.pi / 180)))
|
|
168
|
+
|
|
169
|
+
else:
|
|
170
|
+
solarradiance = directilluminance / \
|
|
171
|
+
(2 * math.pi * (1 - math.cos(half_sun_angle * math.pi / 180)))
|
|
172
|
+
|
|
173
|
+
return solarradiance
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def radians(degres):
|
|
177
|
+
# /* degrees into radians */
|
|
178
|
+
return degres * math.pi / 180.0
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def integ_lv(lv, theta):
|
|
182
|
+
# int i
|
|
183
|
+
buffer = 0.0
|
|
184
|
+
|
|
185
|
+
for i in xrange(145):
|
|
186
|
+
buffer += lv[i] * math.cos(radians(theta[i]))
|
|
187
|
+
|
|
188
|
+
return buffer * 2 * math.pi / 144
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def get_numlin(epsilon):
|
|
192
|
+
|
|
193
|
+
if (epsilon < 1.065):
|
|
194
|
+
return 0
|
|
195
|
+
elif (epsilon < 1.230):
|
|
196
|
+
return 1
|
|
197
|
+
elif (epsilon < 1.500):
|
|
198
|
+
return 2
|
|
199
|
+
elif (epsilon < 1.950):
|
|
200
|
+
return 3
|
|
201
|
+
elif (epsilon < 2.800):
|
|
202
|
+
return 4
|
|
203
|
+
elif (epsilon < 4.500):
|
|
204
|
+
return 5
|
|
205
|
+
elif (epsilon < 6.200):
|
|
206
|
+
return 6
|
|
207
|
+
return 7
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def theta_phi_to_dzeta_gamma(theta, phi, z):
|
|
211
|
+
"""Calculation of the angles dzeta and gamma."""
|
|
212
|
+
dzeta = theta
|
|
213
|
+
|
|
214
|
+
if ((math.cos(z) * math.cos(theta) + math.sin(z) * math.sin(theta) *
|
|
215
|
+
math.cos(phi)) > 1 and (math.cos(z) * math.cos(theta) + math.sin(z) *
|
|
216
|
+
math.sin(theta) * math.cos(phi) < 1.1)):
|
|
217
|
+
gamma = 0
|
|
218
|
+
elif math.cos(z) * math.cos(theta) + math.sin(z) * math.sin(theta) * \
|
|
219
|
+
math.cos(phi) > 1.1:
|
|
220
|
+
raise ValueError("error in calculation of gamma (angle between point and sun)")
|
|
221
|
+
else:
|
|
222
|
+
gamma = math.acos(math.cos(z) * math.cos(theta) + math.sin(z) *
|
|
223
|
+
math.sin(theta) * math.cos(phi))
|
|
224
|
+
|
|
225
|
+
return dzeta, gamma
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def calc_rel_lum_perez(dzeta, gamma, z, epsilon, delta, coeff_perez):
|
|
229
|
+
"""Sky luminance perez model."""
|
|
230
|
+
x = [[], [], [], [], []]
|
|
231
|
+
c_perez = list(range(5))
|
|
232
|
+
|
|
233
|
+
# limitations for the variation of the Perez parameters */
|
|
234
|
+
skyclearinf = 1.0
|
|
235
|
+
skyclearsup = 12.01
|
|
236
|
+
|
|
237
|
+
if epsilon < skyclearinf or epsilon >= skyclearsup:
|
|
238
|
+
raise ValueError("Error: epsilon out of range in function calc_rel_lum_perez!\n")
|
|
239
|
+
|
|
240
|
+
# correction de modele de Perez solar energy ...* \
|
|
241
|
+
if epsilon > 1.065 and epsilon < 2.8:
|
|
242
|
+
if (delta < 0.2):
|
|
243
|
+
delta = 0.2
|
|
244
|
+
|
|
245
|
+
num_lin = get_numlin(epsilon)
|
|
246
|
+
# print "nline %d epsilon %f\n" % (num_lin, epsilon)
|
|
247
|
+
|
|
248
|
+
for i in xrange(5):
|
|
249
|
+
for j in xrange(4):
|
|
250
|
+
x[i].append(coeff_perez[20 * num_lin + 4 * i + j % 60])
|
|
251
|
+
# print "inside_loop %d %d vaut %f\n" % (i, j, x[i][j])
|
|
252
|
+
|
|
253
|
+
if num_lin:
|
|
254
|
+
for i in xrange(5):
|
|
255
|
+
c_perez[i] = x[i][0] + x[i][1] * z + delta * (x[i][2] + x[i][3] * z)
|
|
256
|
+
else:
|
|
257
|
+
c_perez[0] = x[0][0] + x[0][1] * z + delta * (x[0][2] + x[0][3] * z)
|
|
258
|
+
c_perez[1] = x[1][0] + x[1][1] * z + delta * (x[1][2] + x[1][3] * z)
|
|
259
|
+
c_perez[4] = x[4][0] + x[4][1] * z + delta * (x[4][2] + x[4][3] * z)
|
|
260
|
+
c_perez[2] = math.exp(
|
|
261
|
+
math.pow(delta * (x[2][0] + x[2][1] * z), x[2][2])) - x[2][3]
|
|
262
|
+
c_perez[3] = -math.exp(
|
|
263
|
+
delta * (x[3][0] + x[3][1] * z)) + x[3][2] + delta * x[3][3]
|
|
264
|
+
|
|
265
|
+
return (1 + c_perez[0] * math.exp(c_perez[1] / math.cos(dzeta))) * \
|
|
266
|
+
(1 + c_perez[2] * math.exp(c_perez[3] * gamma) +
|
|
267
|
+
c_perez[4] * math.cos(gamma) * math.cos(gamma))
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def sky_clearness(diffuseirradiance, directirradiance, sunzenith):
|
|
271
|
+
"""Perez sky's clearness."""
|
|
272
|
+
try:
|
|
273
|
+
value = (
|
|
274
|
+
(diffuseirradiance + directirradiance) / (diffuseirradiance) +
|
|
275
|
+
1.041 * sunzenith * math.pi / 180 * sunzenith * math.pi /
|
|
276
|
+
180 * sunzenith * math.pi / 180) / (1 + 1.041 * sunzenith * math.pi / 180 *
|
|
277
|
+
sunzenith * math.pi / 180 * sunzenith *
|
|
278
|
+
math.pi / 180)
|
|
279
|
+
except ZeroDivisionError:
|
|
280
|
+
msg = 'diff: {}, dir: {}, zenith: {}'.format(diffuseirradiance,
|
|
281
|
+
directirradiance, sunzenith)
|
|
282
|
+
raise ZeroDivisionError(msg)
|
|
283
|
+
|
|
284
|
+
return value
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def sky_brightness(diffuseirradiance, sunzenith, day_angle):
|
|
288
|
+
solar_constant_e = 1367 # solar constant W/m^2
|
|
289
|
+
"""Perez sky's brightness"""
|
|
290
|
+
brighness = diffuseirradiance * \
|
|
291
|
+
air_mass(sunzenith) / (solar_constant_e * get_eccentricity(day_angle))
|
|
292
|
+
return brighness
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def get_eccentricity(day_angle):
|
|
296
|
+
"""Enter day number, return E0 = square(R0/R): eccentricity correction factor."""
|
|
297
|
+
e0 = 1.00011 + 0.034221 * math.cos(day_angle) + 0.00128 * math.sin(day_angle) + \
|
|
298
|
+
0.000719 * math.cos(2 * day_angle) + 0.000077 * math.sin(2 * day_angle)
|
|
299
|
+
|
|
300
|
+
return e0
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def air_mass(sunzenith):
|
|
304
|
+
"""Enter sunzenith angle (degrees) return relative air mass (double)."""
|
|
305
|
+
if sunzenith > 90:
|
|
306
|
+
# print("Warning: air mass has reached the maximal value: %f \n" % sunzenith)
|
|
307
|
+
sunzenith = 90
|
|
308
|
+
|
|
309
|
+
m = 1 / (math.cos(sunzenith * math.pi / 180) + 0.15 *
|
|
310
|
+
math.exp(math.log(93.885 - sunzenith) * (-1.253)))
|
|
311
|
+
return m
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def check_parametrization(skyclearness, skybrightness):
|
|
315
|
+
"""Check the range of epsilon and delta indexes of the perez parametrization."""
|
|
316
|
+
# # limitations for the variation of the Perez parameters * \
|
|
317
|
+
skyclearinf = 1.0
|
|
318
|
+
skyclearsup = 12.01
|
|
319
|
+
skybriginf = 0.01
|
|
320
|
+
skybrigsup = 0.6
|
|
321
|
+
if skyclearness < skyclearinf or skyclearness > skyclearsup \
|
|
322
|
+
or skybrightness < skybriginf or skybrightness > skybrigsup:
|
|
323
|
+
# # limit sky clearness or sky brightness, 2009 11 13 by J. Wienold */
|
|
324
|
+
|
|
325
|
+
if (skyclearness < skyclearinf):
|
|
326
|
+
# # if (suppress_warnings==0)
|
|
327
|
+
# print(stderr,"Range warning: sky clearness too low (%lf)\n",
|
|
328
|
+
# skyclearness) */
|
|
329
|
+
skyclearness = skyclearinf
|
|
330
|
+
|
|
331
|
+
if (skyclearness > skyclearsup):
|
|
332
|
+
# # if (suppress_warnings==0)
|
|
333
|
+
# print(stderr,"Range warning: sky clearness too high (%lf)\n",
|
|
334
|
+
# skyclearness) */
|
|
335
|
+
skyclearness = skyclearsup - 0.001
|
|
336
|
+
|
|
337
|
+
if (skybrightness < skybriginf):
|
|
338
|
+
# # if (suppress_warnings==0)
|
|
339
|
+
# print(stderr,"Range warning: sky brightness too low (%lf)\n",
|
|
340
|
+
# skybrightness) */
|
|
341
|
+
skybrightness = skybriginf
|
|
342
|
+
|
|
343
|
+
if (skybrightness > skybrigsup):
|
|
344
|
+
# # if (suppress_warnings==0)
|
|
345
|
+
# print(stderr,"Range warning: sky brightness too high (%lf)\n",
|
|
346
|
+
# skybrightness) */
|
|
347
|
+
skybrightness = skybrigsup
|
|
348
|
+
|
|
349
|
+
return skyclearness, skybrightness
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def glob_h_diffuse_effi_perez(skyclearness, skybrightness, sunzenith):
|
|
353
|
+
"""Global horizontal diffuse efficacy model, according to PEREZ."""
|
|
354
|
+
# # initialize category bounds (clearness index bounds) */
|
|
355
|
+
atm_preci_water = 2
|
|
356
|
+
|
|
357
|
+
# //XXX: category_bounds > 0.1 started from 1!
|
|
358
|
+
category_bounds = (1, 1.065, 1.230, 1.500, 1.950, 2.800, 4.500, 6.200, 12.01)
|
|
359
|
+
|
|
360
|
+
# # initialize model coefficients * \
|
|
361
|
+
a = (97.24, 107.22, 104.97, 102.39, 100.71, 106.42, 141.88, 152.23)
|
|
362
|
+
|
|
363
|
+
b = (-0.46, 1.15, 2.96, 5.59, 5.94, 3.83, 1.90, 0.35)
|
|
364
|
+
|
|
365
|
+
c = (12.00, 0.59, -5.53, -13.95, -22.75, -36.15, -53.24, -45.27)
|
|
366
|
+
|
|
367
|
+
d = (-8.91, -3.95, -8.77, -13.90, -23.74, -28.83, -14.03, -7.98)
|
|
368
|
+
|
|
369
|
+
category_number = -1
|
|
370
|
+
for i in xrange(1, 8):
|
|
371
|
+
if category_bounds[i - 1] <= skyclearness < category_bounds[i]:
|
|
372
|
+
category_number = i - 1
|
|
373
|
+
|
|
374
|
+
if category_number == -1:
|
|
375
|
+
ValueError(
|
|
376
|
+
"Warning: sky clearness (= %.3f) too high,"
|
|
377
|
+
" printing error sky\n" % skyclearness
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
value = a[category_number] + b[category_number] * atm_preci_water + \
|
|
381
|
+
c[category_number] * math.cos(sunzenith * math.pi / 180) + \
|
|
382
|
+
d[category_number] * math.log(skybrightness)
|
|
383
|
+
|
|
384
|
+
return value
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def direct_n_effi_perez(skyclearness, skybrightness, sunzenith):
|
|
388
|
+
"""Direct normal efficacy model, according to PEREZ."""
|
|
389
|
+
atm_preci_water = 2
|
|
390
|
+
# # initialize category bounds(clearness index bounds) * \
|
|
391
|
+
category_bounds = (1, 1.065, 1.230, 1.500, 1.950, 2.800, 4.500, 6.200, 12.01)
|
|
392
|
+
|
|
393
|
+
# # initialize model coefficients * \
|
|
394
|
+
a = (57.20, 98.99, 109.83, 110.34, 106.36, 107.19, 105.75, 101.18)
|
|
395
|
+
|
|
396
|
+
b = (-4.55, -3.46, -4.90, -5.84, -3.97, -1.25, 0.77, 1.58)
|
|
397
|
+
|
|
398
|
+
c = (-2.98, -1.21, -1.71, -1.99, -1.75, -1.51, -1.26, -1.10)
|
|
399
|
+
|
|
400
|
+
d = (117.12, 12.38, -8.81, -4.56, -6.16, -26.73, -34.44, -8.29)
|
|
401
|
+
|
|
402
|
+
category_number = -1
|
|
403
|
+
for i in xrange(1, 8):
|
|
404
|
+
if category_bounds[i - 1] <= skyclearness < category_bounds[i]:
|
|
405
|
+
category_number = i - 1
|
|
406
|
+
|
|
407
|
+
value = a[category_number] + b[category_number] * atm_preci_water + \
|
|
408
|
+
c[category_number] * math.exp(5.73 * sunzenith * math.pi / 180 - 5) + \
|
|
409
|
+
d[category_number] * skybrightness
|
|
410
|
+
|
|
411
|
+
if value < 0:
|
|
412
|
+
value = 0
|
|
413
|
+
|
|
414
|
+
return value
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def check_input_values(directilluminance, diffuseilluminance, altitude):
|
|
418
|
+
"""Validity of the direct and diffuse components."""
|
|
419
|
+
solar_constant_l = 127500 # solar constant lux
|
|
420
|
+
if directilluminance < 0:
|
|
421
|
+
print("Warning: direct illuminance < 0. Using 0.0\n")
|
|
422
|
+
directilluminance = 0.0
|
|
423
|
+
|
|
424
|
+
if diffuseilluminance < 0:
|
|
425
|
+
print("Warning: diffuse illuminance < 0. Using 0.0\n")
|
|
426
|
+
diffuseilluminance = 0.0
|
|
427
|
+
|
|
428
|
+
if directilluminance + diffuseilluminance == 0 and altitude > 0:
|
|
429
|
+
raise ValueError("Warning: zero illuminance at sun altitude > 0\n")
|
|
430
|
+
|
|
431
|
+
if directilluminance > solar_constant_l:
|
|
432
|
+
raise ValueError("Warning: direct illuminance exceeds solar constant\n")
|
|
433
|
+
|
|
434
|
+
if directilluminance != 0 and diffuseilluminance == 0:
|
|
435
|
+
diffuseilluminance = 0.00000001
|
|
436
|
+
|
|
437
|
+
return directilluminance, diffuseilluminance
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def coeff_lum_perez(z, epsilon, delta, coeff_perez):
|
|
441
|
+
"""Coefficients for the sky luminance perez model."""
|
|
442
|
+
x = [[], [], [], [], []]
|
|
443
|
+
c_perez = list(range(5))
|
|
444
|
+
|
|
445
|
+
# limitations for the variation of the Perez parameters */
|
|
446
|
+
skyclearinf = 1.0
|
|
447
|
+
skyclearsup = 12.01
|
|
448
|
+
|
|
449
|
+
if epsilon < skyclearinf or epsilon >= skyclearsup:
|
|
450
|
+
raise ValueError("Error: epsilon out of range in function coeff_lum_perez!\n")
|
|
451
|
+
|
|
452
|
+
# /* correction du modele de Perez solar energy ...*/
|
|
453
|
+
if epsilon > 1.065 and epsilon < 2.8:
|
|
454
|
+
if delta < 0.2:
|
|
455
|
+
delta = 0.2
|
|
456
|
+
|
|
457
|
+
return delta
|
|
458
|
+
|
|
459
|
+
# This part of the code won't be executed and is only important for prez sky
|
|
460
|
+
num_lin = get_numlin(epsilon)
|
|
461
|
+
|
|
462
|
+
# /*fprintf(stderr,"numlin %d\n", num_lin)*/
|
|
463
|
+
|
|
464
|
+
for i in range(5):
|
|
465
|
+
for j in range(4):
|
|
466
|
+
x[i].append(coeff_perez[(20 * num_lin + 4 * i + j) % 60])
|
|
467
|
+
|
|
468
|
+
if (num_lin):
|
|
469
|
+
for i in range(5):
|
|
470
|
+
c_perez[i] = x[i][0] + x[i][1] * z + delta * (x[i][2] + x[i][3] * z)
|
|
471
|
+
|
|
472
|
+
else:
|
|
473
|
+
c_perez[0] = x[0][0] + x[0][1] * z + delta * (x[0][2] + x[0][3] * z)
|
|
474
|
+
c_perez[1] = x[1][0] + x[1][1] * z + delta * (x[1][2] + x[1][3] * z)
|
|
475
|
+
c_perez[4] = x[4][0] + x[4][1] * z + delta * (x[4][2] + x[4][3] * z)
|
|
476
|
+
c_perez[2] = math.exp(math.pow(delta * (x[2][0] + x[2][1] * z), x[2][2])) \
|
|
477
|
+
- x[2][3]
|
|
478
|
+
c_perez[3] = -math.exp(delta * (x[3][0] + x[3][1] * z)) + x[3][2] + \
|
|
479
|
+
delta * x[3][3]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Utilities to convert light source dictionaries to Python objects."""
|
|
3
|
+
from honeybee_radiance.lightsource.sunpath import Sunpath
|
|
4
|
+
from honeybee_radiance.lightsource.ground import Ground
|
|
5
|
+
from honeybee_radiance.lightsource.sky.certainirradiance import CertainIrradiance
|
|
6
|
+
from honeybee_radiance.lightsource.sky.cie import CIE
|
|
7
|
+
from honeybee_radiance.lightsource.sky.climatebased import ClimateBased
|
|
8
|
+
from honeybee_radiance.lightsource.sky.hemisphere import Hemisphere
|
|
9
|
+
from honeybee_radiance.lightsource.sky.skydome import SkyDome
|
|
10
|
+
from honeybee_radiance.lightsource.sky.skymatrix import SkyMatrix
|
|
11
|
+
from honeybee_radiance.lightsource.sky.sunmatrix import SunMatrix
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
LIGHT_SOURCE_TYPES = {
|
|
15
|
+
'Sunpath': Sunpath,
|
|
16
|
+
'Ground': Ground,
|
|
17
|
+
'CertainIrradiance': CertainIrradiance,
|
|
18
|
+
'CIE': CIE,
|
|
19
|
+
'ClimateBased': ClimateBased,
|
|
20
|
+
'Hemisphere': Hemisphere,
|
|
21
|
+
'SkyDome': SkyDome,
|
|
22
|
+
'SkyMatrix': SkyMatrix,
|
|
23
|
+
'SunMatrix': SunMatrix
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def dict_to_light_source(light_source_dict, raise_exception=True):
|
|
28
|
+
"""Get a Python object of any light source from a dictionary.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
light_source_dict: A dictionary of any Honeybee Radiance light source. Note
|
|
32
|
+
that this should be a non-abridged dictionary to be valid.
|
|
33
|
+
raise_exception: Boolean to note whether an excpetion should be raised
|
|
34
|
+
if the object is not identified as a light source. Default: True.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
A Python object derived from the input light_source_dict.
|
|
38
|
+
"""
|
|
39
|
+
try: # get the type key from the dictionary
|
|
40
|
+
light_type = light_source_dict['type']
|
|
41
|
+
except KeyError:
|
|
42
|
+
raise ValueError('Light source dictionary lacks required "type" key.')
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
return LIGHT_SOURCE_TYPES[light_type].from_dict(light_source_dict)
|
|
46
|
+
except KeyError:
|
|
47
|
+
if raise_exception:
|
|
48
|
+
raise ValueError(
|
|
49
|
+
'{} is not a recognized radiance Light Source type'.format(light_type))
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Radiance ground.
|
|
2
|
+
|
|
3
|
+
Ground is usually used as part of the sky definition.
|
|
4
|
+
"""
|
|
5
|
+
import honeybee.typing as typing
|
|
6
|
+
import ladybug.futil as futil
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Ground(object):
|
|
10
|
+
"""Radiance ground.
|
|
11
|
+
|
|
12
|
+
Ground definition relies on skyfunc and must be used with one of the Radiance
|
|
13
|
+
skies generated by gendaylit, gensky, etc. You can adjust the ground reflection
|
|
14
|
+
using -g option in gensky / gendaylit. The default value in gensky is %20.
|
|
15
|
+
|
|
16
|
+
.. code-block:: shell
|
|
17
|
+
|
|
18
|
+
skyfunc glow ground_glow
|
|
19
|
+
0
|
|
20
|
+
0
|
|
21
|
+
4 1 1 1 0
|
|
22
|
+
ground_glow source ground
|
|
23
|
+
0
|
|
24
|
+
0
|
|
25
|
+
4 0 0 -1 180
|
|
26
|
+
|
|
27
|
+
oconv some.sky ground.rad scene.rad > scene.oct
|
|
28
|
+
|
|
29
|
+
Note:
|
|
30
|
+
For more information see Chapter `6.3.4 The Ground "Glow": An "Upside-Down"
|
|
31
|
+
Sky` in Rendering with Radiance. The chapter is also accessible online at the
|
|
32
|
+
link below.
|
|
33
|
+
https://www.radiance-online.org/community/workshops/2003-berkeley/presentations/Mardaljevic/rwr_ch6.pdf
|
|
34
|
+
|
|
35
|
+
Properties:
|
|
36
|
+
* r_emittance
|
|
37
|
+
* g_emittance
|
|
38
|
+
* b_emittance
|
|
39
|
+
* modifier
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, modifier='skyfunc'):
|
|
43
|
+
"""Create ground.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
modifier: Optional input to change the modifier from skyfunc.
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
self.modifier = modifier
|
|
50
|
+
self._r_emittance = 1.0
|
|
51
|
+
self._g_emittance = 1.0
|
|
52
|
+
self._b_emittance = 1.0
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def r_emittance(self):
|
|
56
|
+
"""Ground emittance values for red channel (Default: 1.0)."""
|
|
57
|
+
return self._r_emittance
|
|
58
|
+
|
|
59
|
+
@r_emittance.setter
|
|
60
|
+
def r_emittance(self, value):
|
|
61
|
+
self._r_emittance = typing.float_in_range(value, 0, 1, 'r_emittance')
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def g_emittance(self):
|
|
65
|
+
"""Ground emittance values for green channel (Default: 1.0)."""
|
|
66
|
+
return self._g_emittance
|
|
67
|
+
|
|
68
|
+
@g_emittance.setter
|
|
69
|
+
def g_emittance(self, value):
|
|
70
|
+
self._g_emittance = typing.float_in_range(value, 0, 1, 'g_emittance')
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def b_emittance(self):
|
|
74
|
+
"""Ground emittance values for blue channel (Default: 1.0)."""
|
|
75
|
+
return self._b_emittance
|
|
76
|
+
|
|
77
|
+
@b_emittance.setter
|
|
78
|
+
def b_emittance(self, value):
|
|
79
|
+
self._b_emittance = typing.float_in_range(value, 0, 1, 'b_emittance')
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def modifier(self):
|
|
83
|
+
"Ground modifier."
|
|
84
|
+
return self._modifier
|
|
85
|
+
|
|
86
|
+
@modifier.setter
|
|
87
|
+
def modifier(self, value):
|
|
88
|
+
self._modifier = str(value)
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def from_dict(cls, input_dict):
|
|
92
|
+
"""Create ground from_dict.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
input_dict: A python dictionary in the following format
|
|
96
|
+
|
|
97
|
+
.. code-block:: python
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
'type': 'Ground',
|
|
101
|
+
'r_emittance': r_emittance,
|
|
102
|
+
'g_emittance': g_emittance,
|
|
103
|
+
'b_emittance': b_emittance,
|
|
104
|
+
'modifier': modifier
|
|
105
|
+
}
|
|
106
|
+
"""
|
|
107
|
+
assert 'type' in input_dict, \
|
|
108
|
+
'Input dict is missing type. Not a valid ground dictionary.'
|
|
109
|
+
assert input_dict['type'] == 'Ground', \
|
|
110
|
+
'Input type must be Ground not %s' % input_dict['type']
|
|
111
|
+
ground = cls()
|
|
112
|
+
ground.r_emittance = input_dict['r_emittance']
|
|
113
|
+
ground.g_emittance = input_dict['g_emittance']
|
|
114
|
+
ground.b_emittance = input_dict['b_emittance']
|
|
115
|
+
ground.modifier = input_dict['modifier']
|
|
116
|
+
return ground
|
|
117
|
+
|
|
118
|
+
def to_file(self, folder='.', name=None, mkdir=False):
|
|
119
|
+
"""Write ground to a .ground Radiance file.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
Full path to the newly created file.
|
|
123
|
+
"""
|
|
124
|
+
content = self.to_radiance() + '\n'
|
|
125
|
+
name = typing.valid_string(name) if name else 'ground.rad'
|
|
126
|
+
return futil.write_to_file_by_name(folder, name, content, mkdir)
|
|
127
|
+
|
|
128
|
+
def to_radiance(self):
|
|
129
|
+
"""Get ground as a Radiance input string."""
|
|
130
|
+
ground = \
|
|
131
|
+
'%s glow ground_glow\n0\n0\n4 %.3f %.3f %.3f 0\n' \
|
|
132
|
+
'ground_glow source ground\n0\n0\n4 0 0 -1 180' % (
|
|
133
|
+
self._modifier, self.r_emittance, self.g_emittance, self.b_emittance
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
return ground
|
|
137
|
+
|
|
138
|
+
def to_dict(self):
|
|
139
|
+
"""Translate ground to a dictionary."""
|
|
140
|
+
return {
|
|
141
|
+
'type': 'Ground',
|
|
142
|
+
'r_emittance': self.r_emittance,
|
|
143
|
+
'g_emittance': self.g_emittance,
|
|
144
|
+
'b_emittance': self.b_emittance,
|
|
145
|
+
'modifier': self.modifier
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
def __eq__(self, value):
|
|
149
|
+
if type(value) != type(self):
|
|
150
|
+
return False
|
|
151
|
+
if (value.modifier, value.r_emittance, value.g_emittance, value.b_emittance) != \
|
|
152
|
+
(self.modifier, self.r_emittance, self.g_emittance, self.b_emittance):
|
|
153
|
+
return False
|
|
154
|
+
return True
|
|
155
|
+
|
|
156
|
+
def __ne__(self, value):
|
|
157
|
+
return not self.__eq__(value)
|
|
158
|
+
|
|
159
|
+
def __repr__(self):
|
|
160
|
+
return self.to_radiance()
|