honeybee-radiance-postprocess 0.4.543__tar.gz → 0.4.545__tar.gz

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 (62) hide show
  1. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/PKG-INFO +2 -2
  2. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/annual.py +11 -4
  3. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/annualdaylight.py +6 -1
  4. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/breeam/breeam.py +10 -5
  5. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/abnt.py +6 -1
  6. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/datacollection.py +6 -1
  7. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/grid.py +6 -1
  8. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/merge.py +6 -1
  9. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/mtxop.py +6 -1
  10. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/postprocess.py +8 -3
  11. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/translate.py +6 -1
  12. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/two_phase.py +6 -1
  13. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/viewfactor.py +6 -1
  14. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/data_type.py +6 -1
  15. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/electriclight.py +7 -1
  16. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/en17037.py +6 -1
  17. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/helper.py +17 -3
  18. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/ies/lm.py +6 -1
  19. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/ies/lm_schedule.py +6 -1
  20. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/leed/leed.py +38 -32
  21. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/leed/leed_schedule.py +20 -7
  22. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/metrics.py +33 -12
  23. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/reader.py +6 -1
  24. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/results/annual_daylight.py +17 -17
  25. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/results/annual_irradiance.py +6 -1
  26. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/results/results.py +49 -29
  27. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/type_hints.py +8 -1
  28. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/util.py +30 -2
  29. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess.egg-info/PKG-INFO +2 -2
  30. honeybee_radiance_postprocess-0.4.545/honeybee_radiance_postprocess.egg-info/requires.txt +2 -0
  31. honeybee_radiance_postprocess-0.4.545/requirements.txt +2 -0
  32. honeybee_radiance_postprocess-0.4.543/honeybee_radiance_postprocess.egg-info/requires.txt +0 -2
  33. honeybee_radiance_postprocess-0.4.543/requirements.txt +0 -2
  34. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/CODE_OF_CONDUCT.md +0 -0
  35. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/CONTRIBUTING.md +0 -0
  36. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/LICENSE +0 -0
  37. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/MANIFEST.in +0 -0
  38. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/README.md +0 -0
  39. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/dev-requirements.txt +0 -0
  40. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/__init__.py +0 -0
  41. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/__main__.py +0 -0
  42. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/annualirradiance.py +0 -0
  43. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/breeam/__init__.py +0 -0
  44. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/__init__.py +0 -0
  45. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/breeam.py +0 -0
  46. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/leed.py +0 -0
  47. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/schedule.py +0 -0
  48. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/util.py +0 -0
  49. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/cli/well.py +0 -0
  50. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/dynamic.py +0 -0
  51. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/ies/__init__.py +0 -0
  52. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/leed/__init__.py +0 -0
  53. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/results/__init__.py +0 -0
  54. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/vis_metadata.py +0 -0
  55. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/well/__init__.py +0 -0
  56. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess/well/well.py +0 -0
  57. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess.egg-info/SOURCES.txt +0 -0
  58. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess.egg-info/dependency_links.txt +0 -0
  59. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess.egg-info/entry_points.txt +0 -0
  60. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/honeybee_radiance_postprocess.egg-info/top_level.txt +0 -0
  61. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/setup.cfg +0 -0
  62. {honeybee_radiance_postprocess-0.4.543 → honeybee_radiance_postprocess-0.4.545}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: honeybee-radiance-postprocess
3
- Version: 0.4.543
3
+ Version: 0.4.545
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.182
16
+ Requires-Dist: honeybee-radiance==1.66.183
17
17
  Requires-Dist: numpy<2.0.0
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)
@@ -1,10 +1,17 @@
1
1
  """Shared functions for post-processing annual results."""
2
2
  from typing import Union
3
- import numpy as np
3
+ try:
4
+ import cupy as np
5
+ is_gpu = True
6
+ except ImportError:
7
+ is_gpu = False
8
+ import numpy as np
4
9
 
5
10
  from ladybug.analysisperiod import AnalysisPeriod
6
11
  from .util import filter_array
7
12
 
13
+ is_cpu = not is_gpu
14
+
8
15
 
9
16
  def occupancy_schedule_8_to_6(
10
17
  timestep: int = 1, as_list: bool = False) -> Union[np.ndarray, list]:
@@ -19,10 +26,10 @@ def occupancy_schedule_8_to_6(
19
26
  Returns:
20
27
  A schedule as an array or list.
21
28
  """
22
- full_analysis_period = AnalysisPeriod(timestep=timestep)
23
- analysis_period = AnalysisPeriod(st_hour=8, end_hour=17, timestep=timestep)
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)
24
31
  schedule = np.zeros(8760 * timestep).astype(int)
25
- hours = np.where(np.isin(full_analysis_period.hoys, analysis_period.hoys))[0]
32
+ hours = np.where(np.isin(full_analysis_period, analysis_period))[0]
26
33
  schedule[hours] = 1
27
34
  if as_list:
28
35
  schedule = schedule.tolist()
@@ -4,7 +4,12 @@ Note: These functions will most likely be moved to a separate package in the nea
4
4
  """
5
5
  import json
6
6
  import os
7
- import numpy as np
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from ladybug.color import Colorset
10
15
  from ladybug.datatype.fraction import Fraction
@@ -2,7 +2,12 @@
2
2
  from typing import Union
3
3
  from pathlib import Path
4
4
  import json
5
- import numpy as np
5
+ try:
6
+ import cupy as np
7
+ is_gpu = True
8
+ except ImportError:
9
+ is_gpu = False
10
+ import numpy as np
6
11
 
7
12
  from honeybee.model import Model
8
13
  from honeybee_radiance.writer import _filter_by_pattern
@@ -339,7 +344,7 @@ def breeam_daylight_assessment_4b(
339
344
  hb_model.properties.radiance.sensor_grids, filter=grids_filter)
340
345
  for s_grid in filt_grids:
341
346
  if s_grid.mesh is not None:
342
- grid_areas[s_grid.identifier] = np.array(s_grid.mesh.face_areas).sum()
347
+ grid_areas[s_grid.identifier] = int(np.array(s_grid.mesh.face_areas).sum())
343
348
  else:
344
349
  grid_areas[s_grid.identifier] = None
345
350
  hb_room = hb_model.rooms_by_identifier([s_grid.room_identifier])[0]
@@ -397,7 +402,7 @@ def breeam_daylight_assessment_4b(
397
402
  target_hrs = metrics['minimum_daylight_illuminance']['hours']
398
403
  min_comply = hrs_abv_min >= target_hrs
399
404
 
400
- minimum_illuminance_index = np.argsort(hrs_abv_target)[0]
405
+ minimum_illuminance_index = int(np.argsort(hrs_abv_target)[0])
401
406
  minimum_illuminance_sensor = \
402
407
  sensor_grid_mapper[grid_info['full_id']].sensors[minimum_illuminance_index]
403
408
  minimum_illuminance_sensors[grid_info['full_id']] = \
@@ -482,11 +487,11 @@ def breeam_daylight_assessment_4b(
482
487
  area_proportions = np.array(areas) / program_type_summary['total_area']
483
488
 
484
489
  weighted_hours_avg = area_proportions * np.array(avg_hrs)
485
- total_weighted_hours_avg = np.sum(weighted_hours_avg)
490
+ total_weighted_hours_avg = int(np.sum(weighted_hours_avg))
486
491
  program_type_summary['average-illuminance-hours'] = total_weighted_hours_avg
487
492
 
488
493
  weighted_hours_min = area_proportions * np.array(min_hrs)
489
- total_weighted_hours_min = np.sum(weighted_hours_min)
494
+ total_weighted_hours_min = int(np.sum(weighted_hours_min))
490
495
  program_type_summary['minimum-illuminance-hours'] = total_weighted_hours_min
491
496
 
492
497
  program_summary.append(program_type_summary)
@@ -4,7 +4,12 @@ import sys
4
4
  import logging
5
5
  from pathlib import Path
6
6
  import click
7
- import numpy as np
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from honeybee.model import Model
10
15
  from honeybee.room import Room
@@ -1,10 +1,15 @@
1
1
  """Commands to work with data collections."""
2
2
  import sys
3
3
  import logging
4
- import numpy as np
5
4
  from pathlib import Path
6
5
  import click
7
6
  import json
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from ladybug.datacollection import HourlyContinuousCollection, \
10
15
  HourlyDiscontinuousCollection
@@ -3,8 +3,13 @@ import click
3
3
  import sys
4
4
  import logging
5
5
  import json
6
- import numpy as np
7
6
  from pathlib import Path
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from honeybee_radiance_postprocess.reader import binary_to_array
10
15
  from ..annualdaylight import _annual_daylight_vis_metadata
@@ -3,8 +3,13 @@ import click
3
3
  import sys
4
4
  import logging
5
5
  import json
6
- import numpy as np
7
6
  from pathlib import Path
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from honeybee_radiance_postprocess.reader import binary_to_array
10
15
 
@@ -2,8 +2,13 @@
2
2
  import sys
3
3
  import logging
4
4
  from pathlib import Path
5
- import numpy as np
6
5
  import click
6
+ try:
7
+ import cupy as np
8
+ is_gpu = True
9
+ except ImportError:
10
+ is_gpu = False
11
+ import numpy as np
7
12
 
8
13
  from ..reader import binary_to_array, ascii_to_array
9
14
 
@@ -5,7 +5,12 @@ import os
5
5
  import logging
6
6
  import json
7
7
  import click
8
- import numpy as np
8
+ try:
9
+ import cupy as np
10
+ is_gpu = True
11
+ except ImportError:
12
+ is_gpu = False
13
+ import numpy as np
9
14
 
10
15
  from ladybug.location import Location
11
16
  from ladybug.wea import Wea
@@ -721,8 +726,8 @@ def annual_metrics_file(
721
726
  if grid_name is None:
722
727
  grid_name = file.stem
723
728
 
724
- sun_up_hours_mask = np.where(np.isin(study_hours, sun_up_hours))[0]
725
- sun_down_hours_mask = np.where(~np.isin(study_hours, sun_up_hours))[0]
729
+ sun_up_hours_mask = np.where(np.isin(np.array(study_hours), np.array(sun_up_hours)))[0]
730
+ sun_down_hours_mask = np.where(~np.isin(np.array(study_hours), np.array(sun_up_hours)))[0]
726
731
  occ_mask = np.array(schedule, dtype=int)[sun_up_hours_mask]
727
732
  sun_down_occ_hours = np.array(schedule, dtype=int)[sun_down_hours_mask].sum()
728
733
  total_hours = sum(schedule)
@@ -3,9 +3,14 @@ import sys
3
3
  import logging
4
4
  from pathlib import Path
5
5
  import shutil
6
- import numpy as np
7
6
  import click
8
7
  import json
8
+ try:
9
+ import cupy as np
10
+ is_gpu = True
11
+ except ImportError:
12
+ is_gpu = False
13
+ import numpy as np
9
14
 
10
15
  from ..reader import binary_to_array
11
16
  from ..util import get_delimiter
@@ -2,8 +2,13 @@
2
2
  import sys
3
3
  import logging
4
4
  from pathlib import Path
5
- import numpy as np
6
5
  import click
6
+ try:
7
+ import cupy as np
8
+ is_gpu = True
9
+ except ImportError:
10
+ is_gpu = False
11
+ import numpy as np
7
12
 
8
13
  from ..reader import binary_to_array, ascii_to_array
9
14
 
@@ -4,7 +4,12 @@ import os
4
4
  import sys
5
5
  import logging
6
6
  import math
7
- import numpy as np
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from honeybee_radiance.config import folders
10
15
 
@@ -1,6 +1,11 @@
1
1
  """Functions for NumPy data type (dtype)."""
2
2
  from typing import Tuple
3
- import numpy as np
3
+ try:
4
+ import cupy as np
5
+ is_gpu = True
6
+ except ImportError:
7
+ is_gpu = False
8
+ import numpy as np
4
9
 
5
10
 
6
11
  def smallest_integer_dtype(array: np.ndarray) -> np.signedinteger:
@@ -1,6 +1,12 @@
1
1
  """Functions for post-processing daylight outputs into electric lighting schedules."""
2
2
  from typing import List
3
- import numpy as np
3
+ try:
4
+ import cupy as np
5
+ is_gpu = True
6
+ except ImportError:
7
+ is_gpu = False
8
+ import numpy as np
9
+
4
10
 
5
11
  def array_to_dimming_fraction(
6
12
  array: np.ndarray, su_pattern: List[int], setpt: float, m_pow: float,
@@ -2,7 +2,12 @@
2
2
  from typing import Union
3
3
  from pathlib import Path
4
4
  import json
5
- import numpy as np
5
+ try:
6
+ import cupy as np
7
+ is_gpu = True
8
+ except ImportError:
9
+ is_gpu = False
10
+ import numpy as np
6
11
 
7
12
  from ladybug.color import Colorset
8
13
  from ladybug.datatype.fraction import Fraction
@@ -1,7 +1,12 @@
1
1
  """Helper functions."""
2
2
  import json
3
- import numpy as np
4
3
  from pathlib import Path
4
+ try:
5
+ import cupy as np
6
+ is_gpu = True
7
+ except ImportError:
8
+ is_gpu = False
9
+ import numpy as np
5
10
 
6
11
  from honeybee.model import Model
7
12
 
@@ -144,7 +149,10 @@ def grid_summary(
144
149
  arrays.append(tuple(data))
145
150
 
146
151
  # create structured array
147
- struct_array = np.array(arrays, dtype=dtype)
152
+ if is_gpu:
153
+ struct_array = None
154
+ else:
155
+ struct_array = np.array(arrays, dtype=dtype)
148
156
 
149
157
  header = [dt[0] for dt in dtype]
150
158
  # write header to file
@@ -153,7 +161,13 @@ def grid_summary(
153
161
  # write structured array to grid_summary_file
154
162
  with open(folder.joinpath(f'{name}.csv'), 'a') as grid_summary_file:
155
163
  grid_summary_file.write('\n')
156
- np.savetxt(grid_summary_file, struct_array, delimiter=',', fmt=fmt)
164
+ if is_gpu:
165
+ # CuPy doesn't support structured arrays; manually format rows
166
+ for row in arrays:
167
+ row_str = ','.join(fmt_val % val for fmt_val, val in zip(fmt, row))
168
+ grid_summary_file.write(row_str + '\n')
169
+ else:
170
+ np.savetxt(grid_summary_file, struct_array, delimiter=',', fmt=fmt)
157
171
 
158
172
  return grid_summary_file
159
173
 
@@ -2,7 +2,12 @@
2
2
  from typing import Tuple, Union
3
3
  from collections import defaultdict
4
4
  import itertools
5
- import numpy as np
5
+ try:
6
+ import cupy as np
7
+ is_gpu = True
8
+ except ImportError:
9
+ is_gpu = False
10
+ import numpy as np
6
11
 
7
12
  from honeybee_radiance.postprocess.annual import filter_schedule_by_hours
8
13
 
@@ -1,6 +1,11 @@
1
1
  """Module for dynamic LM schedules."""
2
2
  from typing import Tuple
3
- import numpy as np
3
+ try:
4
+ import cupy as np
5
+ is_gpu = True
6
+ except ImportError:
7
+ is_gpu = False
8
+ import numpy as np
4
9
 
5
10
  from ..results.annual_daylight import AnnualDaylight
6
11
  from ..util import filter_array
@@ -4,7 +4,12 @@ from pathlib import Path
4
4
  from collections import defaultdict
5
5
  import json
6
6
  import itertools
7
- import numpy as np
7
+ try:
8
+ import cupy as np
9
+ is_gpu = True
10
+ except ImportError:
11
+ is_gpu = False
12
+ import numpy as np
8
13
 
9
14
  from ladybug.analysisperiod import AnalysisPeriod
10
15
  from ladybug.datatype.generic import GenericType
@@ -22,10 +27,12 @@ from honeybee_radiance.postprocess.annual import filter_schedule_by_hours
22
27
  from ..metrics import da_array2d, ase_array2d
23
28
  from ..annual import schedule_to_hoys, occupancy_schedule_8_to_6
24
29
  from ..results.annual_daylight import AnnualDaylight
25
- from ..util import filter_array, recursive_dict_merge
30
+ from ..util import recursive_dict_merge, filter_array2d
26
31
  from ..dynamic import DynamicSchedule, ApertureGroupSchedule
27
32
  from .leed_schedule import shd_trans_schedule_descending, states_schedule_descending
28
33
 
34
+ is_cpu = not is_gpu
35
+
29
36
 
30
37
  def _create_grid_summary(
31
38
  grid_info, sda_grid, sda_blinds_up_grid, sda_blinds_down_grid, ase_grid,
@@ -117,7 +124,6 @@ def _leed_summary(
117
124
  """
118
125
  summary = {}
119
126
  summary_grid = {}
120
-
121
127
  if all(grid_area is not None for grid_area in grid_areas):
122
128
  # weighted by mesh face area
123
129
  total_area = 0
@@ -127,17 +133,17 @@ def _leed_summary(
127
133
  pass_sda_blinds_down) in \
128
134
  zip(pass_ase_grids, pass_sda_grids, grid_areas, grids_info,
129
135
  pass_sda_blinds_up_grids, pass_sda_blinds_down_grids):
130
- total_grid_area = grid_area.sum()
136
+ total_grid_area = float(grid_area.sum())
131
137
 
132
- area_pass_ase = grid_area[pass_ase].sum()
133
- ase_grid = (total_grid_area - area_pass_ase) / total_grid_area * 100
138
+ area_pass_ase = float(grid_area[pass_ase].sum())
139
+ ase_grid = float((total_grid_area - area_pass_ase) / total_grid_area * 100)
134
140
 
135
- area_pass_sda = grid_area[pass_sda].sum()
141
+ area_pass_sda = float(grid_area[pass_sda].sum())
136
142
  area_pass_sda_blind_up = grid_area[pass_sda_blinds_up].sum()
137
143
  area_pass_sda_blinds_down = grid_area[pass_sda_blinds_down].sum()
138
- sda_grid = area_pass_sda / total_grid_area * 100
139
- sda_blinds_up_grid = area_pass_sda_blind_up / total_grid_area * 100
140
- sda_blinds_down_grid = area_pass_sda_blinds_down / total_grid_area * 100
144
+ sda_grid = float(area_pass_sda / total_grid_area * 100)
145
+ sda_blinds_up_grid = float(area_pass_sda_blind_up / total_grid_area * 100)
146
+ sda_blinds_down_grid = float(area_pass_sda_blinds_down / total_grid_area * 100)
141
147
 
142
148
  # grid summary
143
149
  grid_summary = \
@@ -298,8 +304,7 @@ def shade_transmittance_per_light_path(
298
304
  def leed_states_schedule(
299
305
  results: Union[str, AnnualDaylight], grids_filter: str = '*',
300
306
  shade_transmittance: Union[float, dict] = 0.05,
301
- use_states: bool = False
302
- ) -> Tuple[dict, dict]:
307
+ use_states: bool = False) -> Tuple[dict, dict, dict]:
303
308
  """Calculate a schedule of each aperture group for LEED compliant sDA.
304
309
 
305
310
  This function calculates an annual shading schedule of each aperture
@@ -404,11 +409,9 @@ def leed_states_schedule(
404
409
  fail_to_comply[grid_info['name']] = \
405
410
  [int(hoy) for hoy in grid_comply]
406
411
 
407
- array_combinations_filter = np.apply_along_axis(
408
- filter_array, 1, array_combinations, occ_mask
409
- )
410
- max_indices = array_combinations_filter.argmax(axis=0)
411
- # select the combination for each hour
412
+ array_combinations_filter = filter_array2d(array_combinations, occ_mask)
413
+
414
+ max_indices = [int(i) for i in array_combinations_filter.argmax(axis=0)]
412
415
  combinations = [combinations[idx] for idx in max_indices]
413
416
  # merge the combinations of dicts
414
417
  for combination in combinations:
@@ -416,6 +419,8 @@ def leed_states_schedule(
416
419
  if light_path != '__static_apertures__':
417
420
  grid_states_schedule[light_path].append(value)
418
421
 
422
+ del array_list_combinations, array_combinations, array_combinations_filter, combination_arrays
423
+
419
424
  for key, value in grid_states_schedule.items():
420
425
  if key not in states_schedule:
421
426
  states_schedule[key] = value
@@ -502,7 +507,7 @@ def leed_option_one(
502
507
  schedule = occupancy_schedule_8_to_6(as_list=True)
503
508
 
504
509
  if not isinstance(results, AnnualDaylight):
505
- results = AnnualDaylight(results, schedule=schedule, cache_arrays=False)
510
+ results = AnnualDaylight(results, schedule=schedule, cache_arrays=True)
506
511
  else:
507
512
  # set schedule to default leed schedule
508
513
  results.schedule = schedule
@@ -555,8 +560,7 @@ def leed_option_one(
555
560
  for light_path in light_paths:
556
561
  array = results._get_array(
557
562
  grid_info, light_path, res_type='direct')
558
- array_filter = np.apply_along_axis(
559
- filter_array, 1, array, occ_mask)
563
+ array_filter = filter_array2d(array, occ_mask)
560
564
  arrays.append(array_filter)
561
565
  array = sum(arrays)
562
566
  # calculate ase per grid
@@ -575,6 +579,7 @@ def leed_option_one(
575
579
  hours_above.append(h_above)
576
580
  pass_ase = h_above < occ_hours
577
581
  pass_ase_grids.append(pass_ase)
582
+ results.clear_cached_arrays(res_type='direct') # don't need direct arrays
578
583
 
579
584
  # spatial daylight autonomy
580
585
  da_grids = []
@@ -589,42 +594,40 @@ def leed_option_one(
589
594
  pass
590
595
  else:
591
596
  light_paths.append(_lp)
592
- base_zero_array = np.apply_along_axis(filter_array, 1, np.zeros(
593
- (grid_info['count'], len(results.sun_up_hours))), occ_mask)
597
+ base_zero_array = filter_array2d(
598
+ np.zeros((grid_info['count'], len(results.sun_up_hours))), occ_mask)
594
599
  arrays = [base_zero_array.copy()]
595
600
  arrays_blinds_up = [base_zero_array.copy()]
596
601
  arrays_blinds_down = [base_zero_array.copy()]
597
602
  # combine total array for all light paths
598
603
  if use_states:
599
604
  array = results._array_from_states(grid_info, states=states_schedule, zero_array=True)
600
- array = np.apply_along_axis(filter_array, 1, array, occ_mask)
605
+ array = filter_array2d(array, occ_mask)
601
606
 
602
607
  for light_path in light_paths:
603
608
  # do an extra pass to calculate with blinds always up or down
604
609
  if light_path != '__static_apertures__':
605
610
  array_blinds_up = results._get_array(
606
611
  grid_info, light_path, state=0, res_type='total')
607
- array_filter = np.apply_along_axis(
608
- filter_array, 1, array_blinds_up, occ_mask)
612
+ array_filter = filter_array2d(array_blinds_up, occ_mask)
609
613
  arrays_blinds_up.append(array_filter)
610
614
  array_blinds_down = results._get_array(
611
615
  grid_info, light_path, state=1, res_type='total')
612
- array_filter = np.apply_along_axis(
613
- filter_array, 1, array_blinds_down, occ_mask)
616
+ array_filter = filter_array2d(array_blinds_down, occ_mask)
617
+ arrays_blinds_down.append(array_filter)
614
618
  arrays_blinds_down.append(array_filter)
615
619
  else:
616
620
  static_array = results._get_array(
617
621
  grid_info, light_path, state=0, res_type='total')
618
- array_filter = np.apply_along_axis(
619
- filter_array, 1, static_array, occ_mask)
622
+ array_filter = filter_array2d(static_array, occ_mask)
623
+ arrays.append(array_filter)
620
624
  arrays_blinds_up.append(array_filter)
621
625
  arrays_blinds_down.append(array_filter)
622
626
  else:
623
627
  for light_path in light_paths:
624
628
  array = results._get_array(
625
629
  grid_info, light_path, res_type='total')
626
- array_filter = np.apply_along_axis(
627
- filter_array, 1, array, occ_mask)
630
+ array_filter = filter_array2d(array, occ_mask)
628
631
  if light_path != '__static_apertures__':
629
632
  sun_up_hours = np.array(results.sun_up_hours).astype(int)
630
633
  shd_trans_array = states_schedule[light_path][sun_up_hours]
@@ -652,6 +655,7 @@ def leed_option_one(
652
655
  pass_sda_grids.append(da_grid >= target_time)
653
656
  pass_sda_blinds_up_grids.append(da_blinds_up_grid >= target_time)
654
657
  pass_sda_blinds_down_grids.append(da_blinds_down_grid >= target_time)
658
+ results.clear_cached_arrays(res_type='total')
655
659
 
656
660
  # create summaries for all grids and each grid individually
657
661
  summary, summary_grid = _leed_summary(
@@ -701,7 +705,9 @@ def leed_option_one(
701
705
  return hourly_data.to_dict()
702
706
 
703
707
  if use_states:
704
- states_schedule = {k:to_datacollection(k, v['schedule']) for k, v in states_schedule.to_dict().items()}
708
+ states_schedule = {
709
+ k: to_datacollection(k, v['schedule']) for k,
710
+ v in states_schedule.to_dict().items()}
705
711
  else:
706
712
  states_schedule = {k:to_datacollection(k, v) for k, v in states_schedule.items()}
707
713
 
@@ -1,9 +1,14 @@
1
1
  """Module for dynamic LEED schedules."""
2
2
  from typing import Tuple
3
- import numpy as np
3
+ try:
4
+ import cupy as np
5
+ is_gpu = True
6
+ except ImportError:
7
+ is_gpu = False
8
+ import numpy as np
4
9
 
5
10
  from ..results.annual_daylight import AnnualDaylight
6
- from ..util import filter_array
11
+ from ..util import filter_array2d
7
12
 
8
13
 
9
14
  def shd_trans_schedule_descending(
@@ -16,7 +21,7 @@ def shd_trans_schedule_descending(
16
21
  full_shd_trans_array = []
17
22
  for light_path in light_paths:
18
23
  array = results._get_array(grid_info, light_path, res_type="direct")
19
- array = np.apply_along_axis(filter_array, 1, array, occ_mask)
24
+ array = filter_array2d(array, occ_mask)
20
25
  full_direct.append(array)
21
26
  full_thresh.append((array >= 1000).sum(axis=0))
22
27
  full_shd_trans_array.append(shade_transmittances[light_path][1])
@@ -50,6 +55,7 @@ def shd_trans_schedule_descending(
50
55
  # Use the indices to get the relevant hours.
51
56
  thresh = np.take(full_thresh, above_2_indices, axis=1)
52
57
 
58
+ del full_direct, full_thresh
53
59
  # Sort and get indices. Negate the array to get descending order.
54
60
  # Descending order puts the "highest offender" light path first.
55
61
  sort_thresh = np.argsort(-thresh, axis=0).transpose()
@@ -59,6 +65,8 @@ def shd_trans_schedule_descending(
59
65
  0, (np.arange(full_direct_sum.shape[1]), combinations)
60
66
  )
61
67
 
68
+ del full_direct_sum
69
+
62
70
  if np.any(above_2_indices):
63
71
  # There are hours where the percentage of floor area is > 2%.
64
72
  for idx, lp in enumerate(light_paths):
@@ -142,6 +150,8 @@ def shd_trans_schedule_descending(
142
150
 
143
151
  combinations = _combination
144
152
 
153
+ del full_shd_trans_array, direct_sum, direct, thresh, sort_thresh
154
+
145
155
  # Merge the combinations of dicts.
146
156
  for combination in combinations:
147
157
  for light_path, shd_trans in combination.items():
@@ -162,27 +172,26 @@ def states_schedule_descending(
162
172
  for light_path in light_paths:
163
173
  array = results._get_array(
164
174
  grid_info, light_path, state=0, res_type="direct")
165
- array = np.apply_along_axis(filter_array, 1, array, occ_mask)
175
+ array = filter_array2d(array, occ_mask)
166
176
  full_direct.append(array)
167
177
  full_thresh.append((array >= 1000).sum(axis=0))
168
178
 
169
179
  array = results._get_array(
170
180
  grid_info, light_path, state=1, res_type="direct")
171
- array = np.apply_along_axis(filter_array, 1, array, occ_mask)
181
+ array = filter_array2d(array, occ_mask)
172
182
  full_direct_blinds.append(array)
173
183
 
174
184
  full_direct = np.array(full_direct)
175
185
  full_direct_blinds = np.array(full_direct_blinds)
176
186
  full_direct_sum = full_direct.sum(axis=0)
177
187
 
178
- new_array = full_direct.copy()
179
-
180
188
  percentage_sensors = (full_direct_sum >= 1000).sum(axis=0) / grid_count
181
189
  if not np.any(percentage_sensors > 0.02):
182
190
  combinations = [
183
191
  {light_path: 0 for light_path in light_paths}
184
192
  for i in range(full_direct_sum.shape[1])]
185
193
  else:
194
+ new_array = full_direct.copy()
186
195
  tracking_array = np.zeros(
187
196
  (new_array.shape[0], new_array.shape[2]), dtype=int)
188
197
 
@@ -235,6 +244,10 @@ def states_schedule_descending(
235
244
  fail_to_comply[grid_info['name']] = [
236
245
  int(hoy) for hoy in grid_comply]
237
246
 
247
+ del new_array, tracking_array, percentage_sensors, ranking_indices, final_summed_array
248
+
249
+ del full_direct, full_thresh, full_direct_blinds, full_direct_sum
250
+
238
251
  for combination in combinations:
239
252
  for light_path, value in combination.items():
240
253
  if light_path != '__static_apertures__':