Small corrections in doe_idf import

This commit is contained in:
Guille Gutierrez 2021-09-16 13:45:27 -04:00
parent 2780dd5b7e
commit 5752c5d31d
7 changed files with 116 additions and 43 deletions

View File

@ -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

View File

@ -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)}

View File

@ -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>

View File

@ -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

View File

@ -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]

View File

@ -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
View 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)