forked from s_ranjbar/city_retrofit
Added the importer for sra results
This commit is contained in:
parent
d91b6edfff
commit
11e8949b30
|
@ -101,13 +101,19 @@ class City:
|
||||||
"""
|
"""
|
||||||
return self._get_location().country
|
return self._get_location().country
|
||||||
|
|
||||||
|
@property
|
||||||
|
def location(self):
|
||||||
|
return self._get_location().city
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
Get city name
|
Get city name
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
return self._get_location().city
|
if self._name is None:
|
||||||
|
return self._get_location().city
|
||||||
|
return self._name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def climate_reference_city(self) -> Union[None, str]:
|
def climate_reference_city(self) -> Union[None, str]:
|
||||||
|
|
|
@ -17,7 +17,11 @@ class ExportsFactory:
|
||||||
"""
|
"""
|
||||||
Exports factory class
|
Exports factory class
|
||||||
"""
|
"""
|
||||||
def __init__(self, export_type, city, path, target_buildings=None, adjacent_buildings=None):
|
def __init__(self, export_type, city, path,
|
||||||
|
target_buildings=None,
|
||||||
|
adjacent_buildings=None,
|
||||||
|
weather_file=None,
|
||||||
|
weather_format=None):
|
||||||
self._city = city
|
self._city = city
|
||||||
self._export_type = '_' + export_type.lower()
|
self._export_type = '_' + export_type.lower()
|
||||||
class_funcs = validate_import_export_type(ExportsFactory)
|
class_funcs = validate_import_export_type(ExportsFactory)
|
||||||
|
@ -30,6 +34,8 @@ class ExportsFactory:
|
||||||
self._path = path
|
self._path = path
|
||||||
self._target_buildings = target_buildings
|
self._target_buildings = target_buildings
|
||||||
self._adjacent_buildings = adjacent_buildings
|
self._adjacent_buildings = adjacent_buildings
|
||||||
|
self._weather_file = weather_file
|
||||||
|
self._weather_format = weather_format
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _citygml(self):
|
def _citygml(self):
|
||||||
|
@ -73,7 +79,10 @@ class ExportsFactory:
|
||||||
Export the city to Simplified Radiosity Algorithm xml format
|
Export the city to Simplified Radiosity Algorithm xml format
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
return SimplifiedRadiosityAlgorithm(self._city, (self._path / f'{self._city.name}_sra.xml'),
|
return SimplifiedRadiosityAlgorithm(self._city,
|
||||||
|
(self._path / f'{self._city.name}_sra.xml'),
|
||||||
|
self._weather_file,
|
||||||
|
self._weather_format,
|
||||||
target_buildings=self._target_buildings)
|
target_buildings=self._target_buildings)
|
||||||
|
|
||||||
def export(self):
|
def export(self):
|
||||||
|
|
|
@ -6,12 +6,25 @@ Project Coder Guillermo.GutierrezMorote@concordia.ca
|
||||||
"""
|
"""
|
||||||
import xmltodict
|
import xmltodict
|
||||||
|
|
||||||
|
from hub.imports.weather_factory import WeatherFactory
|
||||||
|
import hub.helpers.constants as cte
|
||||||
|
|
||||||
|
|
||||||
class SimplifiedRadiosityAlgorithm:
|
class SimplifiedRadiosityAlgorithm:
|
||||||
"""
|
"""
|
||||||
Export to SRA format
|
Export to SRA format
|
||||||
"""
|
"""
|
||||||
def __init__(self, city, file_name, target_buildings=None, begin_month=1, begin_day=1, end_month=12, end_day=31):
|
|
||||||
|
def __init__(self,
|
||||||
|
city,
|
||||||
|
file_name,
|
||||||
|
weather_file,
|
||||||
|
weather_format,
|
||||||
|
target_buildings=None,
|
||||||
|
begin_month=1,
|
||||||
|
begin_day=1,
|
||||||
|
end_month=12,
|
||||||
|
end_day=31):
|
||||||
self._file_name = file_name
|
self._file_name = file_name
|
||||||
self._begin_month = begin_month
|
self._begin_month = begin_month
|
||||||
self._begin_day = begin_day
|
self._begin_day = begin_day
|
||||||
|
@ -19,6 +32,8 @@ class SimplifiedRadiosityAlgorithm:
|
||||||
self._end_day = end_day
|
self._end_day = end_day
|
||||||
self._city = city
|
self._city = city
|
||||||
self._target_buildings = target_buildings
|
self._target_buildings = target_buildings
|
||||||
|
self._weather_format = weather_format
|
||||||
|
self._weather_file = weather_file
|
||||||
self._export()
|
self._export()
|
||||||
|
|
||||||
def _correct_point(self, point):
|
def _correct_point(self, point):
|
||||||
|
@ -29,6 +44,34 @@ class SimplifiedRadiosityAlgorithm:
|
||||||
return [x, y, z]
|
return [x, y, z]
|
||||||
|
|
||||||
def _export(self):
|
def _export(self):
|
||||||
|
self._export_sra_xml()
|
||||||
|
self._export_sra_cli()
|
||||||
|
|
||||||
|
def _export_sra_cli(self):
|
||||||
|
file = self._city.climate_file
|
||||||
|
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||||
|
WeatherFactory(self._weather_format, self._city, file_name=self._weather_file).enrich()
|
||||||
|
content = self._city.name + '\n'
|
||||||
|
content += str(self._city.latitude) + ',' + str(self._city.longitude) + ',0.0,' + str(self._city.time_zone) + '\n'
|
||||||
|
content += '\ndm m h G_Dh G_Bn\n'
|
||||||
|
total_days = 0
|
||||||
|
for month in range(1, 13):
|
||||||
|
if month > 1:
|
||||||
|
total_days += days_in_month[month - 2]
|
||||||
|
for day in range(1, days_in_month[month - 1] + 1):
|
||||||
|
for hour in range(1, 25):
|
||||||
|
if month == 1:
|
||||||
|
i = 24 * (day - 1) + hour - 1
|
||||||
|
else:
|
||||||
|
i = (total_days + day - 1) * 24 + hour - 1
|
||||||
|
representative_building = self._city.buildings[0]
|
||||||
|
content += str(day) + ' ' + str(month) + ' ' + str(hour) + ' ' \
|
||||||
|
+ str(representative_building.global_horizontal[cte.HOUR].epw[i]) + ' ' \
|
||||||
|
+ str(representative_building.beam[cte.HOUR].epw[i]) + '\n'
|
||||||
|
with open(file, "w") as file:
|
||||||
|
file.write(content)
|
||||||
|
|
||||||
|
def _export_sra_xml(self):
|
||||||
buildings = []
|
buildings = []
|
||||||
for building_index, building in enumerate(self._city.buildings):
|
for building_index, building in enumerate(self._city.buildings):
|
||||||
if self._target_buildings is None:
|
if self._target_buildings is None:
|
||||||
|
|
92
hub/imports/results/simplified_radiosity_algorithm.py
Normal file
92
hub/imports/results/simplified_radiosity_algorithm.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
"""
|
||||||
|
Simplified Radiosity Algorithm
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2022 Concordia CERC group
|
||||||
|
Project Coder Guillermo.GutierrezMorote@concordia.ca
|
||||||
|
"""
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
import calendar as cal
|
||||||
|
import hub.helpers.constants as cte
|
||||||
|
|
||||||
|
|
||||||
|
class SimplifiedRadiosityAlgorithm:
|
||||||
|
"""
|
||||||
|
Import SRA results
|
||||||
|
"""
|
||||||
|
def __init__(self, city, base_path):
|
||||||
|
|
||||||
|
self._city = city
|
||||||
|
self._base_path = base_path
|
||||||
|
self._input_file_path = (self._base_path / f'{self._city.name}_sra_SW.out')
|
||||||
|
self._month_hour = self._month_hour_data_frame
|
||||||
|
self._results = self._read_results()
|
||||||
|
self._radiation_list = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _month_hour_data_frame(self):
|
||||||
|
array = []
|
||||||
|
for i in range(0, 12):
|
||||||
|
days_of_month = cal.monthrange(2015, i+1)[1]
|
||||||
|
total_hours = days_of_month * 24
|
||||||
|
array = np.concatenate((array, np.full(total_hours, i + 1)))
|
||||||
|
return pd.DataFrame(array, columns=[cte.MONTH])
|
||||||
|
|
||||||
|
def _get_mean_values(self, values):
|
||||||
|
out = None
|
||||||
|
if values is not None:
|
||||||
|
if cte.MONTH not in values.columns:
|
||||||
|
values = pd.concat([self._month_hour, pd.DataFrame(values)], axis=1)
|
||||||
|
out = values.groupby(cte.MONTH, as_index=False).mean()
|
||||||
|
del out[cte.MONTH]
|
||||||
|
return out
|
||||||
|
|
||||||
|
def _read_results(self):
|
||||||
|
try:
|
||||||
|
return pd.read_csv(self._input_file_path, sep='\s+', header=0)
|
||||||
|
except Exception:
|
||||||
|
raise Exception('No SRA output file found')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _radiation(self) -> []:
|
||||||
|
if len(self._radiation_list) == 0:
|
||||||
|
id_building = ''
|
||||||
|
header_building = []
|
||||||
|
for column in self._results.columns.values:
|
||||||
|
if id_building != column.split(':')[1]:
|
||||||
|
id_building = column.split(':')[1]
|
||||||
|
if len(header_building) > 0:
|
||||||
|
self._radiation_list.append(pd.concat([self._month_hour, self._results[header_building]],axis=1))
|
||||||
|
header_building = [column]
|
||||||
|
else:
|
||||||
|
header_building.append(column)
|
||||||
|
self._radiation_list.append(pd.concat([self._month_hour, self._results[header_building]], axis=1))
|
||||||
|
return self._radiation_list
|
||||||
|
|
||||||
|
def enrich(self):
|
||||||
|
"""
|
||||||
|
saves in building surfaces the correspondent irradiance at different time-scales depending on the mode
|
||||||
|
if building is None, it saves all buildings' surfaces in file, if building is specified, it saves only that
|
||||||
|
specific building values
|
||||||
|
:return: none
|
||||||
|
"""
|
||||||
|
for radiation in self._radiation:
|
||||||
|
city_object_name = radiation.columns.values.tolist()[1].split(':')[1]
|
||||||
|
building = self._city.city_object(city_object_name)
|
||||||
|
for column in radiation.columns.values:
|
||||||
|
if column == cte.MONTH:
|
||||||
|
continue
|
||||||
|
header_id = column
|
||||||
|
surface_id = header_id.split(':')[2]
|
||||||
|
surface = building.surface_by_id(surface_id)
|
||||||
|
new_value = pd.DataFrame(radiation[[header_id]].to_numpy(), columns=['sra'])
|
||||||
|
|
||||||
|
month_new_value = self._get_mean_values(new_value)
|
||||||
|
if cte.MONTH not in surface.global_irradiance:
|
||||||
|
surface.global_irradiance[cte.MONTH] = month_new_value
|
||||||
|
else:
|
||||||
|
pd.concat([surface.global_irradiance[cte.MONTH], month_new_value], axis=1)
|
||||||
|
if cte.HOUR not in surface.global_irradiance:
|
||||||
|
surface.global_irradiance[cte.HOUR] = new_value
|
||||||
|
else:
|
||||||
|
pd.concat([surface.global_irradiance[cte.HOUR], new_value], axis=1)
|
42
hub/imports/results_factory.py
Normal file
42
hub/imports/results_factory.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
"""
|
||||||
|
Result factory retrieve the specific tool results and store the data in the given city
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2022 Concordia CERC group
|
||||||
|
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
"""
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from hub.helpers.utils import validate_import_export_type
|
||||||
|
from hub.hub_logger import logger
|
||||||
|
from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
|
||||||
|
|
||||||
|
|
||||||
|
class ResultFactory:
|
||||||
|
"""
|
||||||
|
UsageFactory class
|
||||||
|
"""
|
||||||
|
def __init__(self, handler, city, base_path=None):
|
||||||
|
if base_path is None:
|
||||||
|
base_path = Path(Path(__file__).parent.parent / 'data/results')
|
||||||
|
self._handler = '_' + handler.lower().replace(' ', '_')
|
||||||
|
class_funcs = validate_import_export_type(ResultFactory)
|
||||||
|
if self._handler not in class_funcs:
|
||||||
|
err_msg = f"Wrong import type [{self._handler}]. Valid functions include {class_funcs}"
|
||||||
|
logger.error(err_msg)
|
||||||
|
raise Exception(err_msg)
|
||||||
|
self._city = city
|
||||||
|
self._base_path = base_path
|
||||||
|
|
||||||
|
def _sra(self):
|
||||||
|
"""
|
||||||
|
Enrich the city with Simplified Radiosity Algorithm results
|
||||||
|
"""
|
||||||
|
SimplifiedRadiosityAlgorithm(self._city, self._base_path).enrich()
|
||||||
|
|
||||||
|
def enrich(self):
|
||||||
|
"""
|
||||||
|
Enrich the city given to the class using the usage factory given handler
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
getattr(self, self._handler, lambda: None)()
|
1
setup.py
1
setup.py
|
@ -72,6 +72,7 @@ setup(
|
||||||
'hub.imports.geometry',
|
'hub.imports.geometry',
|
||||||
'hub.imports.geometry.citygml_classes',
|
'hub.imports.geometry.citygml_classes',
|
||||||
'hub.imports.geometry.helpers',
|
'hub.imports.geometry.helpers',
|
||||||
|
'hub.imports.results',
|
||||||
'hub.imports.usage',
|
'hub.imports.usage',
|
||||||
'hub.imports.weather',
|
'hub.imports.weather',
|
||||||
'hub.imports.weather.helpers',
|
'hub.imports.weather.helpers',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user