def from_dict(cls, data): """Create RadianceSubFaceState from a dictionary. Note that the dictionary must be a non-abridged version for this classmethod to work. Args: data: A dictionary representation of RadianceSubFaceState with the format below. .. code-block:: python { 'type': 'RadianceSubFaceState', 'modifier': {}, # A Honeybee Radiance Modifier dictionary 'shades': [], # A list of abridged StateGeometry dictionaries 'modifier_direct': {}, # A Honeybee Radiance Modifier dictionary 'vmtx_geometry': {}, # A Face3D for the view matrix geometry 'dmtx_geometry': {} # A Face3D for the daylight matrix geometry } """ assert data['type'] == 'RadianceSubFaceState', \ 'Expected RadianceSubFaceState. Got {}.'.format(data['type']) new_state = cls() if 'modifier' in data and data['modifier'] is not None: new_state.modifier = dict_to_modifier(data['modifier']) if 'shades' in data and data['shades'] is not None: new_state.shades = [StateGeometry.from_dict(shd) for shd in data['shades']] if 'modifier_direct' in data and data['modifier_direct'] is not None: new_state.modifier_direct = dict_to_modifier(data['modifier_direct']) if 'vmtx_geometry' in data and data['vmtx_geometry'] is not None: new_state.vmtx_geometry = Face3D.from_dict(data['vmtx_geometry']) if 'dmtx_geometry' in data and data['dmtx_geometry'] is not None: new_state.dmtx_geometry = Face3D.from_dict(data['dmtx_geometry']) return new_state
def from_dict(cls, data): """Initialize an Aperture from a dictionary. Args: data: A dictionary representation of an Aperture object. """ # check the type of dictionary assert data['type'] == 'Aperture', 'Expected Aperture dictionary. ' \ 'Got {}.'.format(data['type']) # serialize the aperture is_operable = data['is_operable'] if 'is_operable' in data else False if data['boundary_condition']['type'] == 'Outdoors': boundary_condition = Outdoors.from_dict(data['boundary_condition']) elif data['boundary_condition']['type'] == 'Surface': boundary_condition = Surface.from_dict(data['boundary_condition'], True) else: raise ValueError( 'Boundary condition "{}" is not supported for Apertures.'. format(data['boundary_condition']['type'])) aperture = cls(data['identifier'], Face3D.from_dict(data['geometry']), boundary_condition, is_operable) if 'display_name' in data and data['display_name'] is not None: aperture.display_name = data['display_name'] if 'user_data' in data and data['user_data'] is not None: aperture.user_data = data['user_data'] aperture._recover_shades_from_dict(data) # assign extension properties if data['properties']['type'] == 'ApertureProperties': aperture.properties._load_extension_attr_from_dict( data['properties']) return aperture
def from_dict(cls, data): """Initialize an Door from a dictionary. Args: data: A dictionary representation of an Door object. """ # check the type of dictionary assert data['type'] == 'Door', 'Expected Door dictionary. ' \ 'Got {}.'.format(data['type']) is_glass = data['is_glass'] if 'is_glass' in data else False if data['boundary_condition']['type'] == 'Outdoors': boundary_condition = Outdoors.from_dict(data['boundary_condition']) elif data['boundary_condition']['type'] == 'Surface': boundary_condition = Surface.from_dict(data['boundary_condition'], True) else: raise ValueError( 'Boundary condition "{}" is not supported for Door.'.format( data['boundary_condition']['type'])) door = cls(data['name'], Face3D.from_dict(data['geometry']), boundary_condition, is_glass) if 'display_name' in data and data['display_name'] is not None: door._display_name = data['display_name'] if data['properties']['type'] == 'DoorProperties': door.properties._load_extension_attr_from_dict(data['properties']) return door
def from_dict(cls, ag_dict): """Create a sensor grid from a dictionary in the following format. .. code-block:: python { "type": "SensorGrid", "identifier": str, # SensorGrid identifier "display_name": str, # SensorGrid display name "sensors": [], # list of Sensor dictionaries 'room_identifier': str, # optional room identifier 'group_identifier': str, # optional group identifier 'light_path': [] # optional list of lists for light path } """ assert ag_dict['type'] == 'SensorGrid', \ 'Expected SensorGrid dictionary. Got {}.'.format(ag_dict['type']) sensors = (Sensor.from_dict(sensor) for sensor in ag_dict['sensors']) new_obj = cls(identifier=ag_dict["identifier"], sensors=sensors) if 'display_name' in ag_dict and ag_dict['display_name'] is not None: new_obj.display_name = ag_dict['display_name'] if 'room_identifier' in ag_dict and ag_dict[ 'room_identifier'] is not None: new_obj.room_identifier = ag_dict['room_identifier'] if 'group_identifier' in ag_dict and ag_dict[ 'group_identifier'] is not None: new_obj.group_identifier = ag_dict['group_identifier'] if 'light_path' in ag_dict and ag_dict['light_path'] is not None: new_obj.light_path = ag_dict['light_path'] if 'mesh' in ag_dict and ag_dict['mesh'] is not None: new_obj.mesh = Mesh3D.from_dict(ag_dict['mesh']) if 'base_geometry' in ag_dict and ag_dict['base_geometry'] is not None: new_obj.base_geometry = \ tuple(Face3D.from_dict(face) for face in ag_dict['base_geometry']) return new_obj
def from_dict(cls, data): """Initialize a Terrain from a dictionary. Args: data: A dictionary representation of a Terrain object in the format below. .. code-block:: python { "type": 'Terrain', "geometry": [], # array for Face3D for the terrain surface "pavement_albedo": 0.15, # number for the pavement albedo "pavement_thickness": 0.75, # pavement thickness in meters "pavement_conductivity": 1.0, # pavement conductivity in W/m2-K "pavement_heat_capacity": 1600000 # volumetric heat capacity in J/m3-K } """ # check the type of dictionary assert data['type'] == 'Terrain', 'Expected Terrain dictionary. ' \ 'Got {}.'.format(data['type']) # process the geometry geometry = tuple(Face3D.from_dict(geo) for geo in data['geometry']) # process the other parameters alb = data['pavement_albedo'] if 'pavement_albedo' in data else 0.1 thick = data[ 'pavement_thickness'] if 'pavement_thickness' in data else 0.5 cond = data[ 'pavement_conductivity'] if 'pavement_conductivity' in data else 1.0 h_cap = data['pavement_heat_capacity'] \ if 'pavement_heat_capacity' in data else 1.6e6 return cls(geometry, alb, thick, cond, h_cap)
def from_dict_abridged(cls, data, modifiers): """Create StateGeometry from an abridged dictionary. Args: data: A dictionary representation of StateGeometryAbridged with the format below. modifiers: A dictionary of modifiers with modifier identifiers as keys, which will be used to re-assign modifiers. .. code-block:: python { 'type': 'StateGeometryAbridged', 'identifier': str, # Text for the unique object identifier 'display_name': str, # Optional text for the display name 'geometry': {}, # A ladybug_geometry Face3D dictionary 'modifier': str # A Honeybee Radiance Modifier identifier 'modifier_direct': str # A Honeybee Radiance Modifier identifier } """ # check the type of dictionary assert data['type'] == 'StateGeometryAbridged', \ 'Expected StateGeometryAbridged dictionary. Got {}.'.format(data['type']) geo = cls(data['identifier'], Face3D.from_dict(data['geometry'])) if 'modifier' in data and data['modifier'] is not None: geo.modifier = modifiers[data['modifier']] if 'modifier_direct' in data and data['modifier_direct'] is not None: geo.modifier_direct = modifiers[data['modifier_direct']] if 'display_name' in data and data['display_name'] is not None: geo.display_name = data['display_name'] return geo
def from_dict(cls, data): """Initialize a StateGeometry from a dictionary. Note that the dictionary must be a non-abridged version for this classmethod to work. Args: data: A dictionary representation of an StateGeometry with the format below. .. code-block:: python { 'type': 'StateGeometry', 'identifier': str, # Text for the unique object identifier 'display_name': str, # Optional text for the display name 'geometry': {}, # A ladybug_geometry Face3D dictionary 'modifier': {}, # A Honeybee Radiance Modifier dictionary 'modifier_direct': {} # A Honeybee Radiance Modifier dictionary } """ # check the type of dictionary assert data['type'] == 'StateGeometry', 'Expected StateGeometry dictionary. ' \ 'Got {}.'.format(data['type']) geo = cls(data['identifier'], Face3D.from_dict(data['geometry'])) if 'modifier' in data and data['modifier'] is not None: geo.modifier = dict_to_modifier(data['modifier']) if 'modifier_direct' in data and data['modifier_direct'] is not None: geo.modifier_direct = dict_to_modifier(data['modifier_direct']) if 'display_name' in data and data['display_name'] is not None: geo.display_name = data['display_name'] return geo
def test_face3d_to_from_dict(): """Test the to/from dict of Face3D objects.""" pts = (Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 0, 2)) plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2)) face = Face3D(pts, plane) face_dict = face.to_dict() new_face = Face3D.from_dict(face_dict) assert isinstance(new_face, Face3D) assert new_face.to_dict() == face_dict bound_pts = [Point3D(0, 0), Point3D(4, 0), Point3D(4, 4), Point3D(0, 4)] hole_pts = [Point3D(1, 1), Point3D(3, 1), Point3D(3, 3), Point3D(1, 3)] face = Face3D(bound_pts, None, [hole_pts]) face_dict = face.to_dict() new_face = Face3D.from_dict(face_dict) assert isinstance(new_face, Face3D) assert new_face.to_dict() == face_dict
def from_dict_abridged(cls, data, modifiers): """Create RadianceSubFaceState from an abridged dictionary. Note that the dictionary must be a non-abridged version for this classmethod to work. Args: data: A dictionary representation of RadianceSubFaceStateAbridged with the format below. modifiers: A dictionary of modifiers with modifier identifiers as keys, which will be used to re-assign modifiers. .. code-block:: python { 'type': 'RadianceSubFaceStateAbridged', 'modifier': str, # An identifier of a honeybee-radiance modifier 'shades': [], # A list of abridged StateGeometry dictionaries 'modifier_direct': str, # An identifier of a honeybee-radiance modifier 'vmtx_geometry': {}, # A Face3D for the view matrix geometry 'dmtx_geometry': {} # A Face3D for the daylight matrix geometry } """ assert data['type'] == 'RadianceSubFaceStateAbridged', \ 'Expected RadianceSubFaceStateAbridged. Got {}.'.format(data['type']) new_state = cls() if 'modifier' in data and data['modifier'] is not None: new_state.modifier = modifiers[data['modifier']] if 'shades' in data and data['shades'] is not None: new_state.shades = [StateGeometry.from_dict_abridged(shd, modifiers) for shd in data['shades']] if 'modifier_direct' in data and data['modifier_direct'] is not None: new_state.modifier_direct = modifiers[data['modifier_direct']] if 'vmtx_geometry' in data and data['vmtx_geometry'] is not None: new_state.vmtx_geometry = Face3D.from_dict(data['vmtx_geometry']) if 'dmtx_geometry' in data and data['dmtx_geometry'] is not None: new_state.dmtx_geometry = Face3D.from_dict(data['dmtx_geometry']) return new_state
def from_dict(cls, data): """Initialize an Shade from a dictionary. Args: data: A dictionary representation of an Shade object. """ # check the type of dictionary assert data['type'] == 'Shade', 'Expected Shade dictionary. ' \ 'Got {}.'.format(data['type']) shade = cls(data['name'], Face3D.from_dict(data['geometry'])) if 'display_name' in data and data['display_name'] is not None: shade._display_name = data['display_name'] if data['properties']['type'] == 'ShadeProperties': shade.properties._load_extension_attr_from_dict(data['properties']) return shade
def from_dict(cls, data): """Initialize an ContextShade from a dictionary. Args: data: A dictionary representation of an ContextShade object. """ # check the type of dictionary assert data['type'] == 'ContextShade', 'Expected ContextShade dictionary. ' \ 'Got {}.'.format(data['type']) geometry = tuple( Face3D.from_dict(shd_geo) for shd_geo in data['geometry']) shade = cls(data['identifier'], geometry) if 'display_name' in data and data['display_name'] is not None: shade.display_name = data['display_name'] if 'user_data' in data and data['user_data'] is not None: shade.user_data = data['user_data'] if data['properties']['type'] == 'ContextShadeProperties': shade.properties._load_extension_attr_from_dict(data['properties']) return shade
def from_dict(cls, _dict): new_obj = cls() new_obj.quantity = _dict.get('quantity') new_obj._tolerance = _dict.get('_tolerance') new_obj.aperture = Aperture.from_dict( _dict.get('aperture') ) new_obj._shading_factor_winter =_dict.get('_shading_factor_winter') new_obj._shading_factor_summer =_dict.get('_shading_factor_summer') new_obj._glazing_edge_lengths = _dict.get('_glazing_edge_lengths') new_obj.variant_type = _dict.get('variant_type') new_obj.install_depth = _dict.get('install_depth') #---- _edges = _dict.get('_window_edges', {}) _left = _edges.get('Left') _left = LineSegment3D.from_dict( _left ) _right = _edges.get('Right') _right = LineSegment3D.from_dict( _right ) _bottom = _edges.get('Bottom') _bottom = LineSegment3D.from_dict( _bottom ) _top = _edges.get('Top') _top = LineSegment3D.from_dict( _top ) new_obj._window_edges = cls.Output(_left, _right, _bottom, _top) #---- _glazing_surface = _dict.get('_glazing_surface') _glazing_surface = Face3D.from_dict(_glazing_surface) _glazing_surface = from_face3d(_glazing_surface) new_obj._glazing_surface = _glazing_surface new_obj.frame = LBT2PH.windows.PHPP_Frame.from_dict( _dict.get('_frame') ) new_obj.glazing = LBT2PH.windows.PHPP_Glazing.from_dict( _dict.get('_glazing') ) new_obj.installs = LBT2PH.windows.PHPP_Installs.from_dict( _dict.get('_installs') ) new_obj.shading_dimensions = LBT2PH.shading.PHPP_Shading_Dims.from_dict( _dict.get('shading_dimensions') ) return new_obj
def from_dict(cls, data): """Initialize an Face from a dictionary. Args: data: A dictionary representation of an Face object. """ # check the type of dictionary assert data['type'] == 'Face', 'Expected Face dictionary. ' \ 'Got {}.'.format(data['type']) face_type = face_types.by_name(data['face_type']) try: bc_class = getattr(hbc, data['boundary_condition']['type']) except AttributeError: raise ValueError( 'Boundary condition "{}" is not supported in this honyebee ' 'installation.'.format(data['boundary_condition']['type'])) bc = bc_class.from_dict(data['boundary_condition']) face = cls(data['name'], Face3D.from_dict(data['geometry']), face_type, bc) if 'display_name' in data and data['display_name'] is not None: face._display_name = data['display_name'] # add sub-faces and shades to faces if 'apertures' in data and data['apertures'] is not None: face._apertures = [ Aperture.from_dict(ap) for ap in data['apertures'] ] for ap in face._apertures: ap._parent = face if 'doors' in data and data['doors'] is not None: face._doors = [Door.from_dict(dr) for dr in data['doors']] for dr in face._doors: dr._parent = face face._recover_shades_from_dict(data) if data['properties']['type'] == 'FaceProperties': face.properties._load_extension_attr_from_dict(data['properties']) return face
def test_init_solar_envelope(): """Test the initialization of Sunpath and basic properties.""" # get sun positions sunpath = Sunpath(latitude=40.72, longitude=-74.02) sun_vecs = [] for hour in range(8, 16): sun = sunpath.calculate_sun(12, 21, hour) sun_vecs.append(sun.sun_vector) # load the site and the context site_mesh_file = './tests/assets/geo/mesh.json' with open(site_mesh_file) as json_file: site_mesh_data = json.load(json_file) site_mesh = Mesh3D.from_dict(site_mesh_data) context_file = './tests/assets/geo/faces.json' with open(context_file) as json_file: context_data = json.load(json_file) context_faces = [Face3D.from_dict(con) for con in context_data] # initialize solar envelope envelope = SolarEnvelope(site_mesh, context_faces, sun_vecs, solar_rights=True) str(envelope) # test the string representation envelope_mesh = envelope.envelope_mesh() assert isinstance(envelope_mesh, Mesh3D)