honeybee-radiance-postprocess 0.4.380__py2.py3-none-any.whl → 0.4.382__py2.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.
@@ -0,0 +1,173 @@
1
+ """Commands for ABNT NBR post-processing."""
2
+ import json
3
+ import sys
4
+ import logging
5
+ from pathlib import Path
6
+ import click
7
+ import numpy as np
8
+
9
+ from honeybee.model import Model
10
+
11
+ from ..vis_metadata import _abnt_nbr_15575_daylight_levels_vis_metadata
12
+
13
+
14
+ _logger = logging.getLogger(__name__)
15
+
16
+
17
+ @click.group(help='Commands for ABNT NBR (Brazil) post-processing of Radiance results.')
18
+ def abnt():
19
+ pass
20
+
21
+
22
+ @abnt.command('abnt-nbr-15575')
23
+ @click.argument(
24
+ 'folder',
25
+ type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True)
26
+ )
27
+ @click.argument('model-file', type=click.Path(
28
+ exists=True, file_okay=True, dir_okay=False, resolve_path=True))
29
+ @click.option(
30
+ '--sub-folder', '-sf', help='Relative path for subfolder to write output '
31
+ 'files.', default='abnt_nbr_15575', type=click.Path(
32
+ exists=False, file_okay=False, dir_okay=True, resolve_path=True, path_type=Path)
33
+ )
34
+ def abnt_nbr_15575(
35
+ folder, model_file, sub_folder
36
+ ):
37
+ """Calculate metrics for ABNT NBR 15575.
38
+
39
+ \b
40
+ Args:
41
+ folder: Simulation folder for a ABNT NBR 15575 simulation. It should
42
+ contain four sub-folder of complete point-in-time illuminance
43
+ simulations labeled "4_930AM", "4_330PM", "10_930AM", and "10_330PM".
44
+ These sub-folder should each have results folder that include a
45
+ grids_info.json and .res files with illuminance values for each
46
+ sensor.
47
+ model-file: A Honeybee Model file that was used in the simulations. This
48
+ file is used to extract the center points of the sensor grids. It is
49
+ a requirement that the sensor grids have Meshes.
50
+ """
51
+ def find_surrounding_points(x, y, x_coords, y_coords):
52
+ x1 = np.max(x_coords[x_coords <= x]) if np.any(x_coords <= x) else x_coords[0]
53
+ x2 = np.min(x_coords[x_coords > x]) if np.any(x_coords > x) else x_coords[-1]
54
+ y1 = np.max(y_coords[y_coords <= y]) if np.any(y_coords <= y) else y_coords[0]
55
+ y2 = np.min(y_coords[y_coords > y]) if np.any(y_coords > y) else y_coords[-1]
56
+ return x1, x2, y1, y2
57
+
58
+ def get_value(x, y, x_coords, y_coords, values):
59
+ index = np.where((x_coords == x) & (y_coords == y))
60
+ return values[index][0]
61
+
62
+ def perform_interpolation(x, y, x_coords, y_coords, pit_values):
63
+ x1, x2, y1, y2 = find_surrounding_points(x, y, x_coords, y_coords)
64
+
65
+ # extract the illuminance values at the surrounding points
66
+ f_Q11 = get_value(x1, y1, x_coords, y_coords, pit_values) # bottom-left
67
+ f_Q21 = get_value(x2, y1, x_coords, y_coords, pit_values) # bottom-right
68
+ f_Q12 = get_value(x1, y2, x_coords, y_coords, pit_values) # top-left
69
+ f_Q22 = get_value(x2, y2, x_coords, y_coords, pit_values) # top-right
70
+
71
+ # edge cases
72
+ if x == x1 and y == y1:
73
+ f_xy = f_Q11
74
+ elif x == x2 and y == y1:
75
+ f_xy = f_Q21
76
+ elif x == x1 and y == y2:
77
+ f_xy = f_Q12
78
+ elif x == x2 and y == y2:
79
+ f_xy = f_Q22
80
+ elif x1 == x2:
81
+ # linear interpolation in y direction
82
+ f_xy = f_Q11 + (f_Q12 - f_Q11) * (y - y1) / (y2 - y1)
83
+ elif y1 == y2:
84
+ # linear interpolation in x direction
85
+ f_xy = f_Q11 + (f_Q21 - f_Q11) * (x - x1) / (x2 - x1)
86
+ else:
87
+ # perform bilinear interpolation
88
+ f_xy = (f_Q11 * (x2 - x) * (y2 - y) +
89
+ f_Q21 * (x - x1) * (y2 - y) +
90
+ f_Q12 * (x2 - x) * (y - y1) +
91
+ f_Q22 * (x - x1) * (y - y1)) / ((x2 - x1) * (y2 - y1))
92
+
93
+ return f_xy
94
+
95
+ try:
96
+ folder = Path(folder)
97
+ hb_model = Model.from_file(model_file)
98
+ sensor_grids = hb_model.properties.radiance.sensor_grids
99
+ sg_full_identifier = {sg.full_identifier: sg for sg in sensor_grids}
100
+
101
+ if not sub_folder.exists():
102
+ sub_folder.mkdir(parents=True, exist_ok=True)
103
+ illuminance_levels_folder = sub_folder.joinpath('illuminance_levels')
104
+ if not illuminance_levels_folder.exists():
105
+ illuminance_levels_folder.mkdir(parents=True, exist_ok=True)
106
+
107
+ summary_file = sub_folder.joinpath('abnt_nbr_15575.json')
108
+ folder_names = ['4_930AM', '4_330PM', '10_930AM', '10_330PM']
109
+
110
+ metric_info_dict = _abnt_nbr_15575_daylight_levels_vis_metadata()
111
+ summary_output = {}
112
+ for _subfolder in folder_names:
113
+ res_folder = folder.joinpath(_subfolder, 'results')
114
+ with open(res_folder.joinpath('grids_info.json')) as data_f:
115
+ grids_info = json.load(data_f)
116
+ sub_output = []
117
+ for grid_info in grids_info:
118
+ pit_values = \
119
+ np.loadtxt(res_folder.joinpath(f'{grid_info["full_id"]}.res'))
120
+ sensor_grid = sg_full_identifier[grid_info['full_id']]
121
+ sensor_points = np.array(
122
+ [[sensor.pos[0], sensor.pos[1]] for sensor in sensor_grid.sensors])
123
+
124
+ x_coords = sensor_points[:, 0]
125
+ y_coords = sensor_points[:, 1]
126
+ x, y = sensor_grid.mesh.center.x, sensor_grid.mesh.center.y
127
+ f_xy = perform_interpolation(x, y, x_coords, y_coords, pit_values)
128
+
129
+ if f_xy >= 120:
130
+ level = 'Superior'
131
+ elif f_xy >= 90:
132
+ level = 'Intermediário'
133
+ elif f_xy >= 60: # add check for ground floor (48 lux)
134
+ level = 'Mínimo'
135
+ else:
136
+ level = 'Não atende'
137
+
138
+ sub_output.append(
139
+ {
140
+ 'nível': level,
141
+ 'iluminância': f_xy,
142
+ 'grids_info': grid_info
143
+ }
144
+ )
145
+
146
+ conditions = [pit_values >= 120, pit_values >= 90, pit_values >= 60, pit_values < 60]
147
+ conditions_values = [3, 2, 1, 0]
148
+ illuminance_level = np.select(conditions, conditions_values)
149
+
150
+ ill_level_file = illuminance_levels_folder.joinpath(_subfolder, f'{grid_info["full_id"]}.res')
151
+ ill_level_file.parent.mkdir(parents=True, exist_ok=True)
152
+ np.savetxt(ill_level_file, illuminance_level, fmt='%d')
153
+
154
+ grids_info_file = illuminance_levels_folder.joinpath(_subfolder, 'grids_info.json')
155
+ grids_info_file.write_text(json.dumps(grids_info, indent=2))
156
+
157
+ vis_data = metric_info_dict[_subfolder]
158
+ vis_metadata_file = illuminance_levels_folder.joinpath(_subfolder, 'vis_metadata.json')
159
+ vis_metadata_file.write_text(json.dumps(vis_data, indent=4))
160
+
161
+ summary_output[_subfolder] = sub_output
162
+
163
+ grids_info_file = folder.joinpath(_subfolder, 'grids_info.json')
164
+ grids_info_file.write_text(json.dumps(grids_info, indent=2))
165
+
166
+ with summary_file.open(mode='w', encoding='utf-8') as output_file:
167
+ json.dump(summary_output, output_file, indent=4, ensure_ascii=False)
168
+
169
+ except Exception:
170
+ _logger.exception('Failed to calculate ABNT NBR 15575 metrics.')
171
+ sys.exit(1)
172
+ else:
173
+ sys.exit(0)
@@ -21,6 +21,7 @@ from ..en17037 import en17037_to_folder
21
21
  from ..util import filter_array
22
22
  from .two_phase import two_phase
23
23
  from .leed import leed
24
+ from .abnt import abnt
24
25
  from ..helper import model_grid_areas, grid_summary
25
26
 
26
27
  _logger = logging.getLogger(__name__)
@@ -32,6 +33,7 @@ def post_process():
32
33
 
33
34
  post_process.add_command(two_phase)
34
35
  post_process.add_command(leed)
36
+ post_process.add_command(abnt)
35
37
 
36
38
  @post_process.command('annual-daylight')
37
39
  @click.argument(
@@ -0,0 +1,49 @@
1
+ """Functions for visualization metadata."""
2
+ from ladybug.legend import LegendParameters
3
+ from ladybug.color import Color
4
+ from ladybug.datatype.generic import GenericType
5
+
6
+
7
+ def _abnt_nbr_15575_daylight_levels_vis_metadata():
8
+ """Return visualization metadata for ABNT NBR 15575 Daylight levels."""
9
+ level_value = {
10
+ 0: 'Não atende',
11
+ 1: 'Mínimo',
12
+ 2: 'Intermediário',
13
+ 3: 'Superior'
14
+ }
15
+
16
+ colors = [Color(255, 198, 143), Color(255, 255, 209), Color(192, 231, 189), Color(83, 169, 206)]
17
+ illuminance_levels_lpar = \
18
+ LegendParameters(min=0, max=3, colors=colors, segment_count=4,
19
+ title='Illuminance Level')
20
+ illuminance_levels_lpar.ordinal_dictionary = level_value
21
+
22
+ metric_info_dict = {
23
+ '4_930AM': {
24
+ 'type': 'VisualizationMetaData',
25
+ 'data_type': GenericType('Illuminance April 23rd 9:30am', '').to_dict(),
26
+ 'unit': '',
27
+ 'legend_parameters': illuminance_levels_lpar.to_dict()
28
+ },
29
+ '4_330PM': {
30
+ 'type': 'VisualizationMetaData',
31
+ 'data_type': GenericType('Illuminance April 23rd 3:30pm', '').to_dict(),
32
+ 'unit': '',
33
+ 'legend_parameters': illuminance_levels_lpar.to_dict()
34
+ },
35
+ '10_930AM': {
36
+ 'type': 'VisualizationMetaData',
37
+ 'data_type': GenericType('Illuminance October 23rd 9:30am', '').to_dict(),
38
+ 'unit': '',
39
+ 'legend_parameters': illuminance_levels_lpar.to_dict()
40
+ },
41
+ '10_330PM': {
42
+ 'type': 'VisualizationMetaData',
43
+ 'data_type': GenericType('Illuminance October 23rd 3:30pm', '').to_dict(),
44
+ 'unit': '',
45
+ 'legend_parameters': illuminance_levels_lpar.to_dict()
46
+ }
47
+ }
48
+
49
+ return metric_info_dict
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: honeybee-radiance-postprocess
3
- Version: 0.4.380
3
+ Version: 0.4.382
4
4
  Summary: Postprocessing of Radiance results and matrices
5
5
  Home-page: https://github.com/ladybug-tools/honeybee-radiance-postprocess
6
6
  Author: Ladybug Tools
@@ -13,7 +13,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
13
13
  Classifier: Operating System :: OS Independent
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
- Requires-Dist: honeybee-radiance (==1.66.64)
16
+ Requires-Dist: honeybee-radiance (==1.66.65)
17
17
  Requires-Dist: numpy (>=1.21.6)
18
18
 
19
19
  [![Build Status](https://github.com/ladybug-tools/honeybee-radiance-postprocess/actions/workflows/ci.yaml/badge.svg)](https://github.com/ladybug-tools/honeybee-radiance-postprocess/actions)
@@ -12,11 +12,13 @@ honeybee_radiance_postprocess/metrics.py,sha256=6EHCuXf5jnhh6GglI9mTd0MFpfhfPFoK
12
12
  honeybee_radiance_postprocess/reader.py,sha256=6myKzfGC1pO8zPixg1kKrKjPihHabTKUh2t5BlJvij0,2367
13
13
  honeybee_radiance_postprocess/type_hints.py,sha256=4R0kZgacQrqzoh8Tq7f8MVzUDzynV-C_jlh80UV6GPE,1122
14
14
  honeybee_radiance_postprocess/util.py,sha256=-J5k1dhvyYJkb42jvTS_xxtokfGbmcucVPXdMWU1jUk,5098
15
+ honeybee_radiance_postprocess/vis_metadata.py,sha256=darKbj987NXW72GNcTdKQmgqSTpeG39OBwEgbJGEgPw,1820
15
16
  honeybee_radiance_postprocess/cli/__init__.py,sha256=4RkpR91GPXWatDE4I_27ce-N4FwolQoO6WO7H24DMXE,777
17
+ honeybee_radiance_postprocess/cli/abnt.py,sha256=UjyOBbyskK7lpJ1PkcxomjO3HeWiIIdcrBDwYeYUPxE,7203
16
18
  honeybee_radiance_postprocess/cli/grid.py,sha256=6peLEAPVe-iw05_wdRpFruZLqO8myvC-_QT5W1q5sk8,10677
17
19
  honeybee_radiance_postprocess/cli/leed.py,sha256=QBR6AMJJWuZ0TevyMi2tXCWMLdS-ZSqtVTZDgqxwa7M,3112
18
20
  honeybee_radiance_postprocess/cli/mtxop.py,sha256=UZJnjNpPjDmShy1-Mxos4H2vTUqk_yP3ZyaC1_LLFeI,5015
19
- honeybee_radiance_postprocess/cli/postprocess.py,sha256=vZAw4QFpieUK3Xphi8CvBeuAaVsxxZDO8oqNPmyFn_A,38935
21
+ honeybee_radiance_postprocess/cli/postprocess.py,sha256=JbYPqJqL7iYSyj22yn0g-ImwdTUcMnXI27x0U8gGOsw,38989
20
22
  honeybee_radiance_postprocess/cli/schedule.py,sha256=6uIy98Co4zm-ZRcELo4Lfx_aN3lNiqPe-BSimXwt1F8,3877
21
23
  honeybee_radiance_postprocess/cli/translate.py,sha256=18zkcGeRZALJ5Z82NEB3XZ-iEX2cHyneobGWV-IXWE0,6789
22
24
  honeybee_radiance_postprocess/cli/two_phase.py,sha256=1nZF4jyZ_C7CAfiHCz1UUOEwDaB4yOXr9ga0HIrhOB0,7033
@@ -25,9 +27,9 @@ honeybee_radiance_postprocess/results/__init__.py,sha256=1agBQbfT4Tf8KqSZzlfKYX8
25
27
  honeybee_radiance_postprocess/results/annual_daylight.py,sha256=o4Y5kbD3a4X4KRfsbOlWzgrnNKU365GcivM6qQGUGXU,31605
26
28
  honeybee_radiance_postprocess/results/annual_irradiance.py,sha256=5zwrr4MNeHUebbSRpSBbscPOZUs2AHmYCQfIIbdYImY,8298
27
29
  honeybee_radiance_postprocess/results/results.py,sha256=jkjsxTuvVfBus6tM2UjQE3ZKPooLInWEd2guqO61v9E,53600
28
- honeybee_radiance_postprocess-0.4.380.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
29
- honeybee_radiance_postprocess-0.4.380.dist-info/METADATA,sha256=z6gVZQUz6uFQOv2Xg1B_LhHZWpO_KC3VxfCLEJDik_g,2245
30
- honeybee_radiance_postprocess-0.4.380.dist-info/WHEEL,sha256=unfA4MOaH0icIyIA5oH6E2sn2Hq5zKtLlHsWapZGwes,110
31
- honeybee_radiance_postprocess-0.4.380.dist-info/entry_points.txt,sha256=gFtVPx6UItXt27GfEZZO00eOZChJJEL6JwGSAB_O3rs,96
32
- honeybee_radiance_postprocess-0.4.380.dist-info/top_level.txt,sha256=4-sFbzy7ewP2EDqJV3jeFlAFx7SuxtoBBELWaKAnLdA,30
33
- honeybee_radiance_postprocess-0.4.380.dist-info/RECORD,,
30
+ honeybee_radiance_postprocess-0.4.382.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
31
+ honeybee_radiance_postprocess-0.4.382.dist-info/METADATA,sha256=DeEtlz8Lf-hWRWxvzy4jNJBGBApQ_QiJVg06alRBAQo,2245
32
+ honeybee_radiance_postprocess-0.4.382.dist-info/WHEEL,sha256=unfA4MOaH0icIyIA5oH6E2sn2Hq5zKtLlHsWapZGwes,110
33
+ honeybee_radiance_postprocess-0.4.382.dist-info/entry_points.txt,sha256=gFtVPx6UItXt27GfEZZO00eOZChJJEL6JwGSAB_O3rs,96
34
+ honeybee_radiance_postprocess-0.4.382.dist-info/top_level.txt,sha256=4-sFbzy7ewP2EDqJV3jeFlAFx7SuxtoBBELWaKAnLdA,30
35
+ honeybee_radiance_postprocess-0.4.382.dist-info/RECORD,,