Compare commits

...

6 Commits

22 changed files with 83 additions and 24 deletions

View File

@ -2,16 +2,16 @@
This is an installation guide for Windows, covering all the steps needed to begin developing code for the Urban This is an installation guide for Windows, covering all the steps needed to begin developing code for the Urban
Simulation Platform 'Hub'. At the end of this process you will have installed and configured all the necessary applications, Simulation Platform 'Hub'. At the end of this process you will have installed and configured all the necessary applications,
set up your own project on CERC's Gitlab and created your first python file. set up your own project on CERC's Gitea and created your first python file.
## Prepare your environment ## Prepare your environment
g
To develop any new code for the Urban Simulation Platform you must have the right software applications installed and configured. To develop any new code for the Urban Simulation Platform you must have the right software applications installed and configured.
The Platform is written in python and so the applications you need are: The Platform is written in python and so the applications you need are:
* Miniconda * Miniconda
* SRA Files
* Python Editor * Python Editor
You also need to register a user account with the CERC's code repository on Gitlab and have the necessary permissions for You also need to register a user account with the CERC's code repository on Gitea and have the necessary permissions for
creating new code. For that purpose, please, contact Guillermo (guillermo.gutierrezmorote@concordia.ca) or creating new code. For that purpose, please, contact Guillermo (guillermo.gutierrezmorote@concordia.ca) or
Koa (kekoa.wells@concordia.ca) as soon as possible. Koa (kekoa.wells@concordia.ca) as soon as possible.
@ -47,6 +47,21 @@ _The term '...' is not recognized as the name of a cmdlet, function,..._
To solve it, type 'Set-ExecutionPolicy Unrestricted' as shown in the image. To solve it, type 'Set-ExecutionPolicy Unrestricted' as shown in the image.
### Setup SRA
1. Get the SRA executable and dll files from Guille or Koa
2. Create a folder in "C:\Program Files\" called "sra"
![create_sra](docs/img_windows_install/img_34.png)
3. Copy shortwave_integer.exe and pthreadGC2.dll into the sra folder.
![create_sra](docs/img_windows_install/img_35.png)
4. Add the newly created sra folder to the Path, similar to step 2 from the Miniconda setup above.
![create_sra](docs/img_windows_install/img_36.png)
### Get a Python editor ### Get a Python editor
1. You will need a python editor in order to import the existing Hub source code and to write your own python code. 1. You will need a python editor in order to import the existing Hub source code and to write your own python code.
@ -55,7 +70,7 @@ an excellent open-source python editor.
2. Run the installer, and follow the installation instructions for PyCharm, you may change a few options, 2. Run the installer, and follow the installation instructions for PyCharm, you may change a few options,
but the default ones should be fine. but the default ones should be fine.
**NOTE:** If Pycharm asks you to create a Virtual Environment, click **Cancel**. You will do it later using Conda instead. **NOTE:** If PyCharm asks you to create a Virtual Environment, click **Cancel**. You will do it later using Conda instead.
![creating_virtual_environment](docs/img_windows_install/img_31.png) ![creating_virtual_environment](docs/img_windows_install/img_31.png)
@ -70,14 +85,12 @@ You can find it also at **Git->Clone...**
![pycharm get from version control](docs/img_windows_install/img_6.png) ![pycharm get from version control](docs/img_windows_install/img_6.png)
3. Select **Git** as the **Version control**. For the URL use the link to the Hub repository, as seen below. 3. Select **Git** as the **Version control**. Open the [hub repository](https://nextgenerations-cities.encs.concordia.ca/gitea/CERC/hub)
on Gitea and copy the URL from your browser to use as the URL inside PyCharm.
![pycharm get from version control screen](docs/img_windows_install/img_1.png) ![pycharm get from version control screen](docs/img_windows_install/img_1.png)
(You can also copy this URL by going to the Hub repository in [Gitlab](https://rs-loy-gitlab.concordia.ca/Guille/hub.git) ![gitea get https](docs/img_windows_install/img_39.png)
and clicking on the **Copy URL** button, next to **Clone with HTTPS**)
![gitlab get https](docs/img_windows_install/img_17.png)
The Directory to store the Hub source code locally is automatically created for you. Edit this if you prefer it to be stored somewhere else. The Directory to store the Hub source code locally is automatically created for you. Edit this if you prefer it to be stored somewhere else.
@ -152,7 +165,7 @@ _lca_classes_,... And, click on the **Create** button.
3. Click on the **Git** button in the bottom-left corner to pop-up the window showing the Git information. 3. Click on the **Git** button in the bottom-left corner to pop-up the window showing the Git information.
See your new branch has been created under _Local_. See your new branch has been created under _Local_.
4. Now we need to let the CERC Gitlab repository know about this new branch. You do this by right-clicking on 4. Now we need to let the CERC Gitea repository know about this new branch. You do this by right-clicking on
your branch and selecting **Push...** from the drop-down menu. your branch and selecting **Push...** from the drop-down menu.
5. Then click on the **Push** button at the bottom-right of the **Push Commits** window. 5. Then click on the **Push** button at the bottom-right of the **Push Commits** window.
@ -180,33 +193,35 @@ See the picture below.
![pycharm configuration screen](docs/img_windows_install/img_5.png) ![pycharm configuration screen](docs/img_windows_install/img_5.png)
## Set up a new project on Gitlab ## Set up a new project on Gitea
You will need an account before you can access the Gitea. Please contact Guillermo (guillermo.gutierrezmorote@concordia.ca) or
Koa (kekoa.wells@concordia.ca) to request an account.
1. Open a browser and to the [CERC Git](https://rs-loy-gitlab.concordia.ca/). Click on the blue **New project** button. 1. Open a browser and go to the [CERC Gitea](https://nextgenerations-cities.encs.concordia.ca/). Click on the **+** in the top right
and select "New Repository" or press the **+** below the Organization tab.
![git new project screen](docs/img_windows_install/img_14.png) ![git new project screen](docs/img_windows_install/img_37.png)
2. Choose the **Create blank project** option from the three options seen below. 2. Choose the **Create blank project** option from the three options seen below.
3. Type in a name that describes your project: _hp_workflow_, _bus_system_optimization_... 3. Type in a name that describes your project: _hp_workflow_, _bus_system_optimization_...
(remember to follow the CERC naming conventions described in the [Coding Style](PYGUIDE.md)). (remember to follow the CERC naming conventions described in the [Coding Style](PYGUIDE.md)).
Check the option **Initialize repository with a README**, and ideally, check the **Visibility Level** to be **Public**. Ideally, uncheck the option **Make Repository Private**, and check the **Initialize Repository**
Then click on the **Create project** button. Then click on the **Create project** button.
![git give a name](docs/img_windows_install/img_15.png) ![git give a name](docs/img_windows_install/img_38.png)
You should then see a confirmation screen with all the information about your new project. You should then see a confirmation screen with all the information about your new project.
## Get your project into Pycharm ## Get your project into Pycharm
1. Now you can make a clone of this project, within PyCharm. First, copy the URL by clicking on the blue **Clone** button 1. Now you can make a clone of this project, within PyCharm. First, go to the page of your repository on the Gitea and copy the URL.
and then click on the **Copy URL** button, next to the **Clone with HTTPS** link.
2. Switch back to PyCharm and close the Hub project by choosing **File->Close Project**. You will then see the 2. Switch back to PyCharm and close the Hub project by choosing **File->Close Project**. You will then see the
**Welcome To PyCharm** window again. **Welcome To PyCharm** window again.
3. Clone a copy of your Project into PyCharm, following the steps 2-6 of the _GET THE CERC HUB SOURCE CODE_ 3. Clone a copy of your Project into PyCharm, following the steps 2-6 of the _GET THE CERC HUB SOURCE CODE_
section above, but using the URL link that you just copied for your gitlab project. section above, but using the URL link that you just copied for your Gitea project.
4. Select **File->Settings** to open the **Settings** window. From the panel on the left click on 4. Select **File->Settings** to open the **Settings** window. From the panel on the left click on
**Project:<project name> -> Project Structure**. **Project:<project name> -> Project Structure**.
@ -242,5 +257,5 @@ city = GeometryFactory('citygml', path='myfile.gml').city
9. Always remember to push your own project changes as the last thing you do before ending your working day! 9. Always remember to push your own project changes as the last thing you do before ending your working day!
First, commit your changes by clicking on the green check in the top-right corner of Pycharm. Add a comment that explains briefly your changes. First, commit your changes by clicking on the green check in the top-right corner of Pycharm. Add a comment that explains briefly your changes.
Then, pull by clicking on the blue arrow to be sure that there are no conflicts between your version (local) and the remote one (gitlab). Then, pull by clicking on the blue arrow to be sure that there are no conflicts between your version (local) and the remote one (Gitea).
Once the conflicts are solved and the merge in local is done, push the changes by clicking on the green arrow. Once the conflicts are solved and the merge in local is done, push the changes by clicking on the green arrow.

View File

@ -6,6 +6,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import sys import sys
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
from typing import Dict from typing import Dict
@ -129,3 +130,5 @@ class UsageHelper:
except KeyError: except KeyError:
sys.stderr.write('Error: Comnet keyword not found. An update of the Comnet files might have been ' sys.stderr.write('Error: Comnet keyword not found. An update of the Comnet files might have been '
'done changing the keywords.\n') 'done changing the keywords.\n')
logger.error('Error: Comnet keyword not found. An update of the Comnet files might have been '
'done changing the keywords.\n')

View File

@ -264,8 +264,8 @@ class Polygon:
return mesh return mesh
except ValueError: except ValueError:
logger.error(f'Not able to triangulate polygon\n')
sys.stderr.write(f'Not able to triangulate polygon\n') sys.stderr.write(f'Not able to triangulate polygon\n')
logger.error(f'Not able to triangulate polygon\n')
_vertices = [[0, 0, 0], [0, 0, 1], [0, 1, 0]] _vertices = [[0, 0, 0], [0, 0, 1], [0, 1, 0]]
_faces = [[0, 1, 2]] _faces = [[0, 1, 2]]
return Trimesh(vertices=_vertices, faces=_faces) return Trimesh(vertices=_vertices, faces=_faces)
@ -293,6 +293,7 @@ class Polygon:
""" """
if np.linalg.norm(vec_1) == 0 or np.linalg.norm(vec_2) == 0: if np.linalg.norm(vec_1) == 0 or np.linalg.norm(vec_2) == 0:
sys.stderr.write("Warning: impossible to calculate angle between planes' normal. Return 0\n") sys.stderr.write("Warning: impossible to calculate angle between planes' normal. Return 0\n")
logger.error("Warning: impossible to calculate angle between planes' normal. Return 0\n")
return 0 return 0
cosine = np.dot(vec_1, vec_2) / np.linalg.norm(vec_1) / np.linalg.norm(vec_2) cosine = np.dot(vec_1, vec_2) / np.linalg.norm(vec_1) / np.linalg.norm(vec_2)
if cosine > 1 and cosine - 1 < 1e-5: if cosine > 1 and cosine - 1 < 1e-5:

View File

@ -12,6 +12,7 @@ import math
import numpy as np import numpy as np
from trimesh import Trimesh from trimesh import Trimesh
from hub.helpers.configuration_helper import ConfigurationHelper from hub.helpers.configuration_helper import ConfigurationHelper
from hub.hub_logger import logger
class Polyhedron: class Polyhedron:
@ -116,6 +117,7 @@ class Polyhedron:
for face in self.faces: for face in self.faces:
if len(face) != 3: if len(face) != 3:
sys.stderr.write('Not able to generate trimesh\n') sys.stderr.write('Not able to generate trimesh\n')
logger.error('Not able to generate trimesh\n')
return None return None
self._trimesh = Trimesh(vertices=self.vertices, faces=self.faces) self._trimesh = Trimesh(vertices=self.vertices, faces=self.faces)
return self._trimesh return self._trimesh

View File

@ -71,8 +71,8 @@ class Building(CityObject):
elif surface.type == cte.INTERIOR_SLAB: elif surface.type == cte.INTERIOR_SLAB:
self._interior_slabs.append(surface) self._interior_slabs.append(surface)
else: else:
logger.error(f'Building {self.name} [alias {self.alias}] has an unexpected surface type {surface.type}.\n')
sys.stderr.write(f'Building {self.name} [alias {self.alias}] has an unexpected surface type {surface.type}.\n') sys.stderr.write(f'Building {self.name} [alias {self.alias}] has an unexpected surface type {surface.type}.\n')
logger.error(f'Building {self.name} [alias {self.alias}] has an unexpected surface type {surface.type}.\n')
@property @property
def shell(self) -> Polyhedron: def shell(self) -> Polyhedron:

View File

@ -16,6 +16,7 @@ import pyproj
from typing import List, Union from typing import List, Union
from pyproj import Transformer from pyproj import Transformer
from pathlib import Path from pathlib import Path
from hub.hub_logger import logger
from hub.city_model_structure.building import Building from hub.city_model_structure.building import Building
from hub.city_model_structure.city_object import CityObject from hub.city_model_structure.city_object import CityObject
from hub.city_model_structure.city_objects_cluster import CityObjectsCluster from hub.city_model_structure.city_objects_cluster import CityObjectsCluster
@ -87,6 +88,8 @@ class City:
except pyproj.exceptions.CRSError: except pyproj.exceptions.CRSError:
sys.stderr.write('Invalid projection reference system, please check the input data. ' sys.stderr.write('Invalid projection reference system, please check the input data. '
'(e.g. in CityGML files: srs_name)\n') '(e.g. in CityGML files: srs_name)\n')
logger.error('Invalid projection reference system, please check the input data. '
'(e.g. in CityGML files: srs_name)\n')
sys.exit() sys.exit()
transformer = Transformer.from_crs(input_reference, gps) transformer = Transformer.from_crs(input_reference, gps)
coordinates = transformer.transform(self.lower_corner[0], self.lower_corner[1]) coordinates = transformer.transform(self.lower_corner[0], self.lower_corner[1])
@ -230,6 +233,7 @@ class City:
raise NotImplementedError(city_object.type) raise NotImplementedError(city_object.type)
if self._buildings is None or self._buildings == []: if self._buildings is None or self._buildings == []:
sys.stderr.write('Warning: impossible to remove city_object, the city is empty\n') sys.stderr.write('Warning: impossible to remove city_object, the city is empty\n')
logger.error('Warning: impossible to remove city_object, the city is empty\n')
else: else:
if city_object in self._buildings: if city_object in self._buildings:
self._buildings.remove(city_object) self._buildings.remove(city_object)

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -240,6 +240,7 @@ class GeometryHelper:
""" """
Get Location from latitude and longitude Get Location from latitude and longitude
""" """
return Location('ca', 'montreal')
url = 'https://nominatim.openstreetmap.org/reverse?lat={latitude}&lon={longitude}&format=json' url = 'https://nominatim.openstreetmap.org/reverse?lat={latitude}&lon={longitude}&format=json'
response = requests.get(url.format(latitude=latitude, longitude=longitude)) response = requests.get(url.format(latitude=latitude, longitude=longitude))
if response.status_code != 200: if response.status_code != 200:

View File

@ -2,6 +2,9 @@ import logging as logger
from pathlib import Path from pathlib import Path
import os import os
log = logger.getLogger("trimesh")
log.setLevel(logger.ERROR)
log_dir = (Path(__file__).parent.parent / 'logs').resolve() log_dir = (Path(__file__).parent.parent / 'logs').resolve()
log_file = (log_dir / 'hub.log').resolve() log_file = (log_dir / 'hub.log').resolve()
try: try:

View File

@ -10,6 +10,7 @@ import numpy as np
from typing import List from typing import List
from hub.helpers import constants as cte from hub.helpers import constants as cte
from hub.hub_logger import logger
from hub.city_model_structure.attributes.polygon import Polygon from hub.city_model_structure.attributes.polygon import Polygon
from hub.city_model_structure.attributes.point import Point from hub.city_model_structure.attributes.point import Point
from hub.city_model_structure.building_demand.storey import Storey from hub.city_model_structure.building_demand.storey import Storey
@ -17,6 +18,7 @@ from hub.city_model_structure.building_demand.surface import Surface
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
class StoreysGeneration: class StoreysGeneration:
""" """
StoreysGeneration StoreysGeneration
@ -134,6 +136,8 @@ class StoreysGeneration:
if storeys_above_ground is None or storeys_above_ground <= 0: if storeys_above_ground is None or storeys_above_ground <= 0:
sys.stderr.write('Warning: not enough information to divide building into storeys, ' sys.stderr.write('Warning: not enough information to divide building into storeys, '
'either number of storeys or average storey height must be provided.\n') 'either number of storeys or average storey height must be provided.\n')
logger.error('Warning: not enough information to divide building into storeys, '
'either number of storeys or average storey height must be provided.\n')
return 0, 0 return 0, 0
number_of_storeys = int(storeys_above_ground) number_of_storeys = int(storeys_above_ground)
height = eave_height / number_of_storeys height = eave_height / number_of_storeys

View File

@ -7,7 +7,9 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import math import math
import sys import sys
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.city_model_structure.building_demand.layer import Layer from hub.city_model_structure.building_demand.layer import Layer
from hub.city_model_structure.building_demand.material import Material from hub.city_model_structure.building_demand.material import Material
@ -40,6 +42,10 @@ class NrcanPhysicsParameters:
sys.stderr.write(f'Building {building.name} has unknown construction archetype for building function: ' sys.stderr.write(f'Building {building.name} has unknown construction archetype for building function: '
f'{building.function}, building year of construction: {building.year_of_construction} ' f'{building.function}, building year of construction: {building.year_of_construction} '
f'and climate zone {self._climate_zone}\n') f'and climate zone {self._climate_zone}\n')
logger.error(f'Building {building.name} has unknown construction archetype for building function: '
f'{building.function}, building year of construction: {building.year_of_construction} '
f'and climate zone {self._climate_zone}\n')
return return
# if building has no thermal zones defined from geometry, and the building will be divided in storeys, # if building has no thermal zones defined from geometry, and the building will be divided in storeys,
# one thermal zone per storey is assigned # one thermal zone per storey is assigned

View File

@ -39,12 +39,12 @@ class NrelPhysicsParameters:
archetype = self._search_archetype(nrel_catalog, function, building.year_of_construction, archetype = self._search_archetype(nrel_catalog, function, building.year_of_construction,
self._climate_zone) self._climate_zone)
except KeyError: except KeyError:
logger.error(f'Building {building.name} has unknown archetype for building function: {building.function} '
f'and building year of construction: {building.year_of_construction} '
f'and climate zone reference norm {self._climate_zone}\n')
sys.stderr.write(f'Building {building.name} has unknown archetype for building function: {building.function} ' sys.stderr.write(f'Building {building.name} has unknown archetype for building function: {building.function} '
f'and building year of construction: {building.year_of_construction} ' f'and building year of construction: {building.year_of_construction} '
f'and climate zone reference norm {self._climate_zone}\n') f'and climate zone reference norm {self._climate_zone}\n')
logger.error(f'Building {building.name} has unknown archetype for building function: {building.function} '
f'and building year of construction: {building.year_of_construction} '
f'and climate zone reference norm {self._climate_zone}\n')
return return

View File

@ -9,6 +9,7 @@ import sys
import numpy import numpy
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
from hub.helpers.dictionaries import Dictionaries from hub.helpers.dictionaries import Dictionaries
from hub.city_model_structure.building_demand.usage import Usage from hub.city_model_structure.building_demand.usage import Usage
from hub.city_model_structure.building_demand.lighting import Lighting from hub.city_model_structure.building_demand.lighting import Lighting
@ -42,6 +43,8 @@ class ComnetUsageParameters:
except KeyError: except KeyError:
sys.stderr.write(f'Building {building.name} has unknown usage archetype for building function:' sys.stderr.write(f'Building {building.name} has unknown usage archetype for building function:'
f' {building.function}') f' {building.function}')
logger.error(f'Building {building.name} has unknown usage archetype for building function:'
f' {building.function}')
return return
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:

View File

@ -8,6 +8,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import sys import sys
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
from hub.helpers.dictionaries import Dictionaries from hub.helpers.dictionaries import Dictionaries
from hub.city_model_structure.building_demand.usage import Usage from hub.city_model_structure.building_demand.usage import Usage
from hub.city_model_structure.building_demand.lighting import Lighting from hub.city_model_structure.building_demand.lighting import Lighting
@ -41,6 +42,8 @@ class NrcanUsageParameters:
except KeyError: except KeyError:
sys.stderr.write(f'Building {building.name} has unknown usage archetype for building function:' sys.stderr.write(f'Building {building.name} has unknown usage archetype for building function:'
f' {building.function}') f' {building.function}')
logger.error(f'Building {building.name} has unknown usage archetype for building function:'
f' {building.function}')
return return
usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function] usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
@ -49,6 +52,8 @@ class NrcanUsageParameters:
except KeyError: except KeyError:
sys.stderr.write(f'Building {building.name} has unknown usage archetype for building function:' sys.stderr.write(f'Building {building.name} has unknown usage archetype for building function:'
f' {building.function}') f' {building.function}')
logger.error(f'Building {building.name} has unknown usage archetype for building function:'
f' {building.function}')
return return
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:

View File

@ -9,6 +9,7 @@ import sys
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
class DatWeatherParameters: class DatWeatherParameters:
@ -29,6 +30,7 @@ class DatWeatherParameters:
names=['hour', 'global_horiz', 'temperature', 'diffuse', 'beam', 'empty']) names=['hour', 'global_horiz', 'temperature', 'diffuse', 'beam', 'empty'])
except SystemExit: except SystemExit:
sys.stderr.write(f'Error: weather file {self._path} not found\n') sys.stderr.write(f'Error: weather file {self._path} not found\n')
logger.error(f'Error: weather file {self._path} not found\n')
sys.exit() sys.exit()
for building in self._city.buildings: for building in self._city.buildings:

View File

@ -9,6 +9,7 @@ import sys
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
from hub.imports.weather.helpers.weather import Weather as wh from hub.imports.weather.helpers.weather import Weather as wh
@ -44,6 +45,8 @@ class EpwWeatherParameters:
except SystemExit: except SystemExit:
sys.stderr.write(f'Error: weather file {self._path} not found. Please download it from ' sys.stderr.write(f'Error: weather file {self._path} not found. Please download it from '
f'https://energyplus.net/weather and place it in folder data\\weather\\epw\n') f'https://energyplus.net/weather and place it in folder data\\weather\\epw\n')
logger.error(f'Error: weather file {self._path} not found. Please download it from '
f'https://energyplus.net/weather and place it in folder data\\weather\\epw\n')
sys.exit() sys.exit()
try: try:
@ -71,6 +74,7 @@ class EpwWeatherParameters:
'liquid_precipitation_quality_hr']) 'liquid_precipitation_quality_hr'])
except SystemExit: except SystemExit:
sys.stderr.write(f'Error: wrong formatting of weather file {self._path}\n') sys.stderr.write(f'Error: wrong formatting of weather file {self._path}\n')
logger.error(f'Error: wrong formatting of weather file {self._path}\n')
sys.exit() sys.exit()
for building in self._city.buildings: for building in self._city.buildings:
@ -80,6 +84,7 @@ class EpwWeatherParameters:
number_invalid_records = new_value[new_value.epw == 99.9].count().epw number_invalid_records = new_value[new_value.epw == 99.9].count().epw
if number_invalid_records > 0: if number_invalid_records > 0:
sys.stderr.write(f'Warning: {self._path} invalid records (value of 99.9) in dry bulb temperature\n') sys.stderr.write(f'Warning: {self._path} invalid records (value of 99.9) in dry bulb temperature\n')
logger.error(f'Warning: {self._path} invalid records (value of 99.9) in dry bulb temperature\n')
if cte.HOUR not in building.external_temperature: if cte.HOUR not in building.external_temperature:
building.external_temperature[cte.HOUR] = new_value building.external_temperature[cte.HOUR] = new_value
else: else:
@ -89,6 +94,7 @@ class EpwWeatherParameters:
number_invalid_records = new_value[new_value.epw == 9999].count().epw number_invalid_records = new_value[new_value.epw == 9999].count().epw
if number_invalid_records > 0: if number_invalid_records > 0:
sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in global horizontal radiation\n') sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in global horizontal radiation\n')
logger.error(f'Warning: {self._path} invalid records (value of 9999) in global horizontal radiation\n')
if cte.HOUR not in building.global_horizontal: if cte.HOUR not in building.global_horizontal:
building.global_horizontal[cte.HOUR] = new_value building.global_horizontal[cte.HOUR] = new_value
else: else:
@ -98,6 +104,7 @@ class EpwWeatherParameters:
number_invalid_records = new_value[new_value.epw == 9999].count().epw number_invalid_records = new_value[new_value.epw == 9999].count().epw
if number_invalid_records > 0: if number_invalid_records > 0:
sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in diffuse horizontal radiation\n') sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in diffuse horizontal radiation\n')
logger.error(f'Warning: {self._path} invalid records (value of 9999) in diffuse horizontal radiation\n')
if cte.HOUR not in building.diffuse: if cte.HOUR not in building.diffuse:
building.diffuse[cte.HOUR] = new_value building.diffuse[cte.HOUR] = new_value
else: else:
@ -107,6 +114,7 @@ class EpwWeatherParameters:
number_invalid_records = new_value[new_value.epw == 9999].count().epw number_invalid_records = new_value[new_value.epw == 9999].count().epw
if number_invalid_records > 0: if number_invalid_records > 0:
sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in direct horizontal radiation\n') sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in direct horizontal radiation\n')
logger.error(f'Warning: {self._path} invalid records (value of 9999) in direct horizontal radiation\n')
if cte.HOUR not in building.beam: if cte.HOUR not in building.beam:
building.beam[cte.HOUR] = new_value building.beam[cte.HOUR] = new_value
else: else:

View File

@ -10,6 +10,7 @@ import sys
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.hub_logger import logger
class XlsWeatherParameters: class XlsWeatherParameters:
@ -32,6 +33,7 @@ class XlsWeatherParameters:
'void', 'global_horiz', 'wind_velocity', 'humidity']) 'void', 'global_horiz', 'wind_velocity', 'humidity'])
except SystemExit: except SystemExit:
sys.stderr.write(f'Error reading weather file {self._path}\n') sys.stderr.write(f'Error reading weather file {self._path}\n')
logger.error(f'Error reading weather file {self._path}\n')
sys.exit() sys.exit()
for building in self._city.buildings: for building in self._city.buildings: