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,331 @@
|
|
|
1
|
+
"""honeybee radiance sunpath commands."""
|
|
2
|
+
import click
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from honeybee_radiance.config import folders
|
|
6
|
+
from honeybee_radiance_command.gendaymtx import Gendaymtx, GendaymtxOptions
|
|
7
|
+
from honeybee_radiance_command._command_util import run_command
|
|
8
|
+
|
|
9
|
+
from honeybee_radiance.lightsource.sunpath import Sunpath
|
|
10
|
+
from ladybug.location import Location
|
|
11
|
+
from ladybug.wea import Wea
|
|
12
|
+
import logging
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
from .util import get_hoys
|
|
17
|
+
|
|
18
|
+
_logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.group(help='Commands to generate Radiance Sunpath.')
|
|
22
|
+
def sunpath():
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@sunpath.command('location')
|
|
27
|
+
@click.option(
|
|
28
|
+
'--lat', default=0, type=float, show_default=True,
|
|
29
|
+
help='The latitude of the location in degrees. Values must be between -90 and 90.'
|
|
30
|
+
' Default is set to the equator.')
|
|
31
|
+
@click.option(
|
|
32
|
+
'--lon', default=0, type=float, show_default=True,
|
|
33
|
+
help='The longitude of the location in degrees')
|
|
34
|
+
@click.option(
|
|
35
|
+
'--tz', default=0, type=float, show_default=True,
|
|
36
|
+
help='A number representing the time zone of the location you are constructing. This'
|
|
37
|
+
' can improve the accuracy of the resulting sun plot. The time zone should follow'
|
|
38
|
+
' the epw convention and should be between -12 and +12, where 0 is at Greenwich, UK,'
|
|
39
|
+
' positive values are to the East of Greenwich and negative values are to the West.')
|
|
40
|
+
@click.option(
|
|
41
|
+
'--north', default=0, type=float, show_default=True,
|
|
42
|
+
help='Angle to north (0-360). 90 is west and 270 is east')
|
|
43
|
+
@click.option(
|
|
44
|
+
'--start-date', default='JAN-01', show_default=True,
|
|
45
|
+
help='Start date as MMM-DD (e.g JUL-21). Start date itself will also be included.')
|
|
46
|
+
@click.option(
|
|
47
|
+
'--start-time', default='00:00', show_default=True,
|
|
48
|
+
help='Start time as HH:MM (e.g 14:10). Start time itself will also be included.')
|
|
49
|
+
@click.option(
|
|
50
|
+
'--end-date', default='DEC-31', show_default=True,
|
|
51
|
+
help='End date as MMM-DD (e.g JUL-21). End date itself will also be included.')
|
|
52
|
+
@click.option(
|
|
53
|
+
'--end-time', default='23:00', show_default=True,
|
|
54
|
+
help='End time as HH:MM (e.g 18:30). End time itself will also be included.')
|
|
55
|
+
@click.option(
|
|
56
|
+
'--timestep', default=1, type=int, show_default=True,
|
|
57
|
+
help='An optional integer to set the number of time steps per hour. Default is 1'
|
|
58
|
+
' for one value per hour.')
|
|
59
|
+
@click.option('--leap-year/--full-year', ' /-fy',
|
|
60
|
+
help='Flag for whether to use a leap year.')
|
|
61
|
+
@click.option('--folder', default='.', help='Output folder.')
|
|
62
|
+
@click.option('--name', default='sunpath', help='File name.')
|
|
63
|
+
@click.option(
|
|
64
|
+
'--log-file', help='Optional log file to output the name of the newly created'
|
|
65
|
+
' modifier files. By default the list will be printed out to stdout',
|
|
66
|
+
type=click.File('w'), default='-')
|
|
67
|
+
@click.option(
|
|
68
|
+
'--reverse-vectors', is_flag=True,
|
|
69
|
+
help='Reverse sun vectors to go from ground to sky.')
|
|
70
|
+
def sunpath_from_location(
|
|
71
|
+
lat, lon, tz, north, folder, name, log_file, start_date, start_time, end_date,
|
|
72
|
+
end_time, timestep, leap_year, reverse_vectors):
|
|
73
|
+
"""Generate a non climate-based sunpath for a location.
|
|
74
|
+
|
|
75
|
+
This command also generates a mod file which includes all the modifiers in sunpath.
|
|
76
|
+
mod file is usually used with rcontrib command to indicate the list of modifiers.
|
|
77
|
+
Since rcontrib command has a hard limit of 10,000 modifiers in a single run the files
|
|
78
|
+
will be broken down into multiple files if number of modifiers is more than 10000
|
|
79
|
+
modifiers.
|
|
80
|
+
"""
|
|
81
|
+
location = Location()
|
|
82
|
+
location.latitude = lat
|
|
83
|
+
location.longitude = lon
|
|
84
|
+
location.time_zone = tz
|
|
85
|
+
try:
|
|
86
|
+
sp = Sunpath(location, north)
|
|
87
|
+
hoys = get_hoys(start_date, start_time, end_date, end_time, timestep, leap_year)
|
|
88
|
+
sp_files = sp.to_file(
|
|
89
|
+
folder, name, hoys=hoys, leap_year=leap_year, reverse_vectors=reverse_vectors
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
files = [
|
|
93
|
+
{'path': os.path.relpath(path, folder), 'full_path': path}
|
|
94
|
+
for path in sp_files['suns']
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
log_file.write(json.dumps(files))
|
|
98
|
+
except Exception:
|
|
99
|
+
_logger.exception('Failed to generate sunpath.')
|
|
100
|
+
sys.exit(1)
|
|
101
|
+
else:
|
|
102
|
+
sys.exit(0)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@sunpath.command('wea')
|
|
106
|
+
@click.argument('wea', type=click.Path(
|
|
107
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
108
|
+
@click.option(
|
|
109
|
+
'--north', default=0, type=float, show_default=True,
|
|
110
|
+
help='Angle to north (0-360). 90 is west and 270 is east')
|
|
111
|
+
@click.option(
|
|
112
|
+
'--timestep', default=1, type=int, show_default=True,
|
|
113
|
+
help='An integer to set the number of time steps per hour in the wea. Default is 1'
|
|
114
|
+
' for one value per hour.')
|
|
115
|
+
@click.option(
|
|
116
|
+
'--leap-year/--full-year', ' /-fy',
|
|
117
|
+
help='Flag for whether input wea is for a leap year.'
|
|
118
|
+
)
|
|
119
|
+
@click.option('--folder', default='.', help='Output folder.')
|
|
120
|
+
@click.option('--name', default='sunpath', help='File name.')
|
|
121
|
+
@click.option(
|
|
122
|
+
'--log-file', help='Optional log file to output the name of the newly'
|
|
123
|
+
' created modifier files. By default the list will be printed out to stdout',
|
|
124
|
+
type=click.File('w'), default='-')
|
|
125
|
+
@click.option(
|
|
126
|
+
'--reverse-vectors', is_flag=True,
|
|
127
|
+
help='Reverse sun vectors to go from ground to sky.')
|
|
128
|
+
def sunpath_from_wea(wea, north, folder, name, log_file, timestep, leap_year,
|
|
129
|
+
reverse_vectors):
|
|
130
|
+
"""Generate a climate-based sunpath from a Wea file.
|
|
131
|
+
|
|
132
|
+
This command also generates a mod file which includes all the modifiers in sunpath.
|
|
133
|
+
mod file is usually used with rcontrib command to indicate the list of modifiers.
|
|
134
|
+
Since rcontrib command has a hard limit of 10,000 modifiers in a single run the files
|
|
135
|
+
will be broken down into multiple files if number of modifiers is more than 10000
|
|
136
|
+
modifiers.
|
|
137
|
+
|
|
138
|
+
wea: Path to a wea file.
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
wea = Wea.from_file(wea, timestep=timestep, is_leap_year=leap_year)
|
|
142
|
+
sp = Sunpath(wea.location, north)
|
|
143
|
+
hoys = wea.hoys
|
|
144
|
+
sp_files = sp.to_file(
|
|
145
|
+
folder, name, wea=wea, hoys=hoys, leap_year=leap_year,
|
|
146
|
+
reverse_vectors=reverse_vectors
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
files = [
|
|
150
|
+
{'path': os.path.relpath(path, folder), 'full_path': path}
|
|
151
|
+
for path in sp_files['suns']
|
|
152
|
+
]
|
|
153
|
+
|
|
154
|
+
log_file.write(json.dumps(files))
|
|
155
|
+
except Exception:
|
|
156
|
+
_logger.exception('Failed to generate sunpath.')
|
|
157
|
+
sys.exit(1)
|
|
158
|
+
else:
|
|
159
|
+
sys.exit(0)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@sunpath.command('radiance')
|
|
163
|
+
@click.argument('wea', type=click.Path(
|
|
164
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
165
|
+
@click.option(
|
|
166
|
+
'--north', default=0, type=float, show_default=True,
|
|
167
|
+
help='Angle to north (0-360). 90 is west and 270 is east')
|
|
168
|
+
@click.option('--folder', type=click.Path(
|
|
169
|
+
exists=False, file_okay=False, dir_okay=True, resolve_path=True), default='.',
|
|
170
|
+
help='Output folder.')
|
|
171
|
+
@click.option('--name', default='sunpath', help='File name.')
|
|
172
|
+
@click.option(
|
|
173
|
+
'--visible/--solar', is_flag=True, default=True, help='A flag to indicate the '
|
|
174
|
+
'output type. Visible is equal to -O0 and solar is -O1 in gendaymtx options. '
|
|
175
|
+
'Default: visible.'
|
|
176
|
+
)
|
|
177
|
+
@click.option(
|
|
178
|
+
'--log-file', help='Optional log file to output the name of the newly'
|
|
179
|
+
' created modifier files. By default the list will be printed out to stdout',
|
|
180
|
+
type=click.File('w'), default='-')
|
|
181
|
+
@click.option(
|
|
182
|
+
'--dry-run', is_flag=True, default=False, show_default=True,
|
|
183
|
+
help='A flag to show the command without running it.'
|
|
184
|
+
)
|
|
185
|
+
def sunpath_from_wea_rad(wea, north, folder, name, visible, log_file, dry_run):
|
|
186
|
+
"""Generate a climate-based sunpath from a Wea file using radiance's gendaymtx.
|
|
187
|
+
|
|
188
|
+
This command also generates a mod file which includes all the modifiers in sunpath.
|
|
189
|
+
mod file is usually used with rcontrib command to indicate the list of modifiers.
|
|
190
|
+
Since rcontrib command has a hard limit of 10,000 modifiers in a single run the files
|
|
191
|
+
will be broken down into multiple files if number of modifiers is more than 10000
|
|
192
|
+
modifiers.
|
|
193
|
+
|
|
194
|
+
\b
|
|
195
|
+
Args:
|
|
196
|
+
wea: Path to a wea file. This can also be an epw file.
|
|
197
|
+
|
|
198
|
+
"""
|
|
199
|
+
try:
|
|
200
|
+
if not os.path.exists(folder):
|
|
201
|
+
os.makedirs(folder)
|
|
202
|
+
with open(wea) as inf:
|
|
203
|
+
first_word = inf.read(5)
|
|
204
|
+
is_wea = True if first_word == 'place' else False
|
|
205
|
+
if not is_wea:
|
|
206
|
+
_wea_file = os.path.join(os.path.dirname(wea), 'epw_to_wea.wea')
|
|
207
|
+
wea = Wea.from_epw_file(wea).write(_wea_file)
|
|
208
|
+
opt = GendaymtxOptions()
|
|
209
|
+
opt.n = True
|
|
210
|
+
opt.D = os.path.join(folder, name + '.mtx').replace('\\', '//')
|
|
211
|
+
opt.M = os.path.join(folder, name + '.mod').replace('\\', '//')
|
|
212
|
+
opt.r = north
|
|
213
|
+
opt.O = '0' if visible else '1'
|
|
214
|
+
|
|
215
|
+
cmd = Gendaymtx(wea=wea, options=opt)
|
|
216
|
+
|
|
217
|
+
if dry_run:
|
|
218
|
+
print(cmd.to_radiance())
|
|
219
|
+
sys.exit(0)
|
|
220
|
+
|
|
221
|
+
run_command(cmd.to_radiance(), env=folders.env)
|
|
222
|
+
files = [
|
|
223
|
+
{'path': os.path.relpath(path, folder), 'full_path': path}
|
|
224
|
+
for path in (opt.D.value, opt.M.value)
|
|
225
|
+
]
|
|
226
|
+
|
|
227
|
+
log_file.write(json.dumps(files))
|
|
228
|
+
except Exception:
|
|
229
|
+
_logger.exception('Failed to generate sunpath.')
|
|
230
|
+
sys.exit(1)
|
|
231
|
+
else:
|
|
232
|
+
sys.exit(0)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@sunpath.command('epw')
|
|
236
|
+
@click.argument('epw', type=click.Path(
|
|
237
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
238
|
+
@click.option(
|
|
239
|
+
'--north', default=0, type=float, show_default=True,
|
|
240
|
+
help='Angle to north (0-360). 90 is west and 270 is east')
|
|
241
|
+
@click.option(
|
|
242
|
+
'--start-date', default='JAN-01', show_default=True,
|
|
243
|
+
help='Start date as MMM-DD (e.g JUL-21). Start date itself will also be included.')
|
|
244
|
+
@click.option(
|
|
245
|
+
'--start-time', default='00:00', show_default=True,
|
|
246
|
+
help='Start time as HH:MM (e.g 14:10). Start time itself will also be included.')
|
|
247
|
+
@click.option(
|
|
248
|
+
'--end-date', default='DEC-31', show_default=True,
|
|
249
|
+
help='End date as MMM-DD (e.g JUL-21). End date itself will also be included.')
|
|
250
|
+
@click.option(
|
|
251
|
+
'--end-time', default='23:00', show_default=True,
|
|
252
|
+
help='End time as HH:MM (e.g 18:30). End time itself will also be included.')
|
|
253
|
+
@click.option(
|
|
254
|
+
'--timestep', default=1, type=int, show_default=True,
|
|
255
|
+
help='An optional integer to set the number of time steps per hour. Default is 1'
|
|
256
|
+
' for one value per hour.')
|
|
257
|
+
@click.option(
|
|
258
|
+
'--leap-year/--full-year', ' /-fy',
|
|
259
|
+
help='Flag for whether input epw is for a leap year.'
|
|
260
|
+
)
|
|
261
|
+
@click.option('--folder', default='.', help='Output folder.')
|
|
262
|
+
@click.option('--name', default='sunpath', help='File name.', type=str)
|
|
263
|
+
@click.option(
|
|
264
|
+
'--log-file', help='Optional log file to output the name of the newly'
|
|
265
|
+
' created modifier files. By default the list will be printed out to stdout',
|
|
266
|
+
type=click.File('w'), default='-')
|
|
267
|
+
@click.option(
|
|
268
|
+
'--reverse-vectors', is_flag=True,
|
|
269
|
+
help='Reverse sun vectors to go from ground to sky.')
|
|
270
|
+
def sunpath_from_epw(
|
|
271
|
+
epw, north, folder, name, log_file, start_date, start_time, end_date, end_time,
|
|
272
|
+
timestep, leap_year, reverse_vectors):
|
|
273
|
+
"""Generate a climate-based sunpath from an epw weather file.
|
|
274
|
+
|
|
275
|
+
This command also generates a mod file which includes all the modifiers in sunpath.
|
|
276
|
+
mod file is usually used with rcontrib command to indicate the list of modifiers.
|
|
277
|
+
Since rcontrib command has a hard limit of 10,000 modifiers in a single run the files
|
|
278
|
+
will be broken down into multiple files if number of modifiers is more than 10000
|
|
279
|
+
modifiers.
|
|
280
|
+
|
|
281
|
+
epw: Path to a epw file.
|
|
282
|
+
"""
|
|
283
|
+
try:
|
|
284
|
+
wea = Wea.from_epw_file(epw)
|
|
285
|
+
sp = Sunpath(wea.location, north)
|
|
286
|
+
hoys = get_hoys(start_date, start_time, end_date, end_time, timestep, leap_year)
|
|
287
|
+
sp_files = sp.to_file(
|
|
288
|
+
folder, name, wea=wea, hoys=hoys, leap_year=leap_year,
|
|
289
|
+
reverse_vectors=reverse_vectors
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
files = [
|
|
293
|
+
{'path': os.path.relpath(path, folder), 'full_path': path}
|
|
294
|
+
for path in sp_files['suns']
|
|
295
|
+
]
|
|
296
|
+
|
|
297
|
+
log_file.write(json.dumps(files))
|
|
298
|
+
except Exception:
|
|
299
|
+
_logger.exception('Failed to generate sunpath.')
|
|
300
|
+
sys.exit(1)
|
|
301
|
+
else:
|
|
302
|
+
sys.exit(0)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
@sunpath.command('parse-hours')
|
|
306
|
+
@click.argument('suns', type=click.File(mode='r'))
|
|
307
|
+
@click.option('--timestep', default=1, type=int, show_default=True,
|
|
308
|
+
help='This input is not used and is deprecated.')
|
|
309
|
+
@click.option('--leap-year/--full-year', ' /-fy',
|
|
310
|
+
help='This input is not used and is deprecated.')
|
|
311
|
+
@click.option('--folder', default='.', help='Output folder.')
|
|
312
|
+
@click.option('--name', default='hours.txt', help='Output file name.')
|
|
313
|
+
def parse_hours_from_suns(suns, timestep, leap_year, folder, name):
|
|
314
|
+
"""Parse hours of the year from a suns modifier file generated by Radiance's
|
|
315
|
+
gendaymtx.
|
|
316
|
+
|
|
317
|
+
suns: Path to a suns modifiers file.
|
|
318
|
+
"""
|
|
319
|
+
try:
|
|
320
|
+
hours = []
|
|
321
|
+
for line in suns:
|
|
322
|
+
hours.append(int(line.split('solar')[1]) / 60)
|
|
323
|
+
# write the new file to hoys
|
|
324
|
+
with open(os.path.join(folder, name), 'w') as hf:
|
|
325
|
+
for h in hours:
|
|
326
|
+
hf.write('%s\n' % h)
|
|
327
|
+
except Exception:
|
|
328
|
+
_logger.exception('Failed to parse the hours.')
|
|
329
|
+
sys.exit(1)
|
|
330
|
+
else:
|
|
331
|
+
sys.exit(0)
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
import sys
|
|
5
|
+
import logging
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from honeybee_radiance_command.dctimestep import Dctimestep, DctimestepOptions
|
|
9
|
+
from honeybee_radiance_command.rmtxop import Rmtxop, RmtxopOptions
|
|
10
|
+
from honeybee_radiance_command.getinfo import Getinfo
|
|
11
|
+
from honeybee_radiance.config import folders
|
|
12
|
+
from honeybee_radiance_command._command_util import run_command
|
|
13
|
+
|
|
14
|
+
_logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@click.group(help='Commands to do matrix operations for three-phase.')
|
|
18
|
+
def three_phase():
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@three_phase.command('multiplication')
|
|
23
|
+
@click.argument(
|
|
24
|
+
'sky-vector', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
25
|
+
@click.argument(
|
|
26
|
+
'view-matrix', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
27
|
+
@click.argument(
|
|
28
|
+
't-matrix', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
29
|
+
@click.argument(
|
|
30
|
+
'daylight-matrix', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
31
|
+
@click.argument(
|
|
32
|
+
'output-matrix',
|
|
33
|
+
type=click.Path(
|
|
34
|
+
exists=False, file_okay=True, dir_okay=False, resolve_path=True
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
@click.option(
|
|
38
|
+
'--options', help='a string that will be passed to dctimestep for setting options '
|
|
39
|
+
'such as output file format (-o), input data format(-i) etc.')
|
|
40
|
+
@click.option(
|
|
41
|
+
'--dry-run', is_flag=True, default=False, show_default=True,
|
|
42
|
+
help='A flag to show the command without running it.'
|
|
43
|
+
)
|
|
44
|
+
def three_phase_calc(sky_vector, view_matrix, t_matrix, daylight_matrix, output_matrix,
|
|
45
|
+
options, dry_run):
|
|
46
|
+
"""Matrix multiplication for view matrix, transmission matrix, daylight matrix and
|
|
47
|
+
sky matrix."""
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
base_options = DctimestepOptions()
|
|
51
|
+
options = options.strip() if options else None
|
|
52
|
+
if options:
|
|
53
|
+
base_options.update_from_string(options)
|
|
54
|
+
|
|
55
|
+
cmd = Dctimestep.three_phase_calc(sky_vector=sky_vector, view_matrix=view_matrix,
|
|
56
|
+
t_matrix=t_matrix,
|
|
57
|
+
daylight_matrix=daylight_matrix,
|
|
58
|
+
output=output_matrix, options=base_options)
|
|
59
|
+
if dry_run:
|
|
60
|
+
click.echo(cmd)
|
|
61
|
+
else:
|
|
62
|
+
run_command(cmd.to_radiance(), env=folders.env)
|
|
63
|
+
except OSError:
|
|
64
|
+
os.system(cmd.to_radiance())
|
|
65
|
+
except Exception:
|
|
66
|
+
_logger.exception('Failed to run matrix multiplication calculations with '
|
|
67
|
+
'dctimestep')
|
|
68
|
+
sys.exit(1)
|
|
69
|
+
else:
|
|
70
|
+
sys.exit(0)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@three_phase.command('rmtxop')
|
|
74
|
+
@click.argument(
|
|
75
|
+
'view-matrix', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
76
|
+
@click.argument(
|
|
77
|
+
't-matrix', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
78
|
+
@click.argument(
|
|
79
|
+
'daylight-matrix', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
80
|
+
@click.argument(
|
|
81
|
+
'sky-vector', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
82
|
+
@click.argument(
|
|
83
|
+
'output-matrix',
|
|
84
|
+
type=click.Path(
|
|
85
|
+
exists=False, file_okay=True, dir_okay=False, resolve_path=True
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
|
+
@click.option(
|
|
89
|
+
'--output-format', help='Output format for output matrix. Valid inputs are a, f, d '
|
|
90
|
+
'and c for ASCII, float, double or RGBE colors. If conversion is not provided you '
|
|
91
|
+
'can change the output type using rad-params options.',
|
|
92
|
+
type=click.Choice(['a', 'f', 'd', 'c']), default='a', show_default=True,
|
|
93
|
+
show_choices=True
|
|
94
|
+
)
|
|
95
|
+
@click.option(
|
|
96
|
+
'--illuminance/--raw', is_flag=True, default=True, show_default=True,
|
|
97
|
+
help='A flag to convert the result to illuminance.'
|
|
98
|
+
)
|
|
99
|
+
@click.option(
|
|
100
|
+
'--remove-header/--keep-header', is_flag=True, default=True,
|
|
101
|
+
help='A flag to keep or remove the header from the output file.'
|
|
102
|
+
)
|
|
103
|
+
@click.option(
|
|
104
|
+
'--dry-run', is_flag=True, default=False, show_default=True,
|
|
105
|
+
help='A flag to show the command without running it.'
|
|
106
|
+
)
|
|
107
|
+
def three_phase_rmtxop(
|
|
108
|
+
view_matrix, t_matrix, daylight_matrix, sky_vector, output_matrix, output_format,
|
|
109
|
+
illuminance, remove_header, dry_run
|
|
110
|
+
):
|
|
111
|
+
"""Matrix multiplication for view matrix, transmission matrix, daylight matrix and
|
|
112
|
+
sky matrix."""
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
options = RmtxopOptions()
|
|
116
|
+
options.f = output_format
|
|
117
|
+
matrices = [view_matrix, t_matrix, daylight_matrix, sky_vector]
|
|
118
|
+
|
|
119
|
+
if illuminance:
|
|
120
|
+
# rmtxop concatenation
|
|
121
|
+
calc = Rmtxop(matrices=matrices)
|
|
122
|
+
|
|
123
|
+
cmd = Rmtxop(options=options)
|
|
124
|
+
cmd.transforms = [['47.4', '119.9', '11.6']]
|
|
125
|
+
cmd.matrices = calc
|
|
126
|
+
else:
|
|
127
|
+
cmd = Rmtxop(options=options, matrices=matrices)
|
|
128
|
+
|
|
129
|
+
if remove_header:
|
|
130
|
+
getinfo = Getinfo.remove_header(output=output_matrix)
|
|
131
|
+
cmd.pipe_to = getinfo
|
|
132
|
+
else:
|
|
133
|
+
cmd.output = output_matrix
|
|
134
|
+
|
|
135
|
+
if dry_run:
|
|
136
|
+
click.echo(cmd)
|
|
137
|
+
else:
|
|
138
|
+
run_command(cmd.to_radiance(), env=folders.env)
|
|
139
|
+
except OSError:
|
|
140
|
+
os.system(cmd.to_radiance())
|
|
141
|
+
except Exception:
|
|
142
|
+
_logger.exception(
|
|
143
|
+
'Failed to run matrix multiplication calculations with rmtxop')
|
|
144
|
+
sys.exit(1)
|
|
145
|
+
else:
|
|
146
|
+
sys.exit(0)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@three_phase.command('combinations')
|
|
150
|
+
@click.argument(
|
|
151
|
+
'sender-info', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
152
|
+
@click.argument(
|
|
153
|
+
'receiver-info', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
154
|
+
@click.argument(
|
|
155
|
+
'states_info', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
|
|
156
|
+
@click.option(
|
|
157
|
+
'--folder',
|
|
158
|
+
help='Path to target folder. The command will create two JSON files in this folder.',
|
|
159
|
+
type=click.Path(exists=False, file_okay=False, dir_okay=True, resolve_path=True),
|
|
160
|
+
default='.', show_default=True
|
|
161
|
+
)
|
|
162
|
+
@click.option(
|
|
163
|
+
'--combinations-name', '-cn', help='Output file name for 3 phase multiplication '
|
|
164
|
+
'combinations.', type=click.STRING, default='3phase_multiplication_info',
|
|
165
|
+
show_default=True
|
|
166
|
+
)
|
|
167
|
+
@click.option(
|
|
168
|
+
'--result-mapper-name', '-rn', help='Output file name for results mapper file.',
|
|
169
|
+
type=click.STRING, default='3phase_results_info', show_default=True
|
|
170
|
+
)
|
|
171
|
+
def three_phase_combinations(
|
|
172
|
+
sender_info, receiver_info, states_info, folder, combinations_name,
|
|
173
|
+
result_mapper_name
|
|
174
|
+
):
|
|
175
|
+
"""Matrix multiplication for view matrix, transmission matrix, daylight matrix and
|
|
176
|
+
sky matrix.
|
|
177
|
+
|
|
178
|
+
\b
|
|
179
|
+
args:
|
|
180
|
+
sender_info: A JSON file that includes the information for senders. This file
|
|
181
|
+
is created as an output of the daylight matrix grouping command.
|
|
182
|
+
receiver_info: A JSON file that includes the information for receivers. This
|
|
183
|
+
file is written to model/receiver folder.
|
|
184
|
+
states_info: A JSON file that includes the state information for all the
|
|
185
|
+
aperture groups. This file is created under model/aperture_groups.
|
|
186
|
+
|
|
187
|
+
"""
|
|
188
|
+
def _read_json_content(json_file):
|
|
189
|
+
with open(json_file) as inf:
|
|
190
|
+
return json.loads(inf.read())
|
|
191
|
+
try:
|
|
192
|
+
rec_data = _read_json_content(receiver_info)
|
|
193
|
+
send_data = _read_json_content(sender_info)
|
|
194
|
+
states = _read_json_content(states_info)
|
|
195
|
+
|
|
196
|
+
dmtx_info = {}
|
|
197
|
+
|
|
198
|
+
grid_mapper = {}
|
|
199
|
+
for grid in rec_data:
|
|
200
|
+
grid_mapper[grid['full_id']] = {}
|
|
201
|
+
for apt in grid['aperture_groups']:
|
|
202
|
+
for group in send_data:
|
|
203
|
+
if apt in group['aperture_groups']:
|
|
204
|
+
dmtx_info[apt] = group['identifier']
|
|
205
|
+
break
|
|
206
|
+
else:
|
|
207
|
+
# this should never happen for a valid radiance folder
|
|
208
|
+
raise ValueError('Unrecognizable aperture group: %s' % apt)
|
|
209
|
+
|
|
210
|
+
grid_mapper[grid['full_id']][apt] = \
|
|
211
|
+
[s['identifier'] for s in states[apt]]
|
|
212
|
+
|
|
213
|
+
# create all the possible combinations
|
|
214
|
+
# TODO: find a more generic approach to created the names. Using white_glow
|
|
215
|
+
# is assuming that we will never change the modifier.
|
|
216
|
+
matrix_combinations = []
|
|
217
|
+
for grid in rec_data:
|
|
218
|
+
for apt in grid['aperture_groups']:
|
|
219
|
+
vmtx = '%s..white_glow_%s.vtmx' % (grid['identifier'], apt)
|
|
220
|
+
dmtx = '%s.dmtx' % dmtx_info[apt]
|
|
221
|
+
for info in states[apt]:
|
|
222
|
+
matrix_combinations.append(
|
|
223
|
+
dict(
|
|
224
|
+
# create an identifier from the mix of grid and state
|
|
225
|
+
identifier='%s..%s' % (
|
|
226
|
+
grid['full_id'], info['identifier']
|
|
227
|
+
),
|
|
228
|
+
light_path=apt,
|
|
229
|
+
grid_id=grid['full_id'],
|
|
230
|
+
state_id=info['identifier'],
|
|
231
|
+
tmtx=info['tmtx'],
|
|
232
|
+
vmtx=vmtx,
|
|
233
|
+
dmtx=dmtx
|
|
234
|
+
)
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# write the files to folder
|
|
238
|
+
if not os.path.isdir(folder):
|
|
239
|
+
os.mkdir(folder)
|
|
240
|
+
|
|
241
|
+
comb_file = os.path.join(folder, '%s.json' % combinations_name)
|
|
242
|
+
res_file = os.path.join(folder, '%s.json' % result_mapper_name)
|
|
243
|
+
|
|
244
|
+
with open(comb_file, 'w') as outf:
|
|
245
|
+
json.dump(matrix_combinations, outf, indent=2)
|
|
246
|
+
|
|
247
|
+
with open(res_file, 'w') as outf:
|
|
248
|
+
json.dump(grid_mapper, outf, indent=2)
|
|
249
|
+
|
|
250
|
+
except Exception:
|
|
251
|
+
_logger.exception(
|
|
252
|
+
'Failed to calculate the mapper file for 3 phase studies.')
|
|
253
|
+
sys.exit(1)
|
|
254
|
+
else:
|
|
255
|
+
sys.exit(0)
|