honeybee-radiance-postprocess 0.4.418__py2.py3-none-any.whl → 0.4.420__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.
- honeybee_radiance_postprocess/cli/abnt.py +152 -70
- {honeybee_radiance_postprocess-0.4.418.dist-info → honeybee_radiance_postprocess-0.4.420.dist-info}/METADATA +2 -2
- {honeybee_radiance_postprocess-0.4.418.dist-info → honeybee_radiance_postprocess-0.4.420.dist-info}/RECORD +7 -7
- {honeybee_radiance_postprocess-0.4.418.dist-info → honeybee_radiance_postprocess-0.4.420.dist-info}/LICENSE +0 -0
- {honeybee_radiance_postprocess-0.4.418.dist-info → honeybee_radiance_postprocess-0.4.420.dist-info}/WHEEL +0 -0
- {honeybee_radiance_postprocess-0.4.418.dist-info → honeybee_radiance_postprocess-0.4.420.dist-info}/entry_points.txt +0 -0
- {honeybee_radiance_postprocess-0.4.418.dist-info → honeybee_radiance_postprocess-0.4.420.dist-info}/top_level.txt +0 -0
@@ -61,66 +61,133 @@ def abnt_nbr_15575(
|
|
61
61
|
file is used to extract the center points of the sensor grids. It is
|
62
62
|
a requirement that the sensor grids have Meshes.
|
63
63
|
"""
|
64
|
-
def find_surrounding_points(
|
65
|
-
"""Find the four
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
64
|
+
def find_surrounding_points(points, values, new_point):
|
65
|
+
"""Find the four surrounding points for bilinear interpolation.
|
66
|
+
|
67
|
+
Args:
|
68
|
+
points: 2D array of points, shape.
|
69
|
+
values: 1D array of values at the points.
|
70
|
+
new_point: 1D array of the point to interpolate.
|
71
|
+
|
72
|
+
Returns:
|
73
|
+
tuple: (surrounding_points, surrounding_values) and their counts.
|
74
|
+
"""
|
75
|
+
x, y = new_point
|
76
|
+
lower_left = None
|
77
|
+
upper_left = None
|
78
|
+
lower_right = None
|
79
|
+
upper_right = None
|
80
|
+
|
81
|
+
for i, (px, py) in enumerate(points):
|
82
|
+
if px <= x and py <= y:
|
83
|
+
if lower_left is None or (px >= lower_left[0] and py >= lower_left[1]):
|
84
|
+
lower_left = (px, py, values[i])
|
85
|
+
if px <= x and py >= y:
|
86
|
+
if upper_left is None or (px >= upper_left[0] and py <= upper_left[1]):
|
87
|
+
upper_left = (px, py, values[i])
|
88
|
+
if px >= x and py >= y:
|
89
|
+
if upper_right is None or (px <= upper_right[0] and py <= upper_right[1]):
|
90
|
+
upper_right = (px, py, values[i])
|
91
|
+
if px >= x and py <= y:
|
92
|
+
if lower_right is None or (px <= lower_right[0] and py >= lower_right[1]):
|
93
|
+
lower_right = (px, py, values[i])
|
94
|
+
|
95
|
+
surrounding_points = []
|
96
|
+
surrounding_values = []
|
97
|
+
if lower_left:
|
98
|
+
surrounding_points.append(lower_left[:2])
|
99
|
+
surrounding_values.append(lower_left[2])
|
100
|
+
if upper_left:
|
101
|
+
surrounding_points.append(upper_left[:2])
|
102
|
+
surrounding_values.append(upper_left[2])
|
103
|
+
if upper_right:
|
104
|
+
surrounding_points.append(upper_right[:2])
|
105
|
+
surrounding_values.append(upper_right[2])
|
106
|
+
if lower_right:
|
107
|
+
surrounding_points.append(lower_right[:2])
|
108
|
+
surrounding_values.append(lower_right[2])
|
109
|
+
|
110
|
+
return np.array(surrounding_points), np.array(surrounding_values)
|
111
|
+
|
112
|
+
def bilinear_interpolate(surrounding_points, surrounding_values, new_point):
|
113
|
+
"""Perform bilinear interpolation given four surrounding points.
|
114
|
+
|
115
|
+
Args:
|
116
|
+
surrounding_points: 2D array of points.
|
117
|
+
surrounding_values: 1D array of values at the points.
|
118
|
+
new_point: 1D array of the point to interpolate.
|
119
|
+
|
120
|
+
Returns:
|
121
|
+
Interpolated value at the new_point.
|
122
|
+
"""
|
123
|
+
x1, y1 = surrounding_points[0]
|
124
|
+
x2, y2 = surrounding_points[2]
|
125
|
+
x, y = new_point
|
126
|
+
|
127
|
+
fQ11 = surrounding_values[0]
|
128
|
+
fQ21 = surrounding_values[3]
|
129
|
+
fQ12 = surrounding_values[1]
|
130
|
+
fQ22 = surrounding_values[2]
|
131
|
+
|
132
|
+
interpolated_value = (
|
133
|
+
fQ11 * (x2 - x) * (y2 - y) +
|
134
|
+
fQ21 * (x - x1) * (y2 - y) +
|
135
|
+
fQ12 * (x2 - x) * (y - y1) +
|
136
|
+
fQ22 * (x - x1) * (y - y1)
|
137
|
+
) / ((x2 - x1) * (y2 - y1))
|
138
|
+
|
139
|
+
return interpolated_value
|
140
|
+
|
141
|
+
def inverse_distance_weighting(points, values, new_point, n_nearest=4):
|
142
|
+
"""Perform inverse distance weighting interpolation.
|
143
|
+
|
144
|
+
Args:
|
145
|
+
points: 2D array of points.
|
146
|
+
values: 1D array of values at the points
|
147
|
+
new_point: 1D array of the point to interpolate.
|
148
|
+
n_nearest: Number of nearest points to consider for interpolation.
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
Interpolated value at the new_point.
|
152
|
+
"""
|
153
|
+
distances = np.linalg.norm(points - new_point, axis=1)
|
154
|
+
nearest_indices = np.argsort(distances)[:min(n_nearest, len(points))]
|
155
|
+
|
156
|
+
nearest_values = values[nearest_indices]
|
157
|
+
nearest_distances = distances[nearest_indices]
|
158
|
+
|
159
|
+
if np.any(nearest_distances == 0):
|
160
|
+
# if the new point coincides with an existing point, return its value
|
161
|
+
return nearest_values[nearest_distances == 0][0]
|
162
|
+
|
163
|
+
weights = 1 / nearest_distances
|
164
|
+
weights /= weights.sum() # normalize weights
|
165
|
+
return np.dot(weights, nearest_values)
|
166
|
+
|
167
|
+
def perform_interpolation(x, y, x_coords, y_coords, pit_values):
|
168
|
+
points = np.column_stack((x_coords, y_coords))
|
169
|
+
values = np.array(pit_values)
|
170
|
+
new_point = np.array([x, y])
|
171
|
+
|
172
|
+
surrounding_points, surrounding_values = \
|
173
|
+
find_surrounding_points(points, values, new_point)
|
174
|
+
|
175
|
+
if len(surrounding_points) == 4:
|
176
|
+
interpolated_value = \
|
177
|
+
bilinear_interpolate(surrounding_points,
|
178
|
+
surrounding_values, new_point)
|
73
179
|
else:
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
x1, x2 = min(x_values), max(x_values)
|
78
|
-
y1, y2 = min(y_values), max(y_values)
|
79
|
-
|
80
|
-
return x1, x2, y1, y2
|
81
|
-
|
82
|
-
def get_value(x, y, x_coords, y_coords, values):
|
83
|
-
tolerance = 0.001
|
84
|
-
index = np.where((np.abs(x_coords - x) <= tolerance) & (np.abs(y_coords - y) <= tolerance))
|
85
|
-
return values[index][0]
|
86
|
-
|
87
|
-
def perform_interpolation(x, y, x_coords, y_caoords, pit_values):
|
88
|
-
x1, x2, y1, y2 = find_surrounding_points(x, y, x_coords, y_coords)
|
89
|
-
|
90
|
-
# extract the illuminance values at the surrounding points
|
91
|
-
f_Q11 = get_value(x1, y1, x_coords, y_coords, pit_values) # bottom-left
|
92
|
-
f_Q21 = get_value(x2, y1, x_coords, y_coords, pit_values) # bottom-right
|
93
|
-
f_Q12 = get_value(x1, y2, x_coords, y_coords, pit_values) # top-left
|
94
|
-
f_Q22 = get_value(x2, y2, x_coords, y_coords, pit_values) # top-right
|
95
|
-
|
96
|
-
# edge cases
|
97
|
-
if x == x1 and y == y1:
|
98
|
-
f_xy = f_Q11
|
99
|
-
elif x == x2 and y == y1:
|
100
|
-
f_xy = f_Q21
|
101
|
-
elif x == x1 and y == y2:
|
102
|
-
f_xy = f_Q12
|
103
|
-
elif x == x2 and y == y2:
|
104
|
-
f_xy = f_Q22
|
105
|
-
elif x1 == x2:
|
106
|
-
# linear interpolation in y direction
|
107
|
-
f_xy = f_Q11 + (f_Q12 - f_Q11) * (y - y1) / (y2 - y1)
|
108
|
-
elif y1 == y2:
|
109
|
-
# linear interpolation in x direction
|
110
|
-
f_xy = f_Q11 + (f_Q21 - f_Q11) * (x - x1) / (x2 - x1)
|
111
|
-
else:
|
112
|
-
# perform bilinear interpolation
|
113
|
-
f_xy = (f_Q11 * (x2 - x) * (y2 - y) +
|
114
|
-
f_Q21 * (x - x1) * (y2 - y) +
|
115
|
-
f_Q12 * (x2 - x) * (y - y1) +
|
116
|
-
f_Q22 * (x - x1) * (y - y1)) / ((x2 - x1) * (y2 - y1))
|
180
|
+
interpolated_value = \
|
181
|
+
inverse_distance_weighting(
|
182
|
+
points, values, new_point, n_nearest=4)
|
117
183
|
|
118
|
-
return
|
184
|
+
return interpolated_value
|
119
185
|
|
120
186
|
try:
|
121
187
|
folder = Path(folder)
|
122
188
|
hb_model: Model = Model.from_file(model_file)
|
123
|
-
grouped_rooms, floor_heights = Room.group_by_floor_height(
|
189
|
+
grouped_rooms, floor_heights = Room.group_by_floor_height(
|
190
|
+
hb_model.rooms)
|
124
191
|
|
125
192
|
# pick the first group >= to ground level
|
126
193
|
for gr, fh in zip(grouped_rooms, floor_heights):
|
@@ -157,14 +224,20 @@ def abnt_nbr_15575(
|
|
157
224
|
sub_output = []
|
158
225
|
for grid_info in grids_info:
|
159
226
|
pit_values = \
|
160
|
-
np.loadtxt(res_folder.joinpath(
|
227
|
+
np.loadtxt(res_folder.joinpath(
|
228
|
+
f'{grid_info["full_id"]}.res'))
|
161
229
|
sensor_grid = sg_full_identifier[grid_info['full_id']]
|
162
230
|
sensor_points = np.array(
|
163
|
-
[[sensor.pos[0], sensor.pos[1]
|
231
|
+
[[sensor.pos[0], sensor.pos[1], sensor.pos[2]]
|
232
|
+
for sensor in sensor_grid.sensors]
|
233
|
+
)
|
164
234
|
|
165
235
|
x_coords = sensor_points[:, 0]
|
166
236
|
y_coords = sensor_points[:, 1]
|
167
|
-
|
237
|
+
z_coords = sensor_points[:, 2]
|
238
|
+
|
239
|
+
room = hb_model.rooms_by_identifier(
|
240
|
+
[sensor_grid.room_identifier])[0]
|
168
241
|
|
169
242
|
pof_sensor_grid = \
|
170
243
|
pof_sensor_grids.get(grid_info['full_id'], None)
|
@@ -175,25 +248,30 @@ def abnt_nbr_15575(
|
|
175
248
|
room.horizontal_floor_boundaries(), 0.05
|
176
249
|
)[0]
|
177
250
|
if floor_face.is_convex:
|
178
|
-
|
179
|
-
floor_face.centroid + Vector3D(0, 0, 0.75)
|
251
|
+
centroid = floor_face.centroid
|
180
252
|
else:
|
181
|
-
|
182
|
-
|
253
|
+
centroid = floor_face.pole_of_inaccessibility(0.01)
|
254
|
+
dz = np.mean(z_coords) - centroid.z
|
255
|
+
pof_sensor_grids[grid_info['full_id']] = \
|
256
|
+
centroid + Vector3D(0, 0, dz)
|
183
257
|
else:
|
184
|
-
faces_3d = [
|
185
|
-
|
258
|
+
faces_3d = [
|
259
|
+
Face3D(face_vertices) for face_vertices in sensor_grid.mesh.face_vertices]
|
260
|
+
face_3d_union = Face3D.join_coplanar_faces(
|
261
|
+
faces_3d, 0.05)
|
186
262
|
assert len(face_3d_union) == 1
|
187
263
|
if face_3d_union[0].is_convex:
|
188
264
|
centroid = face_3d_union[0].centroid
|
189
265
|
pof_sensor_grids[grid_info['full_id']] = centroid
|
190
266
|
else:
|
191
|
-
pof = face_3d_union[0].pole_of_inaccessibility(
|
267
|
+
pof = face_3d_union[0].pole_of_inaccessibility(
|
268
|
+
0.01)
|
192
269
|
pof_sensor_grids[grid_info['full_id']] = pof
|
193
270
|
|
194
271
|
x = pof_sensor_grids[grid_info['full_id']].x
|
195
272
|
y = pof_sensor_grids[grid_info['full_id']].y
|
196
|
-
f_xy = perform_interpolation(
|
273
|
+
f_xy = perform_interpolation(
|
274
|
+
x, y, x_coords, y_coords, pit_values)
|
197
275
|
|
198
276
|
if room in ground_level_rooms:
|
199
277
|
minimo = 48
|
@@ -204,7 +282,7 @@ def abnt_nbr_15575(
|
|
204
282
|
level = 'Superior'
|
205
283
|
elif f_xy >= 90:
|
206
284
|
level = 'Intermediário'
|
207
|
-
elif f_xy >= minimo:
|
285
|
+
elif f_xy >= minimo: # add check for ground floor (48 lux)
|
208
286
|
level = 'Mínimo'
|
209
287
|
else:
|
210
288
|
level = 'Não atende'
|
@@ -232,19 +310,23 @@ def abnt_nbr_15575(
|
|
232
310
|
}
|
233
311
|
)
|
234
312
|
|
235
|
-
conditions = [pit_values >= 120, pit_values >=
|
313
|
+
conditions = [pit_values >= 120, pit_values >=
|
314
|
+
90, pit_values >= 60, pit_values < 60]
|
236
315
|
conditions_values = [3, 2, 1, 0]
|
237
316
|
illuminance_level = np.select(conditions, conditions_values)
|
238
317
|
|
239
|
-
ill_level_file = illuminance_levels_folder.joinpath(
|
318
|
+
ill_level_file = illuminance_levels_folder.joinpath(
|
319
|
+
_subfolder, f'{grid_info["full_id"]}.res')
|
240
320
|
ill_level_file.parent.mkdir(parents=True, exist_ok=True)
|
241
321
|
np.savetxt(ill_level_file, illuminance_level, fmt='%d')
|
242
322
|
|
243
|
-
grids_info_file = illuminance_levels_folder.joinpath(
|
323
|
+
grids_info_file = illuminance_levels_folder.joinpath(
|
324
|
+
_subfolder, 'grids_info.json')
|
244
325
|
grids_info_file.write_text(json.dumps(grids_info, indent=2))
|
245
326
|
|
246
327
|
vis_data = metric_info_dict[_subfolder]
|
247
|
-
vis_metadata_file = illuminance_levels_folder.joinpath(
|
328
|
+
vis_metadata_file = illuminance_levels_folder.joinpath(
|
329
|
+
_subfolder, 'vis_metadata.json')
|
248
330
|
vis_metadata_file.write_text(json.dumps(vis_data, indent=4))
|
249
331
|
|
250
332
|
summary_output[_subfolder] = sub_output
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: honeybee-radiance-postprocess
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.420
|
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.
|
16
|
+
Requires-Dist: honeybee-radiance (==1.66.94)
|
17
17
|
Requires-Dist: numpy (>=1.21.6)
|
18
18
|
|
19
19
|
[](https://github.com/ladybug-tools/honeybee-radiance-postprocess/actions)
|
@@ -15,7 +15,7 @@ honeybee_radiance_postprocess/type_hints.py,sha256=4R0kZgacQrqzoh8Tq7f8MVzUDzynV
|
|
15
15
|
honeybee_radiance_postprocess/util.py,sha256=-J5k1dhvyYJkb42jvTS_xxtokfGbmcucVPXdMWU1jUk,5098
|
16
16
|
honeybee_radiance_postprocess/vis_metadata.py,sha256=7ywIgdiuNKcctxifhpy7-Q2oaSX2ngQBeA0Kh7q1Gg0,1780
|
17
17
|
honeybee_radiance_postprocess/cli/__init__.py,sha256=PVfwkuPFl4TnvQt8ovVm01JK0Alon81BaY-0tshAXyg,795
|
18
|
-
honeybee_radiance_postprocess/cli/abnt.py,sha256=
|
18
|
+
honeybee_radiance_postprocess/cli/abnt.py,sha256=GNLmVVrEQ-1oKr5ZmBllY-KODhgJPjLVidQ_dQMcpFk,15537
|
19
19
|
honeybee_radiance_postprocess/cli/grid.py,sha256=6peLEAPVe-iw05_wdRpFruZLqO8myvC-_QT5W1q5sk8,10677
|
20
20
|
honeybee_radiance_postprocess/cli/leed.py,sha256=QBR6AMJJWuZ0TevyMi2tXCWMLdS-ZSqtVTZDgqxwa7M,3112
|
21
21
|
honeybee_radiance_postprocess/cli/mtxop.py,sha256=UZJnjNpPjDmShy1-Mxos4H2vTUqk_yP3ZyaC1_LLFeI,5015
|
@@ -29,9 +29,9 @@ honeybee_radiance_postprocess/results/__init__.py,sha256=1agBQbfT4Tf8KqSZzlfKYX8
|
|
29
29
|
honeybee_radiance_postprocess/results/annual_daylight.py,sha256=ohysFt4OWlWUn_IvM6pjmiQcRTq_x5b998Iv0pw8AEQ,34964
|
30
30
|
honeybee_radiance_postprocess/results/annual_irradiance.py,sha256=5zwrr4MNeHUebbSRpSBbscPOZUs2AHmYCQfIIbdYImY,8298
|
31
31
|
honeybee_radiance_postprocess/results/results.py,sha256=GwyjIYljaCShx1b6NlYUBcU_gHhckmLcCMNrQ6HVDdE,53507
|
32
|
-
honeybee_radiance_postprocess-0.4.
|
33
|
-
honeybee_radiance_postprocess-0.4.
|
34
|
-
honeybee_radiance_postprocess-0.4.
|
35
|
-
honeybee_radiance_postprocess-0.4.
|
36
|
-
honeybee_radiance_postprocess-0.4.
|
37
|
-
honeybee_radiance_postprocess-0.4.
|
32
|
+
honeybee_radiance_postprocess-0.4.420.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
33
|
+
honeybee_radiance_postprocess-0.4.420.dist-info/METADATA,sha256=Wk_YuV0iIsxYoLMUY9gpJYNHZoed872Ej9o86dNQNDU,2245
|
34
|
+
honeybee_radiance_postprocess-0.4.420.dist-info/WHEEL,sha256=unfA4MOaH0icIyIA5oH6E2sn2Hq5zKtLlHsWapZGwes,110
|
35
|
+
honeybee_radiance_postprocess-0.4.420.dist-info/entry_points.txt,sha256=gFtVPx6UItXt27GfEZZO00eOZChJJEL6JwGSAB_O3rs,96
|
36
|
+
honeybee_radiance_postprocess-0.4.420.dist-info/top_level.txt,sha256=4-sFbzy7ewP2EDqJV3jeFlAFx7SuxtoBBELWaKAnLdA,30
|
37
|
+
honeybee_radiance_postprocess-0.4.420.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|