Create concrete classes for O-RAN Nodes 34/11934/1
authorMartin Skorupski <martin.skorupski@highstreet-technologies.com>
Wed, 18 Oct 2023 13:20:08 +0000 (15:20 +0200)
committerMartin Skorupski <martin.skorupski@highstreet-technologies.com>
Wed, 18 Oct 2023 13:20:19 +0000 (15:20 +0200)
- spiral radius profile create to drive the O-RAN node
  "containment" (links)

Issue-ID: OAM-368
Change-Id: I81495f0bcf00817c3d871bd7beebe0646d6dab23
Signed-off-by: Martin Skorupski <martin.skorupski@highstreet-technologies.com>
code/network-generator/model/python/o_ran_spiral_radius_profile.py [new file with mode: 0644]

diff --git a/code/network-generator/model/python/o_ran_spiral_radius_profile.py b/code/network-generator/model/python/o_ran_spiral_radius_profile.py
new file mode 100644 (file)
index 0000000..8ad67c5
--- /dev/null
@@ -0,0 +1,137 @@
+# Copyright 2023 highstreet technologies GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/usr/bin/python
+
+from dataclasses import dataclass
+from typing import List
+from model.python.hexagon import Hex
+
+class SpiralRadiusProfile:
+    def __init__(self, data=None):
+        self._oRanSmoSpiralRadiusOfNearRtRics = data.get("oRanSmoSpiralRadiusOfNearRtRics", 1) if data else 1
+        self._oRanNearRtRicSpiralRadiusOfOCus = data.get("oRanNearRtRicSpiralRadiusOfOCus", 1) if data else 1
+        self._oRanCuSpiralRadiusOfODus = data.get("oRanCuSpiralRadiusOfODus", 1) if data else 1
+        self._oRanDuSpiralRadiusOfTowers = data.get("oRanDuSpiralRadiusOfTowers", 1) if data else 1
+
+    @property
+    def id(self):
+        return f"{self._oRanDuSpiralRadiusOfTowers}{self._oRanCuSpiralRadiusOfODus}{self._oRanNearRtRicSpiralRadiusOfOCus}{self._oRanSmoSpiralRadiusOfNearRtRics}"
+
+    @property
+    def count(self):
+        towers = 1
+        dus = 1
+        cus = 1
+        rics = 1
+
+        for ru in range(self._oRanDuSpiralRadiusOfTowers + 1):
+            towers = towers + 6 * ru
+
+        for du in range(self._oRanCuSpiralRadiusOfODus + 1):
+            dus = dus + 6 * du
+
+        for cu in range(self._oRanNearRtRicSpiralRadiusOfOCus + 1):
+            cus = cus + 6 * cu
+
+        for ric in range(self._oRanSmoSpiralRadiusOfNearRtRics + 1):
+            rics = rics + 6 * ric
+
+        return towers * dus * cus * rics
+
+    @property
+    def oRanSmoSpiralRadiusOfNearRtRics(self):
+        return self._oRanSmoSpiralRadiusOfNearRtRics
+
+    @oRanSmoSpiralRadiusOfNearRtRics.setter
+    def oRanSmoSpiralRadiusOfNearRtRics(self, value):
+        self._oRanSmoSpiralRadiusOfNearRtRics = value
+
+    @property
+    def oRanNearRtRicSpiralRadiusOfOCus(self):
+        return self._oRanNearRtRicSpiralRadiusOfOCus
+
+    @oRanNearRtRicSpiralRadiusOfOCus.setter
+    def oRanNearRtRicSpiralRadiusOfOCus(self, value):
+        self._oRanNearRtRicSpiralRadiusOfOCus = value
+
+    @property
+    def oRanCuSpiralRadiusOfODus(self):
+        return self._oRanCuSpiralRadiusOfODus
+
+    @oRanCuSpiralRadiusOfODus.setter
+    def oRanCuSpiralRadiusOfODus(self, value):
+        self._oRanCuSpiralRadiusOfODus = value
+
+    @property
+    def oRanDuSpiralRadiusOfTowers(self):
+        return self._oRanDuSpiralRadiusOfTowers
+
+    @oRanDuSpiralRadiusOfTowers.setter
+    def oRanDuSpiralRadiusOfTowers(self, value):
+        self._oRanDuSpiralRadiusOfTowers = value
+
+    @property
+    def sectors(self):
+        return self._sectors
+
+    @sectors.setter
+    def sectors(self, value):
+        self._sectors = value
+
+    @property
+    def nrDuCellsPerSector(self):
+        return self._nrDuCellsPerSector
+
+    @nrDuCellsPerSector.setter
+    def nrDuCellsPerSector(self, value):
+        self._nrDuCellsPerSector = value
+
+    def oRanDuDirections(self):
+        q = 2 * self._oRanDuSpiralRadiusOfTowers + 1
+        r = - self._oRanDuSpiralRadiusOfTowers - 1
+        s = -q - r
+        return [
+            Hex(q, r, s), Hex(-s, -q, -r), Hex(r, s, q),
+            Hex(-q, -r, -s), Hex(s, q, r), Hex(-r, -s, -q)
+        ]
+
+    def oRanDuNeighbor(self, cube, direction):
+        return Hex.add(cube, self.oRanDuDirections[direction])
+
+    def oRanDuRing(self, center, radius):
+        if radius <= 0:
+            raise ValueError('Invalid radius. The radius around the hex center must be greater than 0 rings.')
+        results = []
+        hex = Hex.add(center, Hex.scale(self.oRanDuDirections[4], radius))
+        for i in range(6):
+            for j in range(radius):
+                results.append(hex)
+                hex = self.oRanDuNeighbor(hex, i)
+        return results
+
+    def oRanDuSpiral(self, center, radius):
+        result = [center]
+        for k in range(1, radius + 1):
+            result.extend(self.oRanDuRing(center, k))
+        return result
+
+    def oRanCuDirections(self):
+        q0 = 2 * self._oRanCuSpiralRadiusOfODus + 3 * self._oRanCuSpiralRadiusOfODus * self._oRanDuSpiralRadiusOfTowers + self._oRanDuSpiralRadiusOfTowers + 1
+        r0 = self._oRanDuSpiralRadiusOfTowers - self._oRanCuSpiralRadiusOfODus
+        q = 3 * q0 - self._oRanNearRtRicSpiralRadiusOfOCus
+        r = -r0 - self._oRanNearRtRicSpiralRadiusOfOCus
+        switch_id = self.id[2:-1]
+        if switch_id in ("111", "112", "113", "114"):
+            q = 21 + 14