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
def country_code(self):
"""
Get models country code
Get city country code
:return: str
"""
return self._get_location().country
@property
def region_code(self):
"""
Get city region name
:return: str
"""
return self._get_location().region_code
@property
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):
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()
WeatherFactory(self._weather_format, self._city).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'

View File

@ -295,6 +295,7 @@ class GeometryHelper:
distance = math.inf
country = 'Unknown'
city = 'Unknown'
region = 'Unknown'
with open(_data_path, 'r', encoding='utf-8') as file:
for _, line in enumerate(file):
fields = line.split('\t')
@ -302,12 +303,16 @@ class GeometryHelper:
file_latitude = float(fields[4])
file_longitude = float(fields[5])
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))
if distance > new_distance:
distance = new_distance
country = file_country_code
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
def distance_between_points(vertex1, vertex2):

View File

@ -11,20 +11,28 @@ class Location:
"""
Location
"""
def __init__(self, country, city):
def __init__(self, country, city, region_code):
self._country = country
self._city = city
self._region_code = region_code
@property
def city(self):
"""
City name
Get city name
"""
return self._city
@property
def country(self):
"""
Country code
Get country code
"""
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 sys
from pathlib import Path
import pandas as pd
import requests
import hub.helpers.constants as cte
from hub.city_model_structure.city import City
from hub.imports.weather.helpers.weather import Weather as wh
@ -16,10 +20,14 @@ class EpwWeatherParameters:
"""
EpwWeatherParameters class
"""
def __init__(self, city, path, file_name):
def __init__(self, city: City):
self._weather_values = None
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:
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
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
import math
import calendar as cal
import pandas as pd
@ -17,6 +17,14 @@ class Weather:
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
def sky_temperature(ambient_temperature):
"""
@ -111,3 +119,14 @@ class Weather:
total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1)))
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 hub.city_model_structure.city import City
from hub.helpers.utils import validate_import_export_type
from hub.imports.weather.epw_weather_parameters import EpwWeatherParameters
from hub.imports.weather.xls_weather_parameters import XlsWeatherParameters
class WeatherFactory:
@ -16,14 +16,10 @@ class WeatherFactory:
WeatherFactory class
"""
def __init__(self, handler, city, base_path=None, file_name=None):
if base_path is None:
base_path = Path(Path(__file__).parent.parent / 'data/weather')
def __init__(self, handler, city: City):
self._handler = '_' + handler.lower().replace(' ', '_')
validate_import_export_type(WeatherFactory, handler)
self._city = city
self._base_path = base_path
self._file_name = file_name
def _epw(self):
"""
@ -32,15 +28,7 @@ class WeatherFactory:
# EnergyPlus Weather
# to download files: https://energyplus.net/weather
# 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, _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)
return EpwWeatherParameters(self._city)
def enrich(self):
"""

View File

@ -4,7 +4,7 @@ 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
from pathlib import Path
from unittest import TestCase
import pandas as pd
@ -83,7 +83,7 @@ class TestExports(TestCase):
export to Insel MonthlyEnergyBalance
"""
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:
building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']])
@ -147,6 +147,6 @@ class TestExports(TestCase):
# export files
try:
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, self._output_path, 'MEB_Montreal').export()
except Exception:
print(Exception)
except Exception as err:
logging.exception(err)
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
ConstructionFactory('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()
sra_file = str((output_path / f'{self._city.name}_sra.xml').resolve())
subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL)

View File

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

View File

@ -31,7 +31,7 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006
ConstructionFactory('nrel', 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'
soil_thickness = 0.18
soil_name = 'EcoRoofSoil'
@ -73,6 +73,6 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006
ConstructionFactory('nrel', 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()
self.assertIsNotNone(_idf)

View File

@ -83,7 +83,7 @@ class TestExports(TestCase):
export to Insel MonthlyEnergyBalance
"""
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:
building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']])

View File

@ -58,7 +58,7 @@ class TestSystemsFactory(TestCase):
"""
ConstructionFactory('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()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])