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,552 @@
1
+ """Functions for BREEAM post-processing."""
2
+ from typing import Union
3
+ from pathlib import Path
4
+ import json
5
+ try:
6
+ import cupy as np
7
+ is_gpu = True
8
+ except ImportError:
9
+ is_gpu = False
10
+ import numpy as np
11
+
12
+ from honeybee.model import Model
13
+ from honeybee_radiance.writer import _filter_by_pattern
14
+
15
+ from ..results.annual_daylight import AnnualDaylight
16
+
17
+
18
+ program_type_metrics = {
19
+ 'BREEAM::Education_buildings::Preschools': [
20
+ {
21
+ 'type': 'Education buildings',
22
+ 'credits': 2,
23
+ 'area': 80,
24
+ 'average_daylight_illuminance': {
25
+ 'illuminance': 300,
26
+ 'hours': 2000
27
+ },
28
+ 'minimum_daylight_illuminance': {
29
+ 'illuminance': 90,
30
+ 'hours': 2000
31
+ }
32
+ }
33
+ ],
34
+ 'BREEAM::Education_buildings::Higher_education': [
35
+ {
36
+ 'type': 'Education buildings',
37
+ 'credits': 2,
38
+ 'area': 80,
39
+ 'average_daylight_illuminance': {
40
+ 'illuminance': 300,
41
+ 'hours': 2000
42
+ },
43
+ 'minimum_daylight_illuminance': {
44
+ 'illuminance': 90,
45
+ 'hours': 2000
46
+ }
47
+ },
48
+ {
49
+ 'type': 'Education buildings',
50
+ 'credits': 1,
51
+ 'area': 60,
52
+ 'average_daylight_illuminance': {
53
+ 'illuminance': 300,
54
+ 'hours': 2000
55
+ },
56
+ 'minimum_daylight_illuminance': {
57
+ 'illuminance': 90,
58
+ 'hours': 2000
59
+ }
60
+ }
61
+ ],
62
+ 'BREEAM::Healthcare_buildings::Staff_and_public_areas': [
63
+ {
64
+ 'type': 'Healthcare buildings',
65
+ 'credits': 2,
66
+ 'area': 80,
67
+ 'average_daylight_illuminance': {
68
+ 'illuminance': 300,
69
+ 'hours': 2650
70
+ },
71
+ 'minimum_daylight_illuminance': {
72
+ 'illuminance': 90,
73
+ 'hours': 2650
74
+ }
75
+ },
76
+ {
77
+ 'type': 'Healthcare buildings',
78
+ 'credits': 1,
79
+ 'area': 80,
80
+ 'average_daylight_illuminance': {
81
+ 'illuminance': 300,
82
+ 'hours': 2000
83
+ },
84
+ 'minimum_daylight_illuminance': {
85
+ 'illuminance': 90,
86
+ 'hours': 2000
87
+ }
88
+ }
89
+ ],
90
+ 'BREEAM::Healthcare_buildings::Patients_areas_and_consulting_rooms': [
91
+ {
92
+ 'type': 'Healthcare buildings',
93
+ 'credits': 2,
94
+ 'area': 80,
95
+ 'average_daylight_illuminance': {
96
+ 'illuminance': 300,
97
+ 'hours': 2650
98
+ },
99
+ 'minimum_daylight_illuminance': {
100
+ 'illuminance': 90,
101
+ 'hours': 2650
102
+ }
103
+ },
104
+ {
105
+ 'type': 'Healthcare buildings',
106
+ 'credits': 1,
107
+ 'area': 80,
108
+ 'average_daylight_illuminance': {
109
+ 'illuminance': 300,
110
+ 'hours': 2000
111
+ },
112
+ 'minimum_daylight_illuminance': {
113
+ 'illuminance': 90,
114
+ 'hours': 2000
115
+ }
116
+ }
117
+ ],
118
+ 'BREEAM::Multi_residential_buildings::Kitchen': [
119
+ {
120
+ 'type': 'Multi-residential buildings',
121
+ 'credits': 2,
122
+ 'area': 100,
123
+ 'average_daylight_illuminance': {
124
+ 'illuminance': 100,
125
+ 'hours': 3450
126
+ },
127
+ 'minimum_daylight_illuminance': {
128
+ 'illuminance': 30,
129
+ 'hours': 3450
130
+ }
131
+ }
132
+ ],
133
+ 'BREEAM::Multi_residential_buildings::Living_rooms_dining_rooms_studies': [
134
+ {
135
+ 'type': 'Multi-residential buildings',
136
+ 'credits': 2,
137
+ 'area': 100,
138
+ 'average_daylight_illuminance': {
139
+ 'illuminance': 100,
140
+ 'hours': 3450
141
+ },
142
+ 'minimum_daylight_illuminance': {
143
+ 'illuminance': 30,
144
+ 'hours': 3450
145
+ }
146
+ }
147
+ ],
148
+ 'BREEAM::Multi_residential_buildings::Non_residential_or_communal_spaces': [
149
+ {
150
+ 'type': 'Multi-residential buildings',
151
+ 'credits': 2,
152
+ 'area': 80,
153
+ 'average_daylight_illuminance': {
154
+ 'illuminance': 200,
155
+ 'hours': 2650
156
+ },
157
+ 'minimum_daylight_illuminance': {
158
+ 'illuminance': 60,
159
+ 'hours': 2650
160
+ }
161
+ }
162
+ ],
163
+ 'BREEAM::Retail_buildings::Sales_areas': [
164
+ {
165
+ 'type': 'Retail buildings',
166
+ 'credits': 1,
167
+ 'area': 35,
168
+ 'average_daylight_illuminance': {
169
+ 'illuminance': 200,
170
+ 'hours': 2650
171
+ },
172
+ 'minimum_daylight_illuminance': {
173
+ 'illuminance': 200,
174
+ 'hours': 2650
175
+ }
176
+ }
177
+ ],
178
+ 'BREEAM::Retail_buildings::Other_occupied_areas': [
179
+ {
180
+ 'type': 'Retail buildings',
181
+ 'credits': 1,
182
+ 'area': 80,
183
+ 'average_daylight_illuminance': {
184
+ 'illuminance': 200,
185
+ 'hours': 2650
186
+ },
187
+ 'minimum_daylight_illuminance': {
188
+ 'illuminance': 60,
189
+ 'hours': 2650
190
+ }
191
+ }
192
+ ],
193
+ 'BREEAM::Prison_buildings::Cells_and_custody_cells': [
194
+ {
195
+ 'type': 'Prison buildings',
196
+ 'credits': 2,
197
+ 'area': 80,
198
+ 'average_daylight_illuminance': {
199
+ 'illuminance': 100,
200
+ 'hours': 3150
201
+ },
202
+ 'minimum_daylight_illuminance': None
203
+ }
204
+ ],
205
+ 'BREEAM::Prison_buildings::Internal_association_or_atrium': [
206
+ {
207
+ 'type': 'Prison buildings',
208
+ 'credits': 2,
209
+ 'area': 80,
210
+ 'average_daylight_illuminance': {
211
+ 'illuminance': 300,
212
+ 'hours': 2650
213
+ },
214
+ 'minimum_daylight_illuminance': {
215
+ 'illuminance': 210,
216
+ 'hours': 2650
217
+ }
218
+ }
219
+ ],
220
+ 'BREEAM::Prison_buildings::Patient_care_spaces': [
221
+ {
222
+ 'type': 'Prison buildings',
223
+ 'credits': 2,
224
+ 'area': 80,
225
+ 'average_daylight_illuminance': {
226
+ 'illuminance': 300,
227
+ 'hours': 2650
228
+ },
229
+ 'minimum_daylight_illuminance': {
230
+ 'illuminance': 210,
231
+ 'hours': 2650
232
+ }
233
+ }
234
+ ],
235
+ 'BREEAM::Prison_buildings::Teaching_lecture_and_seminar_spaces': [
236
+ {
237
+ 'type': 'Prison buildings',
238
+ 'credits': 2,
239
+ 'area': 80,
240
+ 'average_daylight_illuminance': {
241
+ 'illuminance': 300,
242
+ 'hours': 2000
243
+ },
244
+ 'minimum_daylight_illuminance': {
245
+ 'illuminance': 90,
246
+ 'hours': 2000
247
+ }
248
+ }
249
+ ],
250
+ 'BREEAM::Office_buildings::Occupied_spaces': [
251
+ {
252
+ 'type': 'Office buildings',
253
+ 'credits': 2,
254
+ 'area': 80,
255
+ 'average_daylight_illuminance': {
256
+ 'illuminance': 300,
257
+ 'hours': 2000
258
+ },
259
+ 'minimum_daylight_illuminance': {
260
+ 'illuminance': 90,
261
+ 'hours': 2000
262
+ }
263
+ }
264
+ ],
265
+ 'BREEAM::Crèche_buildings::Occupied_spaces': [
266
+ {
267
+ 'type': 'Crèche buildings',
268
+ 'credits': 2,
269
+ 'area': 80,
270
+ 'average_daylight_illuminance': {
271
+ 'illuminance': 300,
272
+ 'hours': 2000
273
+ },
274
+ 'minimum_daylight_illuminance': {
275
+ 'illuminance': 90,
276
+ 'hours': 2000
277
+ }
278
+ }
279
+ ],
280
+ 'BREEAM::Other_buildings::Occupied_spaces': [
281
+ {
282
+ 'type': 'Other buildings',
283
+ 'credits': 1,
284
+ 'area': 80,
285
+ 'average_daylight_illuminance': {
286
+ 'illuminance': 300,
287
+ 'hours': 2000
288
+ },
289
+ 'minimum_daylight_illuminance': {
290
+ 'illuminance': 90,
291
+ 'hours': 2000
292
+ }
293
+ }
294
+ ]
295
+ }
296
+
297
+
298
+ def breeam_daylight_assessment_4b(
299
+ results: Union[str, AnnualDaylight], model: Union[str, Path, Model] = None,
300
+ grids_filter: str = '*', sub_folder: str = None):
301
+ """Calculate credits for BREEAM 4b.
302
+
303
+ Args:
304
+ results: Path to results folder or a Results class object.
305
+ model: A model as a path or a HB Model object. If None, the function
306
+ will look for a model in the parent of the results folder. If a model
307
+ does not exist in this directory the function will raise an error.
308
+ Defaults to None.
309
+ grids_filter: The name of a grid or a pattern to filter the grids.
310
+ Defaults to '*'.
311
+ sub_folder: Relative path for a subfolder to write the output. If None,
312
+ the files will not be written. Defaults to None.
313
+
314
+ Returns:
315
+ Tuple:
316
+ - credit_summary: Summary of each building type.
317
+ - program_summary: Summary of program type / space type.
318
+ """
319
+ if not isinstance(results, AnnualDaylight):
320
+ results = AnnualDaylight(results)
321
+
322
+ grids_info = results._filter_grids(grids_filter=grids_filter)
323
+
324
+ # check to see if there is a HBJSON with sensor grid meshes for areas
325
+ grid_areas = {}
326
+ grid_program_types = {}
327
+ if model is None:
328
+ found_file = False
329
+ for base_file in Path(results.folder).parent.iterdir():
330
+ if base_file.suffix in ('.hbjson', '.hbpkl'):
331
+ hb_model: Model = Model.from_file(base_file)
332
+ found_file = True
333
+ break
334
+ if not found_file:
335
+ raise FileNotFoundError(
336
+ 'Found no hbjson or hbpkl file in parent of results folder.')
337
+ else:
338
+ if isinstance(model, Model):
339
+ hb_model = model
340
+ else:
341
+ hb_model = Model.from_file(model)
342
+
343
+ filt_grids = _filter_by_pattern(
344
+ hb_model.properties.radiance.sensor_grids, filter=grids_filter)
345
+ for s_grid in filt_grids:
346
+ if s_grid.mesh is not None:
347
+ grid_areas[s_grid.identifier] = int(np.array(s_grid.mesh.face_areas).sum())
348
+ else:
349
+ grid_areas[s_grid.identifier] = None
350
+ hb_room = hb_model.rooms_by_identifier([s_grid.room_identifier])[0]
351
+ try:
352
+ program_type_id = hb_room.properties.energy.program_type.identifier
353
+ except AttributeError as e:
354
+ raise ImportError('honeybee_energy library must be installed to use '
355
+ 'breeam_daylight_assessment method. {}'.format(e))
356
+ if program_type_id in program_type_metrics:
357
+ grid_program_types[s_grid.identifier] = program_type_id
358
+
359
+ if not grid_areas:
360
+ grid_areas = {grid_info['full_id']: None for grid_info in grids_info}
361
+
362
+ sensor_grid_mapper = {}
363
+ for sg in hb_model.properties.radiance.sensor_grids:
364
+ sensor_grid_mapper[sg.identifier] = sg
365
+
366
+ grid_summary = {}
367
+ type_summary = {}
368
+ minimum_illuminance_sensors = {}
369
+ for grid_info in grids_info:
370
+ program_type = grid_program_types.get(grid_info['full_id'], None)
371
+ if program_type is None:
372
+ continue
373
+ if program_type not in type_summary:
374
+ type_summary[program_type] = {} # add dict for program type
375
+ type_summary[program_type][grid_info['full_id']] = []
376
+
377
+ array = results._array_from_states(grid_info, zero_array=True)
378
+ # calculate average along axis 0 (average for each hour)
379
+ avg_ill = array.mean(axis=0)
380
+
381
+ metrics_list = program_type_metrics[program_type]
382
+ for metrics in metrics_list:
383
+ metrics_summary = {}
384
+ metrics_summary['type'] = metrics['type']
385
+ metrics_summary['area'] = grid_areas[grid_info['full_id']]
386
+ # calculate number of hours where avg. illuminance > target illuminance
387
+ target_ill = metrics['average_daylight_illuminance']['illuminance']
388
+ hrs_abv_avg = (avg_ill >= target_ill).sum()
389
+ # check if value is >= target hours
390
+ target_hrs = metrics['average_daylight_illuminance']['hours']
391
+ avg_comply = hrs_abv_avg >= target_hrs
392
+
393
+ # calculate number of hours where illuminance > target illuminance
394
+ if program_type == 'BREEAM::Prison_buildings::Cells_and_custody_cells':
395
+ min_comply = True # no minimum daylight illuminance for this space
396
+ else:
397
+ target_ill = metrics['minimum_daylight_illuminance']['illuminance']
398
+ hrs_abv_target = (array >= target_ill).sum(axis=1)
399
+ # get the minimum, i.e., worst lit point
400
+ hrs_abv_min = np.min(hrs_abv_target)
401
+ # check if values is >= target hours
402
+ target_hrs = metrics['minimum_daylight_illuminance']['hours']
403
+ min_comply = hrs_abv_min >= target_hrs
404
+
405
+ minimum_illuminance_index = int(np.argsort(hrs_abv_target)[0])
406
+ minimum_illuminance_sensor = \
407
+ sensor_grid_mapper[grid_info['full_id']].sensors[minimum_illuminance_index]
408
+ minimum_illuminance_sensors[grid_info['full_id']] = \
409
+ minimum_illuminance_sensor.to_dict()
410
+
411
+ metrics_summary['credits'] = metrics['credits']
412
+ if avg_comply and min_comply:
413
+ metrics_summary['comply'] = True
414
+ else:
415
+ metrics_summary['comply'] = False
416
+ metrics_summary['average-comply'] = True if avg_comply else False
417
+ metrics_summary['minimum-comply'] = True if min_comply else False
418
+
419
+ metrics_summary['count'] = grid_info['count']
420
+
421
+ metrics_summary['average-illuminance-hours'] = hrs_abv_avg
422
+ metrics_summary['minimum-illuminance-hours'] = hrs_abv_min
423
+
424
+ type_summary[program_type][grid_info['full_id']].append(metrics_summary)
425
+
426
+ grid_summary[grid_info['full_id']] = {
427
+ 'type': metrics['type'],
428
+ 'program-type': program_type,
429
+ 'display-name': grid_info['name'],
430
+ 'average-illuminance-hours': hrs_abv_avg.item(),
431
+ 'minimum-illuminance-hours': hrs_abv_min.item()
432
+ }
433
+
434
+ program_summary = []
435
+ for program_type, _grid_summary in type_summary.items():
436
+ program_type_summary = {}
437
+ program_type_summary['program_type'] = program_type
438
+ program_type_summary['credits'] = 0 # set 0 by default
439
+ program_type_summary['comply'] = False # set False by default
440
+
441
+ metrics_summary = {}
442
+ for grid_id, metrics_list in _grid_summary.items():
443
+ for metric in metrics_list:
444
+ if metric['credits'] not in metrics_summary:
445
+ metrics_summary[metric['credits']] = {}
446
+ metrics_summary[metric['credits']]['type'] = metric['type']
447
+ if 'total_area' not in metrics_summary[metric['credits']]:
448
+ metrics_summary[metric['credits']]['total_area'] = 0
449
+ metrics_summary[metric['credits']]['total_area'] += metric['area']
450
+ if 'area_comply' not in metrics_summary[metric['credits']]:
451
+ metrics_summary[metric['credits']]['area_comply'] = 0
452
+ if metric['comply']:
453
+ metrics_summary[metric['credits']]['area_comply'] += metric['area']
454
+
455
+ for credit, metric_summary in metrics_summary.items():
456
+ area_comply_pct = metric_summary['area_comply'] / metric_summary['total_area'] * 100
457
+ metric_summary['area_comply_%'] = area_comply_pct
458
+ for metric in program_type_metrics[program_type]:
459
+ if credit == metric['credits']:
460
+ if area_comply_pct >= metric['area']:
461
+ metric_summary['comply'] = True
462
+ else:
463
+ metric_summary['comply'] = False
464
+
465
+ for credit, metric_summary in metrics_summary.items():
466
+ if metric_summary['comply'] and credit > program_type_summary['credits']:
467
+ program_type_summary['comply'] = True
468
+ program_type_summary['credits'] = credit
469
+ program_type_summary['total_area'] = metric_summary['total_area']
470
+ program_type_summary['area_comply'] = metric_summary['area_comply']
471
+ program_type_summary['area_comply_%'] = metric_summary['area_comply_%']
472
+ program_type_summary['type'] = metric_summary['type']
473
+ else:
474
+ program_type_summary['total_area'] = metric_summary['total_area']
475
+ program_type_summary['area_comply'] = metric_summary['area_comply']
476
+ program_type_summary['area_comply_%'] = metric_summary['area_comply_%']
477
+ program_type_summary['type'] = metric_summary['type']
478
+
479
+ avg_hrs, min_hrs, areas = [], [], []
480
+ for grid_id, metrics_list in _grid_summary.items():
481
+ for metric in metrics_list:
482
+ areas.append(metric['area'])
483
+ avg_hrs.append(metric['average-illuminance-hours'])
484
+ min_hrs.append(metric['minimum-illuminance-hours'])
485
+ break # only need to get the first one
486
+
487
+ area_proportions = np.array(areas) / program_type_summary['total_area']
488
+
489
+ weighted_hours_avg = area_proportions * np.array(avg_hrs)
490
+ total_weighted_hours_avg = int(np.sum(weighted_hours_avg))
491
+ program_type_summary['average-illuminance-hours'] = total_weighted_hours_avg
492
+
493
+ weighted_hours_min = area_proportions * np.array(min_hrs)
494
+ total_weighted_hours_min = int(np.sum(weighted_hours_min))
495
+ program_type_summary['minimum-illuminance-hours'] = total_weighted_hours_min
496
+
497
+ program_summary.append(program_type_summary)
498
+
499
+ building_type_summary = {}
500
+ for _program_summary in program_summary:
501
+ if _program_summary['type'] not in building_type_summary:
502
+ building_type_summary[_program_summary['type']] = []
503
+ building_type_summary[_program_summary['type']].append(_program_summary)
504
+
505
+ credit_summary = []
506
+ for building_type, summary in building_type_summary.items():
507
+ _building_type_summary = {}
508
+ _building_type_summary['type'] = building_type
509
+ if all([v['comply'] for v in summary]):
510
+ _building_type_summary['comply'] = True
511
+ _building_type_summary['credits'] = min([v['credits'] for v in summary])
512
+ else:
513
+ _building_type_summary['comply'] = False
514
+ _building_type_summary['credits'] = 0
515
+ _building_type_summary['total_area'] = sum([v['total_area'] for v in summary])
516
+
517
+ credit_summary.append(_building_type_summary)
518
+
519
+ if sub_folder:
520
+ sub_folder = Path(sub_folder)
521
+ sub_folder.mkdir(parents=True, exist_ok=True)
522
+
523
+ minimum_illuminance_points_file = sub_folder.joinpath('minimum_illuminance_sensors.json')
524
+ minimum_illuminance_points_file.write_text(
525
+ json.dumps(minimum_illuminance_sensors, indent=2))
526
+ credit_summary_file = sub_folder.joinpath('summary.json')
527
+ credit_summary_file.write_text(json.dumps(credit_summary, indent=2))
528
+ program_summary_file = sub_folder.joinpath('program_summary.json')
529
+ program_summary_file.write_text(json.dumps(program_summary, indent=2))
530
+ grid_summary_file = sub_folder.joinpath('grid_summary.json')
531
+ grid_summary_file.write_text(json.dumps(grid_summary, indent=2))
532
+
533
+ pf_folder = sub_folder.joinpath('pass_fail')
534
+ pf_folder.mkdir(parents=True, exist_ok=True)
535
+ grids_info_file = pf_folder.joinpath('grids_info.json')
536
+ grids_info_file.write_text(json.dumps(grids_info, indent=2))
537
+ for program_type, grid_summary in type_summary.items():
538
+ for grid_id, metrics_list in grid_summary.items():
539
+ fill_value = 0
540
+ for metric in metrics_list:
541
+ if metric['comply']:
542
+ fill_value = 3
543
+ break
544
+ elif metric['average-comply']:
545
+ fill_value = 2
546
+ elif metric['minimum-comply']:
547
+ fill_value = 1
548
+ pf_file = pf_folder.joinpath(f'{grid_id}.pf')
549
+ pf_array = np.full(metric['count'], fill_value)
550
+ np.savetxt(pf_file, pf_array, fmt='%d')
551
+
552
+ return credit_summary, program_summary
@@ -0,0 +1,33 @@
1
+ """Modules for post-processing simulation outputs."""
2
+ import click
3
+
4
+ from honeybee.cli import main
5
+ from .grid import grid
6
+ from .mtxop import mtxop
7
+ from .postprocess import post_process
8
+ from .schedule import schedule
9
+ from .translate import translate
10
+ from .viewfactor import view_factor
11
+ from .merge import merge
12
+ from .datacollection import datacollection
13
+
14
+
15
+ # command group for all postprocess extension commands.
16
+ @click.group(help='honeybee radiance postprocess commands.')
17
+ @click.version_option()
18
+ def postprocess():
19
+ pass
20
+
21
+
22
+ # add sub-commands to postprocess
23
+ postprocess.add_command(grid)
24
+ postprocess.add_command(mtxop)
25
+ postprocess.add_command(post_process, name='post-process')
26
+ postprocess.add_command(schedule)
27
+ postprocess.add_command(translate)
28
+ postprocess.add_command(view_factor)
29
+ postprocess.add_command(merge)
30
+ postprocess.add_command(datacollection, name='data-collection')
31
+
32
+ # add postprocess sub-commands to honeybee CLI
33
+ main.add_command(postprocess)