honeybee-radiance-postprocess 0.4.555__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.
Files changed (50) hide show
  1. honeybee_radiance_postprocess/__init__.py +1 -0
  2. honeybee_radiance_postprocess/__main__.py +4 -0
  3. honeybee_radiance_postprocess/annual.py +73 -0
  4. honeybee_radiance_postprocess/annualdaylight.py +289 -0
  5. honeybee_radiance_postprocess/annualirradiance.py +35 -0
  6. honeybee_radiance_postprocess/breeam/__init__.py +1 -0
  7. honeybee_radiance_postprocess/breeam/breeam.py +552 -0
  8. honeybee_radiance_postprocess/cli/__init__.py +33 -0
  9. honeybee_radiance_postprocess/cli/abnt.py +392 -0
  10. honeybee_radiance_postprocess/cli/breeam.py +96 -0
  11. honeybee_radiance_postprocess/cli/datacollection.py +133 -0
  12. honeybee_radiance_postprocess/cli/grid.py +295 -0
  13. honeybee_radiance_postprocess/cli/leed.py +143 -0
  14. honeybee_radiance_postprocess/cli/merge.py +161 -0
  15. honeybee_radiance_postprocess/cli/mtxop.py +161 -0
  16. honeybee_radiance_postprocess/cli/postprocess.py +1092 -0
  17. honeybee_radiance_postprocess/cli/schedule.py +103 -0
  18. honeybee_radiance_postprocess/cli/translate.py +216 -0
  19. honeybee_radiance_postprocess/cli/two_phase.py +252 -0
  20. honeybee_radiance_postprocess/cli/util.py +121 -0
  21. honeybee_radiance_postprocess/cli/viewfactor.py +157 -0
  22. honeybee_radiance_postprocess/cli/well.py +110 -0
  23. honeybee_radiance_postprocess/data_type.py +102 -0
  24. honeybee_radiance_postprocess/dynamic.py +273 -0
  25. honeybee_radiance_postprocess/electriclight.py +24 -0
  26. honeybee_radiance_postprocess/en17037.py +304 -0
  27. honeybee_radiance_postprocess/helper.py +266 -0
  28. honeybee_radiance_postprocess/ies/__init__.py +1 -0
  29. honeybee_radiance_postprocess/ies/lm.py +224 -0
  30. honeybee_radiance_postprocess/ies/lm_schedule.py +248 -0
  31. honeybee_radiance_postprocess/leed/__init__.py +1 -0
  32. honeybee_radiance_postprocess/leed/leed.py +801 -0
  33. honeybee_radiance_postprocess/leed/leed_schedule.py +256 -0
  34. honeybee_radiance_postprocess/metrics.py +439 -0
  35. honeybee_radiance_postprocess/reader.py +80 -0
  36. honeybee_radiance_postprocess/results/__init__.py +4 -0
  37. honeybee_radiance_postprocess/results/annual_daylight.py +752 -0
  38. honeybee_radiance_postprocess/results/annual_irradiance.py +196 -0
  39. honeybee_radiance_postprocess/results/results.py +1416 -0
  40. honeybee_radiance_postprocess/type_hints.py +38 -0
  41. honeybee_radiance_postprocess/util.py +211 -0
  42. honeybee_radiance_postprocess/vis_metadata.py +49 -0
  43. honeybee_radiance_postprocess/well/__init__.py +1 -0
  44. honeybee_radiance_postprocess/well/well.py +509 -0
  45. honeybee_radiance_postprocess-0.4.555.dist-info/METADATA +79 -0
  46. honeybee_radiance_postprocess-0.4.555.dist-info/RECORD +50 -0
  47. honeybee_radiance_postprocess-0.4.555.dist-info/WHEEL +5 -0
  48. honeybee_radiance_postprocess-0.4.555.dist-info/entry_points.txt +2 -0
  49. honeybee_radiance_postprocess-0.4.555.dist-info/licenses/LICENSE +661 -0
  50. honeybee_radiance_postprocess-0.4.555.dist-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ """honeybee-radiance-postprocess library."""
@@ -0,0 +1,4 @@
1
+ from honeybee_radiance_postprocess.cli import postprocess
2
+
3
+ if __name__ == '__main__':
4
+ postprocess()
@@ -0,0 +1,73 @@
1
+ """Shared functions for post-processing annual results."""
2
+ from typing import Union
3
+ try:
4
+ import cupy as np
5
+ is_gpu = True
6
+ except ImportError:
7
+ is_gpu = False
8
+ import numpy as np
9
+
10
+ from ladybug.analysisperiod import AnalysisPeriod
11
+ from .util import filter_array
12
+
13
+ is_cpu = not is_gpu
14
+
15
+
16
+ def occupancy_schedule_8_to_6(
17
+ timestep: int = 1, as_list: bool = False) -> Union[np.ndarray, list]:
18
+ """Create an occupancy schedule for LEED (8 am to 6 pm).
19
+
20
+ Args:
21
+ timestep: An integer value noting the number of timesteps per hour.
22
+ Defaults to 1.
23
+ as_list: Boolean toggle to output the schedule as a Python list instead
24
+ of a NumPy array. Defaults to False.
25
+
26
+ Returns:
27
+ A schedule as an array or list.
28
+ """
29
+ full_analysis_period = np.array(AnalysisPeriod(timestep=timestep).hoys)
30
+ analysis_period = np.array(AnalysisPeriod(st_hour=8, end_hour=17, timestep=timestep).hoys)
31
+ schedule = np.zeros(8760 * timestep).astype(int)
32
+ hours = np.where(np.isin(full_analysis_period, analysis_period))[0]
33
+ schedule[hours] = 1
34
+ if as_list:
35
+ schedule = schedule.tolist()
36
+
37
+ return schedule
38
+
39
+
40
+ def schedule_to_hoys(
41
+ schedule: Union[list, np.ndarray],
42
+ sun_up_hours: Union[list, np.ndarray] = None, as_list: bool = False
43
+ ) -> Union[np.ndarray, list]:
44
+ """Convert a schedule to hoys.
45
+
46
+ Args:
47
+ schedule: A list of 8760 values for the occupancy schedule.
48
+ sun_up_hours: An optional list of sun up hours as integers. If sun up
49
+ hours are provided the function will exclude all values from the
50
+ schedule that are not among the sun up hours. Defaults to None.
51
+ as_list: Boolean toggle to output the schedule as a Python list instead
52
+ of a NumPy array. Defaults to False.
53
+
54
+ Returns:
55
+ An array or list of occupancy expressed as hoys.
56
+ """
57
+ assert len(schedule) == 8760
58
+ if not isinstance(schedule, np.ndarray):
59
+ schedule = np.array(schedule).astype(int)
60
+
61
+ hours = np.arange(0, 8760, 1)
62
+ if sun_up_hours:
63
+ sun_up_hours = np.array(sun_up_hours).astype(int)
64
+ mask = np.ones(schedule.size, dtype=bool)
65
+ mask[sun_up_hours] = False
66
+ schedule[mask] = 0
67
+
68
+ occ_hoys = filter_array(hours, np.array(schedule))
69
+
70
+ if as_list:
71
+ occ_hoys = occ_hoys.tolist()
72
+
73
+ return occ_hoys
@@ -0,0 +1,289 @@
1
+ """Functions for post-processing annual daylight outputs.
2
+
3
+ Note: These functions will most likely be moved to a separate package in the near future.
4
+ """
5
+ import json
6
+ import os
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
13
+
14
+ from ladybug.color import Colorset
15
+ from ladybug.datatype.fraction import Fraction
16
+ from ladybug.legend import LegendParameters
17
+ from honeybee_radiance.postprocess.annual import filter_schedule_by_hours, \
18
+ _process_input_folder
19
+
20
+ from .metrics import da_array2d, cda_array2d, udi_array2d, \
21
+ udi_lower_array2d, udi_upper_array2d
22
+ from .util import filter_array
23
+
24
+
25
+ def metrics_to_files(ill_file, occ_pattern, output_folder, threshold=300,
26
+ min_t=100, max_t=3000, grid_name=None, total_hours=None,
27
+ sun_down_occ_hours=0):
28
+ """Compute annual metrics for an ill file and write the results to a folder.
29
+
30
+ This function generates 5 different files or daylight autonomy, continuous daylight
31
+ autonomy, lower than useful daylight illuminance, useful daylight illuminance and
32
+ higher than useful daylight illuminance.
33
+
34
+ Args:
35
+ ill_file: Path to an ill file generated by Radiance. The ill file should be
36
+ tab separated and shot NOT have a header. The results for each sensor point
37
+ should be available in a row and and each column should be the illuminance
38
+ value for a sun_up_hour. The number of columns should match the number of
39
+ sun up hours.
40
+ occ_pattern: A list of 0 and 1 values for hours of occupancy.
41
+ output_folder: An output folder where the results will be written to. The folder
42
+ will be created if not exist.
43
+ threshold: Threshold illuminance level for daylight autonomy. Default: 300.
44
+ min_t: Minimum threshold for useful daylight illuminance. Default: 100.
45
+ max_t: Maximum threshold for useful daylight illuminance. Default: 3000.
46
+ grid_name: An optional name for grid name which will be used to name the output
47
+ files. If None the name of the input file will be used.
48
+ total_hours: An integer for the total number of occupied hours in the
49
+ occupancy schedule. If None, it will be assumed that all of the
50
+ occupied hours are sun-up hours and are already accounted for
51
+ in the the occ_pattern.
52
+
53
+ Returns:
54
+ Tuple(file.da, file.cda, file.udi, file.udi, file.udi)
55
+
56
+ """
57
+ if not os.path.isdir(output_folder):
58
+ os.makedirs(output_folder)
59
+
60
+ grid_name = grid_name or os.path.split(ill_file)[-1][-4:]
61
+ da = os.path.join(output_folder, 'da', '%s.da' % grid_name).replace('\\', '/')
62
+ cda = os.path.join(output_folder, 'cda', '%s.cda' % grid_name).replace('\\', '/')
63
+ udi = os.path.join(output_folder, 'udi', '%s.udi' % grid_name).replace('\\', '/')
64
+ udi_lower = \
65
+ os.path.join(output_folder, 'udi_lower', '%s.udi' % grid_name).replace('\\', '/')
66
+ udi_upper = \
67
+ os.path.join(output_folder, 'udi_upper', '%s.udi' % grid_name).replace('\\', '/')
68
+
69
+ for file_path in [da, cda, udi, udi_upper, udi_lower]:
70
+ folder = os.path.dirname(file_path)
71
+ if not os.path.isdir(folder):
72
+ os.makedirs(folder)
73
+
74
+ mask = np.array(occ_pattern)
75
+ results = np.load(ill_file)
76
+ results_occ = np.apply_along_axis(filter_array, 1, results, mask=mask)
77
+
78
+ dar = da_array2d(results_occ, total_occ=total_hours, threshold=threshold)
79
+ np.savetxt(da, dar, fmt='%.2f')
80
+
81
+ cdar = cda_array2d(results_occ, total_occ=total_hours, threshold=threshold)
82
+ np.savetxt(cda, cdar, fmt='%.2f')
83
+
84
+ udir = udi_array2d(results_occ, total_occ=total_hours, min_t=min_t, max_t=max_t)
85
+ np.savetxt(udi, udir, fmt='%.2f')
86
+
87
+ udi_lowerr = udi_lower_array2d(results_occ, total_occ=total_hours, min_t=min_t,
88
+ sun_down_occ_hours=sun_down_occ_hours)
89
+ np.savetxt(udi_lower, udi_lowerr, fmt='%.2f')
90
+
91
+ udi_upperr = udi_upper_array2d(results_occ, total_occ=total_hours, max_t=max_t)
92
+ np.savetxt(udi_upper, udi_upperr, fmt='%.2f')
93
+
94
+ return da, cda, udi_lower, udi, udi_upper
95
+
96
+
97
+ # TODO - support a list of schedules/schedule folder to match the input grids
98
+ def metrics_to_folder(
99
+ results_folder, schedule=None, threshold=300, min_t=100, max_t=3000,
100
+ grids_filter='*', sub_folder='metrics'
101
+ ):
102
+ """Compute annual metrics in a folder and write them in a subfolder.
103
+
104
+ This folder is an output folder of annual daylight recipe. Folder should include
105
+ grids_info.json and sun-up-hours.txt - the script uses the list in grids_info.json
106
+ to find the result files for each sensor grid.
107
+
108
+ Args:
109
+ results_folder: Results folder.
110
+ schedule: An annual schedule for 8760 hours of the year as a list of values.
111
+ threshold: Threshold illuminance level for daylight autonomy. Default: 300.
112
+ min_t: Minimum threshold for useful daylight illuminance. Default: 100.
113
+ max_t: Maximum threshold for useful daylight illuminance. Default: 3000.
114
+ grids_filter: A pattern to filter the grids. By default all the grids will be
115
+ processed.
116
+ sub_folder: An optional relative path for subfolder to copy results files.
117
+ Default: metrics
118
+
119
+ Returns:
120
+ str -- Path to results folder.
121
+
122
+ """
123
+ grids, sun_up_hours = _process_input_folder(results_folder, grids_filter)
124
+ occ_pattern, total_occ, sun_down_occ_hours = \
125
+ filter_schedule_by_hours(sun_up_hours=sun_up_hours, schedule=schedule)
126
+
127
+ metrics_folder = os.path.join(results_folder, sub_folder)
128
+ if not os.path.isdir(metrics_folder):
129
+ os.makedirs(metrics_folder)
130
+
131
+ for grid in grids:
132
+ ill_file = os.path.join(results_folder, '%s.npy' % grid['full_id'])
133
+ metrics_to_files(
134
+ ill_file, occ_pattern, metrics_folder, threshold, min_t,
135
+ max_t, grid['full_id'], total_occ, sun_down_occ_hours
136
+ )
137
+
138
+ # copy info.json to all results folders
139
+ for folder_name in ['da', 'cda', 'udi_lower', 'udi', 'udi_upper']:
140
+ grid_info = os.path.join(metrics_folder, folder_name, 'grids_info.json')
141
+ with open(grid_info, 'w') as outf:
142
+ json.dump(grids, outf)
143
+
144
+ metric_info_dict = _annual_daylight_vis_metadata()
145
+ for metric, data in metric_info_dict.items():
146
+ file_path = os.path.join(metrics_folder, metric, 'vis_metadata.json')
147
+ with open(file_path, 'w') as fp:
148
+ json.dump(data, fp, indent=4)
149
+
150
+ return metrics_folder
151
+
152
+
153
+ def _annual_daylight_vis_metadata():
154
+ """Return visualization metadata for annual daylight."""
155
+ udi_l_lpar = LegendParameters(min=0, max=100, colors=Colorset.nuanced())
156
+ udi_u_lpar = LegendParameters(min=0, max=100, colors=Colorset.glare_study())
157
+ udi_lpar = LegendParameters(min=0, max=100, colors=Colorset.annual_comfort())
158
+ cda_lpar = LegendParameters(min=0, max=100, colors=Colorset.annual_comfort())
159
+ da_lpar = LegendParameters(min=0, max=100, colors=Colorset.annual_comfort())
160
+
161
+ metric_info_dict = {
162
+ 'udi_lower': {
163
+ 'type': 'VisualizationMetaData',
164
+ 'data_type': Fraction('Useful Daylight Illuminance Lower').to_dict(),
165
+ 'unit': '%',
166
+ 'legend_parameters': udi_l_lpar.to_dict()
167
+ },
168
+ 'udi_upper': {
169
+ 'type': 'VisualizationMetaData',
170
+ 'data_type': Fraction('Useful Daylight Illuminance Upper').to_dict(),
171
+ 'unit': '%',
172
+ 'legend_parameters': udi_u_lpar.to_dict()
173
+ },
174
+ 'udi': {
175
+ 'type': 'VisualizationMetaData',
176
+ 'data_type': Fraction('Useful Daylight Illuminance').to_dict(),
177
+ 'unit': '%',
178
+ 'legend_parameters': udi_lpar.to_dict()
179
+ },
180
+ 'cda': {
181
+ 'type': 'VisualizationMetaData',
182
+ 'data_type': Fraction('Continuous Daylight Autonomy').to_dict(),
183
+ 'unit': '%',
184
+ 'legend_parameters': cda_lpar.to_dict()
185
+ },
186
+ 'da': {
187
+ 'type': 'VisualizationMetaData',
188
+ 'data_type': Fraction('Daylight Autonomy').to_dict(),
189
+ 'unit': '%',
190
+ 'legend_parameters': da_lpar.to_dict()
191
+ }
192
+ }
193
+
194
+ return metric_info_dict
195
+
196
+
197
+ def _annual_daylight_config():
198
+ """Return vtk-config for annual daylight. """
199
+ cfg = {
200
+ "data": [
201
+ {
202
+ "identifier": "Useful Daylight Illuminance Lower",
203
+ "object_type": "grid",
204
+ "unit": "Percentage",
205
+ "path": "udi_lower",
206
+ "hide": False,
207
+ "legend_parameters": {
208
+ "hide_legend": False,
209
+ "min": 0,
210
+ "max": 100,
211
+ "color_set": "nuanced",
212
+ },
213
+ },
214
+ {
215
+ "identifier": "Useful Daylight Illuminance Upper",
216
+ "object_type": "grid",
217
+ "unit": "Percentage",
218
+ "path": "udi_upper",
219
+ "hide": False,
220
+ "legend_parameters": {
221
+ "hide_legend": False,
222
+ "min": 0,
223
+ "max": 100,
224
+ "color_set": "glare_study",
225
+ "label_parameters": {
226
+ "color": [34, 247, 10],
227
+ "size": 0,
228
+ "bold": True,
229
+ },
230
+ },
231
+ },
232
+ {
233
+ "identifier": "Useful Daylight Illuminance",
234
+ "object_type": "grid",
235
+ "unit": "Percentage",
236
+ "path": "udi",
237
+ "hide": False,
238
+ "legend_parameters": {
239
+ "hide_legend": False,
240
+ "min": 0,
241
+ "max": 100,
242
+ "color_set": "annual_comfort",
243
+ "label_parameters": {
244
+ "color": [34, 247, 10],
245
+ "size": 0,
246
+ "bold": True,
247
+ },
248
+ },
249
+ },
250
+ {
251
+ "identifier": "Continuous Daylight Autonomy",
252
+ "object_type": "grid",
253
+ "unit": "Percentage",
254
+ "path": "cda",
255
+ "hide": False,
256
+ "legend_parameters": {
257
+ "hide_legend": False,
258
+ "min": 0,
259
+ "max": 100,
260
+ "color_set": "annual_comfort",
261
+ "label_parameters": {
262
+ "color": [34, 247, 10],
263
+ "size": 0,
264
+ "bold": True,
265
+ },
266
+ },
267
+ },
268
+ {
269
+ "identifier": "Daylight Autonomy",
270
+ "object_type": "grid",
271
+ "unit": "Percentage",
272
+ "path": "da",
273
+ "hide": False,
274
+ "legend_parameters": {
275
+ "hide_legend": False,
276
+ "min": 0,
277
+ "max": 100,
278
+ "color_set": "annual_comfort",
279
+ "label_parameters": {
280
+ "color": [34, 247, 10],
281
+ "size": 0,
282
+ "bold": True,
283
+ },
284
+ },
285
+ },
286
+ ]
287
+ }
288
+
289
+ return cfg
@@ -0,0 +1,35 @@
1
+ """Functions for post-processing annual irradiance outputs."""
2
+
3
+ from ladybug.datatype.energyflux import EnergyFlux
4
+ from ladybug.datatype.energyintensity import EnergyIntensity
5
+ from ladybug.legend import LegendParameters
6
+
7
+
8
+ def _annual_irradiance_vis_metadata():
9
+ """Return visualization metadata for annual irradiance."""
10
+ cumulative_radiation_lpar = LegendParameters(min=0)
11
+ peak_irradiance_lpar = LegendParameters(min=0)
12
+ average_irradiance_lpar = LegendParameters(min=0)
13
+
14
+ metric_info_dict = {
15
+ 'cumulative_radiation': {
16
+ 'type': 'VisualizationMetaData',
17
+ 'data_type': EnergyIntensity('Cumulative Radiance').to_dict(),
18
+ 'unit': 'kWh/m2',
19
+ 'legend_parameters': cumulative_radiation_lpar.to_dict()
20
+ },
21
+ 'peak_irradiance': {
22
+ 'type': 'VisualizationMetaData',
23
+ 'data_type': EnergyFlux('Peak Irradiance').to_dict(),
24
+ 'unit': 'W/m2',
25
+ 'legend_parameters': peak_irradiance_lpar.to_dict()
26
+ },
27
+ 'average_irradiance': {
28
+ 'type': 'VisualizationMetaData',
29
+ 'data_type': EnergyFlux('Average Irradiance').to_dict(),
30
+ 'unit': 'W/m2',
31
+ 'legend_parameters': average_irradiance_lpar.to_dict()
32
+ }
33
+ }
34
+
35
+ return metric_info_dict
@@ -0,0 +1 @@
1
+ """honeybee-radiance-postprocess library."""