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.

Files changed (152) hide show
  1. honeybee_radiance/__init__.py +11 -0
  2. honeybee_radiance/__main__.py +4 -0
  3. honeybee_radiance/_extend_honeybee.py +93 -0
  4. honeybee_radiance/cli/__init__.py +88 -0
  5. honeybee_radiance/cli/dc.py +400 -0
  6. honeybee_radiance/cli/edit.py +529 -0
  7. honeybee_radiance/cli/glare.py +118 -0
  8. honeybee_radiance/cli/grid.py +859 -0
  9. honeybee_radiance/cli/lib.py +458 -0
  10. honeybee_radiance/cli/modifier.py +133 -0
  11. honeybee_radiance/cli/mtx.py +226 -0
  12. honeybee_radiance/cli/multiphase.py +1034 -0
  13. honeybee_radiance/cli/octree.py +640 -0
  14. honeybee_radiance/cli/postprocess.py +1186 -0
  15. honeybee_radiance/cli/raytrace.py +219 -0
  16. honeybee_radiance/cli/rpict.py +125 -0
  17. honeybee_radiance/cli/schedule.py +56 -0
  18. honeybee_radiance/cli/setconfig.py +63 -0
  19. honeybee_radiance/cli/sky.py +545 -0
  20. honeybee_radiance/cli/study.py +66 -0
  21. honeybee_radiance/cli/sunpath.py +331 -0
  22. honeybee_radiance/cli/threephase.py +255 -0
  23. honeybee_radiance/cli/translate.py +400 -0
  24. honeybee_radiance/cli/util.py +121 -0
  25. honeybee_radiance/cli/view.py +261 -0
  26. honeybee_radiance/cli/viewfactor.py +347 -0
  27. honeybee_radiance/config.json +6 -0
  28. honeybee_radiance/config.py +427 -0
  29. honeybee_radiance/dictutil.py +50 -0
  30. honeybee_radiance/dynamic/__init__.py +5 -0
  31. honeybee_radiance/dynamic/group.py +479 -0
  32. honeybee_radiance/dynamic/multiphase.py +557 -0
  33. honeybee_radiance/dynamic/state.py +718 -0
  34. honeybee_radiance/dynamic/stategeo.py +352 -0
  35. honeybee_radiance/geometry/__init__.py +13 -0
  36. honeybee_radiance/geometry/bubble.py +42 -0
  37. honeybee_radiance/geometry/cone.py +215 -0
  38. honeybee_radiance/geometry/cup.py +54 -0
  39. honeybee_radiance/geometry/cylinder.py +197 -0
  40. honeybee_radiance/geometry/geometrybase.py +37 -0
  41. honeybee_radiance/geometry/instance.py +40 -0
  42. honeybee_radiance/geometry/mesh.py +38 -0
  43. honeybee_radiance/geometry/polygon.py +174 -0
  44. honeybee_radiance/geometry/ring.py +214 -0
  45. honeybee_radiance/geometry/source.py +182 -0
  46. honeybee_radiance/geometry/sphere.py +178 -0
  47. honeybee_radiance/geometry/tube.py +46 -0
  48. honeybee_radiance/lib/__init__.py +1 -0
  49. honeybee_radiance/lib/_loadmodifiers.py +72 -0
  50. honeybee_radiance/lib/_loadmodifiersets.py +69 -0
  51. honeybee_radiance/lib/modifiers.py +58 -0
  52. honeybee_radiance/lib/modifiersets.py +63 -0
  53. honeybee_radiance/lightpath.py +204 -0
  54. honeybee_radiance/lightsource/__init__.py +1 -0
  55. honeybee_radiance/lightsource/_gendaylit.py +479 -0
  56. honeybee_radiance/lightsource/dictutil.py +49 -0
  57. honeybee_radiance/lightsource/ground.py +160 -0
  58. honeybee_radiance/lightsource/sky/__init__.py +7 -0
  59. honeybee_radiance/lightsource/sky/_skybase.py +177 -0
  60. honeybee_radiance/lightsource/sky/certainirradiance.py +232 -0
  61. honeybee_radiance/lightsource/sky/cie.py +378 -0
  62. honeybee_radiance/lightsource/sky/climatebased.py +501 -0
  63. honeybee_radiance/lightsource/sky/hemisphere.py +160 -0
  64. honeybee_radiance/lightsource/sky/skydome.py +113 -0
  65. honeybee_radiance/lightsource/sky/skymatrix.py +163 -0
  66. honeybee_radiance/lightsource/sky/strutil.py +34 -0
  67. honeybee_radiance/lightsource/sky/sunmatrix.py +212 -0
  68. honeybee_radiance/lightsource/sunpath.py +247 -0
  69. honeybee_radiance/modifier/__init__.py +3 -0
  70. honeybee_radiance/modifier/material/__init__.py +30 -0
  71. honeybee_radiance/modifier/material/absdf.py +477 -0
  72. honeybee_radiance/modifier/material/antimatter.py +54 -0
  73. honeybee_radiance/modifier/material/ashik2.py +51 -0
  74. honeybee_radiance/modifier/material/brtdfunc.py +81 -0
  75. honeybee_radiance/modifier/material/bsdf.py +292 -0
  76. honeybee_radiance/modifier/material/dielectric.py +53 -0
  77. honeybee_radiance/modifier/material/glass.py +431 -0
  78. honeybee_radiance/modifier/material/glow.py +246 -0
  79. honeybee_radiance/modifier/material/illum.py +51 -0
  80. honeybee_radiance/modifier/material/interface.py +49 -0
  81. honeybee_radiance/modifier/material/light.py +206 -0
  82. honeybee_radiance/modifier/material/materialbase.py +36 -0
  83. honeybee_radiance/modifier/material/metal.py +167 -0
  84. honeybee_radiance/modifier/material/metal2.py +41 -0
  85. honeybee_radiance/modifier/material/metdata.py +41 -0
  86. honeybee_radiance/modifier/material/metfunc.py +41 -0
  87. honeybee_radiance/modifier/material/mirror.py +340 -0
  88. honeybee_radiance/modifier/material/mist.py +86 -0
  89. honeybee_radiance/modifier/material/plasdata.py +58 -0
  90. honeybee_radiance/modifier/material/plasfunc.py +59 -0
  91. honeybee_radiance/modifier/material/plastic.py +354 -0
  92. honeybee_radiance/modifier/material/plastic2.py +58 -0
  93. honeybee_radiance/modifier/material/prism1.py +57 -0
  94. honeybee_radiance/modifier/material/prism2.py +48 -0
  95. honeybee_radiance/modifier/material/spotlight.py +50 -0
  96. honeybee_radiance/modifier/material/trans.py +518 -0
  97. honeybee_radiance/modifier/material/trans2.py +49 -0
  98. honeybee_radiance/modifier/material/transdata.py +50 -0
  99. honeybee_radiance/modifier/material/transfunc.py +53 -0
  100. honeybee_radiance/modifier/mixture/__init__.py +6 -0
  101. honeybee_radiance/modifier/mixture/mixdata.py +49 -0
  102. honeybee_radiance/modifier/mixture/mixfunc.py +54 -0
  103. honeybee_radiance/modifier/mixture/mixpict.py +52 -0
  104. honeybee_radiance/modifier/mixture/mixtext.py +66 -0
  105. honeybee_radiance/modifier/mixture/mixturebase.py +28 -0
  106. honeybee_radiance/modifier/modifierbase.py +40 -0
  107. honeybee_radiance/modifier/pattern/__init__.py +9 -0
  108. honeybee_radiance/modifier/pattern/brightdata.py +49 -0
  109. honeybee_radiance/modifier/pattern/brightfunc.py +47 -0
  110. honeybee_radiance/modifier/pattern/brighttext.py +81 -0
  111. honeybee_radiance/modifier/pattern/colordata.py +56 -0
  112. honeybee_radiance/modifier/pattern/colorfunc.py +47 -0
  113. honeybee_radiance/modifier/pattern/colorpict.py +54 -0
  114. honeybee_radiance/modifier/pattern/colortext.py +73 -0
  115. honeybee_radiance/modifier/pattern/patternbase.py +34 -0
  116. honeybee_radiance/modifier/texture/__init__.py +4 -0
  117. honeybee_radiance/modifier/texture/texdata.py +29 -0
  118. honeybee_radiance/modifier/texture/texfunc.py +26 -0
  119. honeybee_radiance/modifier/texture/texturebase.py +27 -0
  120. honeybee_radiance/modifierset.py +1091 -0
  121. honeybee_radiance/mutil.py +60 -0
  122. honeybee_radiance/postprocess/__init__.py +1 -0
  123. honeybee_radiance/postprocess/annual.py +108 -0
  124. honeybee_radiance/postprocess/annualdaylight.py +425 -0
  125. honeybee_radiance/postprocess/annualglare.py +201 -0
  126. honeybee_radiance/postprocess/annualirradiance.py +187 -0
  127. honeybee_radiance/postprocess/electriclight.py +119 -0
  128. honeybee_radiance/postprocess/en17037.py +261 -0
  129. honeybee_radiance/postprocess/leed.py +304 -0
  130. honeybee_radiance/postprocess/solartracking.py +90 -0
  131. honeybee_radiance/primitive.py +554 -0
  132. honeybee_radiance/properties/__init__.py +1 -0
  133. honeybee_radiance/properties/_base.py +390 -0
  134. honeybee_radiance/properties/aperture.py +197 -0
  135. honeybee_radiance/properties/door.py +198 -0
  136. honeybee_radiance/properties/face.py +123 -0
  137. honeybee_radiance/properties/model.py +1291 -0
  138. honeybee_radiance/properties/room.py +490 -0
  139. honeybee_radiance/properties/shade.py +186 -0
  140. honeybee_radiance/properties/shademesh.py +116 -0
  141. honeybee_radiance/putil.py +44 -0
  142. honeybee_radiance/reader.py +214 -0
  143. honeybee_radiance/sensor.py +166 -0
  144. honeybee_radiance/sensorgrid.py +1008 -0
  145. honeybee_radiance/view.py +1101 -0
  146. honeybee_radiance/writer.py +951 -0
  147. honeybee_radiance-1.66.190.dist-info/METADATA +89 -0
  148. honeybee_radiance-1.66.190.dist-info/RECORD +152 -0
  149. honeybee_radiance-1.66.190.dist-info/WHEEL +5 -0
  150. honeybee_radiance-1.66.190.dist-info/entry_points.txt +2 -0
  151. honeybee_radiance-1.66.190.dist-info/licenses/LICENSE +661 -0
  152. 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)