honeybee-radiance-postprocess 0.4.226__py2.py3-none-any.whl → 0.4.228__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.
@@ -697,6 +697,7 @@ def annual_metrics_file(
697
697
  @click.option(
698
698
  '--grids-info', '-gi', help='An optional JSON file with grid information. '
699
699
  'If no file is provided the command will look for a file in the folder.',
700
+ default=None, show_default=True,
700
701
  type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
701
702
  )
702
703
  @click.option(
@@ -726,27 +727,88 @@ def grid_summary_metric(
726
727
  if grids_info:
727
728
  with open(grids_info) as gi:
728
729
  grids_info = json.load(gi)
729
- else:
730
- gi_file = folder.joinpath('grids_info.json')
731
- with open(gi_file) as gi:
732
- grids_info = json.load(gi)
733
730
 
734
731
  # get grid metrics
735
732
  if grid_metrics:
736
733
  with open(grid_metrics) as gm:
737
734
  grid_metrics = json.load(gm)
735
+
736
+ # check to see if there is a HBJSON with sensor grid meshes for areas
737
+ if model:
738
+ grid_areas = model_grid_areas(model, grids_info)
738
739
  else:
739
- gi_file = folder.joinpath('grids_info.json')
740
- with open(gi_file) as gi:
740
+ grid_areas = None
741
+
742
+ grid_summary(folder, extension, grid_areas, grids_info, name, grid_metrics)
743
+
744
+ except Exception:
745
+ _logger.exception('Failed to calculate grid summary.')
746
+ sys.exit(1)
747
+ else:
748
+ sys.exit(0)
749
+
750
+
751
+ @post_process.command('grid-summary-annual-daylight')
752
+ @click.argument(
753
+ 'folder',
754
+ type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True)
755
+ )
756
+ @click.option(
757
+ '--model', '-m', help='An optional HBJSON model file. This will be used to '
758
+ 'find the area of the grids. The area is used when calculating percentages '
759
+ 'of floor area.',
760
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
761
+ )
762
+ @click.option(
763
+ '--grids-info', '-gi', help='An optional JSON file with grid information. '
764
+ 'If no file is provided the command will look for a file in the folder.',
765
+ default=None, show_default=True,
766
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
767
+ )
768
+ @click.option(
769
+ '--name', '-n', help='Optional filename of grid summary.',
770
+ type=str, default='grid_summary', show_default=True
771
+ )
772
+ @click.option(
773
+ '--grid-metrics', '-gm', help='An optional JSON file with additional '
774
+ 'custom metrics to calculate.', default=None,
775
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
776
+ )
777
+ def grid_summary_annual_daylight_metric(
778
+ folder, model, grids_info, name, grid_metrics
779
+ ):
780
+ """Calculate a grid summary.
781
+
782
+ \b
783
+ Args:
784
+ folder: A folder with annual daylight metrics.
785
+ """
786
+ try:
787
+ # create Path object
788
+ folder = Path(folder)
789
+
790
+ # get grids information
791
+ if grids_info:
792
+ with open(grids_info) as gi:
741
793
  grids_info = json.load(gi)
742
794
 
795
+ # get grid metrics
796
+ if grid_metrics:
797
+ with open(grid_metrics) as gm:
798
+ grid_metrics = json.load(gm)
799
+
743
800
  # check to see if there is a HBJSON with sensor grid meshes for areas
744
801
  if model:
745
802
  grid_areas = model_grid_areas(model, grids_info)
746
803
  else:
747
- grid_areas = [None] * len(grids_info)
804
+ grid_areas = None
748
805
 
749
- grid_summary(folder, extension, grids_info, grid_areas, name, grid_metrics)
806
+ for metric in ['da', 'cda', 'udi', 'udi_lower', 'udi_upper']:
807
+ metric_folder = folder.joinpath(metric)
808
+ extension = metric.split('_')[0]
809
+ grid_summary(
810
+ metric_folder, extension, grids_info, grid_areas, name,
811
+ grid_metrics)
750
812
 
751
813
  except Exception:
752
814
  _logger.exception('Failed to calculate grid summary.')
@@ -1,9 +1,11 @@
1
1
  """Commands to translate objects."""
2
2
  import sys
3
3
  import logging
4
+ from pathlib import Path
5
+ import shutil
4
6
  import numpy as np
5
7
  import click
6
- from pathlib import Path
8
+ import json
7
9
 
8
10
  from ..reader import binary_to_array
9
11
 
@@ -129,3 +131,70 @@ def binary_to_npy(mtx_file, conversion, name, output_folder):
129
131
  sys.exit(1)
130
132
  else:
131
133
  sys.exit(0)
134
+
135
+
136
+ @translate.command('annual-daylight-npy-to-ill')
137
+ @click.argument(
138
+ 'folder',
139
+ type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True)
140
+ )
141
+ @click.option(
142
+ '--output-folder', '-of', help='Output folder. If not provided the output '
143
+ 'folder will be created in the same directory as the results folder. The '
144
+ 'new folder will be called results_ill.', default=None,
145
+ type=click.Path(exists=False, file_okay=False, dir_okay=True, resolve_path=True)
146
+ )
147
+ def annual_daylight_npy_to_ill(folder, output_folder):
148
+ """Convert an annual daylight results folder to older version.
149
+
150
+ This command reads an annual daylight results folder with results saved as
151
+ npy files (NumPy), and converts the npy files to text files in the old
152
+ results folder format.
153
+
154
+ \b
155
+ Args:
156
+ folder: Results folder. This folder is an output folder of annual
157
+ daylight recipe. Folder should include grids_info.json and
158
+ sun-up-hours.txt.
159
+ """
160
+ try:
161
+ folder = Path(folder)
162
+ static_ill_folder = folder.joinpath('__static_apertures__/default/total')
163
+ if not static_ill_folder.exists():
164
+ raise FileNotFoundError(
165
+ 'No results were found for static apertures in the results '
166
+ 'folder.')
167
+ grids_info_file = folder.joinpath('grids_info.json')
168
+ if not grids_info_file.exists():
169
+ raise FileNotFoundError(
170
+ 'The file grids_info.json was not found in the results folder.')
171
+ sun_up_hours_file = folder.joinpath('sun-up-hours.txt')
172
+ if not sun_up_hours_file.exists():
173
+ raise FileNotFoundError(
174
+ 'The file sun-up-hours.txt was not found in the results folder.')
175
+
176
+ if output_folder is None:
177
+ output_folder = folder.parent.joinpath('results_ill')
178
+ else:
179
+ output_folder = Path(output_folder)
180
+ output_folder.mkdir(parents=True, exist_ok=True)
181
+
182
+ with open(grids_info_file) as json_file:
183
+ grids_info = json.load(json_file)
184
+
185
+ for grid_info in grids_info:
186
+ full_id = grid_info['full_id']
187
+ npy_file = static_ill_folder.joinpath(f'{full_id}.npy')
188
+
189
+ array = np.load(npy_file)
190
+ output = Path(output_folder, full_id + '.ill')
191
+ np.savetxt(output, array, fmt='%.7e', delimiter='\t')
192
+
193
+ # copy grids_info and sun-up-hours
194
+ shutil.copy(grids_info_file, output_folder.joinpath('grids_info.json'))
195
+ shutil.copy(sun_up_hours_file, output_folder.joinpath('sun-up-hours.txt'))
196
+ except Exception:
197
+ _logger.exception('Converting annual daylight results folder failed.')
198
+ sys.exit(1)
199
+ else:
200
+ sys.exit(0)
@@ -1,4 +1,5 @@
1
1
  """Helper functions."""
2
+ import json
2
3
  import numpy as np
3
4
 
4
5
  from honeybee.model import Model
@@ -25,7 +26,7 @@ def model_grid_areas(model, grids_info):
25
26
 
26
27
 
27
28
  def grid_summary(
28
- folder, extension, grids_info, grid_areas, name='grid_summary',
29
+ folder, extension, grid_areas=None, grids_info=None, name='grid_summary',
29
30
  grid_metrics=None
30
31
  ):
31
32
  """Calculate a grid summary for a single metric.
@@ -33,11 +34,22 @@ def grid_summary(
33
34
  Args:
34
35
  folder: A folder with results.
35
36
  extension: Extension of the files to collect data from.
37
+ grid_areas: A list of area of each sensor.
36
38
  grids_info: Grid information as a dictionary.
37
- grid_areas:
38
39
  name: Optional filename of grid summary.
39
40
  grid_metrics: Additional customized metrics to calculate.
40
41
  """
42
+ if grids_info is None:
43
+ gi_file = folder.joinpath('grids_info.json')
44
+ if not gi_file.exists():
45
+ raise FileNotFoundError(
46
+ f'The file grids_info.json was not found in the folder: {folder}.')
47
+ with open(gi_file) as gi:
48
+ grids_info = json.load(gi)
49
+
50
+ if grid_areas is None:
51
+ grid_areas = [None] * len(grids_info)
52
+
41
53
  # set up the default data types
42
54
  dtype = [
43
55
  ('Sensor Grid', 'O'),
@@ -67,58 +79,11 @@ def grid_summary(
67
79
 
68
80
  data = [full_id, _mean, _min, _max, _uniformity_ratio]
69
81
 
70
- grid_metrics_data = []
71
82
  if grid_metrics is not None:
72
- for gr_metric in grid_metrics:
73
- if len(gr_metric) == 1:
74
- for k, v in gr_metric.items():
75
- if k == 'anyOff' or k == 'allOff':
76
- gr_metric_arrays = []
77
- for vv in v:
78
- for kk, threshold in vv.items():
79
- if kk == 'minimum':
80
- gr_metric_arrays.append(array > threshold)
81
- elif kk == 'exclusiveMinimum':
82
- gr_metric_arrays.append(array >= threshold)
83
- elif kk == 'maximum':
84
- gr_metric_arrays.append(array < threshold)
85
- elif kk == 'exclusiveMaximum':
86
- gr_metric_arrays.append(array <= threshold)
87
- if k == 'anyOff':
88
- gr_metric_bool = np.any(gr_metric_arrays, axis=0)
89
- else:
90
- gr_metric_bool = np.all(gr_metric_arrays, axis=0)
91
- gr_metric_pct = \
92
- _calculate_percentage(gr_metric_bool, grid_info, grid_area)
93
- else:
94
- threshold = v
95
- if k == 'minimum':
96
- gr_metric_bool = array > threshold
97
- elif k == 'exclusiveMinimum':
98
- gr_metric_bool = array >= threshold
99
- elif k == 'maximum':
100
- gr_metric_bool = array < threshold
101
- elif k == 'exclusiveMaximum':
102
- gr_metric_bool = array <= threshold
103
- gr_metric_pct = \
104
- _calculate_percentage(gr_metric_bool, grid_info, grid_area)
105
- elif len(gr_metric) == 2:
106
- gr_metric_arrays = []
107
- for k, threshold in gr_metric.items():
108
- if k == 'minimum':
109
- gr_metric_arrays.append(array > threshold)
110
- elif k == 'exclusiveMinimum':
111
- gr_metric_arrays.append(array >= threshold)
112
- elif k == 'maximum':
113
- gr_metric_arrays.append(array < threshold)
114
- elif k == 'exclusiveMaximum':
115
- gr_metric_arrays.append(array <= threshold)
116
- gr_metric_bool = np.all(gr_metric_arrays, axis=0)
117
- gr_metric_pct = \
118
- _calculate_percentage(gr_metric_bool, grid_info, grid_area)
119
- grid_metrics_data.append(gr_metric_pct)
120
-
121
- data.extend(grid_metrics_data)
83
+ # get grid metrics
84
+ grid_metrics_data = \
85
+ _get_grid_metrics(array, grid_metrics, grid_info, grid_area)
86
+ data.extend(grid_metrics_data)
122
87
 
123
88
  arrays.append(tuple(data))
124
89
 
@@ -126,17 +91,17 @@ def grid_summary(
126
91
  struct_array = np.array(arrays, dtype=dtype)
127
92
 
128
93
  # write header to file
129
- with open(folder.joinpath(f'{name}.csv'), 'w') as file:
130
- file.write(','.join(header))
131
- # write structured array to file
94
+ with open(folder.joinpath(f'{name}.csv'), 'w') as grid_summary_file:
95
+ grid_summary_file.write(','.join(header))
96
+ # write structured array to grid_summary_file
132
97
  fmt = ['%s' , '%.2f', '%.2f', '%.2f', '%.2f']
133
98
  if grid_metrics is not None:
134
- fmt.extend(['%.2f' for d in grid_metrics])
135
- with open(folder.joinpath(f'{name}.csv'), 'a') as file:
136
- file.write('\n')
137
- np.savetxt(file, struct_array, delimiter=',', fmt=fmt)
99
+ fmt.extend(['%.2f' for _gr_m in grid_metrics])
100
+ with open(folder.joinpath(f'{name}.csv'), 'a') as grid_summary_file:
101
+ grid_summary_file.write('\n')
102
+ np.savetxt(grid_summary_file, struct_array, delimiter=',', fmt=fmt)
138
103
 
139
- return file
104
+ return grid_summary_file
140
105
 
141
106
 
142
107
  def _calculate_percentage(gr_metric_bool, grid_info, grid_area=None):
@@ -157,3 +122,56 @@ def _calculate_percentage(gr_metric_bool, grid_info, grid_area=None):
157
122
  gr_metric_pct = \
158
123
  gr_metric_bool.sum() / grid_info['count'] * 100
159
124
  return gr_metric_pct
125
+
126
+
127
+ def _numeric_type(array, gr_metric):
128
+ if 'minimum' in gr_metric:
129
+ gr_metric_bool = array > gr_metric['minimum']
130
+ elif 'exclusiveMinimum' in gr_metric:
131
+ gr_metric_bool = array >= gr_metric['minimum']
132
+ elif 'maximum' in gr_metric:
133
+ gr_metric_bool = array < gr_metric['maximum']
134
+ elif 'exclusiveMaximum' in gr_metric:
135
+ gr_metric_bool = array <= gr_metric['exclusiveMaximum']
136
+ return gr_metric_bool
137
+
138
+
139
+ def _grid_summary_all_any(array, gr_metric, grid_info, grid_area, keyword):
140
+ gr_metric_arrays = []
141
+ for gr_m in gr_metric[keyword]:
142
+ assert len(gr_m) == 1
143
+ gr_metric_arrays.append(_numeric_type(array, gr_m))
144
+ if keyword == 'allOf':
145
+ gr_metric_bool = np.all(gr_metric_arrays, axis=0)
146
+ else:
147
+ gr_metric_bool = np.any(gr_metric_arrays, axis=0)
148
+ gr_metric_pct = \
149
+ _calculate_percentage(gr_metric_bool, grid_info, grid_area)
150
+ return gr_metric_pct
151
+
152
+
153
+ def _get_grid_metrics(array, grid_metrics, grid_info, grid_area):
154
+ grid_metrics_data = []
155
+ for gr_metric in grid_metrics:
156
+ if len(gr_metric) == 1:
157
+ if 'allOf' in gr_metric:
158
+ gr_metric_pct = \
159
+ _grid_summary_all_any(
160
+ array, gr_metric, grid_info, grid_area, 'allOf')
161
+ elif 'anyOf' in gr_metric:
162
+ gr_metric_pct = \
163
+ _grid_summary_all_any(
164
+ array, gr_metric, grid_info, grid_area, 'anyOf')
165
+ else:
166
+ gr_metric_bool = _numeric_type(array, gr_metric)
167
+ gr_metric_pct = \
168
+ _calculate_percentage(gr_metric_bool, grid_info, grid_area)
169
+ elif len(gr_metric) == 2:
170
+ gr_metric_arrays = []
171
+ for k, threshold in gr_metric.items():
172
+ gr_metric_arrays.append(_numeric_type(array, {k: threshold}))
173
+ gr_metric_bool = np.all(gr_metric_arrays, axis=0)
174
+ gr_metric_pct = \
175
+ _calculate_percentage(gr_metric_bool, grid_info, grid_area)
176
+ grid_metrics_data.append(gr_metric_pct)
177
+ return grid_metrics_data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: honeybee-radiance-postprocess
3
- Version: 0.4.226
3
+ Version: 0.4.228
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
@@ -5,7 +5,7 @@ honeybee_radiance_postprocess/annualdaylight.py,sha256=uC1CeIL3oBdkLTxaAUGB022RD
5
5
  honeybee_radiance_postprocess/dynamic.py,sha256=YpUxFB1IQgwvJleg1pez3JGpacGZymCBomnAiOTquks,7982
6
6
  honeybee_radiance_postprocess/electriclight.py,sha256=E7uhq7-YtZ02F9a1FbEdrXnxmYJNOFnfLF0Yw3JLQ-g,732
7
7
  honeybee_radiance_postprocess/en17037.py,sha256=tFoEOhJ4GgB45E6PmTrV1uMAS9e8QQo8eoDkX7Wb2S8,10731
8
- honeybee_radiance_postprocess/helper.py,sha256=fO1fCns096us0WmxNEx3Xh_gjrIGhPiIZzSaumIlLGM,6259
8
+ honeybee_radiance_postprocess/helper.py,sha256=syaxOjymkSRb69NH5EjD2gplp6idwSZsH0R6yYQAcvc,6140
9
9
  honeybee_radiance_postprocess/leed.py,sha256=FPCD5Eg-hBzA2PK2yxHqi9RUEGQhprGLhajgH_Sy00A,26042
10
10
  honeybee_radiance_postprocess/metrics.py,sha256=TVChEPtyYrn9MjTRtDL77B3-QZL3J4nP9zrWJDNwC40,13511
11
11
  honeybee_radiance_postprocess/reader.py,sha256=6myKzfGC1pO8zPixg1kKrKjPihHabTKUh2t5BlJvij0,2367
@@ -16,14 +16,14 @@ honeybee_radiance_postprocess/cli/__init__.py,sha256=4RkpR91GPXWatDE4I_27ce-N4Fw
16
16
  honeybee_radiance_postprocess/cli/grid.py,sha256=qpugRC4kWdJd3N8AubeLstcm0D5bW3CjTopsdwXHlPE,8957
17
17
  honeybee_radiance_postprocess/cli/leed.py,sha256=o10tYnp_eRLEX7QV6jHj6cVRQA_6zYg_v9bZGbHo3eo,3082
18
18
  honeybee_radiance_postprocess/cli/mtxop.py,sha256=UZJnjNpPjDmShy1-Mxos4H2vTUqk_yP3ZyaC1_LLFeI,5015
19
- honeybee_radiance_postprocess/cli/postprocess.py,sha256=EL1ujHitShsD79xHIfDVIZqjW6oy9lseu7yc2zkVuuo,27022
19
+ honeybee_radiance_postprocess/cli/postprocess.py,sha256=GUANSqugbvalcBcvNwsASS6yyVBPlxsDMnjwpVrXpSU,29042
20
20
  honeybee_radiance_postprocess/cli/schedule.py,sha256=OokuuH9_pdgkt2zFgfjBvrV2Fj1Ow1WtiGRPvpyHfNk,3884
21
- honeybee_radiance_postprocess/cli/translate.py,sha256=tMyFcT80_NXhNIMH1Nn-10dRrk534NRl-_L-mK-0sHQ,4031
21
+ honeybee_radiance_postprocess/cli/translate.py,sha256=18zkcGeRZALJ5Z82NEB3XZ-iEX2cHyneobGWV-IXWE0,6789
22
22
  honeybee_radiance_postprocess/cli/two_phase.py,sha256=O0ugIQh0MOAEl3Q8IsZU4IQ8jNPPOOfeqs5ccwlix6Q,4559
23
23
  honeybee_radiance_postprocess/cli/util.py,sha256=Be9cGmYhcV2W37ma6SgQPCWCpWLLLlroxRYN_l58kY0,4077
24
- honeybee_radiance_postprocess-0.4.226.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
25
- honeybee_radiance_postprocess-0.4.226.dist-info/METADATA,sha256=1wNmIjNStnjoQZT3xl2R0e8sR8AY5VJoiSyadZuCrj4,2227
26
- honeybee_radiance_postprocess-0.4.226.dist-info/WHEEL,sha256=unfA4MOaH0icIyIA5oH6E2sn2Hq5zKtLlHsWapZGwes,110
27
- honeybee_radiance_postprocess-0.4.226.dist-info/entry_points.txt,sha256=gFtVPx6UItXt27GfEZZO00eOZChJJEL6JwGSAB_O3rs,96
28
- honeybee_radiance_postprocess-0.4.226.dist-info/top_level.txt,sha256=4-sFbzy7ewP2EDqJV3jeFlAFx7SuxtoBBELWaKAnLdA,30
29
- honeybee_radiance_postprocess-0.4.226.dist-info/RECORD,,
24
+ honeybee_radiance_postprocess-0.4.228.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
25
+ honeybee_radiance_postprocess-0.4.228.dist-info/METADATA,sha256=xh7iMof6MgmWgHextLuhQKO4tD1Q5LnKydLwVAdVjrQ,2227
26
+ honeybee_radiance_postprocess-0.4.228.dist-info/WHEEL,sha256=unfA4MOaH0icIyIA5oH6E2sn2Hq5zKtLlHsWapZGwes,110
27
+ honeybee_radiance_postprocess-0.4.228.dist-info/entry_points.txt,sha256=gFtVPx6UItXt27GfEZZO00eOZChJJEL6JwGSAB_O3rs,96
28
+ honeybee_radiance_postprocess-0.4.228.dist-info/top_level.txt,sha256=4-sFbzy7ewP2EDqJV3jeFlAFx7SuxtoBBELWaKAnLdA,30
29
+ honeybee_radiance_postprocess-0.4.228.dist-info/RECORD,,