Correct the weather factory and remove useless files

This commit is contained in:
Guille Gutierrez 2023-06-06 13:32:37 -04:00
parent 8d3d1ac427
commit ff642a2c0c
20 changed files with 44927 additions and 26435 deletions

View File

@ -82,11 +82,19 @@ class City:
@property @property
def country_code(self): def country_code(self):
""" """
Get models country code Get city country code
:return: str :return: str
""" """
return self._get_location().country return self._get_location().country
@property
def region_code(self):
"""
Get city region name
:return: str
"""
return self._get_location().region_code
@property @property
def location(self) -> Location: def location(self) -> Location:
""" """

File diff suppressed because it is too large Load Diff

2
hub/data/weather/epw/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,7 @@ class SimplifiedRadiosityAlgorithm:
def _export_sra_cli(self): def _export_sra_cli(self):
file = self._city.climate_file file = self._city.climate_file
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 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() WeatherFactory(self._weather_format, self._city).enrich()
content = self._city.name + '\n' content = self._city.name + '\n'
content += str(self._city.latitude) + ',' + str(self._city.longitude) + ',0.0,' + str(self._city.time_zone) + '\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' content += '\ndm m h G_Dh G_Bn\n'

View File

@ -295,6 +295,7 @@ class GeometryHelper:
distance = math.inf distance = math.inf
country = 'Unknown' country = 'Unknown'
city = 'Unknown' city = 'Unknown'
region = 'Unknown'
with open(_data_path, 'r', encoding='utf-8') as file: with open(_data_path, 'r', encoding='utf-8') as file:
for _, line in enumerate(file): for _, line in enumerate(file):
fields = line.split('\t') fields = line.split('\t')
@ -302,12 +303,16 @@ class GeometryHelper:
file_latitude = float(fields[4]) file_latitude = float(fields[4])
file_longitude = float(fields[5]) file_longitude = float(fields[5])
file_country_code = fields[8] file_country_code = fields[8]
admin1_code = fields[10]
admin2_code = fields[11]
new_distance = math.sqrt(pow((latitude - file_latitude), 2) + pow((longitude - file_longitude), 2)) new_distance = math.sqrt(pow((latitude - file_latitude), 2) + pow((longitude - file_longitude), 2))
if distance > new_distance: if distance > new_distance:
distance = new_distance distance = new_distance
country = file_country_code country = file_country_code
city = file_city_name city = file_city_name
return Location(country, city) region_code = f'{file_country_code}.{admin1_code}.{admin2_code}'
return Location(country, city, region_code)
@staticmethod @staticmethod
def distance_between_points(vertex1, vertex2): def distance_between_points(vertex1, vertex2):

View File

@ -11,20 +11,28 @@ class Location:
""" """
Location Location
""" """
def __init__(self, country, city): def __init__(self, country, city, region_code):
self._country = country self._country = country
self._city = city self._city = city
self._region_code = region_code
@property @property
def city(self): def city(self):
""" """
City name Get city name
""" """
return self._city return self._city
@property @property
def country(self): def country(self):
""" """
Country code Get country code
""" """
return self._country return self._country
@property
def region_code(self):
"""
Get region
"""
return self._region_code

View File

@ -1,57 +0,0 @@
"""
DatWeatherParameters class to extract weather parameters from a defined region in .dat format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
import sys
from pathlib import Path
import pandas as pd
import hub.helpers.constants as cte
class DatWeatherParameters:
"""
DatWeatherParameters class
"""
def __init__(self, city, path):
self._weather_values = None
self._city = city
self._city_name = city.climate_reference_city
file_name = 'inseldb_' + self._city_name + '.dat'
self._path = Path(path / file_name)
if self._weather_values is None:
try:
self._weather_values = pd.read_csv(self._path, sep=r'\s+', header=None,
names=['hour', 'global_horiz', 'temperature', 'diffuse', 'beam', 'empty'])
except SystemExit:
logging.Logger(f'Error: weather file {self._path} not found\n')
sys.exit()
for building in self._city.buildings:
new_value = pd.DataFrame(self._weather_values[['temperature']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.external_temperature:
building.external_temperature[cte.HOUR] = new_value
else:
pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['global_horiz']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.global_horizontal:
building.global_horizontal[cte.HOUR] = new_value
else:
pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['diffuse']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.diffuse:
building.diffuse[cte.HOUR] = new_value
else:
pd.concat([building.diffuse[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['beam']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.beam:
building.beam[cte.HOUR] = new_value
else:
pd.concat([building.beam[cte.HOUR], new_value], axis=1)

View File

@ -7,8 +7,12 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import logging import logging
import sys import sys
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
import requests
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.city_model_structure.city import City
from hub.imports.weather.helpers.weather import Weather as wh from hub.imports.weather.helpers.weather import Weather as wh
@ -16,10 +20,14 @@ class EpwWeatherParameters:
""" """
EpwWeatherParameters class EpwWeatherParameters class
""" """
def __init__(self, city, path, file_name): def __init__(self, city: City):
self._weather_values = None self._weather_values = None
self._city = city self._city = city
self._path = Path(path / file_name) self._url = wh().epw_file(city.region_code)
self._path = (Path(__file__).parent.parent.parent / f'data/weather/epw/{self._url.rsplit("/", 1)[1]}').resolve()
if not self._path.exists():
with open(self._path, 'wb') as epw_file:
epw_file.write(requests.get(self._url, allow_redirects=True).content)
try: try:
with open(self._path, 'r', encoding='utf8') as file: with open(self._path, 'r', encoding='utf8') as file:

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import logging
import math import math
import calendar as cal import calendar as cal
import pandas as pd import pandas as pd
@ -17,6 +17,14 @@ class Weather:
Weather class Weather class
""" """
# todo: this dictionary need to be completed, a data science student task?
_epw_file = {
'CA.02.5935': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/BC/CAN_BC_Summerland.717680_CWEC/CAN_BC_Summerland.717680_CWEC.epw',
'CA.10.06': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/PQ/CAN_PQ_Montreal.Intl.AP.716270_CWEC/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw',
'DE.01.082': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/DEU/DEU_Stuttgart.107380_IWEC/DEU_Stuttgart.107380_IWEC.epw',
'US.NY.047': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/USA/NY/USA_NY_New.York.City-Central.Park.94728_TMY/USA_NY_New.York.City-Central.Park.94728_TMY.epw'
}
@staticmethod @staticmethod
def sky_temperature(ambient_temperature): def sky_temperature(ambient_temperature):
""" """
@ -111,3 +119,14 @@ class Weather:
total_hours = days_of_month * 24 total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1))) array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=['month']) return pd.DataFrame(array, columns=['month'])
def epw_file(self, region_code):
"""
returns the url for the weather file for the given location or default (Montreal data)
:return: str
"""
if region_code not in self._epw_file:
logging.warning('Specific weather data unknown for %s using Montreal data instead', region_code)
return self._epw_file['CA.10.06']
return self._epw_file[region_code]

View File

@ -1,48 +0,0 @@
"""
XlsWeatherParameters class to extract weather parameters from a defined region in .xls format
defined and used by the norm iso 52016-1:2017
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import sys
from pathlib import Path
import pandas as pd
import hub.helpers.constants as cte
class XlsWeatherParameters:
"""
XlsWeatherParameters class
"""
def __init__(self, city, path, name):
self._weather_values = None
self._city = city
self._file_name = name
file_name = self._file_name + '.xls'
self._path = Path(path / file_name)
if self._weather_values is None:
try:
self._weather_values = pd.read_excel(self._path, skiprows=4, nrows=9504,
names=['hours_calc', 'month', 'week', 'day_of_week', 'hours_of_day',
'temperature', 'I_sol_vertical_N', 'I_sol_vertical_E',
'I_sol_vertical_S', 'I_sol_vertical_W', 'I_sol_45_N', 'I_sol_45_S',
'void', 'global_horiz', 'wind_velocity', 'humidity'])
except SystemExit:
sys.stderr.write(f'Error reading weather file {self._path}\n')
sys.exit()
for building in self._city.buildings:
new_value = pd.DataFrame(self._weather_values[['temperature']].to_numpy(), columns=['iso52016'])
if cte.HOUR not in building.external_temperature:
building.external_temperature[cte.HOUR] = new_value
else:
pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['global_horiz']].to_numpy(), columns=['iso52016'])
if cte.HOUR not in building.global_horizontal:
building.global_horizontal[cte.HOUR] = new_value
else:
pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1)

View File

@ -6,9 +6,9 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
from pathlib import Path from pathlib import Path
from hub.city_model_structure.city import City
from hub.helpers.utils import validate_import_export_type from hub.helpers.utils import validate_import_export_type
from hub.imports.weather.epw_weather_parameters import EpwWeatherParameters from hub.imports.weather.epw_weather_parameters import EpwWeatherParameters
from hub.imports.weather.xls_weather_parameters import XlsWeatherParameters
class WeatherFactory: class WeatherFactory:
@ -16,14 +16,10 @@ class WeatherFactory:
WeatherFactory class WeatherFactory class
""" """
def __init__(self, handler, city, base_path=None, file_name=None): def __init__(self, handler, city: City):
if base_path is None:
base_path = Path(Path(__file__).parent.parent / 'data/weather')
self._handler = '_' + handler.lower().replace(' ', '_') self._handler = '_' + handler.lower().replace(' ', '_')
validate_import_export_type(WeatherFactory, handler) validate_import_export_type(WeatherFactory, handler)
self._city = city self._city = city
self._base_path = base_path
self._file_name = file_name
def _epw(self): def _epw(self):
""" """
@ -32,15 +28,7 @@ class WeatherFactory:
# EnergyPlus Weather # EnergyPlus Weather
# to download files: https://energyplus.net/weather # to download files: https://energyplus.net/weather
# description of the format: https://energyplus.net/sites/default/files/pdfs_v8.3.0/AuxiliaryPrograms.pdf # description of the format: https://energyplus.net/sites/default/files/pdfs_v8.3.0/AuxiliaryPrograms.pdf
_path = Path(self._base_path / 'epw').resolve() return EpwWeatherParameters(self._city)
return EpwWeatherParameters(self._city, _path, self._file_name)
def _xls(self):
"""
Enrich the city with ISO_52016_1_BESTEST_ClimData_2016.08.24 weather file
"""
name = 'ISO_52016_1_BESTEST_ClimData_2016.08.24'
return XlsWeatherParameters(self._city, self._base_path, name)
def enrich(self): def enrich(self):
""" """

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import logging
from pathlib import Path from pathlib import Path
from unittest import TestCase from unittest import TestCase
import pandas as pd import pandas as pd
@ -83,7 +83,7 @@ class TestExports(TestCase):
export to Insel MonthlyEnergyBalance export to Insel MonthlyEnergyBalance
""" """
city = self._get_citygml('one_building_in_kelowna.gml') city = self._get_citygml('one_building_in_kelowna.gml')
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', city).enrich()
for building in city.buildings: for building in city.buildings:
building.external_temperature[cte.MONTH] = MonthlyValues().\ building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']]) get_mean_values(building.external_temperature[cte.HOUR][['epw']])
@ -147,6 +147,6 @@ class TestExports(TestCase):
# export files # export files
try: try:
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, self._output_path, 'MEB_Montreal').export() EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, self._output_path, 'MEB_Montreal').export()
except Exception: except Exception as err:
print(Exception) logging.exception(err)
self.fail("Insel MonthlyEnergyBalance ExportsFactory raised ExceptionType unexpectedly!") self.fail("Insel MonthlyEnergyBalance ExportsFactory raised ExceptionType unexpectedly!")

View File

@ -79,7 +79,7 @@ class Control:
function_to_hub=Dictionaries().alkis_function_to_hub_function).city function_to_hub=Dictionaries().alkis_function_to_hub_function).city
ConstructionFactory('nrcan', self._city).enrich() ConstructionFactory('nrcan', self._city).enrich()
UsageFactory('nrcan', self._city).enrich() UsageFactory('nrcan', self._city).enrich()
WeatherFactory('epw', self._city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', self._city).enrich()
ExportsFactory('sra', self._city, output_path, weather_file=weather_file, weather_format='epw').export() ExportsFactory('sra', self._city, output_path, weather_file=weather_file, weather_format='epw').export()
sra_file = str((output_path / f'{self._city.name}_sra.xml').resolve()) sra_file = str((output_path / f'{self._city.name}_sra.xml').resolve())
subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL) subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL)

View File

@ -110,7 +110,7 @@ class TestExports(TestCase):
ConstructionFactory('nrcan', city).enrich() ConstructionFactory('nrcan', city).enrich()
EnergyBuildingsExportsFactory('idf', city, self._output_path).export() EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
UsageFactory('nrcan', city).enrich() UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', city).enrich()
try: try:
EnergyBuildingsExportsFactory('idf', city, self._output_path).export() EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
except Exception: except Exception:

View File

@ -31,7 +31,7 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006 building.year_of_construction = 2006
ConstructionFactory('nrel', city).enrich() ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich() UsageFactory('comnet', city).enrich()
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', city).enrich()
vegetation_name = 'BaseEco' vegetation_name = 'BaseEco'
soil_thickness = 0.18 soil_thickness = 0.18
soil_name = 'EcoRoofSoil' soil_name = 'EcoRoofSoil'
@ -73,6 +73,6 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006 building.year_of_construction = 2006
ConstructionFactory('nrel', city).enrich() ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich() UsageFactory('comnet', city).enrich()
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', city).enrich()
_idf = EnergyBuildingsExportsFactory('idf', city, output_path).export() _idf = EnergyBuildingsExportsFactory('idf', city, output_path).export()
self.assertIsNotNone(_idf) self.assertIsNotNone(_idf)

View File

@ -83,7 +83,7 @@ class TestExports(TestCase):
export to Insel MonthlyEnergyBalance export to Insel MonthlyEnergyBalance
""" """
city = self._get_citygml('one_building_in_kelowna.gml') city = self._get_citygml('one_building_in_kelowna.gml')
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', city).enrich()
for building in city.buildings: for building in city.buildings:
building.external_temperature[cte.MONTH] = MonthlyValues().\ building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']]) get_mean_values(building.external_temperature[cte.HOUR][['epw']])

View File

@ -58,7 +58,7 @@ class TestSystemsFactory(TestCase):
""" """
ConstructionFactory('nrcan', self._city).enrich() ConstructionFactory('nrcan', self._city).enrich()
UsageFactory('nrcan', self._city).enrich() UsageFactory('nrcan', self._city).enrich()
WeatherFactory('epw', self._city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich() WeatherFactory('epw', self._city).enrich()
ExportsFactory('sra', self._city, self._output_path).export() ExportsFactory('sra', self._city, self._output_path).export()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve() sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)]) subprocess.run(['sra', str(sra_path)])