From 75e7c88e53a85bad86adef4d0e717c1ef964ac74 Mon Sep 17 00:00:00 2001 From: Martin Skorupski Date: Fri, 3 Nov 2023 17:20:20 +0100 Subject: [PATCH] Reformat files according to template - done - (nice!) Issue-ID: OAM-387 Change-Id: Ia38b6b4567bc9a3402a57b856be09f37dafe6e6d Signed-off-by: Martin Skorupski --- code/network-generator/CONTRIBUTING.md | 6 + code/network-generator/network_generation/base.py | 1 + code/network-generator/network_generation/cli.py | 19 +- .../network_generation/model/python/countries.py | 391 +++++++++++---------- .../model/python/geo_location.py | 59 ++-- .../network_generation/model/python/hexagon.py | 85 +++-- .../network_generation/model/python/nr_cell_du.py | 44 ++- .../model/python/o_ran_cloud_du.py | 36 +- .../network_generation/model/python/o_ran_cu.py | 37 +- .../network_generation/model/python/o_ran_du.py | 39 +- .../model/python/o_ran_near_rt_ric.py | 35 +- .../model/python/o_ran_network.py | 42 ++- .../network_generation/model/python/o_ran_node.py | 56 ++- .../network_generation/model/python/o_ran_ru.py | 34 +- .../network_generation/model/python/o_ran_smo.py | 34 +- .../model/python/o_ran_spiral_radius_profile.py | 23 +- .../model/python/o_ran_termination_point.py | 14 +- .../network_generation/model/python/point.py | 4 +- .../network_generation/model/python/top.py | 17 +- .../network_generation/model/python/tower.py | 58 +-- .../model/python/type_definitions.py | 1 + .../network_generation/parameter_validator.py | 3 +- .../network_generation/view/network_viewer.py | 13 +- 23 files changed, 633 insertions(+), 418 deletions(-) diff --git a/code/network-generator/CONTRIBUTING.md b/code/network-generator/CONTRIBUTING.md index edddb6f..d045207 100644 --- a/code/network-generator/CONTRIBUTING.md +++ b/code/network-generator/CONTRIBUTING.md @@ -14,6 +14,12 @@ This instructions are for linux base systems. (Linux, MacOS, BSD, etc.) - Enter the directory `cd oam/code/network-generation` - Please see [O-RAN-SC Code Contributions Tutorial](https://wiki.o-ran-sc.org/display/ORAN/Tutorial%3A+Making+code+contributions+to+O-RAN+open+source+project) +## Prerequisites + +``` +pip install isort +pip install black +``` ## Setting up your own virtual environment diff --git a/code/network-generator/network_generation/base.py b/code/network-generator/network_generation/base.py index 2261295..7fe3964 100644 --- a/code/network-generator/network_generation/base.py +++ b/code/network-generator/network_generation/base.py @@ -25,6 +25,7 @@ from network_generation.model.python.o_ran_network import ORanNetwork # example constant variable NAME = "network_generation" + class NetworkGenerator: """ Class containing all methods to generate a network. diff --git a/code/network-generator/network_generation/cli.py b/code/network-generator/network_generation/cli.py index 53c844b..ada37e1 100644 --- a/code/network-generator/network_generation/cli.py +++ b/code/network-generator/network_generation/cli.py @@ -25,16 +25,16 @@ Be creative! do whatever you want! """ - """ Module as entry point to generate an ietf topology json """ import os import sys -from network_generation.view.network_viewer import NetworkViewer from network_generation.base import NetworkGenerator from network_generation.parameter_validator import ParameterValidator +from network_generation.view.network_viewer import NetworkViewer + def main(): # pragma: no cover """ @@ -46,32 +46,31 @@ def main(): # pragma: no cover if validator.is_valid(): configuration = validator.configuration() - generator = NetworkGenerator(configuration['network']) + generator = NetworkGenerator(configuration["network"]) network = generator.generate() viewer = NetworkViewer(network) - output_folder:str = configuration['output-folder'] + output_folder: str = configuration["output-folder"] # If folder doesn't exist, then create it. if not os.path.isdir(output_folder): os.makedirs(output_folder) - - name: str = configuration['network']['name'] + + name: str = configuration["network"]["name"] # topology json - if configuration['generation-tasks']['topology'] is True: + if configuration["generation-tasks"]["topology"] is True: filename: str = output_folder + "/" + name + "-operational.json" viewer.json().save(filename) # svg xml - if configuration['generation-tasks']['svg'] is True: + if configuration["generation-tasks"]["svg"] is True: filename: str = output_folder + "/" + name + ".svg" viewer.svg(filename) # kml xml - if configuration['generation-tasks']['kml'] is True: + if configuration["generation-tasks"]["kml"] is True: filename: str = output_folder + "/" + name + ".kml" viewer.kml(filename) else: print(validator.error_message()) - diff --git a/code/network-generator/network_generation/model/python/countries.py b/code/network-generator/network_generation/model/python/countries.py index 0598176..44e4eab 100644 --- a/code/network-generator/network_generation/model/python/countries.py +++ b/code/network-generator/network_generation/model/python/countries.py @@ -19,201 +19,202 @@ A TypeDefinition as enum for countries """ from enum import Enum + # Define Country enum class Country(Enum): - Afghanistan = 'Afghanistan' - Albania = 'Albania' - Algeria = 'Algeria' - Andorra = 'Andorra' - Angola = 'Angola' - AntiguaAndBarbuda = 'Antigua and Barbuda' - Argentina = 'Argentina' - Armenia = 'Armenia' - Australia = 'Australia' - Austria = 'Austria' - Azerbaijan = 'Azerbaijan' - Bahamas = 'Bahamas' - Bahrain = 'Bahrain' - Bangladesh = 'Bangladesh' - Barbados = 'Barbados' - Belarus = 'Belarus' - Belgium = 'Belgium' - Belize = 'Belize' - Benin = 'Benin' - Bhutan = 'Bhutan' - Bolivia = 'Bolivia' - BosniaAndHerzegovina = 'Bosnia and Herzegovina' - Botswana = 'Botswana' - Brazil = 'Brazil' - Brunei = 'Brunei' - Bulgaria = 'Bulgaria' - BurkinaFaso = 'Burkina Faso' - Burundi = 'Burundi' - CaboVerde = 'Cabo Verde' - Cambodia = 'Cambodia' - Cameroon = 'Cameroon' - Canada = 'Canada' - CentralAfricanRepublic = 'Central African Republic' - Chad = 'Chad' - Chile = 'Chile' - China = 'China' - Colombia = 'Colombia' - Comoros = 'Comoros' - CongoDemocraticRepublic = 'Congo (Democratic Republic of the)' - CongoRepublic = 'Congo (Republic of the)' - CostaRica = 'Costa Rica' + Afghanistan = "Afghanistan" + Albania = "Albania" + Algeria = "Algeria" + Andorra = "Andorra" + Angola = "Angola" + AntiguaAndBarbuda = "Antigua and Barbuda" + Argentina = "Argentina" + Armenia = "Armenia" + Australia = "Australia" + Austria = "Austria" + Azerbaijan = "Azerbaijan" + Bahamas = "Bahamas" + Bahrain = "Bahrain" + Bangladesh = "Bangladesh" + Barbados = "Barbados" + Belarus = "Belarus" + Belgium = "Belgium" + Belize = "Belize" + Benin = "Benin" + Bhutan = "Bhutan" + Bolivia = "Bolivia" + BosniaAndHerzegovina = "Bosnia and Herzegovina" + Botswana = "Botswana" + Brazil = "Brazil" + Brunei = "Brunei" + Bulgaria = "Bulgaria" + BurkinaFaso = "Burkina Faso" + Burundi = "Burundi" + CaboVerde = "Cabo Verde" + Cambodia = "Cambodia" + Cameroon = "Cameroon" + Canada = "Canada" + CentralAfricanRepublic = "Central African Republic" + Chad = "Chad" + Chile = "Chile" + China = "China" + Colombia = "Colombia" + Comoros = "Comoros" + CongoDemocraticRepublic = "Congo (Democratic Republic of the)" + CongoRepublic = "Congo (Republic of the)" + CostaRica = "Costa Rica" CoteDIvoire = "Côte d'Ivoire" - Croatia = 'Croatia' - Cuba = 'Cuba' - Cyprus = 'Cyprus' - CzechRepublic = 'Czech Republic' - Denmark = 'Denmark' - Djibouti = 'Djibouti' - Dominica = 'Dominica' - DominicanRepublic = 'Dominican Republic' - Ecuador = 'Ecuador' - Egypt = 'Egypt' - ElSalvador = 'El Salvador' - EquatorialGuinea = 'Equatorial Guinea' - Eritrea = 'Eritrea' - Estonia = 'Estonia' - Eswatini = 'Eswatini' - Ethiopia = 'Ethiopia' - Fiji = 'Fiji' - Finland = 'Finland' - France = 'France' - Gabon = 'Gabon' - Gambia = 'Gambia' - Georgia = 'Georgia' - Germany = 'Germany' - Ghana = 'Ghana' - Greece = 'Greece' - Grenada = 'Grenada' - Guatemala = 'Guatemala' - Guinea = 'Guinea' - GuineaBissau = 'Guinea-Bissau' - Guyana = 'Guyana' - Haiti = 'Haiti' - Honduras = 'Honduras' - Hungary = 'Hungary' - Iceland = 'Iceland' - India = 'India' - Indonesia = 'Indonesia' - Iran = 'Iran' - Iraq = 'Iraq' - Ireland = 'Ireland' - Israel = 'Israel' - Italy = 'Italy' - Jamaica = 'Jamaica' - Japan = 'Japan' - Jordan = 'Jordan' - Kazakhstan = 'Kazakhstan' - Kenya = 'Kenya' - Kiribati = 'Kiribati' - KoreaNorth = 'Korea (North)' - KoreaSouth = 'Korea (South)' - Kosovo = 'Kosovo' - Kuwait = 'Kuwait' - Kyrgyzstan = 'Kyrgyzstan' - Laos = 'Laos' - Latvia = 'Latvia' - Lebanon = 'Lebanon' - Lesotho = 'Lesotho' - Liberia = 'Liberia' - Libya = 'Libya' - Liechtenstein = 'Liechtenstein' - Lithuania = 'Lithuania' - Luxembourg = 'Luxembourg' - Madagascar = 'Madagascar' - Malawi = 'Malawi' - Malaysia = 'Malaysia' - Maldives = 'Maldives' - Mali = 'Mali' - Malta = 'Malta' - MarshallIslands = 'Marshall Islands' - Mauritania = 'Mauritania' - Mauritius = 'Mauritius' - Mexico = 'Mexico' - Micronesia = 'Micronesia' - Moldova = 'Moldova' - Monaco = 'Monaco' - Mongolia = 'Mongolia' - Montenegro = 'Montenegro' - Morocco = 'Morocco' - Mozambique = 'Mozambique' - Myanmar = 'Myanmar' - Namibia = 'Namibia' - Nauru = 'Nauru' - Nepal = 'Nepal' - Netherlands = 'Netherlands' - NewZealand = 'New Zealand' - Nicaragua = 'Nicaragua' - Niger = 'Niger' - Nigeria = 'Nigeria' - NorthMacedonia = 'North Macedonia' - Norway = 'Norway' - Oman = 'Oman' - Pakistan = 'Pakistan' - Palau = 'Palau' - Panama = 'Panama' - PapuaNewGuinea = 'Papua New Guinea' - Paraguay = 'Paraguay' - Peru = 'Peru' - Philippines = 'Philippines' - Poland = 'Poland' - Portugal = 'Portugal' - Qatar = 'Qatar' - Romania = 'Romania' - Russia = 'Russia' - Rwanda = 'Rwanda' - SaintKittsAndNevis = 'Saint Kitts and Nevis' - SaintLucia = 'Saint Lucia' - SaintVincentAndGrenadines = 'Saint Vincent and the Grenadines' - Samoa = 'Samoa' - SanMarino = 'San Marino' - SaoTomeAndPrincipe = 'Sao Tome and Principe' - SaudiArabia = 'Saudi Arabia' - Senegal = 'Senegal' - Serbia = 'Serbia' - Seychelles = 'Seychelles' - SierraLeone = 'Sierra Leone' - Singapore = 'Singapore' - Slovakia = 'Slovakia' - Slovenia = 'Slovenia' - SolomonIslands = 'Solomon Islands' - Somalia = 'Somalia' - SouthAfrica = 'South Africa' - SouthSudan = 'South Sudan' - Spain = 'Spain' - SriLanka = 'Sri Lanka' - Sudan = 'Sudan' - Suriname = 'Suriname' - Sweden = 'Sweden' - Switzerland = 'Switzerland' - Syria = 'Syria' - Taiwan = 'Taiwan' - Tajikistan = 'Tajikistan' - Tanzania = 'Tanzania' - Thailand = 'Thailand' - TimorLeste = 'Timor-Leste' - Togo = 'Togo' - Tonga = 'Tonga' - TrinidadAndTobago = 'Trinidad and Tobago' - Tunisia = 'Tunisia' - Turkey = 'Turkey' - Turkmenistan = 'Turkmenistan' - Tuvalu = 'Tuvalu' - Uganda = 'Uganda' - Ukraine = 'Ukraine' - UnitedArabEmirates = 'United Arab Emirates' - UnitedKingdom = 'United Kingdom' - UnitedStates = 'United States' - Uruguay = 'Uruguay' - Uzbekistan = 'Uzbekistan' - Vanuatu = 'Vanuatu' - VaticanCity = 'Vatican City' - Venezuela = 'Venezuela' - Vietnam = 'Vietnam' - Yemen = 'Yemen' - Zambia = 'Zambia' - Zimbabwe = 'Zimbabwe' \ No newline at end of file + Croatia = "Croatia" + Cuba = "Cuba" + Cyprus = "Cyprus" + CzechRepublic = "Czech Republic" + Denmark = "Denmark" + Djibouti = "Djibouti" + Dominica = "Dominica" + DominicanRepublic = "Dominican Republic" + Ecuador = "Ecuador" + Egypt = "Egypt" + ElSalvador = "El Salvador" + EquatorialGuinea = "Equatorial Guinea" + Eritrea = "Eritrea" + Estonia = "Estonia" + Eswatini = "Eswatini" + Ethiopia = "Ethiopia" + Fiji = "Fiji" + Finland = "Finland" + France = "France" + Gabon = "Gabon" + Gambia = "Gambia" + Georgia = "Georgia" + Germany = "Germany" + Ghana = "Ghana" + Greece = "Greece" + Grenada = "Grenada" + Guatemala = "Guatemala" + Guinea = "Guinea" + GuineaBissau = "Guinea-Bissau" + Guyana = "Guyana" + Haiti = "Haiti" + Honduras = "Honduras" + Hungary = "Hungary" + Iceland = "Iceland" + India = "India" + Indonesia = "Indonesia" + Iran = "Iran" + Iraq = "Iraq" + Ireland = "Ireland" + Israel = "Israel" + Italy = "Italy" + Jamaica = "Jamaica" + Japan = "Japan" + Jordan = "Jordan" + Kazakhstan = "Kazakhstan" + Kenya = "Kenya" + Kiribati = "Kiribati" + KoreaNorth = "Korea (North)" + KoreaSouth = "Korea (South)" + Kosovo = "Kosovo" + Kuwait = "Kuwait" + Kyrgyzstan = "Kyrgyzstan" + Laos = "Laos" + Latvia = "Latvia" + Lebanon = "Lebanon" + Lesotho = "Lesotho" + Liberia = "Liberia" + Libya = "Libya" + Liechtenstein = "Liechtenstein" + Lithuania = "Lithuania" + Luxembourg = "Luxembourg" + Madagascar = "Madagascar" + Malawi = "Malawi" + Malaysia = "Malaysia" + Maldives = "Maldives" + Mali = "Mali" + Malta = "Malta" + MarshallIslands = "Marshall Islands" + Mauritania = "Mauritania" + Mauritius = "Mauritius" + Mexico = "Mexico" + Micronesia = "Micronesia" + Moldova = "Moldova" + Monaco = "Monaco" + Mongolia = "Mongolia" + Montenegro = "Montenegro" + Morocco = "Morocco" + Mozambique = "Mozambique" + Myanmar = "Myanmar" + Namibia = "Namibia" + Nauru = "Nauru" + Nepal = "Nepal" + Netherlands = "Netherlands" + NewZealand = "New Zealand" + Nicaragua = "Nicaragua" + Niger = "Niger" + Nigeria = "Nigeria" + NorthMacedonia = "North Macedonia" + Norway = "Norway" + Oman = "Oman" + Pakistan = "Pakistan" + Palau = "Palau" + Panama = "Panama" + PapuaNewGuinea = "Papua New Guinea" + Paraguay = "Paraguay" + Peru = "Peru" + Philippines = "Philippines" + Poland = "Poland" + Portugal = "Portugal" + Qatar = "Qatar" + Romania = "Romania" + Russia = "Russia" + Rwanda = "Rwanda" + SaintKittsAndNevis = "Saint Kitts and Nevis" + SaintLucia = "Saint Lucia" + SaintVincentAndGrenadines = "Saint Vincent and the Grenadines" + Samoa = "Samoa" + SanMarino = "San Marino" + SaoTomeAndPrincipe = "Sao Tome and Principe" + SaudiArabia = "Saudi Arabia" + Senegal = "Senegal" + Serbia = "Serbia" + Seychelles = "Seychelles" + SierraLeone = "Sierra Leone" + Singapore = "Singapore" + Slovakia = "Slovakia" + Slovenia = "Slovenia" + SolomonIslands = "Solomon Islands" + Somalia = "Somalia" + SouthAfrica = "South Africa" + SouthSudan = "South Sudan" + Spain = "Spain" + SriLanka = "Sri Lanka" + Sudan = "Sudan" + Suriname = "Suriname" + Sweden = "Sweden" + Switzerland = "Switzerland" + Syria = "Syria" + Taiwan = "Taiwan" + Tajikistan = "Tajikistan" + Tanzania = "Tanzania" + Thailand = "Thailand" + TimorLeste = "Timor-Leste" + Togo = "Togo" + Tonga = "Tonga" + TrinidadAndTobago = "Trinidad and Tobago" + Tunisia = "Tunisia" + Turkey = "Turkey" + Turkmenistan = "Turkmenistan" + Tuvalu = "Tuvalu" + Uganda = "Uganda" + Ukraine = "Ukraine" + UnitedArabEmirates = "United Arab Emirates" + UnitedKingdom = "United Kingdom" + UnitedStates = "United States" + Uruguay = "Uruguay" + Uzbekistan = "Uzbekistan" + Vanuatu = "Vanuatu" + VaticanCity = "Vatican City" + Venezuela = "Venezuela" + Vietnam = "Vietnam" + Yemen = "Yemen" + Zambia = "Zambia" + Zimbabwe = "Zimbabwe" diff --git a/code/network-generator/network_generation/model/python/geo_location.py b/code/network-generator/network_generation/model/python/geo_location.py index a94d5e7..3b6793a 100644 --- a/code/network-generator/network_generation/model/python/geo_location.py +++ b/code/network-generator/network_generation/model/python/geo_location.py @@ -18,25 +18,32 @@ A collection of TypeDefinitions for a geographical location """ import math + from network_generation.model.python.point import Point class IGeoLocationData: - - def __init__(self, latitude: float, longitude: float, aboveMeanSeaLevel: float): + def __init__( + self, latitude: float, longitude: float, aboveMeanSeaLevel: float + ): self.latitude = latitude self.longitude = longitude self.aboveMeanSeaLevel = aboveMeanSeaLevel -class IGeoLocation: - def __init__(self, latitude: float = 0, longitude: float = 0, aboveMeanSeaLevel: float = 0): +class IGeoLocation: + def __init__( + self, + latitude: float = 0, + longitude: float = 0, + aboveMeanSeaLevel: float = 0, + ): self.latitude = latitude self.longitude = longitude self.aboveMeanSeaLevel = aboveMeanSeaLevel - def __str__(self)-> str: - return f'lat : {self.latitude} : lon : {self.longitude} : amsl : {self.aboveMeanSeaLevel}' + def __str__(self) -> str: + return f"lat : {self.latitude} : lon : {self.longitude} : amsl : {self.aboveMeanSeaLevel}" class GeoLocation(IGeoLocation): @@ -45,9 +52,9 @@ class GeoLocation(IGeoLocation): def __init__(self, geoLocation: IGeoLocationData = None): super().__init__( - geoLocation['latitude'] if geoLocation else 0, - geoLocation['longitude'] if geoLocation else 0, - geoLocation['aboveMeanSeaLevel'] if geoLocation else 0 + geoLocation["latitude"] if geoLocation else 0, + geoLocation["longitude"] if geoLocation else 0, + geoLocation["aboveMeanSeaLevel"] if geoLocation else 0, ) @property @@ -55,30 +62,34 @@ class GeoLocation(IGeoLocation): return GeoLocation._equatorialRadius @property - def polarRadius(self)-> int: + def polarRadius(self) -> int: return GeoLocation._polarRadius def set_latitude(self, value: float): if not (-90 <= value <= 90): - raise ValueError('Invalid latitude. Latitude must be between -90 and 90.') + raise ValueError( + "Invalid latitude. Latitude must be between -90 and 90." + ) self.latitude = value def set_longitude(self, value: float): if not (-180 <= value <= 180): - raise ValueError('Invalid longitude. Longitude must be between -180 and 180.') + raise ValueError( + "Invalid longitude. Longitude must be between -180 and 180." + ) self.longitude = value def json(self) -> dict[str, float]: return { - "latitude": self.latitude, - "longitude": self.longitude, - "aboveMeanSeaLevel": self.aboveMeanSeaLevel, + "latitude": self.latitude, + "longitude": self.longitude, + "aboveMeanSeaLevel": self.aboveMeanSeaLevel, } - + def __str__(self) -> str: return str(self.json()) - - def point_to_geo_location(self, point:Point): + + def point_to_geo_location(self, point: Point): """ A static function which converts a point in pixels into a geographical location when the self is represented as Point(0,0) @@ -86,12 +97,16 @@ class GeoLocation(IGeoLocation): returns The converted GeoLocation object. """ equatorialRadius = 6378137 # meters - new_lat = self.latitude + (point.y / equatorialRadius) * (180 / math.pi) - new_lon = self.longitude + (point.x / equatorialRadius) * (180 / math.pi) / math.cos(self.latitude * math.pi / 180) + new_lat = self.latitude + (point.y / equatorialRadius) * ( + 180 / math.pi + ) + new_lon = self.longitude + (point.x / equatorialRadius) * ( + 180 / math.pi + ) / math.cos(self.latitude * math.pi / 180) geo_location: IGeoLocationData = { "longitude": new_lon, "latitude": new_lat, - "aboveMeanSeaLevel": self.aboveMeanSeaLevel + "aboveMeanSeaLevel": self.aboveMeanSeaLevel, } - return GeoLocation(geo_location) \ No newline at end of file + return GeoLocation(geo_location) diff --git a/code/network-generator/network_generation/model/python/hexagon.py b/code/network-generator/network_generation/model/python/hexagon.py index 489b294..5a81c23 100644 --- a/code/network-generator/network_generation/model/python/hexagon.py +++ b/code/network-generator/network_generation/model/python/hexagon.py @@ -16,14 +16,14 @@ #!/usr/bin/python -from __future__ import division -from __future__ import print_function +from __future__ import division, print_function + import collections import math from typing import NamedTuple -from network_generation.model.python.point import Point from network_generation.model.python.geo_location import GeoLocation +from network_generation.model.python.point import Point class Hex: @@ -117,7 +117,9 @@ def hex_round(hex: Hex) -> Hex: def hex_lerp(a: Hex, b: Hex, t: int) -> Hex: # linearly interpolation return Hex( - a.q * (1.0 - t) + b.q * t, a.r * (1.0 - t) + b.r * t, a.s * (1.0 - t) + b.s * t + a.q * (1.0 - t) + b.q * t, + a.r * (1.0 - t) + b.r * t, + a.s * (1.0 - t) + b.s * t, ) @@ -202,7 +204,8 @@ def rdoubled_to_cube(hex: Hex): Orientation = collections.namedtuple( - "Orientation", ["f0", "f1", "f2", "f3", "b0", "b1", "b2", "b3", "start_angle"] + "Orientation", + ["f0", "f1", "f2", "f3", "b0", "b1", "b2", "b3", "start_angle"], ) @@ -315,7 +318,9 @@ def equal_hex_array(name, a, b): def test_hex_arithmetic(): equal_hex("hex_add", Hex(4, -10, 6), hex_add(Hex(1, -3, 2), Hex(3, -7, 4))) equal_hex( - "hex_subtract", Hex(-2, 4, -2), hex_subtract(Hex(1, -3, 2), Hex(3, -7, 4)) + "hex_subtract", + Hex(-2, 4, -2), + hex_subtract(Hex(1, -3, 2), Hex(3, -7, 4)), ) @@ -328,7 +333,9 @@ def test_hex_neighbor(): def test_hex_diagonal(): - equal_hex("hex_diagonal", Hex(-1, -1, 2), hex_diagonal_neighbor(Hex(1, -2, 1), 3)) + equal_hex( + "hex_diagonal", Hex(-1, -1, 2), hex_diagonal_neighbor(Hex(1, -2, 1), 3) + ) def test_hex_distance(): @@ -336,11 +343,15 @@ def test_hex_distance(): def test_hex_rotate_right(): - equal_hex("hex_rotate_right", hex_rotate_right(Hex(1, -3, 2)), Hex(3, -2, -1)) + equal_hex( + "hex_rotate_right", hex_rotate_right(Hex(1, -3, 2)), Hex(3, -2, -1) + ) def test_hex_rotate_left(): - equal_hex("hex_rotate_left", hex_rotate_left(Hex(1, -3, 2)), Hex(-2, -1, 3)) + equal_hex( + "hex_rotate_left", hex_rotate_left(Hex(1, -3, 2)), Hex(-2, -1, 3) + ) def test_hex_round(): @@ -396,9 +407,13 @@ def test_hex_linedraw(): def test_layout(): h = Hex(3, 4, -7) flat = Layout(layout_flat, Point(10.0, 15.0), Point(35.0, 71.0)) - equal_hex("layout", h, hex_round(pixel_to_hex(flat, hex_to_pixel(flat, h)))) + equal_hex( + "layout", h, hex_round(pixel_to_hex(flat, hex_to_pixel(flat, h))) + ) pointy = Layout(layout_pointy, Point(10.0, 15.0), Point(35.0, 71.0)) - equal_hex("layout", h, hex_round(pixel_to_hex(pointy, hex_to_pixel(pointy, h)))) + equal_hex( + "layout", h, hex_round(pixel_to_hex(pointy, hex_to_pixel(pointy, h))) + ) def test_offset_roundtrip(): @@ -415,10 +430,14 @@ def test_offset_roundtrip(): qoffset_from_cube(EVEN, qoffset_to_cube(EVEN, b)), ) equal_hex( - "conversion_roundtrip odd-q", a, qoffset_to_cube(ODD, qoffset_from_cube(ODD, a)) + "conversion_roundtrip odd-q", + a, + qoffset_to_cube(ODD, qoffset_from_cube(ODD, a)), ) equal_offsetcoord( - "conversion_roundtrip odd-q", b, qoffset_from_cube(ODD, qoffset_to_cube(ODD, b)) + "conversion_roundtrip odd-q", + b, + qoffset_from_cube(ODD, qoffset_to_cube(ODD, b)), ) equal_hex( "conversion_roundtrip even-r", @@ -431,10 +450,14 @@ def test_offset_roundtrip(): roffset_from_cube(EVEN, roffset_to_cube(EVEN, b)), ) equal_hex( - "conversion_roundtrip odd-r", a, roffset_to_cube(ODD, roffset_from_cube(ODD, a)) + "conversion_roundtrip odd-r", + a, + roffset_to_cube(ODD, roffset_from_cube(ODD, a)), ) equal_offsetcoord( - "conversion_roundtrip odd-r", b, roffset_from_cube(ODD, roffset_to_cube(ODD, b)) + "conversion_roundtrip odd-r", + b, + roffset_from_cube(ODD, roffset_to_cube(ODD, b)), ) @@ -453,10 +476,14 @@ def test_offset_from_cube(): def test_offset_to_cube(): equal_hex( - "offset_to_cube even-", Hex(1, 2, -3), qoffset_to_cube(EVEN, OffsetCoord(1, 3)) + "offset_to_cube even-", + Hex(1, 2, -3), + qoffset_to_cube(EVEN, OffsetCoord(1, 3)), ) equal_hex( - "offset_to_cube odd-q", Hex(1, 2, -3), qoffset_to_cube(ODD, OffsetCoord(1, 2)) + "offset_to_cube odd-q", + Hex(1, 2, -3), + qoffset_to_cube(ODD, OffsetCoord(1, 2)), ) @@ -464,16 +491,24 @@ def test_doubled_roundtrip(): a = Hex(3, 4, -7) b = DoubledCoord(1, -3) equal_hex( - "conversion_roundtrip doubled-q", a, qdoubled_to_cube(qdoubled_from_cube(a)) + "conversion_roundtrip doubled-q", + a, + qdoubled_to_cube(qdoubled_from_cube(a)), ) equal_doubledcoord( - "conversion_roundtrip doubled-q", b, qdoubled_from_cube(qdoubled_to_cube(b)) + "conversion_roundtrip doubled-q", + b, + qdoubled_from_cube(qdoubled_to_cube(b)), ) equal_hex( - "conversion_roundtrip doubled-r", a, rdoubled_to_cube(rdoubled_from_cube(a)) + "conversion_roundtrip doubled-r", + a, + rdoubled_to_cube(rdoubled_from_cube(a)), ) equal_doubledcoord( - "conversion_roundtrip doubled-r", b, rdoubled_from_cube(rdoubled_to_cube(b)) + "conversion_roundtrip doubled-r", + b, + rdoubled_from_cube(rdoubled_to_cube(b)), ) @@ -492,10 +527,14 @@ def test_doubled_from_cube(): def test_doubled_to_cube(): equal_hex( - "doubled_to_cube doubled-q", Hex(1, 2, -3), qdoubled_to_cube(DoubledCoord(1, 5)) + "doubled_to_cube doubled-q", + Hex(1, 2, -3), + qdoubled_to_cube(DoubledCoord(1, 5)), ) equal_hex( - "doubled_to_cube doubled-r", Hex(1, 2, -3), rdoubled_to_cube(DoubledCoord(4, 2)) + "doubled_to_cube doubled-r", + Hex(1, 2, -3), + rdoubled_to_cube(DoubledCoord(4, 2)), ) diff --git a/code/network-generator/network_generation/model/python/nr_cell_du.py b/code/network-generator/network_generation/model/python/nr_cell_du.py index b104267..a0fb6e8 100644 --- a/code/network-generator/network_generation/model/python/nr_cell_du.py +++ b/code/network-generator/network_generation/model/python/nr_cell_du.py @@ -17,15 +17,17 @@ """ A Class representing a 3GPP new radio cell du (NrCellDu) """ +import xml.etree.ElementTree as ET from typing import overload -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -from network_generation.model.python.o_ran_object import IORanObject -from network_generation.model.python.o_ran_node import ORanNode import network_generation.model.python.hexagon as Hexagon -from network_generation.model.python.point import Point from network_generation.model.python.geo_location import GeoLocation -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_node import ORanNode +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) +from network_generation.model.python.point import Point # Define the "INrCellDu" interface @@ -41,7 +43,9 @@ class NrCellDu(ORanNode, INrCellDu): def __init__(self, cell_data: INrCellDu = None, **kwargs): super().__init__(cell_data, **kwargs) self._cell_angle = ( - cell_data["cellAngle"] if cell_data and "cellAngle" in cell_data else 120 + cell_data["cellAngle"] + if cell_data and "cellAngle" in cell_data + else 120 ) self._azimuth = ( cell_data["azimuth"] if cell_data and "azimuth" in cell_data else 0 @@ -50,7 +54,9 @@ class NrCellDu(ORanNode, INrCellDu): @property def termination_points(self) -> list[ORanTerminationPoint]: result: list[ORanTerminationPoint] = super().termination_points - result.append(ORanTerminationPoint({"id": self.name, "name": self.name})) + result.append( + ORanTerminationPoint({"id": self.name, "name": self.name}) + ) return result def to_topology_nodes(self) -> list[dict[str, dict]]: @@ -75,7 +81,9 @@ class NrCellDu(ORanNode, INrCellDu): linear_ring: ET.Element = ET.SubElement(outer_boundary, "LinearRing") coordinates: ET.Element = ET.SubElement(linear_ring, "coordinates") - points: list[Point] = Hexagon.polygon_corners(self.layout, self.position) + points: list[Point] = Hexagon.polygon_corners( + self.layout, self.position + ) method = GeoLocation( self.parent.parent.parent.parent.parent.parent.geoLocation ).point_to_geo_location @@ -88,19 +96,23 @@ class NrCellDu(ORanNode, INrCellDu): ) intersect1: Point = Point( - (points[(2 * index + 1) % 6].x + points[(2 * index + 2) % 6].x) / 2, - (points[(2 * index + 1) % 6].y + points[(2 * index + 2) % 6].y) / 2, + (points[(2 * index + 1) % 6].x + points[(2 * index + 2) % 6].x) + / 2, + (points[(2 * index + 1) % 6].y + points[(2 * index + 2) % 6].y) + / 2, ) - intersect_geo_location1: GeoLocation = network_center.point_to_geo_location( - intersect1 + intersect_geo_location1: GeoLocation = ( + network_center.point_to_geo_location(intersect1) ) intersect2: Point = Point( - (points[(2 * index + 3) % 6].x + points[(2 * index + 4) % 6].x) / 2, - (points[(2 * index + 3) % 6].y + points[(2 * index + 4) % 6].y) / 2, + (points[(2 * index + 3) % 6].x + points[(2 * index + 4) % 6].x) + / 2, + (points[(2 * index + 3) % 6].y + points[(2 * index + 4) % 6].y) + / 2, ) - intersect_geo_location2: GeoLocation = network_center.point_to_geo_location( - intersect2 + intersect_geo_location2: GeoLocation = ( + network_center.point_to_geo_location(intersect2) ) tower: GeoLocation = GeoLocation(self.geoLocation) diff --git a/code/network-generator/network_generation/model/python/o_ran_cloud_du.py b/code/network-generator/network_generation/model/python/o_ran_cloud_du.py index ab72f72..0c5b782 100644 --- a/code/network-generator/network_generation/model/python/o_ran_cloud_du.py +++ b/code/network-generator/network_generation/model/python/o_ran_cloud_du.py @@ -20,15 +20,18 @@ By default all O-RAN-DUs associated with the towers around are deployed here. Maybe dedicated hardware is required to host O-DUs, but it is expected that the O-Cloud mechanism and concepts can be applied here. """ +import xml.etree.ElementTree as ET from typing import overload + import network_generation.model.python.hexagon as Hexagon -from network_generation.model.python.hexagon import Hex from network_generation.model.python.cube import Cube -from network_generation.model.python.tower import Tower -from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.hexagon import Hex from network_generation.model.python.o_ran_node import ORanNode -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) +from network_generation.model.python.tower import Tower # Define the "IORanDu" interface @@ -44,13 +47,18 @@ class ORanCloudDu(ORanNode, IORanCloudDu): self._towers: list[Tower] = self._calculate_towers() def _calculate_towers(self) -> list[Tower]: - hex_ring_radius: int = self.spiralRadiusProfile.oRanDuSpiralRadiusOfTowers + hex_ring_radius: int = ( + self.spiralRadiusProfile.oRanDuSpiralRadiusOfTowers + ) hex_list: list[Hex] = Cube.spiral(self.position, hex_ring_radius) result: list[Tower] = [] for index, hex in enumerate(hex_list): s: str = "00" + str(index) name: str = "-".join( - [self.name.replace("O-Cloud-DU", "Tower"), s[len(s) - 2 : len(s)]] + [ + self.name.replace("O-Cloud-DU", "Tower"), + s[len(s) - 2 : len(s)], + ] ) network_center: dict = self.parent.parent.parent.parent.center newGeo = Hexagon.hex_to_geo_location( @@ -80,22 +88,26 @@ class ORanCloudDu(ORanNode, IORanCloudDu): phy_tp: str = "-".join([self.name, "phy".upper()]) result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp})) for interface in ["o2"]: - id:str = "-".join([self.name, interface.upper()]) - result.append(ORanTerminationPoint({"id": id, "name":id, "supporter": phy_tp, "parent":self})) + id: str = "-".join([self.name, interface.upper()]) + result.append( + ORanTerminationPoint( + {"id": id, "name": id, "supporter": phy_tp, "parent": self} + ) + ) return result def to_topology_nodes(self) -> list[dict[str, dict]]: result: list[dict[str, dict]] = super().to_topology_nodes() for tower in self.towers: - result.extend(tower.to_topology_nodes()) + result.extend(tower.to_topology_nodes()) return result def to_topology_links(self) -> list[dict[str, dict]]: result: list[dict[str, dict]] = super().to_topology_links() for tower in self.towers: - result.extend(tower.to_topology_links()) + result.extend(tower.to_topology_links()) return result - + def toKml(self) -> ET.Element: o_ran_cloud_du: ET.Element = ET.Element("Folder") open: ET.Element = ET.SubElement(o_ran_cloud_du, "open") diff --git a/code/network-generator/network_generation/model/python/o_ran_cu.py b/code/network-generator/network_generation/model/python/o_ran_cu.py index 484fc00..d3034b4 100644 --- a/code/network-generator/network_generation/model/python/o_ran_cu.py +++ b/code/network-generator/network_generation/model/python/o_ran_cu.py @@ -18,16 +18,19 @@ A Class representing an O-RAN centralized unit (ORanCu) and at the same time a location for an O-Cloud resource pool """ +import xml.etree.ElementTree as ET from typing import overload + +import network_generation.model.python.hexagon as Hexagon from network_generation.model.python.cube import Cube from network_generation.model.python.hexagon import Hex -import network_generation.model.python.hexagon as Hexagon from network_generation.model.python.o_ran_cloud_du import ORanCloudDu -from network_generation.model.python.tower import Tower -from network_generation.model.python.o_ran_object import IORanObject from network_generation.model.python.o_ran_node import ORanNode -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) +from network_generation.model.python.tower import Tower # Define the "IORanCu" interface @@ -43,8 +46,12 @@ class ORanCu(ORanNode, IORanCu): self._o_ran_cloud_dus: list[ORanCu] = self._calculate_o_ran_dus() def _calculate_o_ran_dus(self) -> list[ORanCloudDu]: - hex_ring_radius: int = self.spiralRadiusProfile.oRanCuSpiralRadiusOfODus - hex_list: list[Hex] = self.spiralRadiusProfile.oRanDuSpiral(self.position, hex_ring_radius) + hex_ring_radius: int = ( + self.spiralRadiusProfile.oRanCuSpiralRadiusOfODus + ) + hex_list: list[Hex] = self.spiralRadiusProfile.oRanDuSpiral( + self.position, hex_ring_radius + ) result: list[ORanCloudDu] = [] for index, hex in enumerate(hex_list): s: str = "00" + str(index) @@ -69,7 +76,6 @@ class ORanCu(ORanNode, IORanCu): ) return result - @property def o_ran_cloud_dus(self) -> list[ORanCloudDu]: return self._o_ran_cloud_dus @@ -88,8 +94,12 @@ class ORanCu(ORanNode, IORanCu): phy_tp: str = "-".join([self.name, "phy".upper()]) result.append({"tp-id": phy_tp, "name": phy_tp}) for interface in ["e2", "o1"]: - id:str = "-".join([self.name, interface.upper()]) - result.append(ORanTerminationPoint({"id": id, "name":id, "supporter": phy_tp, "parent":self})) + id: str = "-".join([self.name, interface.upper()]) + result.append( + ORanTerminationPoint( + {"id": id, "name": id, "supporter": phy_tp, "parent": self} + ) + ) return result def to_topology_nodes(self) -> list[dict[str, dict]]: @@ -97,15 +107,15 @@ class ORanCu(ORanNode, IORanCu): # for o_ran_du in self.o_ran_dus: # TODO # result.extend(o_ran_du.to_topology_nodes()) for o_ran_cloud_du in self.o_ran_cloud_dus: - result.extend(o_ran_cloud_du.to_topology_nodes()) + result.extend(o_ran_cloud_du.to_topology_nodes()) return result def to_topology_links(self) -> list[dict[str, dict]]: result: list[dict[str, dict]] = super().to_topology_links() # for o_ran_du in self.o_ran_dus: - # result.extend(o_ran_du.to_topology_links()) + # result.extend(o_ran_du.to_topology_links()) for o_ran_cloud_du in self.o_ran_cloud_dus: - result.extend(o_ran_cloud_du.to_topology_links()) + result.extend(o_ran_cloud_du.to_topology_links()) return result def toKml(self) -> ET.Element: @@ -118,6 +128,5 @@ class ORanCu(ORanNode, IORanCu): o_ran_cu.append(o_ran_cloud_du.toKml()) return o_ran_cu - def toSvg(self) -> None: return None diff --git a/code/network-generator/network_generation/model/python/o_ran_du.py b/code/network-generator/network_generation/model/python/o_ran_du.py index 96baab1..6e5149b 100644 --- a/code/network-generator/network_generation/model/python/o_ran_du.py +++ b/code/network-generator/network_generation/model/python/o_ran_du.py @@ -17,11 +17,14 @@ """ A Class representing an O-RAN distributed unit (ORanDu) """ +import xml.etree.ElementTree as ET from typing import overload -from network_generation.model.python.o_ran_object import IORanObject + from network_generation.model.python.o_ran_node import ORanNode -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) # Define the "IORanDu" interface @@ -36,7 +39,9 @@ class ORanDu(ORanNode, IORanDu): def __init__(self, o_ran_du_data: IORanDu = None, **kwargs): super().__init__(o_ran_du_data, **kwargs) self._o_ran_ru_count = ( - o_ran_du_data["oRanRuCount"] if o_ran_du_data and "oRanRuCount" in o_ran_du_data else 1 + o_ran_du_data["oRanRuCount"] + if o_ran_du_data and "oRanRuCount" in o_ran_du_data + else 1 ) @property @@ -44,9 +49,13 @@ class ORanDu(ORanNode, IORanDu): result: list[ORanTerminationPoint] = super().termination_points phy_tp: str = "-".join([self.name, "phy".upper()]) result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp})) - for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu","ofhs"]: - id:str = "-".join([self.name, interface.upper()]) - result.append(ORanTerminationPoint({"id": id, "name":id, "supporter": phy_tp, "parent":self})) + for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu", "ofhs"]: + id: str = "-".join([self.name, interface.upper()]) + result.append( + ORanTerminationPoint( + {"id": id, "name": id, "supporter": phy_tp, "parent": self} + ) + ) return result def to_topology_nodes(self) -> list[dict[str, dict]]: @@ -56,18 +65,26 @@ class ORanDu(ORanNode, IORanDu): def to_topology_links(self) -> list[dict[str, dict]]: result: list[dict[str, dict]] = super().to_topology_links() for interface in ["e2", "o1"]: - link_id: str = "".join([interface, ":", self.name, "<->", self.parent.name]) + link_id: str = "".join( + [interface, ":", self.name, "<->", self.parent.name] + ) source_tp: str = "-".join([self.name, interface.upper()]) dest_tp: str = "-".join([self.parent.name, interface.upper()]) result.append( { "link-id": link_id, - "source": {"source-node": self.name, "source-tp": source_tp}, - "destination": {"dest-node": self.parent.name, "dest-tp": dest_tp}, + "source": { + "source-node": self.name, + "source-tp": source_tp, + }, + "destination": { + "dest-node": self.parent.name, + "dest-tp": dest_tp, + }, } ) return result - + def toKml(self) -> ET.Element: o_ran_du: ET.Element = ET.Element("Folder") open: ET.Element = ET.SubElement(o_ran_du, "open") diff --git a/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py b/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py index b556f3c..4e92a5b 100644 --- a/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py +++ b/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py @@ -17,15 +17,18 @@ """ A Class representing an O-RAN Near real-time intelligent controller (ORanNearRtRic) """ +import xml.etree.ElementTree as ET from typing import overload -from network_generation.model.python.tower import Tower + +import network_generation.model.python.hexagon as Hexagon +from network_generation.model.python.hexagon import Hex from network_generation.model.python.o_ran_cu import ORanCu -from network_generation.model.python.o_ran_object import IORanObject from network_generation.model.python.o_ran_node import ORanNode -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -from network_generation.model.python.hexagon import Hex -import network_generation.model.python.hexagon as Hexagon -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) +from network_generation.model.python.tower import Tower # Define the "IORanNearRtRic" interface @@ -36,12 +39,16 @@ class IORanNearRtRic(IORanObject): # Define an abstract O-RAN Node class class ORanNearRtRic(ORanNode, IORanNearRtRic): - def __init__(self, o_ran_near_rt_ric_data: IORanNearRtRic = None, **kwargs): + def __init__( + self, o_ran_near_rt_ric_data: IORanNearRtRic = None, **kwargs + ): super().__init__(o_ran_near_rt_ric_data, **kwargs) self._o_ran_cus: list[ORanCu] = self._calculate_o_ran_cus() def _calculate_o_ran_cus(self) -> list[ORanCu]: - hex_ring_radius: int = self.spiralRadiusProfile.oRanNearRtRicSpiralRadiusOfOCus + hex_ring_radius: int = ( + self.spiralRadiusProfile.oRanNearRtRicSpiralRadiusOfOCus + ) hex_list: list[Hex] = self.spiralRadiusProfile.oRanCuSpiral( self.position, hex_ring_radius ) @@ -63,7 +70,7 @@ class ORanNearRtRic(ORanNode, IORanNearRtRic): "position": hex, "layout": self.layout, "spiralRadiusProfile": self.spiralRadiusProfile, - "parent": self + "parent": self, } ) ) @@ -87,8 +94,12 @@ class ORanNearRtRic(ORanNode, IORanNearRtRic): phy_tp: str = "-".join([self.name, "phy".upper()]) result.append({"tp-id": phy_tp, "name": phy_tp}) for interface in ["a1", "o1", "o2", "e2"]: - id:str = "-".join([self.name, interface.upper()]) - result.append(ORanTerminationPoint({"id": id, "name":id, "supporter": phy_tp, "parent":self})) + id: str = "-".join([self.name, interface.upper()]) + result.append( + ORanTerminationPoint( + {"id": id, "name": id, "supporter": phy_tp, "parent": self} + ) + ) return result def to_topology_nodes(self) -> list[dict[str, dict]]: @@ -102,7 +113,7 @@ class ORanNearRtRic(ORanNode, IORanNearRtRic): for o_ran_cu in self.o_ran_cus: result.extend(o_ran_cu.to_topology_links()) return result - + def toKml(self) -> ET.Element: ric: ET.Element = ET.Element("Folder") open: ET.Element = ET.SubElement(ric, "open") diff --git a/code/network-generator/network_generation/model/python/o_ran_network.py b/code/network-generator/network_generation/model/python/o_ran_network.py index be61796..bb39b61 100644 --- a/code/network-generator/network_generation/model/python/o_ran_network.py +++ b/code/network-generator/network_generation/model/python/o_ran_network.py @@ -16,13 +16,19 @@ """ Module for a class representing a O-RAN Network """ -from network_generation.model.python.o_ran_smo import ORanSmo -from network_generation.model.python.o_ran_spiral_radius_profile import SpiralRadiusProfile -from network_generation.model.python.o_ran_object import IORanObject, ORanObject +import xml.etree.ElementTree as ET + import network_generation.model.python.hexagon as Hexagon from network_generation.model.python.hexagon import Layout +from network_generation.model.python.o_ran_object import ( + IORanObject, + ORanObject, +) +from network_generation.model.python.o_ran_smo import ORanSmo +from network_generation.model.python.o_ran_spiral_radius_profile import ( + SpiralRadiusProfile, +) from network_generation.model.python.point import Point -import xml.etree.ElementTree as ET class ORanNetwork(ORanObject): @@ -31,7 +37,9 @@ class ORanNetwork(ORanObject): """ # constructor - def __init__(self, configuration: dict[str, dict], of: IORanObject = None, **kwargs): + def __init__( + self, configuration: dict[str, dict], of: IORanObject = None, **kwargs + ): super().__init__(of, **kwargs) self.__configuration = configuration self.name = configuration["name"] @@ -42,18 +50,18 @@ class ORanNetwork(ORanObject): ) # 1 pixel = 1 meter spiral_radius_profile = SpiralRadiusProfile( { - "oRanSmoSpiralRadiusOfNearRtRics": configuration["pattern"]["smo"][ - "near-rt-ric-spiral-radius" - ], + "oRanSmoSpiralRadiusOfNearRtRics": configuration["pattern"][ + "smo" + ]["near-rt-ric-spiral-radius"], "oRanNearRtRicSpiralRadiusOfOCus": configuration["pattern"][ "near-rt-ric" ]["o-ran-cu-spiral-radius"], - "oRanCuSpiralRadiusOfODus": configuration["pattern"]["o-ran-cu"][ - "o-ran-du-spiral-radius" - ], - "oRanDuSpiralRadiusOfTowers": configuration["pattern"]["o-ran-du"][ - "tower-spiral-radius" - ], + "oRanCuSpiralRadiusOfODus": configuration["pattern"][ + "o-ran-cu" + ]["o-ran-du-spiral-radius"], + "oRanDuSpiralRadiusOfTowers": configuration["pattern"][ + "o-ran-du" + ]["tower-spiral-radius"], } ) self._o_ran_smo = ORanSmo( @@ -88,9 +96,11 @@ class ORanNetwork(ORanObject): ], } } - + def toKml(self) -> ET.Element: - root: ET.Element = ET.Element("kml", xmlns="http://www.opengis.net/kml/2.2") + root: ET.Element = ET.Element( + "kml", xmlns="http://www.opengis.net/kml/2.2" + ) document = ET.SubElement(root, "Document") open: ET.Element = ET.SubElement(document, "open") open.text = "1" diff --git a/code/network-generator/network_generation/model/python/o_ran_node.py b/code/network-generator/network_generation/model/python/o_ran_node.py index ba9b0e8..7e5ec63 100644 --- a/code/network-generator/network_generation/model/python/o_ran_node.py +++ b/code/network-generator/network_generation/model/python/o_ran_node.py @@ -17,20 +17,26 @@ """ An abstract Class for O-RAN Node """ +import json +import xml.etree.ElementTree as ET from abc import abstractmethod, abstractproperty from typing import Any -import xml.etree.ElementTree as ET -import json -from network_generation.model.python.geo_location import GeoLocation -from network_generation.model.python.o_ran_object import IORanObject, ORanObject + import network_generation.model.python.hexagon as Hexagon +from network_generation.model.python.geo_location import GeoLocation from network_generation.model.python.hexagon import Hex, Layout -from network_generation.model.python.point import Point -from network_generation.model.python.o_ran_spiral_radius_profile import SpiralRadiusProfile -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -from network_generation.model.python.type_definitions import ( - AddressType, +from network_generation.model.python.o_ran_object import ( + IORanObject, + ORanObject, ) +from network_generation.model.python.o_ran_spiral_radius_profile import ( + SpiralRadiusProfile, +) +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) +from network_generation.model.python.point import Point +from network_generation.model.python.type_definitions import AddressType # Define the "IORanObject" interface @@ -65,7 +71,9 @@ class ORanNode(ORanObject, IORanNode): of["geoLocation"] if of and "geoLocation" in of else GeoLocation() ) self.url = of["url"] if of and "url" in of else self.id - self.position = of["position"] if of and "position" in of else Hex(0, 0, 0) + self.position = ( + of["position"] if of and "position" in of else Hex(0, 0, 0) + ) self.layout = ( of["layout"] if of and "layout" in of @@ -128,7 +136,9 @@ class ORanNode(ORanObject, IORanNode): self._spiralRadiusProfile = value @property - def parent(self) -> Any: # expected are ORanNodes and all inherits for ORanNode + def parent( + self, + ) -> Any: # expected are ORanNodes and all inherits for ORanNode return self._parent @parent.setter @@ -153,14 +163,19 @@ class ORanNode(ORanObject, IORanNode): def to_topology_nodes(self) -> list[dict[str, dict]]: tps: list[dict[str, dict]] = [] for tp in self.termination_points: - if str(type(tp)) == "": + if ( + str(type(tp)) + == "" + ): tps.append(tp.to_topology()) result: list[dict[str, dict]] = [] - result.append({ - "node-id": self.name, - "ietf-network-topology:termination-point": tps, - }) + result.append( + { + "node-id": self.name, + "ietf-network-topology:termination-point": tps, + } + ) return result @abstractmethod @@ -169,11 +184,16 @@ class ORanNode(ORanObject, IORanNode): source_tp: str = "-".join([self.name, "phy".upper()]) dest_tp: str = "-".join([self.parent.name, "phy".upper()]) if self.parent and not "Tower" in source_tp and not "Tower" in dest_tp: - link_id: str = "".join(["phy", ":", self.name, "<->", self.parent.name]) + link_id: str = "".join( + ["phy", ":", self.name, "<->", self.parent.name] + ) link = { "link-id": link_id, "source": {"source-node": self.name, "source-tp": source_tp}, - "destination": {"dest-node": self.parent.name, "dest-tp": dest_tp}, + "destination": { + "dest-node": self.parent.name, + "dest-tp": dest_tp, + }, } result.append(link) return result diff --git a/code/network-generator/network_generation/model/python/o_ran_ru.py b/code/network-generator/network_generation/model/python/o_ran_ru.py index 7783d87..d9b119d 100644 --- a/code/network-generator/network_generation/model/python/o_ran_ru.py +++ b/code/network-generator/network_generation/model/python/o_ran_ru.py @@ -17,19 +17,23 @@ """ A Class representing an O-RAN radio unit (ORanRu) """ +import xml.etree.ElementTree as ET from typing import overload -from network_generation.model.python.o_ran_du import ORanDu -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint from network_generation.model.python.nr_cell_du import NrCellDu -from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_du import ORanDu from network_generation.model.python.o_ran_node import ORanNode -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) # Define the "IORanRu" interface class IORanRu(IORanObject): - def __init__(self, cell_count: int, ru_angle: int, ru_azimuth: int, **kwargs): + def __init__( + self, cell_count: int, ru_angle: int, ru_azimuth: int, **kwargs + ): super().__init__(**kwargs) self._cell_count = cell_count self._ru_angle = ru_angle @@ -70,9 +74,9 @@ class ORanRu(ORanNode, IORanRu): def _create_cells(self) -> list[NrCellDu]: result: list[NrCellDu] = [] cell_angle: int = ( - self.parent.parent.parent.parent.parent.parent.configuration()["pattern"][ - "nr-cell-du" - ]["cell-angle"] + self.parent.parent.parent.parent.parent.parent.configuration()[ + "pattern" + ]["nr-cell-du"]["cell-angle"] ) for index in range(self._cell_count): s: str = "00" + str(index) @@ -129,14 +133,22 @@ class ORanRu(ORanNode, IORanRu): result: list[dict[str, dict]] = super().to_topology_links() result.extend(self.oRanDu.to_topology_links()) for interface in ["phy", "ofhm", "ofhc", "ofhu", "ofhs"]: - link_id: str = "".join([interface, ":", self.name, "<->", self.oRanDu.name]) + link_id: str = "".join( + [interface, ":", self.name, "<->", self.oRanDu.name] + ) source_tp: str = "-".join([self.name, interface.upper()]) dest_tp: str = "-".join([self.oRanDu.name, interface.upper()]) result.append( { "link-id": link_id, - "source": {"source-node": self.name, "source-tp": source_tp}, - "destination": {"dest-node": self.oRanDu.name, "dest-tp": dest_tp}, + "source": { + "source-node": self.name, + "source-tp": source_tp, + }, + "destination": { + "dest-node": self.oRanDu.name, + "dest-tp": dest_tp, + }, } ) return result diff --git a/code/network-generator/network_generation/model/python/o_ran_smo.py b/code/network-generator/network_generation/model/python/o_ran_smo.py index 7320bad..9b1be83 100644 --- a/code/network-generator/network_generation/model/python/o_ran_smo.py +++ b/code/network-generator/network_generation/model/python/o_ran_smo.py @@ -17,15 +17,18 @@ """ A Class representing an O-RAN Service Management and Orchestration Framework (SMO) """ +import xml.etree.ElementTree as ET from typing import overload -from network_generation.model.python.tower import Tower + +import network_generation.model.python.hexagon as Hexagon +from network_generation.model.python.hexagon import Hex from network_generation.model.python.o_ran_near_rt_ric import ORanNearRtRic -from network_generation.model.python.o_ran_object import IORanObject from network_generation.model.python.o_ran_node import ORanNode -from network_generation.model.python.hexagon import Hex -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -import network_generation.model.python.hexagon as Hexagon -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_object import IORanObject +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) +from network_generation.model.python.tower import Tower # Define the "IORanSmo" interface @@ -38,10 +41,14 @@ class IORanSmo(IORanObject): class ORanSmo(ORanNode, IORanSmo): def __init__(self, o_ran_smo_data: IORanSmo = None, **kwargs): super().__init__(o_ran_smo_data, **kwargs) - self._o_ran_near_rt_rics: list[ORanNearRtRic] = self._calculate_near_rt_rics() + self._o_ran_near_rt_rics: list[ + ORanNearRtRic + ] = self._calculate_near_rt_rics() def _calculate_near_rt_rics(self) -> list[ORanNearRtRic]: - hex_ring_radius: int = self.spiralRadiusProfile.oRanSmoSpiralRadiusOfNearRtRics + hex_ring_radius: int = ( + self.spiralRadiusProfile.oRanSmoSpiralRadiusOfNearRtRics + ) hex_list: list[Hex] = self.spiralRadiusProfile.oRanNearRtRicSpiral( self.position, hex_ring_radius ) @@ -69,7 +76,6 @@ class ORanSmo(ORanNode, IORanSmo): ) return result - @property def o_ran_near_rt_rics(self) -> list[ORanNearRtRic]: return self._o_ran_near_rt_rics @@ -80,8 +86,12 @@ class ORanSmo(ORanNode, IORanSmo): phy_tp: str = "-".join([self.name, "phy".upper()]) result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp})) for interface in ["a1", "o1", "o2"]: - id:str = "-".join([self.name, interface.upper()]) - result.append(ORanTerminationPoint({"id": id, "name":id, "supporter": phy_tp, "parent":self})) + id: str = "-".join([self.name, interface.upper()]) + result.append( + ORanTerminationPoint( + {"id": id, "name": id, "supporter": phy_tp, "parent": self} + ) + ) return result @property @@ -99,7 +109,7 @@ class ORanSmo(ORanNode, IORanSmo): return result def to_topology_links(self) -> list[dict[str, dict]]: - result: list[dict[str, dict]] = [] # super().to_topology_links() + result: list[dict[str, dict]] = [] # super().to_topology_links() for ric in self.o_ran_near_rt_rics: result.extend(ric.to_topology_links()) return result diff --git a/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py b/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py index 185c0f2..fd8c289 100644 --- a/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py +++ b/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py @@ -14,9 +14,9 @@ #!/usr/bin/python +import network_generation.model.python.hexagon as Hexagon from network_generation.model.python.cube import Cube from network_generation.model.python.hexagon import Hex -import network_generation.model.python.hexagon as Hexagon class SpiralRadiusProfile: @@ -147,11 +147,15 @@ class SpiralRadiusProfile: def oRanCuDirections(self) -> list[Hex]: q: int = ( 2 * self.oRanCuSpiralRadiusOfODus - + 3 * self.oRanCuSpiralRadiusOfODus * self.oRanDuSpiralRadiusOfTowers + + 3 + * self.oRanCuSpiralRadiusOfODus + * self.oRanDuSpiralRadiusOfTowers + self.oRanDuSpiralRadiusOfTowers + 1 ) - r: int = self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus + r: int = ( + self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus + ) s: int = -q - r return [ Hex(+q, +r, +s), @@ -190,16 +194,20 @@ class SpiralRadiusProfile: def oRanNearRtRicDirections(self) -> list[Hex]: q0: int = ( 2 * self.oRanCuSpiralRadiusOfODus - + 3 * self.oRanCuSpiralRadiusOfODus * self.oRanDuSpiralRadiusOfTowers + + 3 + * self.oRanCuSpiralRadiusOfODus + * self.oRanDuSpiralRadiusOfTowers + self.oRanDuSpiralRadiusOfTowers + 1 ) - r0: int = self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus + r0: int = ( + self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus + ) q: int = 3 * q0 - self.oRanNearRtRicSpiralRadiusOfOCus r: int = -r0 - self.oRanNearRtRicSpiralRadiusOfOCus - profile_id: str = self.id[0 : len(self.id)-1] + profile_id: str = self.id[0 : len(self.id) - 1] if profile_id in {"111", "112", "113", "114"}: q: int = 21 + 14 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1) r: int = -7 * self.oRanNearRtRicSpiralRadiusOfOCus @@ -263,7 +271,8 @@ class SpiralRadiusProfile: results: list[Hex] = [] hex: Hex = Hexagon.hex_add( - center, Hexagon.hex_scale(self.oRanNearRtRicDirections()[4], radius) + center, + Hexagon.hex_scale(self.oRanNearRtRicDirections()[4], radius), ) for i in range(6): for j in range(radius): diff --git a/code/network-generator/network_generation/model/python/o_ran_termination_point.py b/code/network-generator/network_generation/model/python/o_ran_termination_point.py index e7fe98a..6aba16d 100644 --- a/code/network-generator/network_generation/model/python/o_ran_termination_point.py +++ b/code/network-generator/network_generation/model/python/o_ran_termination_point.py @@ -18,7 +18,11 @@ An abstract Class for O-RAN TerminationPoint """ from abc import abstractmethod -from network_generation.model.python.o_ran_object import IORanObject, ORanObject + +from network_generation.model.python.o_ran_object import ( + IORanObject, + ORanObject, +) # Define the "IORanObject" interface @@ -52,10 +56,14 @@ class ORanTerminationPoint(ORanObject, IORanTerminationPointData): case "": network_ref = self.parent.parent.parent.parent.parent.id case "": - network_ref = self.parent.parent.parent.parent.parent.parent.id + network_ref = ( + self.parent.parent.parent.parent.parent.parent.id + ) case _: print("unknown: implement " + str(type(self.parent))) - network_ref = "unknown: implement " + str(type(self.parent)) + network_ref = "unknown: implement " + str( + type(self.parent) + ) result["supporting-termination-point"] = [ { diff --git a/code/network-generator/network_generation/model/python/point.py b/code/network-generator/network_generation/model/python/point.py index a4e5283..1a9b772 100644 --- a/code/network-generator/network_generation/model/python/point.py +++ b/code/network-generator/network_generation/model/python/point.py @@ -16,8 +16,8 @@ #!/usr/bin/python -from __future__ import division -from __future__ import print_function +from __future__ import division, print_function + from typing import NamedTuple diff --git a/code/network-generator/network_generation/model/python/top.py b/code/network-generator/network_generation/model/python/top.py index 214a773..5d6ac02 100644 --- a/code/network-generator/network_generation/model/python/top.py +++ b/code/network-generator/network_generation/model/python/top.py @@ -19,13 +19,14 @@ An abstract Class for all classes """ import uuid from abc import ABC + from network_generation.model.python.type_definitions import ( AdministrativeState, + AlarmState, + LifeCycleState, OperationalState, UsageState, Utilization, - LifeCycleState, - AlarmState, ) @@ -76,11 +77,17 @@ class Top(ABC, ITop): if data and "lifeCycleState" in data else LifeCycleState.PLANNED ) - self._alarmState = data["alarmState"] if data and "alarmState" in data else 0 + self._alarmState = ( + data["alarmState"] if data and "alarmState" in data else 0 + ) self._usageState = ( - data["usageState"] if data and "usageState" in data else UsageState.UNUSED + data["usageState"] + if data and "usageState" in data + else UsageState.UNUSED + ) + self._utilization = ( + data["utilization"] if data and "utilization" in data else 0 ) - self._utilization = data["utilization"] if data and "utilization" in data else 0 @property def id(self) -> str: diff --git a/code/network-generator/network_generation/model/python/tower.py b/code/network-generator/network_generation/model/python/tower.py index f7135ee..d708d5e 100644 --- a/code/network-generator/network_generation/model/python/tower.py +++ b/code/network-generator/network_generation/model/python/tower.py @@ -19,12 +19,15 @@ A Class representing a Tower to mount O-RAN RUs It can be interpreted as 'resource pool' for physical network functions. """ +import xml.etree.ElementTree as ET from typing import overload + +from network_generation.model.python.o_ran_node import ORanNode from network_generation.model.python.o_ran_object import IORanObject from network_generation.model.python.o_ran_ru import ORanRu -from network_generation.model.python.o_ran_node import ORanNode -from network_generation.model.python.o_ran_termination_point import ORanTerminationPoint -import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_termination_point import ( + ORanTerminationPoint, +) # Define the "IORanDu" interface @@ -52,12 +55,16 @@ class Tower(ORanNode): name: str = "-".join( [self.name.replace("Tower", "RU"), s[len(s) - 2 : len(s)]] ) - cell_count: int = self.parent.parent.parent.parent.parent.configuration()[ - "pattern" - ]["o-ran-ru"]["nr-cell-du-count"] - cell_angle : int = self.parent.parent.parent.parent.parent.configuration()[ - "pattern" - ]["nr-cell-du"]["cell-angle"] + cell_count: int = ( + self.parent.parent.parent.parent.parent.configuration()[ + "pattern" + ]["o-ran-ru"]["nr-cell-du-count"] + ) + cell_angle: int = ( + self.parent.parent.parent.parent.parent.configuration()[ + "pattern" + ]["nr-cell-du"]["cell-angle"] + ) ru_angle: int = cell_count * cell_angle ru_azimuth: int = index * ru_angle result.append( @@ -86,31 +93,35 @@ class Tower(ORanNode): result: list[ORanTerminationPoint] = super().termination_points phy_tp: str = "-".join([self.name, "phy".upper()]) result.append({"tp-id": phy_tp}) - for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu","ofhs"]: - result.append( { - "tp-id": "-".join([self.name, interface.upper()]), - "supporting-termination-point": [ - { - "network-ref": type(self.parent.parent.parent.parent), - "node-ref":self.name, - "tp-ref": phy_tp - } - ] - }) + for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu", "ofhs"]: + result.append( + { + "tp-id": "-".join([self.name, interface.upper()]), + "supporting-termination-point": [ + { + "network-ref": type( + self.parent.parent.parent.parent + ), + "node-ref": self.name, + "tp-ref": phy_tp, + } + ], + } + ) return result def to_topology_nodes(self) -> list[dict[str, dict]]: result: list[dict[str, dict]] = super().to_topology_nodes() for o_ran_ru in self.o_ran_rus: - result.extend(o_ran_ru.to_topology_nodes()) + result.extend(o_ran_ru.to_topology_nodes()) return result def to_topology_links(self) -> list[dict[str, dict]]: result: list[dict[str, dict]] = super().to_topology_links() for o_ran_ru in self.o_ran_rus: - result.extend(o_ran_ru.to_topology_links()) + result.extend(o_ran_ru.to_topology_links()) return result - + def toKml(self) -> ET.Element: tower: ET.Element = ET.Element("Folder") open: ET.Element = ET.SubElement(tower, "open") @@ -121,6 +132,5 @@ class Tower(ORanNode): tower.append(o_ran_ru.toKml()) return tower - def toSvg(self) -> None: return None diff --git a/code/network-generator/network_generation/model/python/type_definitions.py b/code/network-generator/network_generation/model/python/type_definitions.py index 43a7162..1430c3c 100644 --- a/code/network-generator/network_generation/model/python/type_definitions.py +++ b/code/network-generator/network_generation/model/python/type_definitions.py @@ -18,6 +18,7 @@ A collection of TypeDefinitions """ from enum import Enum + from network_generation.model.python.countries import Country diff --git a/code/network-generator/network_generation/parameter_validator.py b/code/network-generator/network_generation/parameter_validator.py index 2d035a3..2c47299 100644 --- a/code/network-generator/network_generation/parameter_validator.py +++ b/code/network-generator/network_generation/parameter_validator.py @@ -16,9 +16,10 @@ """ Module containing a class for parameter validation """ +import json import os import os.path -import json + import jsonschema diff --git a/code/network-generator/network_generation/view/network_viewer.py b/code/network-generator/network_generation/view/network_viewer.py index 6610251..54ba84f 100644 --- a/code/network-generator/network_generation/view/network_viewer.py +++ b/code/network-generator/network_generation/view/network_viewer.py @@ -18,9 +18,10 @@ Provides functions to convert the Network into different formats """ import json -from network_generation.model.python.o_ran_network import ORanNetwork import xml.etree.ElementTree as ET +from network_generation.model.python.o_ran_network import ORanNetwork + class NetworkViewer: """ @@ -61,7 +62,7 @@ class NetworkViewer: :type filename: string """ with open(filename, "w", encoding="utf-8") as json_file: - output:dict[str, dict] = self.__network.to_topology() + output: dict[str, dict] = self.__network.to_topology() json.dump(output, json_file, ensure_ascii=False, indent=2) print("File '" + filename + "' saved!") @@ -85,7 +86,9 @@ class NetworkViewer: style = ET.Element("style") style.text = self.readStylesFromFile() root.findall(".//desc")[0].append(style) - ET.ElementTree(root).write(filename, encoding="utf-8", xml_declaration=True) + ET.ElementTree(root).write( + filename, encoding="utf-8", xml_declaration=True + ) print("File '" + filename + "' saved!") def kml(self, filename: str) -> None: @@ -111,5 +114,7 @@ class NetworkViewer: fill.text = value["fill"]["color"] root.findall(".//Document")[0].append(style) - ET.ElementTree(root).write(filename, encoding="utf-8", xml_declaration=True) + ET.ElementTree(root).write( + filename, encoding="utf-8", xml_declaration=True + ) print("File '" + filename + "' saved!") -- 2.16.6