- 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
# example constant variable
NAME = "network_generation"
+
class NetworkGenerator:
"""
Class containing all methods to generate a network.
"""
-
"""
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
"""
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())
-
"""
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"
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):
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
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)
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)
#!/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:
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,
)
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"],
)
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)),
)
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():
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():
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():
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",
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)),
)
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)),
)
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)),
)
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)),
)
"""
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
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
@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]]:
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
)
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)
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
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(
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")
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
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)
)
return result
-
@property
def o_ran_cloud_dus(self) -> list[ORanCloudDu]:
return self._o_ran_cloud_dus
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]]:
# 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:
o_ran_cu.append(o_ran_cloud_du.toKml())
return o_ran_cu
-
def toSvg(self) -> None:
return None
"""
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
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
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]]:
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")
"""
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
# 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
)
"position": hex,
"layout": self.layout,
"spiralRadiusProfile": self.spiralRadiusProfile,
- "parent": self
+ "parent": self,
}
)
)
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]]:
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")
"""
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):
"""
# 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"]
) # 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(
],
}
}
-
+
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"
"""
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
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
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
def to_topology_nodes(self) -> list[dict[str, dict]]:
tps: list[dict[str, dict]] = []
for tp in self.termination_points:
- if str(type(tp)) == "<class 'model.python.o_ran_termination_point.ORanTerminationPoint'>":
+ if (
+ str(type(tp))
+ == "<class 'model.python.o_ran_termination_point.ORanTerminationPoint'>"
+ ):
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
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
"""
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
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)
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
"""
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
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
)
)
return result
-
@property
def o_ran_near_rt_rics(self) -> list[ORanNearRtRic]:
return self._o_ran_near_rt_rics
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
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
#!/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:
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),
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
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):
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
case "<class 'model.python.o_ran_cloud_du.ORanCloudDu'>":
network_ref = self.parent.parent.parent.parent.parent.id
case "<class 'model.python.o_ran_ru.ORanRu'>":
- 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"] = [
{
#!/usr/bin/python
-from __future__ import division
-from __future__ import print_function
+from __future__ import division, print_function
+
from typing import NamedTuple
"""
import uuid
from abc import ABC
+
from network_generation.model.python.type_definitions import (
AdministrativeState,
+ AlarmState,
+ LifeCycleState,
OperationalState,
UsageState,
Utilization,
- LifeCycleState,
- AlarmState,
)
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:
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
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(
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")
tower.append(o_ran_ru.toKml())
return tower
-
def toSvg(self) -> None:
return None
A collection of TypeDefinitions
"""
from enum import Enum
+
from network_generation.model.python.countries import Country
"""
Module containing a class for parameter validation
"""
+import json
import os
import os.path
-import json
+
import jsonschema
"""
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:
"""
: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!")
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:
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!")