Source code for honeybee_plus.radiance.sky.skymatrix

from ladybug.wea import Wea
from ._skyBase import RadianceSky
from ..command.gendaymtx import Gendaymtx
from ..parameters.gendaymtx import GendaymtxParameters
import os


[docs]class SkyMatrix(RadianceSky): """Radiance sky matrix based on an epw weather file. Attributes: wea: An instance of ladybug Wea. sky_density: A positive intger for sky density. [1] Tregenza Sky, [2] Reinhart Sky, etc. (Default: 1) north: An angle in degrees between 0-360 to indicate north direction (Default: 0). hoys: The list of hours for generating the sky matrix (Default: 0..8759). mode: Sky mode 0: total, 1: direct-only, 2: diffuse-only (Default: 0). suffix: An optional suffix for sky name. The suffix will be added at the end of the standard name. Use this input to customize the new and avoid sky being overwritten by other skymatrix components. """ __slots__ = ('_wea', 'hoys', '_sky_type', '_sky_matrixParameters', '_mode', 'suffix') def __init__(self, wea, sky_density=1, north=0, hoys=None, mode=0, suffix=None): """Create sky.""" RadianceSky.__init__(self) self.wea = wea self.hoys = hoys or wea.hoys if not hoys and wea.timestep == 1: # adjust for half an hour so all the annual metric methods work for now # this is a design issue in Honeybee and should be fixed by removing defulting # values to range(8760) self.hoys = [hour - 0.5 for hour in wea.hoys] sky_density = sky_density or 1 self._sky_type = 0 # default to visible radiation self._sky_matrixParameters = GendaymtxParameters(output_type=self._sky_type) self.north = north self.sky_density = sky_density self.mode = mode self.suffix = suffix or ''
[docs] @classmethod def from_json(cls, rec_json): """Create sky from json file { "wea": {}, // ladybug wea schema "sky_density": int, // [1] Tregenza Sky, [2] Reinhart Sky, etc. (Default: 1) "north": float, // Angle in degrees between 0-360 to indicate North "hoys": [], // List of hours for generating the sky "mode": int, // Sky mode, integer between 0 and 2 "suffix": string //Suffix for sky matrix } """ wea = Wea.from_dict(rec_json["wea"]) return cls(wea, rec_json["sky_density"], rec_json["north"], rec_json["hoys"], rec_json["mode"], rec_json["suffix"])
[docs] @classmethod def from_epw_file(cls, epw_file, sky_density=1, north=0, hoys=None, mode=0, suffix=None): """Create sky from an epw file.""" return cls(Wea.from_epw_file(epw_file), sky_density, north, hoys, mode, suffix=suffix)
@property def isSkyMatrix(self): """Return True.""" return True @property def is_climate_based(self): """Return True if the sky is generated from values from weather file.""" return True @property def sky_matrix_parameters(self): """Return sky matrix parameters.""" return self._sky_matrixParameters @property def wea(self): """An instance of ladybug Wea.""" return self._wea @wea.setter def wea(self, w): assert isinstance(w, Wea), \ TypeError('wea must be a WEA object not a {}'.format(type(w))) self._wea = w @property def sky_density(self): """A positive intger for sky density. [1] Tregenza Sky, [2] Reinhart Sky, etc.""" return self._sky_matrixParameters.sky_density @sky_density.setter def sky_density(self, s): sky_density = s or 1 self._sky_matrixParameters.sky_density = sky_density @property def north(self): """An angle in degrees between 0-360 to indicate north direction (Default: 0).""" return self._sky_matrixParameters.rotation @north.setter def north(self, n): north = n or 0 self._sky_matrixParameters.rotation = north @property def mode(self): """Sky mode 0: total, 1: direct-only, 2: diffuse-only (Default: 0).""" return self._mode @mode.setter def mode(self, m): self._mode = m or 0 if self._mode == 0: self._sky_matrixParameters.only_direct = False self._sky_matrixParameters.only_sky = False elif self._mode == 1: self._sky_matrixParameters.only_direct = True self._sky_matrixParameters.only_sky = False elif self._mode == 2: self._sky_matrixParameters.only_direct = False self._sky_matrixParameters.only_sky = True @property def name(self): """Sky default name.""" return "skymtx_{}_r{}_{}_{}_{}_{}_{}{}".format( self.sky_type_human_readable, self.sky_density, self.mode, self.wea.location.station_id, self.wea.location.latitude, self.wea.location.longitude, self.north, '_{}'.format(self.suffix) if self.suffix else '' ) @property def sky_type(self): """Specify 0 for visible radiation, 1 for total solar radiation.""" return self._sky_type @sky_type.setter def sky_type(self, t): """Specify 0 for visible radiation, 1 for total solar radiation.""" self._sky_type = t % 2 self._sky_matrixParameters.output_type = self._sky_type @property def sky_type_human_readable(self): """Human readable sky type.""" values = ('vis', 'sol') return values[self.sky_type]
[docs] def to_json(self): """Create json file from sky matrix { "wea": {}, // ladybug wea schema "sky_density": int, // [1] Tregenza Sky, [2] Reinhart Sky, etc. (Default: 1) "north": float, // Angle in degrees between 0-360 to indicate North "hoys": [], // List of hours for generating the sky "mode": int, // Sky mode, integer between 0 and 2 "suffix": string //Suffix for sky matrix } """ return { "wea": self.wea.to_json(), "sky_density": int(self.sky_density), "north": float(self.north), "hoys": self.hoys, "mode": self.mode, "suffix": self.suffix }
[docs] def hours_match(self, hours_file): """Check if hours in the hours file matches the hours of wea.""" if not os.path.isfile(hours_file): return False with open(hours_file, 'r') as hrf: line = hrf.read() return line == ','.join(str(h) for h in self.hoys) + '\n'
[docs] def write_wea(self, target_dir, write_hours=False): """Write the wea file. WEA carries radiation values from epw and is what gendaymtx uses to generate the sky. Args: target_dir: Path to target directory. write_hours: Write hours in a separate file in folder. """ weafilepath = os.path.join(target_dir, '{}.wea'.format(self.name)) wea = self.wea.filter_by_hoys(self.hoys) return wea.write(weafilepath, write_hours)
[docs] def to_rad_string(self, working_dir, write_hours=False): """Get the radiance command line as a string.""" # check if wea file in available otherwise include the line outfilepath = os.path.join(working_dir, '{}.smx'.format(self.name)) weafilepath = os.path.join(working_dir, '{}.wea'.format(self.name)) # filter hours wea = self.wea.filter_by_hoys(self.hoys) weafilepath = wea.write(weafilepath, write_hours) genday = Gendaymtx(wea_file=weafilepath, output_name=outfilepath) genday.gendaymtx_parameters = self._sky_matrixParameters genday.gendaymtx_parameters.output_type = self.sky_type return genday.to_rad_string()
[docs] def execute(self, working_dir, reuse=True): """Generate sky matrix. Args: working_dir: Folder to execute and write the output. reuse: Reuse the matrix if already existed in the folder. """ outfilepath = os.path.join(working_dir, '{}.smx'.format(self.name)) weafilepath = os.path.join(working_dir, '{}.wea'.format(self.name)) hoursfilepath = weafilepath[:-4] + '.hrs' if reuse and os.path.isfile(outfilepath) and self.hours_match(hoursfilepath): print('Using the same SkyMatrix from an older run.'.format()) return outfilepath else: outfilepath = os.path.join(working_dir, '{}.smx'.format(self.name)) weafilepath = os.path.join(working_dir, '{}.wea'.format(self.name)) weafilepath = self.wea.write(weafilepath) genday = Gendaymtx(wea_file=weafilepath, output_name=outfilepath) genday.gendaymtx_parameters = self._sky_matrixParameters genday.gendaymtx_parameters.output_type = self.sky_type return genday.execute()
[docs] def duplicate(self): """Duplicate this class.""" skymtx = SkyMatrix(self.wea, self.sky_density, self.north, self.hoys, self.mode, self.suffix) skymtx.sky_type = self.sky_type return skymtx
[docs] def ToString(self): """Overwrite .NET ToString method.""" return self.__repr__()
def __repr__(self): """Sky representation.""" return self.name