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,390 @@
1
+ # coding=utf-8
2
+ """Base class of Radiance Properties for all planar geometry objects."""
3
+ from ..modifier import Modifier
4
+ from ..mutil import dict_to_modifier # imports all modifiers classes
5
+ from ..dynamic.state import _RadianceState
6
+ from ..lib.modifiers import black
7
+
8
+ from honeybee.typing import valid_rad_string
9
+ from honeybee.checkdup import is_equivalent
10
+
11
+
12
+ class _RadianceProperties(object):
13
+ """Base class of Radiance Properties for all planar geometry objects.
14
+
15
+ This includes (Face, Aperture, Door, Shade).
16
+
17
+ Args:
18
+ host: A honeybee_core object that hosts these properties.
19
+ modifier: A Honeybee Radiance Modifier for the object. If None,
20
+ it will be set by the parent Room ModifierSet or the Honeybee
21
+ default generic ModifierSet.
22
+ modifier_blk: A Honeybee Radiance Modifier to be used for this object
23
+ in direct solar simulations and in isolation studies (assessing
24
+ the contribution of individual Apertures).
25
+
26
+ Properties:
27
+ * host
28
+ * modifier
29
+ * modifier_blk
30
+ * is_opaque
31
+ * is_modifier_set_on_object
32
+ * is_blk_overridden
33
+ """
34
+
35
+ __slots__ = ('_host', '_modifier', '_modifier_blk')
36
+
37
+ def __init__(self, host, modifier=None, modifier_blk=None):
38
+ """Initialize GeometryRadianceProperties."""
39
+ self._host = host
40
+ self.modifier = modifier
41
+ self.modifier_blk = modifier_blk
42
+
43
+ @property
44
+ def host(self):
45
+ """Get the object hosting these properties."""
46
+ return self._host
47
+
48
+ @property
49
+ def modifier(self):
50
+ """Get or set the object modifier."""
51
+ return self._modifier
52
+
53
+ @modifier.setter
54
+ def modifier(self, value):
55
+ if value is not None:
56
+ assert isinstance(value, Modifier), \
57
+ 'Expected Radiance Modifier for shade. Got {}'.format(type(value))
58
+ value.lock() # lock editing in case modifier has multiple references
59
+ self._modifier = value
60
+
61
+ @property
62
+ def modifier_blk(self):
63
+ """Get or set a modifier to be used in direct solar and in isolation studies.
64
+
65
+ If None, this will be a completely black material if the object's modifier is
66
+ opaque and will be equal to the modifier if the object's modifier is non-opaque.
67
+ """
68
+ if self._modifier_blk: # set by user
69
+ return self._modifier_blk
70
+ mod = self.modifier # assign a default based on whether the modifier is opaque
71
+ if mod.is_void or mod.is_opaque:
72
+ return black
73
+ else:
74
+ return mod
75
+
76
+ @modifier_blk.setter
77
+ def modifier_blk(self, value):
78
+ if value is not None:
79
+ assert isinstance(value, Modifier), \
80
+ 'Expected Radiance Modifier. Got {}'.format(type(value))
81
+ value.lock() # lock editing in case modifier has multiple references
82
+ self._modifier_blk = value
83
+
84
+ @property
85
+ def is_opaque(self):
86
+ """Boolean noting whether this object has an opaque modifier.
87
+
88
+ This has repercussions for how this object is written into the Radiance
89
+ folder structure.
90
+ """
91
+ return True if self.modifier.is_void else self.modifier.is_opaque
92
+
93
+ @property
94
+ def is_modifier_set_on_object(self):
95
+ """Boolean noting if modifier is assigned on the level of this object.
96
+
97
+ This is opposed to having the modifier assigned by a ModifierSet.
98
+ """
99
+ return self._modifier is not None
100
+
101
+ @property
102
+ def is_blk_overridden(self):
103
+ """Boolean noting if modifier_blk has been overridden from default on this object.
104
+ """
105
+ return self._modifier is not None
106
+
107
+ def reset_to_default(self):
108
+ """Reset a Modifier assigned at the level of this Shade to the default.
109
+
110
+ This means that the Shade's modifier will be assigned by a ModifierSet instead.
111
+ """
112
+ self._modifier = None
113
+
114
+ def duplicate(self, new_host=None):
115
+ """Get a copy of this object.
116
+
117
+ new_host: A new object that hosts these properties.
118
+ If None, the properties will be duplicated with the same host.
119
+ """
120
+ _host = new_host or self._host
121
+ return self.__class__(_host, self._modifier, self._modifier_blk)
122
+
123
+ def is_equivalent(self, other):
124
+ """Check to see if these energy properties are equivalent to another object.
125
+
126
+ This will only be True if all properties match (except for the host) and
127
+ will otherwise be False.
128
+ """
129
+ if not is_equivalent(self._modifier, other._modifier):
130
+ return False
131
+ if not is_equivalent(self._modifier_blk, other._modifier_blk):
132
+ return False
133
+ return True
134
+
135
+ def _apply_modifiers_from_dict(self, abridged_data, modifiers):
136
+ """Apply modifiers from an Abridged dictionary.
137
+
138
+ Args:
139
+ abridged_data: An Abridged dictionary (typically coming from a Model).
140
+ modifiers: A dictionary of modifiers with modifier identifiers as keys,
141
+ which will be used to re-assign modifiers.
142
+ """
143
+ if 'modifier' in abridged_data and abridged_data['modifier'] is not None:
144
+ self.modifier = modifiers[abridged_data['modifier']]
145
+ if 'modifier_blk' in abridged_data and abridged_data['modifier_blk'] is not None:
146
+ self.modifier_blk = modifiers[abridged_data['modifier_blk']]
147
+
148
+ def _add_modifiers_to_dict(self, base, abridged=False):
149
+ """Add modifiers to a base dictionary.
150
+
151
+ Args:
152
+ base: A base dictionary to which modifiers will be added.
153
+ abridged: Boolean to note whether the full dictionary describing the
154
+ object should be returned (False) or just an abridged version (True).
155
+ Default: False.
156
+ """
157
+ if self._modifier is not None:
158
+ base['radiance']['modifier'] = self._modifier.identifier if \
159
+ abridged else self._modifier.to_dict()
160
+ if self._modifier_blk is not None:
161
+ base['radiance']['modifier_blk'] = self._modifier_blk.identifier if \
162
+ abridged else self._modifier_blk.to_dict()
163
+ return base
164
+
165
+ @staticmethod
166
+ def _restore_modifiers_from_dict(new_prop, data):
167
+ """Restore modifiers from a data dictionary to a new properties object."""
168
+ if 'modifier' in data and data['modifier'] is not None:
169
+ new_prop.modifier = dict_to_modifier(data['modifier'])
170
+ if 'modifier_blk' in data and data['modifier_blk'] is not None:
171
+ new_prop.modifier_blk = dict_to_modifier(data['modifier_blk'])
172
+ return new_prop
173
+
174
+ def ToString(self):
175
+ return self.__repr__()
176
+
177
+ def __repr__(self):
178
+ return 'Base Radiance Properties: [host: {}]'.format(self.host.display_name)
179
+
180
+
181
+ class _DynamicRadianceProperties(_RadianceProperties):
182
+ """Base class of Radiance Properties for all planar geometry objects.
183
+
184
+ This includes Apertures and Shades.
185
+
186
+ Args:
187
+ host: A honeybee_core object that hosts these properties.
188
+ modifier: A Honeybee Radiance Modifier for the object. If None,
189
+ it will be set by the parent Room ModifierSet or the Honeybee
190
+ default generic ModifierSet.
191
+ modifier_blk: A Honeybee Radiance Modifier to be used for this object
192
+ in direct solar simulations and in isolation studies (assessing
193
+ the contribution of individual Apertures).
194
+ dynamic_group_identifier: An optional string to note the dynamic group
195
+ to which the object is a part of. Objects sharing the same
196
+ dynamic_group_identifier will have their states change in unison.
197
+ If None, the object is assumed to be static.
198
+
199
+ Properties:
200
+ * host
201
+ * modifier
202
+ * modifier_blk
203
+ * dynamic_group_identifier
204
+ * states
205
+ * state_count
206
+ * is_opaque
207
+ * is_modifier_set_on_object
208
+ * is_blk_overridden
209
+ """
210
+
211
+ __slots__ = ('_dynamic_group_identifier', '_states')
212
+
213
+ def __init__(self, host, modifier=None, modifier_blk=None,
214
+ dynamic_group_identifier=None):
215
+ """Initialize radiance properties."""
216
+ _RadianceProperties.__init__(self, host, modifier, modifier_blk)
217
+ self._states = []
218
+ self.dynamic_group_identifier = dynamic_group_identifier
219
+
220
+ @property
221
+ def dynamic_group_identifier(self):
222
+ """Get or set a text string for the dynamic_group_identifier.
223
+
224
+ Objects sharing the same dynamic_group_identifier will have their
225
+ states change in unison. If None, the object is assumed to be static.
226
+ """
227
+ return self._dynamic_group_identifier
228
+
229
+ @dynamic_group_identifier.setter
230
+ def dynamic_group_identifier(self, identifier):
231
+ if identifier is not None:
232
+ identifier = valid_rad_string(identifier)
233
+ else:
234
+ assert len(self._states) == 0, 'dynamic_group_identifier cannot be ' \
235
+ 'None while states are assigned. Use the remove_states method ' \
236
+ 'before setting to None.'
237
+ self._dynamic_group_identifier = identifier
238
+
239
+ @property
240
+ def states(self):
241
+ """Get or set an array of radiance states assigned to this object.
242
+
243
+ These cannot be set unless there is also a dynamic_group_identifier for
244
+ the object.
245
+ """
246
+ return tuple(self._states)
247
+
248
+ @states.setter
249
+ def states(self, value):
250
+ if value is not None:
251
+ assert self._dynamic_group_identifier is not None, 'Object must have ' \
252
+ 'a dynamic_group_identifier to assign states.'
253
+ try:
254
+ self._states = [self._check_state(st) for st in value]
255
+ except (ValueError, TypeError):
256
+ raise TypeError('Expected iterable for Object states. '
257
+ 'Got {}.'.format(type(value)))
258
+ else:
259
+ self._states = []
260
+
261
+ @property
262
+ def state_count(self):
263
+ """Get an integer for the number of dynamic states assigned to the object."""
264
+ return len(self._states)
265
+
266
+ def remove_states(self):
267
+ """Remove all states assigned to this object."""
268
+ for state in self._states:
269
+ state._parent = None
270
+ self._states = []
271
+
272
+ def add_state(self, state):
273
+ """Add a Radiance state object to this object.
274
+
275
+ Args:
276
+ state: A Radiance state object to add to the this object.
277
+ """
278
+ assert self._dynamic_group_identifier is not None, 'Object must have ' \
279
+ 'a dynamic_group_identifier to assign states.'
280
+ self._states.append(self._check_state(state))
281
+
282
+ def move(self, moving_vec):
283
+ """Move all state geometry along a vector.
284
+
285
+ Args:
286
+ moving_vec: A ladybug_geometry Vector3D with the direction and distance
287
+ to move the shades.
288
+ """
289
+ for state in self._states:
290
+ state.move(moving_vec)
291
+
292
+ def rotate(self, axis, angle, origin):
293
+ """Rotate all state geometry.
294
+
295
+ Args:
296
+ axis: A ladybug_geometry Vector3D axis representing the axis of rotation.
297
+ angle: An angle for rotation in degrees.
298
+ origin: A ladybug_geometry Point3D for the origin around which the
299
+ object will be rotated.
300
+ """
301
+ for state in self._states:
302
+ state.rotate(axis, angle, origin)
303
+
304
+ def rotate_xy(self, angle, origin):
305
+ """Rotate all state geometry counterclockwise in the world XY plane.
306
+
307
+ Args:
308
+ angle: An angle in degrees.
309
+ origin: A ladybug_geometry Point3D for the origin around which the
310
+ object will be rotated.
311
+ """
312
+ for state in self._states:
313
+ state.rotate_xy(angle, origin)
314
+
315
+ def reflect(self, plane):
316
+ """Reflect all state geometry across a plane.
317
+
318
+ Args:
319
+ plane: A ladybug_geometry Plane across which the object will
320
+ be reflected.
321
+ """
322
+ for state in self._states:
323
+ state.reflect(plane)
324
+
325
+ def scale(self, factor, origin=None):
326
+ """Scale all state geometry by a factor.
327
+
328
+ Args:
329
+ factor: A number representing how much the object should be scaled.
330
+ origin: A ladybug_geometry Point3D representing the origin from which
331
+ to scale. If None, it will be scaled from the World origin (0, 0, 0).
332
+ """
333
+ for state in self._states:
334
+ state.scale(factor, origin)
335
+
336
+ def duplicate(self, new_host=None):
337
+ """Get a copy of this object.
338
+
339
+ new_host: A new object that hosts these properties.
340
+ If None, the properties will be duplicated with the same host.
341
+ """
342
+ _host = new_host or self._host
343
+ new_prop = self.__class__(
344
+ _host, self._modifier, self._modifier_blk, self._dynamic_group_identifier)
345
+ new_prop._states = []
346
+ for st in self._states:
347
+ new_st = st.duplicate()
348
+ new_st._parent = _host
349
+ new_prop._states.append(new_st)
350
+ return new_prop
351
+
352
+ def is_equivalent(self, other):
353
+ """Check to see if these energy properties are equivalent to another object.
354
+
355
+ This will only be True if all properties match (except for the host) and
356
+ will otherwise be False.
357
+ """
358
+ if not is_equivalent(self._modifier, other._modifier):
359
+ return False
360
+ if not is_equivalent(self._modifier_blk, other._modifier_blk):
361
+ return False
362
+ if not is_equivalent(self._dynamic_group_identifier,
363
+ other._dynamic_group_identifier):
364
+ return False
365
+ if not is_equivalent(self.state_count, other.state_count):
366
+ return False
367
+ return True
368
+
369
+ def _check_state(self, obj):
370
+ assert isinstance(obj, _RadianceState), \
371
+ 'Expected RadianceState. Got {}.'.format(type(obj))
372
+ assert obj.parent is None, \
373
+ 'RadianceState cannot already have a parent object.'
374
+ obj._parent = self.host
375
+ return obj
376
+
377
+ def _add_states_to_dict(self, base, abridged=False):
378
+ """Add states to a base dictionary.
379
+
380
+ Args:
381
+ base: A base dictionary to which states will be added.
382
+ abridged: Boolean to note whether the full dictionary describing the
383
+ object should be returned (False) or just an abridged version (True).
384
+ Default: False.
385
+ """
386
+ if self._dynamic_group_identifier is not None:
387
+ base['radiance']['dynamic_group_identifier'] = self.dynamic_group_identifier
388
+ if len(self._states) != 0:
389
+ base['radiance']['states'] = [st.to_dict(abridged) for st in self._states]
390
+ return base
@@ -0,0 +1,197 @@
1
+ # coding=utf-8
2
+ """Aperture Radiance Properties."""
3
+ from ._base import _DynamicRadianceProperties
4
+ from ..modifier import Modifier
5
+ from ..dynamic.state import RadianceSubFaceState
6
+ from ..lib.modifiers import black
7
+ from ..lib.modifiersets import generic_modifier_set_visible
8
+
9
+
10
+ class ApertureRadianceProperties(_DynamicRadianceProperties):
11
+ """Radiance Properties for Honeybee Aperture.
12
+
13
+ Args:
14
+ host: A honeybee_core Aperture object that hosts these properties.
15
+ modifier: A Honeybee Radiance Modifier object for the aperture. If None,
16
+ it will be set by the parent Room ModifierSet or the Honeybee
17
+ default generic ModifierSet.
18
+ modifier_blk: A Honeybee Radiance Modifier object to be used for this
19
+ aperture in direct solar simulations and in isolation studies (assessing
20
+ the contribution of individual Apertures). If None, this will be
21
+ a completely black material.
22
+ dynamic_group_identifier: An optional string to note the dynamic group
23
+ to which the Aperture is a part of. Apertures sharing the same
24
+ dynamic_group_identifier will have their states change in unison.
25
+ If None, the Aperture is assumed to be static.
26
+
27
+ Properties:
28
+ * host
29
+ * modifier
30
+ * modifier_blk
31
+ * dynamic_group_identifier
32
+ * states
33
+ * state_count
34
+ * is_opaque
35
+ * is_modifier_set_on_object
36
+ * is_blk_overridden
37
+ """
38
+
39
+ __slots__ = ()
40
+
41
+ def __init__(self, host, modifier=None, modifier_blk=None,
42
+ dynamic_group_identifier=None):
43
+ """Initialize Aperture radiance properties."""
44
+ _DynamicRadianceProperties.__init__(
45
+ self, host, modifier, modifier_blk, dynamic_group_identifier)
46
+
47
+ @property
48
+ def modifier(self):
49
+ """Get or set the Aperture modifier.
50
+
51
+ If the modifier is not set on the aperture-level, then it will be assigned
52
+ based on the ModifierSet assigned to the parent Room. If there is no
53
+ parent Room or the parent Room's ModifierSet has no modifier for
54
+ the Aperture type and boundary_condition, it will be assigned using the
55
+ honeybee default generic ModifierSet.
56
+ """
57
+ if self._modifier: # set by user
58
+ return self._modifier
59
+ elif self._host.has_parent and self._host.parent.has_parent: # set by room
60
+ constr_set = self._host.parent.parent.properties.radiance.modifier_set
61
+ return constr_set.get_aperture_modifier(
62
+ self._host.boundary_condition.name, self._host.is_operable,
63
+ self._host.parent.type.name)
64
+ elif self._host.has_parent: # generic but influenced by parent aperture
65
+ return generic_modifier_set_visible.get_aperture_modifier(
66
+ self._host.boundary_condition.name, self._host.is_operable,
67
+ self._host.parent.type.name)
68
+ else:
69
+ return generic_modifier_set_visible.get_aperture_modifier(
70
+ self._host.boundary_condition.name, self._host.is_operable, 'Wall')
71
+
72
+ @modifier.setter
73
+ def modifier(self, value):
74
+ if value is not None:
75
+ assert isinstance(value, Modifier), \
76
+ 'Expected Radiance Modifier for aperture. Got {}'.format(type(value))
77
+ value.lock() # lock editing in case modifier has multiple references
78
+ self._modifier = value
79
+
80
+ @property
81
+ def modifier_blk(self):
82
+ """Get or set a modifier to be used in direct solar and in isolation studies.
83
+
84
+ If None, this will be a completely black material.
85
+ """
86
+ if self._modifier_blk: # set by user
87
+ return self._modifier_blk
88
+ return black
89
+
90
+ @modifier_blk.setter
91
+ def modifier_blk(self, value):
92
+ if value is not None:
93
+ assert isinstance(value, Modifier), \
94
+ 'Expected Radiance Modifier for aperture. Got {}'.format(type(value))
95
+ value.lock() # lock editing in case modifier has multiple references
96
+ self._modifier_blk = value
97
+
98
+ @classmethod
99
+ def from_dict(cls, data, host):
100
+ """Create ApertureRadianceProperties from a dictionary.
101
+
102
+ Note that the dictionary must be a non-abridged version for this
103
+ classmethod to work.
104
+
105
+ Args:
106
+ data: A dictionary representation of ApertureRadianceProperties with the
107
+ format below.
108
+ host: A Aperture object that hosts these properties.
109
+
110
+ .. code-block:: python
111
+
112
+ {
113
+ 'type': 'ApertureRadianceProperties',
114
+ 'modifier': {}, # A Honeybee Radiance Modifier dictionary
115
+ 'modifier_blk': {}, # A Honeybee Radiance Modifier dictionary
116
+ 'dynamic_group_identifier': str, # An optional dynamic group identifier
117
+ 'states': [] # An optional list of states
118
+ }
119
+ """
120
+ assert data['type'] == 'ApertureRadianceProperties', \
121
+ 'Expected ApertureRadianceProperties. Got {}.'.format(data['type'])
122
+ new_prop = cls(host)
123
+ new_prop = cls._restore_modifiers_from_dict(new_prop, data)
124
+ return cls._restore_states_from_dict(new_prop, data)
125
+
126
+ def apply_properties_from_dict(self, abridged_data, modifiers):
127
+ """Apply properties from a ApertureRadiancePropertiesAbridged dictionary.
128
+
129
+ Args:
130
+ abridged_data: A ApertureRadiancePropertiesAbridged dictionary (typically
131
+ coming from a Model) with the format below.
132
+ modifiers: A dictionary of modifiers with modifier identifiers as keys,
133
+ which will be used to re-assign modifiers.
134
+
135
+ .. code-block:: python
136
+
137
+ {
138
+ 'type': 'ApertureRadiancePropertiesAbridged',
139
+ 'modifier': str, # A Honeybee Radiance Modifier identifier
140
+ 'modifier_blk': str, # A Honeybee Radiance Modifier identifier
141
+ 'dynamic_group_identifier': str, # An optional dynamic group identifier
142
+ 'states': [] # An optional list of states
143
+ }
144
+ """
145
+ self._apply_modifiers_from_dict(abridged_data, modifiers)
146
+ self._apply_states_from_dict(abridged_data, modifiers)
147
+
148
+ def to_dict(self, abridged=False):
149
+ """Return radiance properties as a dictionary.
150
+
151
+ Args:
152
+ abridged: Boolean to note whether the full dictionary describing the
153
+ object should be returned (False) or just an abridged version (True).
154
+ Default: False.
155
+ """
156
+ base = {'radiance': {}}
157
+ base['radiance']['type'] = 'ApertureRadianceProperties' if not \
158
+ abridged else 'ApertureRadiancePropertiesAbridged'
159
+ self._add_modifiers_to_dict(base, abridged)
160
+ return self._add_states_to_dict(base, abridged)
161
+
162
+ def _check_state(self, obj):
163
+ assert isinstance(obj, RadianceSubFaceState), \
164
+ 'Expected RadianceSubFaceState. Got {}.'.format(type(obj))
165
+ assert obj.parent is None, \
166
+ 'RadianceSubFaceState cannot already have a parent object.'
167
+ obj._parent = self.host
168
+ return obj
169
+
170
+ def _apply_states_from_dict(self, abridged_data, modifiers):
171
+ """Apply statess from an Abridged dictionary.
172
+
173
+ Args:
174
+ abridged_data: An Abridged dictionary (typically coming from a Model).
175
+ modifiers: A dictionary of modifiers with modifier identifiers as keys,
176
+ which will be used to re-assign modifiers.
177
+ """
178
+ if 'dynamic_group_identifier' in abridged_data and \
179
+ abridged_data['dynamic_group_identifier'] is not None:
180
+ self.dynamic_group_identifier = abridged_data['dynamic_group_identifier']
181
+ if 'states' in abridged_data and abridged_data['states'] is not None:
182
+ self.states = [RadianceSubFaceState.from_dict_abridged(st, modifiers)
183
+ for st in abridged_data['states']]
184
+
185
+ @staticmethod
186
+ def _restore_states_from_dict(new_prop, data):
187
+ """Restore states from a data dictionary to a new properties object."""
188
+ if 'dynamic_group_identifier' in data and \
189
+ data['dynamic_group_identifier'] is not None:
190
+ new_prop.dynamic_group_identifier = data['dynamic_group_identifier']
191
+ if 'states' in data and data['states'] is not None:
192
+ new_prop.states = [RadianceSubFaceState.from_dict(shd)
193
+ for shd in data['states']]
194
+ return new_prop
195
+
196
+ def __repr__(self):
197
+ return 'Aperture Radiance Properties: [host: {}]'.format(self.host.display_name)