kml representation of O-DU O-Cloud resource pool
[oam.git] / code / network-generator / model / python / o_ran_spiral_radius_profile.py
1 # Copyright 2023 highstreet technologies GmbH
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 #!/usr/bin/python
16
17 from dataclasses import dataclass
18 from typing import Any
19
20 from model.python.cube import Cube
21 from model.python.hexagon import Hex
22
23
24 class SpiralRadiusProfile:
25     def __init__(self, data: [dict[str, Any] | None] = None):
26         self._oRanSmoSpiralRadiusOfNearRtRics = (
27             data.get("oRanSmoSpiralRadiusOfNearRtRics", 1) if data else 1
28         )
29         self._oRanNearRtRicSpiralRadiusOfOCus = (
30             data.get("oRanNearRtRicSpiralRadiusOfOCus", 1) if data else 1
31         )
32         self._oRanCuSpiralRadiusOfODus = (
33             data.get("oRanCuSpiralRadiusOfODus", 1) if data else 1
34         )
35         self._oRanDuSpiralRadiusOfTowers = (
36             data.get("oRanDuSpiralRadiusOfTowers", 1) if data else 1
37         )
38
39     @property
40     def id(self) -> str:
41         return f"{self._oRanDuSpiralRadiusOfTowers}{self._oRanCuSpiralRadiusOfODus}{self._oRanNearRtRicSpiralRadiusOfOCus}{self._oRanSmoSpiralRadiusOfNearRtRics}"
42
43     @property
44     def count(self) -> int:
45         towers = 1
46         dus = 1
47         cus = 1
48         rics = 1
49
50         for ru in range(self._oRanDuSpiralRadiusOfTowers + 1):
51             towers = towers + 6 * ru
52
53         for du in range(self._oRanCuSpiralRadiusOfODus + 1):
54             dus = dus + 6 * du
55
56         for cu in range(self._oRanNearRtRicSpiralRadiusOfOCus + 1):
57             cus = cus + 6 * cu
58
59         for ric in range(self._oRanSmoSpiralRadiusOfNearRtRics + 1):
60             rics = rics + 6 * ric
61
62         return towers * dus * cus * rics
63
64     @property
65     def oRanSmoSpiralRadiusOfNearRtRics(self) -> int:
66         return self._oRanSmoSpiralRadiusOfNearRtRics
67
68     @oRanSmoSpiralRadiusOfNearRtRics.setter
69     def oRanSmoSpiralRadiusOfNearRtRics(self, value: int):
70         self._oRanSmoSpiralRadiusOfNearRtRics = value
71
72     @property
73     def oRanNearRtRicSpiralRadiusOfOCus(self) -> int:
74         return self._oRanNearRtRicSpiralRadiusOfOCus
75
76     @oRanNearRtRicSpiralRadiusOfOCus.setter
77     def oRanNearRtRicSpiralRadiusOfOCus(self, value: int):
78         self._oRanNearRtRicSpiralRadiusOfOCus = value
79
80     @property
81     def oRanCuSpiralRadiusOfODus(self) -> int:
82         return self._oRanCuSpiralRadiusOfODus
83
84     @oRanCuSpiralRadiusOfODus.setter
85     def oRanCuSpiralRadiusOfODus(self, value: int):
86         self._oRanCuSpiralRadiusOfODus = value
87
88     @property
89     def oRanDuSpiralRadiusOfTowers(self) -> int:
90         return self._oRanDuSpiralRadiusOfTowers
91
92     @oRanDuSpiralRadiusOfTowers.setter
93     def oRanDuSpiralRadiusOfTowers(self, value: int):
94         self._oRanDuSpiralRadiusOfTowers = value
95
96     @property
97     def sectors(self) -> int:
98         return self._sectors
99
100     @sectors.setter
101     def sectors(self, value: int):
102         self._sectors = value
103
104     @property
105     def nrDuCellsPerSector(self) -> int:
106         return self._nrDuCellsPerSector
107
108     @nrDuCellsPerSector.setter
109     def nrDuCellsPerSector(self, value: int):
110         self._nrDuCellsPerSector = value
111
112     def oRanDuDirections(self) -> list[Hex]:
113         q = 2 * self._oRanDuSpiralRadiusOfTowers + 1
114         r = -self._oRanDuSpiralRadiusOfTowers - 1
115         s = -q - r
116         return [
117             Hex(q, r, s),
118             Hex(-s, -q, -r),
119             Hex(r, s, q),
120             Hex(-q, -r, -s),
121             Hex(s, q, r),
122             Hex(-r, -s, -q),
123         ]
124
125     def oRanDuNeighbor(self, cube: Cube, direction: int):
126         return Hex.add(cube, self.oRanDuDirections[direction])
127
128     def oRanDuRing(self, center: Hex, radius: int) -> list[Hex]:
129         if radius <= 0:
130             raise ValueError(
131                 "Invalid radius. The radius around the hex center must be greater than 0 rings."
132             )
133         results: list[Hex] = []
134         hex = Hex.add(center, Hex.scale(self.oRanDuDirections[4], radius))
135         for i in range(6):
136             for j in range(radius):
137                 results.append(hex)
138                 hex = self.oRanDuNeighbor(hex, i)
139         return results
140
141     def oRanDuSpiral(self, center: Hex, radius: int) -> list[Hex]:
142         result: list[Hex] = [center]
143         for k in range(1, radius + 1):
144             result.extend(self.oRanDuRing(center, k))
145         return result
146
147     def oRanNearRtRicDirections(self) -> list[Hex]:
148         q0 = (
149             2 * self.oRanCuSpiralRadiusOfODus
150             + 3 * self.oRanCuSpiralRadiusOfODus * self.oRanDuSpiralRadiusOfORus
151             + self.oRanDuSpiralRadiusOfORus
152             + 1
153         )
154         r0 = self.oRanDuSpiralRadiusOfORus - self.oRanCuSpiralRadiusOfODus
155
156         q = 3 * q0 - self.oRanNearRtRicSpiralRadiusOfOCus
157         r = -r0 - self.oRanNearRtRicSpiralRadiusOfOCus
158
159         profile_id = self.id[2:-1]
160
161         if profile_id in {"111", "112", "113", "114"}:
162             q = 21 + 14 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
163             r = -7 * self.oRanNearRtRicSpiralRadiusOfOCus
164         elif profile_id in {"121", "122", "123", "124"}:
165             q = 25 + 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
166             r = 9 + 10 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
167         elif profile_id in {"131", "132"}:
168             q = 49 + 30 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
169             r = -21 - 34 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
170         elif profile_id == "133":
171             q = 74
172             r = 37
173         elif profile_id == "134":
174             q = 93
175             r = 50
176         elif profile_id in {"211", "212", "213", "214"}:
177             q = 34 + 23 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
178             r = -10 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
179         elif profile_id in {"221", "222", "223", "224"}:
180             q = 57 + 38 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
181             r = -19 * self.oRanNearRtRicSpiralRadiusOfOCus
182         elif profile_id in {"231", "232", "233", "234"}:
183             q = 80 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
184             r = -28 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
185         elif profile_id in {"241", "242", "243", "244"}:
186             q = 103 + 68 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
187             r = -39 * self.oRanNearRtRicSpiralRadiusOfOCus + 2 * (
188                 self.oRanNearRtRicSpiralRadiusOfOCus - 1
189             )
190         elif profile_id in {"311", "312", "313", "314"}:
191             q = 47 + 32 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
192             r = -11 - 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
193         elif profile_id in {"321", "322", "323", "324"}:
194             q = 79 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
195             r = -24 - 25 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
196         elif profile_id in {"331", "332", "333", "334"}:
197             q = 111 + 75 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
198             r = -37 - 37 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
199         else:
200             # Handle the default case or raise a warning
201             pass
202
203         s = -q - r
204         return [
205             Hex(q, r, s),
206             Hex(-s, -q, -r),
207             Hex(r, s, q),
208             Hex(-q, -r, -s),
209             Hex(s, q, r),
210             Hex(-r, -s, -q),
211         ]