<jupyter_start><jupyter_text>Part 3: City district objectThe city district object of pycity is an inheritance of the uesgraph object of uesgraphs package, which itself is an inheritance of networkx.Graph.If you are not familiar with networkx.Graph or uesgraph, please go through the uesgraphs tutorial first. You can access it within the uesgraphs package, which is available under:[UESGraphs](https://github.com/RWTH-EBC/uesgraphs)You can install it locally via pip. Open a console and type:'pip install -e your_path_to_uesgraphs' (with your local path to uesgraphs package)If you have not installed it, please do so now, because you are going to need it to execute the following lines.<jupyter_code>import pycity_base.classes.timer as Timer
import pycity_base.classes.weather as Weather
import pycity_base.classes.prices as Prices
import pycity_base.classes.environment as Env

#  Setting up environment
#  Timestep in seconds
timestep = 3600

#  Total number of timesteps
timesteps_total = int(365 * 24 * 3600 / timestep)

#   Generate timer object for environment
timer = Timer.Timer(time_discretization=timestep, timesteps_total=timesteps_total, 
                    timesteps_used_horizon=timesteps_total, timesteps_horizon=timesteps_total)
#  Timer object holds timestep, number of timesteps as well as
#  forecast horizon

#  Generate weather object
weather = Weather.Weather(timer)
#  Weather object holds weather data, such as outdoor temperatures,
#  direct and diffuse radiation
#  Default TRY value is TRY2010_05_Jahr.dat
#  (Test reference year 2010 for region 5 in Germany)

#  Generate price object
price = Prices.Prices()
#  Holding energy prices and subsidies

#  Generate environment object
environment = Env.Environment(timer=timer, weather=weather, prices=price)

print(environment)

import pycity_base.classes.city_district as CityDistrict

#  Generate city district object
city_district = CityDistrict.CityDistrict(environment)
#  You can generate a CityDistrict object without handing over the environment. This is done to enable some 
#  networkx functions for the citydistrict object. However, you should add the environment either way,
#  because you will not be able to work with your district later on, if the environment pointer is missing!
#  Thus, we recommmend to add the environment pointer directly!

print(city_district)<jupyter_output><uesgraphs.UESGraph object><jupyter_text>Now we will generate 3 single family buildings with loads and add them to the city district object<jupyter_code>import random
import sympy.geometry.point as point

import pycity_base.classes.demand.domestic_hot_water as DomesticHotWater
import pycity_base.classes.demand.electrical_demand as ElectricalDemand
import pycity_base.classes.demand.space_heating as SpaceHeating

import pycity_base.classes.demand.apartment as Apartment
import pycity_base.classes.building as Building


#  Loop to generate building objects
for i in range(3):
    
    #  Generate space heating object
    heat_demand = SpaceHeating.SpaceHeating(environment,
                                            method=1,  # Standard load profile
                                            living_area=150,
                                            specific_demand=100)

    #  Generate electrical demand object
    el_demand = ElectricalDemand.ElectricalDemand(environment,
                                                  method=1,  # Standard load profile
                                                  annual_demand=3000)

    #  Generate domestic hot water demand object
    dhw_annex42 = DomesticHotWater.DomesticHotWater(environment,
                                                    t_flow=60,
                                                    thermal=True,
                                                    method=1,  # Annex 42
                                                    daily_consumption=70,
                                                    supply_temperature=25)
    
    #  Generate apartment and add load objects
    apartment = Apartment.Apartment(environment)
    apartment.addEntity(heat_demand)
    apartment.addMultipleEntities([el_demand, dhw_annex42])
    
    #  Generate building and add apartment
    building = Building.Building(environment)
    building.addEntity(entity=apartment)
    
    #  Generate sympy point positions (with random coordinates)
    position = point.Point(random.randint(0, 100), random.randint(0, 100))
    
    #  Add buildings to city district
    city_district.addEntity(entity=building, position=position)

print('Number of building entities:')
print(city_district.get_nb_of_building_entities())<jupyter_output>Number of building entities:
3<jupyter_text>You can also add pv- or wind farms to the city district:<jupyter_code>import pycity_base.classes.supply.photovoltaic as PV

#  Generate PV field within city district
pv = PV.PV(environment=environment, method=0, area=20, eta_noct=0.15)

#  Generate sympy point positions
position_1 = point.Point(0, 0)

#  Add PV fields to city district
city_district.addEntity(entity=pv, position=position_1)

print('Number of PV farms:')
print(city_district.get_nb_of_entities(entity_name='pv'))<jupyter_output>Number of PV farms:
1<jupyter_text>CAUTION: If you add pv- or windfarms to the city district, the number of buildings is not the same as tne length of nodelist_building. The reason is, that pv- and windfarms are also handled as building nodes within uesgraph. If you deal with building nodes, you should also check the _kind of entity within the node!<jupyter_code>assert len(city_district.nodelist_building) == city_district.get_nb_of_building_entities()+1,\
    'Be aware that PV units and wind energy converters are also handled as building nodes in uesgraph!'
#  Get complete node information of city district (possible, because city district is a graph)

print('Node information:')
print(city_district.nodes(data=True))
print()

print('Node numbers only:')
print(city_district.nodes())<jupyter_output>Node information:
[(1001, {'name': 1001, 'node_type': 'building', 'position': Point2D(87, 32), 'is_supply_heating': False, 'is_supply_cooling': False, 'is_supply_electricity': False, 'is_supply_gas': False, 'is_supply_other': False, 'entity': <pycity_base.classes.building.Building object at 0x00000220C02A3F60>}), (1002, {'name': 1002, 'node_type': 'building', 'position': Point2D(71, 78), 'is_supply_heating': False, 'is_supply_cooling': False, 'is_supply_electricity': False, 'is_supply_gas': False, 'is_supply_other': False, 'entity': <pycity_base.classes.building.Building object at 0x00000220BEA1B048>}), (1003, {'name': 1003, 'node_type': 'building', 'position': Point2D(38, 62), 'is_supply_heating': False, 'is_supply_cooling': False, 'is_supply_electricity': False, 'is_supply_gas': False, 'is_supply_other': False, 'entity': <pycity_base.classes.building.Building object at 0x00000220ACB92860>}), (1004, {'name': 1004, 'node_type': 'building', 'position': Point2D(0, 0), 'is_supply_heating'[...]<jupyter_text>CityDistrict holds further methods. Some are shown below:<jupyter_code>print('Get number of building objects:')
print(city_district.get_nb_of_building_entities())
print()

print('Get list of nodes with building objects:')
print(city_district.get_list_build_entity_node_ids())<jupyter_output>Get number of building objects:
3

Get list of nodes with building objects:
[1001, 1002, 1003]<jupyter_text>It is also possible to extract aggregated load curves of all building objects<jupyter_code>aggr_load_curve = city_district.get_aggr_space_heating_power_curve()

print(aggr_load_curve)<jupyter_output>[5682.09607927 5830.32467264 5978.55326602 ... 7451.04147065 5086.44155188
 3708.50922512]
{'fraction_non_alphanumeric': 0.07717208338728473, 'fraction_numerical': 0.03224135698562735, 'mean_word_length': 4.084924292297564, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '533066', 'license': 'MIT', 'n_tokens_mistral': 2421, 'n_tokens_neox': 2167, 'n_words': 686, 'path': 'pycity_base/examples/tutorials/tutorial_pycity_base_2.ipynb', 'repo_name': 'RWTH-EBC/pyCity', 'size': '7723'}