113 lines
4.9 KiB
Python
113 lines
4.9 KiB
Python
|
"""
|
||
|
This project aims to assign energy systems archetype names to Montreal buildings.
|
||
|
The random assignation is based on statistical information extracted from different sources, being:
|
||
|
- For residential buildings:
|
||
|
- SHEU 2015: https://oee.nrcan.gc.ca/corporate/statistics/neud/dpa/menus/sheu/2015/tables.cfm
|
||
|
- For non-residential buildings:
|
||
|
- Montreal dataportal: https://dataportalforcities.org/north-america/canada/quebec/montreal
|
||
|
- https://www.eia.gov/consumption/commercial/data/2018/
|
||
|
"""
|
||
|
import json
|
||
|
import random
|
||
|
|
||
|
from hub.city_model_structure.building import Building
|
||
|
|
||
|
energy_systems_format = 'montreal_custom'
|
||
|
|
||
|
# parameters:
|
||
|
residential_systems_percentage = {'system 1 gas': 44,
|
||
|
'system 1 electricity': 6,
|
||
|
'system 2 gas': 0,
|
||
|
'system 2 electricity': 0,
|
||
|
'system 3 and 4 gas': 0,
|
||
|
'system 3 and 4 electricity': 0,
|
||
|
'system 5 gas': 0,
|
||
|
'system 5 electricity': 0,
|
||
|
'system 6 gas': 0,
|
||
|
'system 6 electricity': 0,
|
||
|
'system 8 gas': 44,
|
||
|
'system 8 electricity': 6}
|
||
|
|
||
|
residential_new_systems_percentage = {'PV+ASHP+GasBoiler+TES': 100,
|
||
|
'PV+ASHP+ElectricBoiler+TES': 0,
|
||
|
'PV+GSHP+GasBoiler+TES': 0,
|
||
|
'PV+GSHP+ElectricBoiler+TES': 0,
|
||
|
'PV+WSHP+GasBoiler+TES': 0,
|
||
|
'PV+WSHP+ElectricBoiler+TES': 0}
|
||
|
|
||
|
non_residential_systems_percentage = {'system 1 gas': 0,
|
||
|
'system 1 electricity': 0,
|
||
|
'system 2 gas': 0,
|
||
|
'system 2 electricity': 0,
|
||
|
'system 3 and 4 gas': 39,
|
||
|
'system 3 and 4 electricity': 36,
|
||
|
'system 5 gas': 0,
|
||
|
'system 5 electricity': 0,
|
||
|
'system 6 gas': 13,
|
||
|
'system 6 electricity': 12,
|
||
|
'system 8 gas': 0,
|
||
|
'system 8 electricity': 0}
|
||
|
|
||
|
|
||
|
def _retrieve_buildings(path, year_of_construction_field=None,
|
||
|
function_field=None, function_to_hub=None, aliases_field=None):
|
||
|
_buildings = []
|
||
|
with open(path, 'r', encoding='utf8') as json_file:
|
||
|
_geojson = json.loads(json_file.read())
|
||
|
for feature in _geojson['features']:
|
||
|
_building = {}
|
||
|
year_of_construction = None
|
||
|
if year_of_construction_field is not None:
|
||
|
year_of_construction = int(feature['properties'][year_of_construction_field])
|
||
|
function = None
|
||
|
if function_field is not None:
|
||
|
function = feature['properties'][function_field]
|
||
|
if function_to_hub is not None:
|
||
|
# use the transformation dictionary to retrieve the proper function
|
||
|
if function in function_to_hub:
|
||
|
function = function_to_hub[function]
|
||
|
building_name = ''
|
||
|
building_aliases = []
|
||
|
if 'id' in feature:
|
||
|
building_name = feature['id']
|
||
|
if aliases_field is not None:
|
||
|
for alias_field in aliases_field:
|
||
|
building_aliases.append(feature['properties'][alias_field])
|
||
|
_building['year_of_construction'] = year_of_construction
|
||
|
_building['function'] = function
|
||
|
_building['building_name'] = building_name
|
||
|
_building['building_aliases'] = building_aliases
|
||
|
_buildings.append(_building)
|
||
|
return _buildings
|
||
|
|
||
|
|
||
|
def call_random(_buildings: [Building], _systems_percentage):
|
||
|
_buildings_with_systems = []
|
||
|
_systems_distribution = []
|
||
|
_selected_buildings = list(range(0, len(_buildings)))
|
||
|
random.shuffle(_selected_buildings)
|
||
|
total = 0
|
||
|
maximum = 0
|
||
|
add_to = 0
|
||
|
for _system in _systems_percentage:
|
||
|
if _systems_percentage[_system] > 0:
|
||
|
number_of_buildings = round(_systems_percentage[_system] / 100 * len(_selected_buildings))
|
||
|
_systems_distribution.append({'system': _system, 'number': _systems_percentage[_system],
|
||
|
'number_of_buildings': number_of_buildings})
|
||
|
if number_of_buildings > maximum:
|
||
|
maximum = number_of_buildings
|
||
|
add_to = len(_systems_distribution) - 1
|
||
|
total += number_of_buildings
|
||
|
missing = 0
|
||
|
if total != len(_selected_buildings):
|
||
|
missing = len(_selected_buildings) - total
|
||
|
if missing != 0:
|
||
|
_systems_distribution[add_to]['number_of_buildings'] += missing
|
||
|
_position = 0
|
||
|
for case in _systems_distribution:
|
||
|
for i in range(0, case['number_of_buildings']):
|
||
|
_buildings[_selected_buildings[_position]].energy_systems_archetype_name = case['system']
|
||
|
_position += 1
|
||
|
return _buildings
|
||
|
|