dragonfly-radiance 0.4.121__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 dragonfly-radiance might be problematic. Click here for more details.

@@ -0,0 +1,9 @@
1
+ """dragonfly-radiance library."""
2
+ from honeybee.logutil import get_logger
3
+
4
+
5
+ # load all functions that extends dragonfly core library
6
+ import dragonfly_radiance._extend_dragonfly
7
+
8
+
9
+ logger = get_logger(__name__, filename='dragonfly-radiance.log')
@@ -0,0 +1,4 @@
1
+ from dragonfly_radiance.cli import radiance
2
+
3
+ if __name__ == '__main__':
4
+ radiance()
@@ -0,0 +1,56 @@
1
+ # coding=utf-8
2
+ from dragonfly.properties import ModelProperties, BuildingProperties, StoryProperties, \
3
+ Room2DProperties, ContextShadeProperties
4
+
5
+ from .properties.model import ModelRadianceProperties
6
+ from .properties.building import BuildingRadianceProperties
7
+ from .properties.story import StoryRadianceProperties
8
+ from .properties.room2d import Room2DRadianceProperties
9
+ from .properties.context import ContextShadeRadianceProperties
10
+
11
+
12
+ # set a hidden radiance attribute on each core geometry Property class to None
13
+ # define methods to produce radiance property instances on each Property instance
14
+ ModelProperties._radiance = None
15
+ BuildingProperties._radiance = None
16
+ StoryProperties._radiance = None
17
+ Room2DProperties._radiance = None
18
+ ContextShadeProperties._radiance = None
19
+
20
+
21
+ def model_radiance_properties(self):
22
+ if self._radiance is None:
23
+ self._radiance = ModelRadianceProperties(self.host)
24
+ return self._radiance
25
+
26
+
27
+ def building_radiance_properties(self):
28
+ if self._radiance is None:
29
+ self._radiance = BuildingRadianceProperties(self.host)
30
+ return self._radiance
31
+
32
+
33
+ def story_radiance_properties(self):
34
+ if self._radiance is None:
35
+ self._radiance = StoryRadianceProperties(self.host)
36
+ return self._radiance
37
+
38
+
39
+ def room2d_radiance_properties(self):
40
+ if self._radiance is None:
41
+ self._radiance = Room2DRadianceProperties(self.host)
42
+ return self._radiance
43
+
44
+
45
+ def context_radiance_properties(self):
46
+ if self._radiance is None:
47
+ self._radiance = ContextShadeRadianceProperties(self.host)
48
+ return self._radiance
49
+
50
+
51
+ # add radiance property methods to the Properties classes
52
+ ModelProperties.radiance = property(model_radiance_properties)
53
+ BuildingProperties.radiance = property(building_radiance_properties)
54
+ StoryProperties.radiance = property(story_radiance_properties)
55
+ Room2DProperties.radiance = property(room2d_radiance_properties)
56
+ ContextShadeProperties.radiance = property(context_radiance_properties)
@@ -0,0 +1,18 @@
1
+ """dragonfly-radiance commands which will be added to the dragonfly CLI."""
2
+ import click
3
+
4
+ from dragonfly.cli import main
5
+ from .translate import translate
6
+
7
+
8
+ # command group for all radiance extension commands.
9
+ @click.group(help='dragonfly radiance commands.')
10
+ def radiance():
11
+ pass
12
+
13
+
14
+ # add sub-commands for radiance
15
+ radiance.add_command(translate)
16
+
17
+ # add radiance sub-commands to dragonfly CLI
18
+ main.add_command(radiance)
@@ -0,0 +1,394 @@
1
+ """dragonfly radiance translation commands."""
2
+ import click
3
+ import sys
4
+ import os
5
+ import logging
6
+ import zipfile
7
+
8
+ from ladybug.futil import unzip_file
9
+ from ladybug.commandutil import process_content_to_output
10
+ from dragonfly.model import Model
11
+
12
+
13
+ _logger = logging.getLogger(__name__)
14
+
15
+
16
+ @click.group(help='Commands for translating Dragonfly files to/from Radiance.')
17
+ def translate():
18
+ pass
19
+
20
+
21
+ @translate.command('model-to-rad-folder')
22
+ @click.argument('model-file', type=click.Path(
23
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
24
+ @click.option(
25
+ '--multiplier/--full-geometry', ' /-fg', help='Flag to note if the '
26
+ 'multipliers on each Building story will be passed along to the '
27
+ 'generated Honeybee Room objects or if full geometry objects should be '
28
+ 'written for each story in the building.', default=True, show_default=True
29
+ )
30
+ @click.option(
31
+ '--plenum/--no-plenum', '-p/-np', help='Flag to indicate whether '
32
+ 'ceiling/floor plenum depths assigned to Room2Ds should generate '
33
+ 'distinct 3D Rooms in the translation.', default=True, show_default=True
34
+ )
35
+ @click.option(
36
+ '--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate '
37
+ 'whether adjacencies should be solved between interior stories when '
38
+ 'Room2Ds perfectly match one another in their floor plate. This ensures '
39
+ 'that Surface boundary conditions are used instead of Adiabatic ones. '
40
+ 'Note that this input has no effect when the object-per-model is Story.',
41
+ default=True, show_default=True
42
+ )
43
+ @click.option(
44
+ '--merge-method', '-m', help='Text to describe how the Room2Ds should '
45
+ 'be merged into individual Rooms during the translation. Specifying a '
46
+ 'value here can be an effective way to reduce the number of Room '
47
+ 'volumes in the resulting Model and, ultimately, yield less results to manage. '
48
+ 'Choose from: None, Zones, PlenumZones, Stories, PlenumStories.',
49
+ type=str, default='None', show_default=True
50
+ )
51
+ @click.option(
52
+ '--folder', help='Folder into which the model Radiance '
53
+ 'folders will be written. If None, the files will be output in the '
54
+ 'same location as the model_file.', default=None, show_default=True
55
+ )
56
+ @click.option(
57
+ '--grid', '-g', multiple=True, help='List of grids to be included in folder. By '
58
+ 'default all the sensor grids will be exported. You can also use wildcards here. '
59
+ 'For instance first_floor_* will select all the sensor grids that has an identifier '
60
+ 'that starts with first_floor. To filter based on group_identifier use /. For '
61
+ 'example daylight/* will select all the grids that belong to daylight group.')
62
+ @click.option(
63
+ '--view', '-v', multiple=True, help='List of views to be included in folder. By '
64
+ 'default all the views will be exported. You can also use wildcards to filter '
65
+ 'multiple views. For instance first_floor_* will select all the views that has an '
66
+ 'identifier that starts with first_floor. To filter based on group_identifier use '
67
+ '/. For example daylight/* will select all the views that belong to daylight group.')
68
+ @click.option(
69
+ '--full-match/--no-full-match', help='Flag to note whether the grids and'
70
+ 'views should be filtered by their identifiers as full matches. Setting '
71
+ 'this to True indicates that wildcard symbols will not be used in the '
72
+ 'filtering of grids and views.', default=False, show_default=True)
73
+ @click.option(
74
+ '--config-file', '-c', help='An optional config file path to modify the '
75
+ 'default folder names. If None, folder.cfg in honeybee-radiance-folder '
76
+ 'will be used.', default=None, show_default=True)
77
+ @click.option(
78
+ '--minimal/--maximal', '-min/-max', help='Flag to note whether the radiance strings '
79
+ 'should be written in a minimal format (with spaces instead of line '
80
+ 'breaks).', default=False, show_default=True)
81
+ @click.option(
82
+ '--no-grid-check/--grid-check', ' /-gc', help='Flag to note whether the '
83
+ 'model should be checked for the presence of sensor grids. If the check '
84
+ 'is set and the model has no grids, an explicit error will be raised.',
85
+ default=True, show_default=True)
86
+ @click.option(
87
+ '--no-view-check/--view-check', ' /-vc', help='Flag to note whether the '
88
+ 'model should be checked for the presence of views. If the check '
89
+ 'is set and the model has no views, an explicit error will be raised.',
90
+ default=True, show_default=True)
91
+ @click.option(
92
+ '--create-grids', '-cg', default=False, show_default=True, is_flag=True,
93
+ help='Flag to note whether sensor grids should be created if none exists. '
94
+ 'This will only create sensor grids for rooms if there are no sensor grids '
95
+ 'in the model.'
96
+ )
97
+ @click.option(
98
+ '--log-file', help='Optional log file to output the path of the radiance '
99
+ 'folder generated from the model. By default this will be printed '
100
+ 'to stdout', type=click.File('w'), default='-')
101
+ def model_to_rad_folder_cli(
102
+ model_file, multiplier, plenum, no_ceil_adjacency, merge_method,
103
+ folder, view, grid, full_match, config_file, minimal,
104
+ no_grid_check, no_view_check, create_grids, log_file
105
+ ):
106
+ """Translate a Model file into a Radiance Folder.
107
+
108
+ \b
109
+ Args:
110
+ model_file: Full path to a Model JSON file (DFJSON) or a Model
111
+ pkl (DFpkl) file. This can also be a zipped version of a Radiance
112
+ folder, in which case this command will simply unzip the file
113
+ into the --folder and no other operations will be performed on it.
114
+ """
115
+ try:
116
+ full_geometry = not multiplier
117
+ no_plenum = not plenum
118
+ ceil_adjacency = not no_ceil_adjacency
119
+ grid_check = not no_grid_check
120
+ view_check = not no_view_check
121
+ model_to_rad_folder(
122
+ model_file, full_geometry, no_plenum, ceil_adjacency, merge_method,
123
+ folder, view, grid, full_match, config_file,
124
+ minimal, grid_check, view_check, create_grids, log_file)
125
+ except Exception as e:
126
+ _logger.exception('Model translation failed.\n{}'.format(e))
127
+ sys.exit(1)
128
+ else:
129
+ sys.exit(0)
130
+
131
+
132
+ def model_to_rad_folder(
133
+ model_file, full_geometry=False, no_plenum=False, ceil_adjacency=False,
134
+ merge_method='None', folder=None, view=None, grid=None, full_match=False,
135
+ config_file=None, minimal=False, grid_check=False, view_check=False,
136
+ create_grids=False, log_file=None,
137
+ multiplier=True, plenum=True, no_ceil_adjacency=True,
138
+ no_full_match=True, maximal=True, no_grid_check=False, no_view_check=False,
139
+ ):
140
+ """Translate a Model file into a Radiance Folder.
141
+
142
+ Args:
143
+ model_file: Full path to a Model JSON file (DFJSON) or a Model
144
+ pkl (DFpkl) file. This can also be a zipped version of a Radiance
145
+ folder, in which case this command will simply unzip the file
146
+ into the --folder and no other operations will be performed on it.
147
+ full_geometry: Boolean to note if the multipliers on each Building story
148
+ will be passed along to the generated Honeybee Room objects or if
149
+ full geometry objects should be written for each story in the
150
+ building. (Default: False).
151
+ no_plenum: Boolean to indicate whether ceiling/floor plenum depths
152
+ assigned to Room2Ds should generate distinct 3D Rooms in the
153
+ translation. (Default: False).
154
+ ceil_adjacency: Boolean to indicate whether adjacencies should be solved
155
+ between interior stories when Room2Ds perfectly match one another
156
+ in their floor plate. This ensures that Surface boundary conditions
157
+ are used instead of Adiabatic ones. Note that this input has no
158
+ effect when the object-per-model is Story. (Default: False).
159
+ merge_method: An optional text string to describe how the Room2Ds should
160
+ be merged into individual Rooms during the translation. Specifying a
161
+ value here can be an effective way to reduce the number of Room
162
+ volumes in the resulting Model and, ultimately, yield less
163
+ results to manage. Note that Room2Ds will only be merged if they
164
+ form a contiguous volume. Otherwise, there will be multiple Rooms per
165
+ zone or story, each with an integer added at the end of their
166
+ identifiers. Choose from the following options:
167
+
168
+ * None - No merging will occur
169
+ * Zones - Room2Ds in the same zone will be merged
170
+ * PlenumZones - Only plenums in the same zone will be merged
171
+ * Stories - Rooms in the same story will be merged
172
+ * PlenumStories - Only plenums in the same story will be merged
173
+
174
+ folder: Folder into which the model Radiance folders will be written.
175
+ If None, the files will be output in the same location as the model_file.
176
+ view: List of grids to be included in folder. By default all the sensor
177
+ grids will be exported. You can also use wildcards here. For instance
178
+ first_floor_* will select all the sensor grids that has an identifier
179
+ that starts with first_floor. To filter based on group_identifier
180
+ use /. For example daylight/* will select all the grids that belong
181
+ to daylight group. (Default: None).
182
+ grid: List of views to be included in folder. By default all the views
183
+ will be exported. You can also use wildcards to filter multiple views.
184
+ For instance first_floor_* will select all the views that has an
185
+ identifier that starts with first_floor. To filter based on
186
+ group_identifier use /. For example daylight/* will select all the
187
+ views that belong to daylight group. (Default: None).
188
+ full_match: Boolean to note whether the grids and views should be
189
+ filtered by their identifiers as full matches. Setting this to
190
+ True indicates that wildcard symbols will not be used in the
191
+ filtering of grids and views. (Default: False).
192
+ config_file: An optional config file path to modify the default folder
193
+ names. If None, folder.cfg in honeybee-radiance-folder will be used.
194
+ minimal: Boolean to note whether the radiance strings should be written
195
+ in a minimal format (with spaces instead of line breaks). (Default: False).
196
+ grid_check: Boolean to note whether the model should be checked for the
197
+ presence of sensor grids. If the check is set and the model has no
198
+ grids, an explicit error will be raised. (Default: False).
199
+ view_check: Boolean to note whether the model should be checked for the
200
+ presence of views. If the check is set and the model has no views,
201
+ an explicit error will be raised. (Default: False).
202
+ log_file: Optional log file to output the path of the radiance folder
203
+ generated from the model. If None, it will be returned from this method.
204
+ """
205
+ # set the default folder if it's not specified
206
+ if folder is None:
207
+ folder = os.path.dirname(os.path.abspath(model_file))
208
+
209
+ # first check to see if the model_file is a zipped radiance folder
210
+ if zipfile.is_zipfile(model_file):
211
+ unzip_file(model_file, folder)
212
+ if log_file is None:
213
+ return folder
214
+ else:
215
+ log_file.write(folder)
216
+ else:
217
+ # re-serialize the Dragonfly Model
218
+ model = Model.from_file(model_file)
219
+
220
+ # convert Dragonfly Model to Honeybee
221
+ multiplier = not full_geometry
222
+ hb_models = model.to_honeybee(
223
+ object_per_model='District', use_multiplier=multiplier,
224
+ exclude_plenums=no_plenum, solve_ceiling_adjacencies=ceil_adjacency,
225
+ merge_method=merge_method)
226
+ model = hb_models[0]
227
+
228
+ if create_grids:
229
+ if not model.properties.radiance.has_sensor_grids:
230
+ sensor_grids = []
231
+
232
+ unit_conversion = {
233
+ 'Meters': 1,
234
+ 'Millimeters': 0.001,
235
+ 'Centimeters': 0.01,
236
+ 'Feet': 0.3048,
237
+ 'Inches': 0.0254
238
+ }
239
+
240
+ if model.units in ['Meters', 'Millimeters', 'Centimeters']:
241
+ grid_size = 0.5 / unit_conversion[model.units]
242
+ offset = 0.76 / unit_conversion[model.units]
243
+ wall_offset = 0.3 / unit_conversion[model.units]
244
+ else: # assume IP units
245
+ grid_size = 2 * 0.3048 / unit_conversion[model.units]
246
+ offset = 2.5 * 0.3048 / unit_conversion[model.units]
247
+ wall_offset = 1 * 0.3048 / unit_conversion[model.units]
248
+
249
+ for room in model.rooms:
250
+ sensor_grids.append(room.properties.radiance.generate_sensor_grid(
251
+ grid_size, offset=offset, wall_offset=wall_offset))
252
+ model.properties.radiance.sensor_grids = sensor_grids
253
+
254
+ if grid_check and len(model.properties.radiance.sensor_grids) == 0:
255
+ raise ValueError('Model contains no sensor grids. These are required.')
256
+ if view_check and len(model.properties.radiance.views) == 0:
257
+ raise ValueError('Model contains no views These are required.')
258
+
259
+ # translate the model to a radiance folder
260
+ rad_fold = model.to.rad_folder(
261
+ model, folder, config_file, minimal, views=view, grids=grid,
262
+ full_match=full_match
263
+ )
264
+
265
+ if log_file is None:
266
+ return rad_fold
267
+ else:
268
+ log_file.write(rad_fold)
269
+
270
+
271
+ @translate.command('model-to-rad')
272
+ @click.argument('model-file', type=click.Path(
273
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
274
+ @click.option('--multiplier/--full-geometry', ' /-fg', help='Flag to note if the '
275
+ 'multipliers on each Building story will be passed along to the '
276
+ 'generated Honeybee Room objects or if full geometry objects should be '
277
+ 'written for each story in the building.', default=True, show_default=True)
278
+ @click.option('--plenum/--no-plenum', '-p/-np', help='Flag to indicate whether '
279
+ 'ceiling/floor plenum depths assigned to Room2Ds should generate '
280
+ 'distinct 3D Rooms in the translation.', default=True, show_default=True)
281
+ @click.option('--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate '
282
+ 'whether adjacencies should be solved between interior stories when '
283
+ 'Room2Ds perfectly match one another in their floor plate. This ensures '
284
+ 'that Surface boundary conditions are used instead of Adiabatic ones. '
285
+ 'Note that this input has no effect when the object-per-model is Story.',
286
+ default=True, show_default=True)
287
+ @click.option('--merge-method', '-m', help='Text to describe how the Room2Ds should '
288
+ 'be merged into individual Rooms during the translation. Specifying a '
289
+ 'value here can be an effective way to reduce the number of Room '
290
+ 'volumes in the resulting Model and, ultimately, yield less results to manage. '
291
+ 'Choose from: None, Zones, PlenumZones, Stories, PlenumStories.',
292
+ type=str, default='None', show_default=True)
293
+ @click.option('--blk', help='Boolean to note whether the "blacked out" version '
294
+ 'of the geometry should be output, which is useful for direct studies '
295
+ 'and isolation studies of individual apertures.',
296
+ default=False, show_default=True)
297
+ @click.option('--minimal/--maximal', help='Flag to note whether the radiance strings '
298
+ 'should be written in a minimal format (with spaces instead of line '
299
+ 'breaks).', default=False, show_default=True)
300
+ @click.option('--output-file', '-f', help='Optional Rad file to output the Rad string '
301
+ 'of the translation. By default this will be printed out to stdout',
302
+ type=click.File('w'), default='-', show_default=True)
303
+ def model_to_rad_cli(model_file, multiplier, plenum, no_ceil_adjacency, merge_method,
304
+ blk, minimal, output_file):
305
+ """Translate a Dragonfly Model file to a Radiance string.
306
+
307
+ The resulting string will include all geometry and all modifiers.
308
+
309
+ \b
310
+ Args:
311
+ model_file: Full path to a Dragonfly Model JSON or Pkl file.
312
+ """
313
+ try:
314
+ full_geometry = not multiplier
315
+ no_plenum = not plenum
316
+ ceil_adjacency = not no_ceil_adjacency
317
+ model_to_rad(model_file, full_geometry, no_plenum, ceil_adjacency,
318
+ merge_method, blk, minimal, output_file)
319
+ except Exception as e:
320
+ _logger.exception('Model translation failed.\n{}\n'.format(e))
321
+ sys.exit(1)
322
+ else:
323
+ sys.exit(0)
324
+
325
+
326
+ def model_to_rad(
327
+ model_file, full_geometry=False, no_plenum=False, ceil_adjacency=False,
328
+ merge_method='None', blk=False, minimal=False, output_file=None,
329
+ multiplier=True, plenum=True, no_ceil_adjacency=True, maximal=True
330
+ ):
331
+ """Translate a Model file to a Radiance string.
332
+
333
+ The resulting strings will include all geometry (Rooms, Faces, Shades, Apertures,
334
+ Doors) and all modifiers. However, it does not include any states for dynamic
335
+ geometry and will only write the default state for each dynamic object. To
336
+ correctly account for dynamic objects, model-to-rad-folder should be used.
337
+
338
+ Args:
339
+ model_file: Full path to a Model JSON file (DFJSON) or a Model pkl (DFpkl) file.
340
+ full_geometry: Boolean to note if the multipliers on each Building story
341
+ will be passed along to the generated Honeybee Room objects or if
342
+ full geometry objects should be written for each story in the
343
+ building. (Default: False).
344
+ no_plenum: Boolean to indicate whether ceiling/floor plenum depths
345
+ assigned to Room2Ds should generate distinct 3D Rooms in the
346
+ translation. (Default: False).
347
+ ceil_adjacency: Boolean to indicate whether adjacencies should be solved
348
+ between interior stories when Room2Ds perfectly match one another
349
+ in their floor plate. This ensures that Surface boundary conditions
350
+ are used instead of Adiabatic ones. Note that this input has no
351
+ effect when the object-per-model is Story. (Default: False).
352
+ merge_method: An optional text string to describe how the Room2Ds should
353
+ be merged into individual Rooms during the translation. Specifying a
354
+ value here can be an effective way to reduce the number of Room
355
+ volumes in the resulting Model and, ultimately, yield less
356
+ results to manage. Note that Room2Ds will only be merged if they
357
+ form a contiguous volume. Otherwise, there will be multiple Rooms per
358
+ zone or story, each with an integer added at the end of their
359
+ identifiers. Choose from the following options:
360
+
361
+ * None - No merging will occur
362
+ * Zones - Room2Ds in the same zone will be merged
363
+ * PlenumZones - Only plenums in the same zone will be merged
364
+ * Stories - Rooms in the same story will be merged
365
+ * PlenumStories - Only plenums in the same story will be merged
366
+
367
+ blk: Boolean to note whether the "blacked out" version of the geometry
368
+ should be output, which is useful for direct studies and isolation
369
+ studies of individual apertures.
370
+ minimal: Boolean to note whether the radiance strings should be written
371
+ in a minimal format (with spaces instead of line breaks).
372
+ output_file: Optional RAD file to output the RAD string of the translation.
373
+ If None, the string will be returned from this method. (Default: None).
374
+ """
375
+ # re-serialize the Dragonfly Model
376
+ model = Model.from_file(model_file)
377
+
378
+ # convert Dragonfly Model to Honeybee
379
+ multiplier = not full_geometry
380
+ hb_models = model.to_honeybee(
381
+ object_per_model='District', use_multiplier=multiplier,
382
+ exclude_plenums=no_plenum, solve_ceiling_adjacencies=ceil_adjacency,
383
+ merge_method=merge_method
384
+ )
385
+ hb_model = hb_models[0]
386
+
387
+ # create the strings for modifiers and geometry
388
+ model_str, modifier_str = hb_model.to.rad(hb_model, blk, minimal)
389
+ rad_str_list = ['# ======== MODEL MODIFIERS ========', modifier_str,
390
+ '# ======== MODEL GEOMETRY ========', model_str]
391
+ rad_str = '\n\n'.join(rad_str_list)
392
+
393
+ # write out the rad string
394
+ return process_content_to_output(rad_str, output_file)