forked from s_ranjbar/city_retrofit
Small corrections in doe_idf import
This commit is contained in:
parent
2780dd5b7e
commit
5752c5d31d
|
@ -240,14 +240,14 @@ class City:
|
|||
"""
|
||||
Save a city into the given filename
|
||||
:param city_filename: destination city filename
|
||||
:return:
|
||||
:return: None
|
||||
"""
|
||||
with open(city_filename, 'wb') as file:
|
||||
pickle.dump(self, file)
|
||||
|
||||
def region(self, center, radius) -> City:
|
||||
"""
|
||||
Save a city into the given filename
|
||||
Get a region from the city
|
||||
:param center: specific point in space [x, y, z]
|
||||
:param radius: distance to center of the sphere selected in meters
|
||||
:return: selected_region_city
|
||||
|
|
|
@ -7,7 +7,6 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
import math
|
||||
from typing import List, Union
|
||||
|
||||
|
||||
from city_model_structure.iot.sensor import Sensor
|
||||
from city_model_structure.building_demand.surface import Surface
|
||||
from city_model_structure.attributes.polyhedron import Polyhedron
|
||||
|
@ -38,7 +37,7 @@ class CityObject:
|
|||
self._sensors = []
|
||||
|
||||
@property
|
||||
def lod(self):
|
||||
def lod(self) -> int:
|
||||
"""
|
||||
Get city object level of detail 1, 2, 3 or 4
|
||||
:return: int
|
||||
|
@ -47,7 +46,7 @@ class CityObject:
|
|||
return lod
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
def type(self) -> str:
|
||||
"""
|
||||
Get city object type
|
||||
:return: str
|
||||
|
@ -55,7 +54,7 @@ class CityObject:
|
|||
return self._type
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
def volume(self) -> float:
|
||||
"""
|
||||
Get city object volume in cubic meters
|
||||
:return: float
|
||||
|
@ -132,7 +131,7 @@ class CityObject:
|
|||
return self._centroid
|
||||
|
||||
@property
|
||||
def max_height(self):
|
||||
def max_height(self) -> float:
|
||||
"""
|
||||
Get city object maximal height in meters
|
||||
:return: float
|
||||
|
@ -140,7 +139,7 @@ class CityObject:
|
|||
return self.simplified_polyhedron.max_z
|
||||
|
||||
@property
|
||||
def external_temperature(self) -> dict:
|
||||
def external_temperature(self) -> {float}:
|
||||
"""
|
||||
Get external temperature surrounding the city object in Celsius
|
||||
:return: dict{DataFrame(float)}
|
||||
|
|
|
@ -2,82 +2,82 @@
|
|||
<archetypes reference_library_building_type="DOE">
|
||||
<archetypes ID="0" building_type="high-rise apartment" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_ApartmentHighRise_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_OfficeSmall_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="1" building_type="midrise apartment" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_ApartmentMidRise_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_ApartmentMidRise_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="2" building_type="hospital" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_Hospital_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_Hospital_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="3" building_type="large hotel" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_HotelLarge_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_HotelLarge_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="4" building_type="small hotel" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_HotelSmall_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_HotelSmall_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="5" building_type="large office" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_OfficeLarge_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_OfficeLarge_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="6" building_type="medium office" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_OfficeMedium_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_OfficeMedium_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="7" building_type="small office" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_OfficeSmall_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_OfficeSmall_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="8" building_type="outpatient healthcare" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_OutPatientHealthCare_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_OutPatientHealthCare_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="9" building_type="quick service restaurant" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_RestaurantFastFood_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_RestaurantFastFood_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="10" building_type="full service restaurant" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_RestaurantSitDown_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_RestaurantSitDown_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="11" building_type="stand-alone-retail" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_RetailStandalone_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_RetailStandalone_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="12" building_type="strip mall" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_RetailStripmall_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_RetailStripmall_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="13" building_type="primary school" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_SchoolPrimary_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_SchoolPrimary_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="14" building_type="secondary school" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_SchoolSecondary_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_SchoolSecondary_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
<archetypes ID="15" building_type="warehouse" reference_standard="ASHRAE 90.1-2019" climate_zone="ASHRAE_2009:6A">
|
||||
<idf>
|
||||
<path>data/schedules/idf_files/ASHRAE901_Warehouse_STD2019_Rochester.idf</path>
|
||||
<path>idf_files/ASHRAE901_Warehouse_STD2019_Rochester.idf</path>
|
||||
</idf>
|
||||
</archetypes>
|
||||
</archetypes>
|
||||
|
|
|
@ -6,6 +6,7 @@ Copyright © 2020 Project
|
|||
import pandas as pd
|
||||
import parseidf
|
||||
import xmltodict
|
||||
from imports.schedules.helpers.schedules_helper import SchedulesHelper
|
||||
|
||||
|
||||
class DoeIdf:
|
||||
|
@ -21,7 +22,7 @@ class DoeIdf:
|
|||
_SCHEDULE_COMPACT_TYPE = 'SCHEDULE:COMPACT'
|
||||
_SCHEDULE_TYPE_NAME = 1
|
||||
|
||||
def __init__(self, city, base_path):
|
||||
def __init__(self, city, base_path, doe_idf_file):
|
||||
self._hours = []
|
||||
panda_hours = pd.timedelta_range(0, periods=24, freq='H')
|
||||
for _, hour in enumerate(panda_hours):
|
||||
|
@ -29,20 +30,22 @@ class DoeIdf:
|
|||
self._city = city
|
||||
|
||||
path = str(base_path / doe_idf_file)
|
||||
print(path)
|
||||
with open(path) as xml:
|
||||
self._library = xmltodict.parse(xml.read())
|
||||
for archetype in self._library['archetypes']['archetypes']:
|
||||
self._archetype_keys = {}
|
||||
for key, value in archetype.items():
|
||||
if key[0] == '@':
|
||||
archetype_keys[key] = value
|
||||
self._schedule_library = xmltodict.parse(xml.read())
|
||||
|
||||
self._idf_schedules_path = archetype['idf']['path']
|
||||
with open(self._idf_schedules_path, 'r') as file:
|
||||
idf = parseidf.parse(file.read())
|
||||
self._load_schedule(idf, archetype_keys['@building_type'])
|
||||
for building in self._city.buildings:
|
||||
for usage_zone in building.usage_zones:
|
||||
for schedule_archetype in self._schedule_library['archetypes']['archetypes']:
|
||||
function = schedule_archetype['@building_type']
|
||||
if SchedulesHelper.usage_from_function(function) == usage_zone.usage:
|
||||
self._idf_schedules_path = (base_path / schedule_archetype['idf']['path']).resolve()
|
||||
with open(self._idf_schedules_path, 'r') as file:
|
||||
idf = parseidf.parse(file.read())
|
||||
self._load_schedule(idf, usage_zone)
|
||||
break
|
||||
|
||||
def _load_schedule(self, idf, building_usage):
|
||||
def _load_schedule(self, idf, usage_zone):
|
||||
schedules_day = {}
|
||||
for compact_schedule in idf[self._SCHEDULE_COMPACT_TYPE]:
|
||||
if compact_schedule[self._SCHEDULE_TYPE_NAME] in self.idf_schedule_to_comnet_schedule:
|
||||
|
@ -116,9 +119,6 @@ class DoeIdf:
|
|||
else:
|
||||
continue
|
||||
df = pd.DataFrame(data, index=rows)
|
||||
for building in self._city.buildings:
|
||||
for usage_zone in building.usage_zones:
|
||||
if usage_zone.usage == building_usage:
|
||||
if usage_zone.schedules is None:
|
||||
usage_zone.schedules = {}
|
||||
usage_zone.schedules[schedule_type] = df
|
||||
if usage_zone.schedules is None:
|
||||
usage_zone.schedules = {}
|
||||
usage_zone.schedules[schedule_type] = df
|
||||
|
|
|
@ -31,6 +31,30 @@ class SchedulesHelper:
|
|||
'Temperature': cte.TEMPERATURE
|
||||
}
|
||||
|
||||
# usage
|
||||
function_to_usage = {
|
||||
'full service restaurant': 'restaurant',
|
||||
'high-rise apartment': cte.RESIDENTIAL,
|
||||
'hospital': 'health care',
|
||||
'large hotel': 'hotel',
|
||||
'large office': 'office and administration',
|
||||
'medium office': 'office and administration',
|
||||
'midrise apartment': cte.RESIDENTIAL,
|
||||
'outpatient healthcare': 'health care',
|
||||
'primary school': 'education',
|
||||
'quick service restaurant': 'restaurant',
|
||||
'secondary school': 'education',
|
||||
'small hotel': 'hotel',
|
||||
'small office': 'office and administration',
|
||||
'stand-alone-retail': 'retail',
|
||||
'strip mall': 'hall',
|
||||
'supermarket': 'retail',
|
||||
'warehouse': 'industry',
|
||||
'residential': cte.RESIDENTIAL
|
||||
}
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def comnet_from_usage(usage):
|
||||
"""
|
||||
|
@ -55,3 +79,12 @@ class SchedulesHelper:
|
|||
return SchedulesHelper.comnet_to_data_type[comnet_data_type]
|
||||
except KeyError:
|
||||
raise ValueError(f"Error: comnet data type keyword not found.")
|
||||
|
||||
@staticmethod
|
||||
def usage_from_function(building_function):
|
||||
"""
|
||||
Get the internal usage for the given internal building function
|
||||
:param building_function: str
|
||||
:return: str
|
||||
"""
|
||||
return SchedulesHelper.function_to_usage[building_function]
|
||||
|
|
|
@ -27,7 +27,7 @@ class SchedulesFactory:
|
|||
ComnetSchedules(self._city, self._base_path)
|
||||
|
||||
def _doe_idf(self):
|
||||
DoeIdf(self._city, self._base_path)
|
||||
DoeIdf(self._city, self._base_path, 'doe_idf.xml')
|
||||
|
||||
def enrich(self):
|
||||
"""
|
||||
|
|
41
unittests/test_doe_idf.py
Normal file
41
unittests/test_doe_idf.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
"""
|
||||
Building test
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez Morote Guillermo.GutierrezMorote@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.schedules_factory import SchedulesFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from exports.exports_factory import ExportsFactory
|
||||
|
||||
|
||||
class TestBuildings(TestCase):
|
||||
"""
|
||||
TestBuilding TestCase 1
|
||||
"""
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Test setup
|
||||
:return: None
|
||||
"""
|
||||
self._city_gml = None
|
||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||
|
||||
def test_doe_idf(self):
|
||||
city_file = "../unittests/tests_data/C40_Final.gml"
|
||||
output_path = Path('../unittests/tests_outputs/').resolve()
|
||||
city = GeometryFactory('citygml', city_file).city
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
UsageFactory('ca', city).enrich()
|
||||
SchedulesFactory('doe_idf', city).enrich()
|
||||
ExportsFactory('idf', city, output_path).export()
|
||||
self.assertEqual(10, len(city.buildings))
|
||||
for building in city.buildings:
|
||||
self.assertTrue(len(building.usage_zones) > 0)
|
||||
for usage_zone in building.usage_zones:
|
||||
self.assertTrue('Lights' in usage_zone.schedules)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user