Source code for honeybee_radiance_command.options.rfluxmtx

import re

from .optionbase import BoolOption
from .rcontrib import RcontribOptions

import honeybee_radiance_command._exception as exceptions


[docs]class RfluxmtxOptions(RcontribOptions): """rcontrib command options.""" __slots__ = ('_v',) def __init__(self): """rcontrib command options.""" RcontribOptions.__init__(self) self._on_setattr_check = False self._v = BoolOption('v', 'verbose report - default: off') self._protected = ('f', 'e', 'p', 'b', 'bn', 'm', 'M') self._on_setattr_check = True def _on_setattr(self): """This method executes after setting each new attribute. Use this method to add checks that are necessary for OptionCollection. For instance in rtrace option collection -ti and -te are exclusive. You can include a check to ensure this is always correct. """ RcontribOptions._on_setattr(self) for opt in self._protected: if getattr(self, opt).is_set: raise exceptions.ProtectedOptionError('rfluxmtx', opt) @property def v(self): """Verbose report - default: off""" return self._v @v.setter def v(self, value): self._v.value = value
[docs]class RfluxmtxControlParameters(object): """Rfluxmtx ControlParameters. Set the values for hemisphere sampling type, hemisphere up direction and output file location. This class generates a string for rflumtx which should be included with a receiver aperture group. Here is a sample rfluxmtx control parmaters: ``#@rfluxmtx u=0,1,0 h=kf o=output.vmx`` Args: sampling_type: Set hemisphere sampling type. Acceptable inputs for hemisphere sampling type are: * u for uniform.(Usually applicable for ground). * kf for klems full. * kh for klems half. * kq for klems quarter. * rN for Reinhart - Tregenza type skies. N stands for subdivisions and defaults to 1. * scN for shirley-chiu subdivisions. Add a ``-`` in front of the input for left-handed coordinates. For more information see rfluxmtx docs. https://www.radiance-online.org/learning/documentation/manual-pages/pdfs/rfluxmtx.pdf/at_download/file up_direction: Orient the "up" direction for the hemisphere using the indicated axis or direction vector using a tuple of 3 numbers. Valid string inputs are [-]{X|Y|Z|ux,uy,uz}. Default: Y output_spec: Send the matrix data for this receiver to the indicated file or command. Single or double quotes may be used to contain strings with spaces, and commands must begin with an exclamation mark (`!`). The file format will be determined by the command-line -fio option and will include an information header unless the -h option was used to turn headers off. (The output file specification is ignored for senders.) """ __slots__ = ('_sampling_type', '_up_direction', '_output_spec') def __init__(self, sampling_type='u', up_direction='Y', output_spec=None): self.sampling_type = sampling_type self.up_direction = up_direction self._output_spec = output_spec
[docs] @classmethod def from_string(cls, value): """Create RfluxmtxControlParameters from a string. Args: value: A string in the format: #@rfluxmtx u=0,1,0 h=kf o=output.vmx """ assert value.startswith('#@rfluxmtx'), \ 'Rfulxmtx control parameters should start with #@rfluxmtx.' # get sampling type segments = value.replace('#@rfluxmtx', '').strip().split(' ') sampling_type = 'u' up_direction = 'Y' output_spec = None for seg in segments: if seg.startswith('h='): sampling_type = seg.replace('h=', '').strip() elif seg.startswith('u='): up_direction = seg.replace('u=', '').strip() elif seg.startswith('o='): output_spec = seg.replace('o=', '').strip() if ',' in up_direction: up_direction = up_direction.split(',') return cls(sampling_type, up_direction, output_spec)
[docs] @classmethod def from_file(cls, path): """Create RfluxmtxControlParameters from a file. Args: path: A file path to a receiver file containing a RfluxmtxControlParameters. """ with open(path, 'r') as f: content = f.read() try: value = re.search(r'^#@rfluxmtx[\s\S].*$', content, re.MULTILINE).group(0) except AttributeError: raise ValueError( '%s is not a valid receiver file with RfluxmtxControlParameters.' % path ) return cls.from_string(value)
@property def sampling_type(self): return self._sampling_type @sampling_type.setter def sampling_type(self, value): if value is None: value = 'u' input_value = 'u' elif value.startswith('-'): input_value = value[1:] else: input_value = value if input_value in ['u', 'kf', 'kh', 'kq']: self._sampling_type = value elif input_value.startswith('r'): self._validate_reinhart_tregenza(input_value) self._sampling_type = value elif input_value.startswith('sc'): self._validate_shirley_chiu(input_value) self._sampling_type = value else: raise ValueError('Invalid sampling type: {}'.format(value)) @staticmethod def _validate_reinhart_tregenza(value): """Validate Reinhart-Tregenza sampling type.""" number_of_subdivisions = value[1:] if not number_of_subdivisions.isdigit(): raise ValueError('Invalid sampling_type: {}'.format(value)) @staticmethod def _validate_shirley_chiu(value): """Validate Shirley-Chiu sampling type.""" number_of_subdivisions = value[2:] if not number_of_subdivisions.isdigit(): raise ValueError('Invalid sampling_type: {}'.format(value)) @property def up_direction(self): """hemisphere direction. The acceptable inputs for hemisphere direction are a tuple with 3 values or 'X', 'Y', 'Z', 'x', 'y', 'z', '-X', '-Y','-Z', '-x', '-y','-z'.""" return self._up_direction @up_direction.setter def up_direction(self, value): if value is None: self._up_direction = 'Y' elif value in ('X', 'Y', 'Z', 'x', 'y', 'z', '-X', '-Y', '-Z', '-x', '-y', '-z', '+X', '+Y', '+Z', '+x', "+y", "+z"): self._up_direction = value elif isinstance(value, (tuple, list)): assert len(value) == 3, 'The length of the up direction vector must be 3.' self._up_direction = ','.join((str(v) for v in value)) else: raise ValueError('Invalid up direction: {}'.format(value)) @property def output_spec(self): """ Send the matrix data for this receiver to the indicated file or command. Single or double quotes may be used to contain strings with spaces, and commands must begin with an exclamation mark (`!`). The file format will be determined by the command-line -fio option and will include an information header unless the -h option was used to turn headers off. (The output file specification is ignored for senders.) """ return self._output_spec def __repr__(self): output_spec = 'o=%s' % self.output_spec if self.output_spec else '' spec = '#@rfluxmtx h=%s u=%s %s' % (self.sampling_type, self.up_direction, output_spec) return spec.strip()
[docs] def to_radiance(self): """Return a radiance definition as a string.""" return self.__repr__()