1 # Copyright 2023 highstreet technologies GmbH
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 from typing import Any
19 import network_generation.model.python.hexagon as Hexagon
20 from network_generation.model.python.hexagon import Hex
23 class SpiralRadiusProfile:
24 def __init__(self, data: dict[str, Any] | None = None) -> None:
25 self._oRanSmoSpiralRadiusOfNearRtRics = (
26 data.get("oRanSmoSpiralRadiusOfNearRtRics", 1) if data else 1
28 self._oRanNearRtRicSpiralRadiusOfOCus = (
29 data.get("oRanNearRtRicSpiralRadiusOfOCus", 1) if data else 1
31 self._oRanCuSpiralRadiusOfODus = (
32 data.get("oRanCuSpiralRadiusOfODus", 1) if data else 1
34 self._oRanDuSpiralRadiusOfTowers = (
35 data.get("oRanDuSpiralRadiusOfTowers", 1) if data else 1
37 # self._nrDuCellsPerSector: int = (
38 # int(str(data.get("sectorCount"))) if data else 1
45 str(self._oRanDuSpiralRadiusOfTowers),
46 str(self._oRanCuSpiralRadiusOfODus),
47 str(self._oRanNearRtRicSpiralRadiusOfOCus),
48 str(self._oRanSmoSpiralRadiusOfNearRtRics),
53 def count(self) -> int:
59 for ru in range(self._oRanDuSpiralRadiusOfTowers + 1):
60 towers = towers + 6 * ru
62 for du in range(self._oRanCuSpiralRadiusOfODus + 1):
65 for cu in range(self._oRanNearRtRicSpiralRadiusOfOCus + 1):
68 for ric in range(self._oRanSmoSpiralRadiusOfNearRtRics + 1):
71 return towers * dus * cus * rics
74 def oRanSmoSpiralRadiusOfNearRtRics(self) -> int:
75 return self._oRanSmoSpiralRadiusOfNearRtRics
77 @oRanSmoSpiralRadiusOfNearRtRics.setter
78 def oRanSmoSpiralRadiusOfNearRtRics(self, value: int) -> None:
79 self._oRanSmoSpiralRadiusOfNearRtRics = value
82 def oRanNearRtRicSpiralRadiusOfOCus(self) -> int:
83 return self._oRanNearRtRicSpiralRadiusOfOCus
85 @oRanNearRtRicSpiralRadiusOfOCus.setter
86 def oRanNearRtRicSpiralRadiusOfOCus(self, value: int) -> None:
87 self._oRanNearRtRicSpiralRadiusOfOCus = value
90 def oRanCuSpiralRadiusOfODus(self) -> int:
91 return self._oRanCuSpiralRadiusOfODus
93 @oRanCuSpiralRadiusOfODus.setter
94 def oRanCuSpiralRadiusOfODus(self, value: int) -> None:
95 self._oRanCuSpiralRadiusOfODus = value
98 def oRanDuSpiralRadiusOfTowers(self) -> int:
99 return self._oRanDuSpiralRadiusOfTowers
101 @oRanDuSpiralRadiusOfTowers.setter
102 def oRanDuSpiralRadiusOfTowers(self, value: int) -> None:
103 self._oRanDuSpiralRadiusOfTowers = value
106 def sectors(self) -> int:
110 def sectors(self, value: int) -> None:
111 self._sectors = value
114 def nrDuCellsPerSector(self) -> int:
115 return self._nrDuCellsPerSector
117 @nrDuCellsPerSector.setter
118 def nrDuCellsPerSector(self, value: int) -> None:
119 self._nrDuCellsPerSector = value
121 def oRanDuDirections(self) -> list[Hex]:
122 q: int = 2 * self._oRanDuSpiralRadiusOfTowers + 1
123 r: int = -self._oRanDuSpiralRadiusOfTowers - 1
134 def oRanDuNeighbor(self, cube: Hex, direction: int) -> Hex:
135 return Hexagon.hex_add(cube, self.oRanDuDirections()[direction])
137 def oRanDuRing(self, center: Hex, radius: int) -> list[Hex]:
140 "Invalid radius. The radius around the hex center "
141 + "must be greater than 0 rings."
143 results: list[Hex] = []
144 hex: Hex = Hexagon.hex_add(
145 center, Hexagon.hex_scale(self.oRanDuDirections()[4], radius)
148 for j in range(radius):
150 hex = self.oRanDuNeighbor(hex, i)
153 def oRanDuSpiral(self, o_ran_du_center: Hex, radius: int) -> list[Hex]:
154 result: list[Hex] = [o_ran_du_center]
155 for k in range(1, radius + 1):
156 result.extend(self.oRanDuRing(o_ran_du_center, k))
159 def oRanCuDirections(self) -> list[Hex]:
161 2 * self.oRanCuSpiralRadiusOfODus
163 * self.oRanCuSpiralRadiusOfODus
164 * self.oRanDuSpiralRadiusOfTowers
165 + self.oRanDuSpiralRadiusOfTowers
169 self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus
181 def oRanCuNeighbor(self, cube: Hex, direction: int) -> Hex:
182 return Hexagon.hex_add(cube, self.oRanCuDirections()[direction])
184 def oRanCuRing(self, center: Hex, radius: int) -> list[Hex]:
187 "Invalid radius. The radius around the hex center "
188 + "must be greater than 0 rings."
191 results: list[Hex] = []
192 hex: Hex = Hexagon.hex_add(
193 center, Hexagon.hex_scale(self.oRanCuDirections()[4], radius)
196 for j in range(radius):
198 hex = self.oRanCuNeighbor(hex, i)
201 def oRanCuSpiral(self, center: Hex, radius: int) -> list[Hex]:
202 result: list[Hex] = [center]
203 for k in range(1, radius + 1):
204 result += self.oRanCuRing(center, k)
207 def oRanNearRtRicDirections(self) -> list[Hex]:
209 2 * self.oRanCuSpiralRadiusOfODus
211 * self.oRanCuSpiralRadiusOfODus
212 * self.oRanDuSpiralRadiusOfTowers
213 + self.oRanDuSpiralRadiusOfTowers
217 self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus
220 q: int = 3 * q0 - self.oRanNearRtRicSpiralRadiusOfOCus
221 r: int = -r0 - self.oRanNearRtRicSpiralRadiusOfOCus
223 profile_id: str = self.id[0: len(self.id) - 1]
224 if profile_id in {"111", "112", "113", "114"}:
225 q = 21 + 14 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
226 r = -7 * self.oRanNearRtRicSpiralRadiusOfOCus
227 elif profile_id in {"121", "122", "123", "124"}:
228 q = 25 + 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
229 r = 9 + 10 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
230 elif profile_id in {"131", "132"}:
231 q = 49 + 30 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
232 r = -21 - 34 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
233 elif profile_id == "133":
236 elif profile_id == "134":
239 elif profile_id in {"211", "212", "213", "214"}:
240 q = 34 + 23 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
241 r = -10 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
242 elif profile_id in {"221", "222", "223", "224"}:
243 q = 57 + 38 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
244 r = -19 * self.oRanNearRtRicSpiralRadiusOfOCus
245 elif profile_id in {"231", "232", "233", "234"}:
246 q = 80 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
247 r = -28 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
248 elif profile_id in {"241", "242", "243", "244"}:
249 q = 103 + 68 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
250 r = -39 * self.oRanNearRtRicSpiralRadiusOfOCus + 2 * (
251 self.oRanNearRtRicSpiralRadiusOfOCus - 1
253 elif profile_id in {"311", "312", "313", "314"}:
254 q = 47 + 32 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
255 r = -11 - 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
256 elif profile_id in {"321", "322", "323", "324"}:
257 q = 79 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
258 r = -24 - 25 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
259 elif profile_id in {"331", "332", "333", "334"}:
260 q = 111 + 75 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
261 r = -37 - 37 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
263 # Handle the default case or raise a warning
276 def oRanNearRtRicNeighbor(self, cube: Hex, direction: int) -> Hex:
277 return Hexagon.hex_add(cube, self.oRanNearRtRicDirections()[direction])
279 def oRanNearRtRicRing(self, center: Hex, radius: int) -> list[Hex]:
282 "Invalid radius. The radius around the hex center "
283 + "must be greater than 0 rings."
286 results: list[Hex] = []
287 hex: Hex = Hexagon.hex_add(
289 Hexagon.hex_scale(self.oRanNearRtRicDirections()[4], radius),
292 for j in range(radius):
294 hex = self.oRanNearRtRicNeighbor(hex, i)
297 def oRanNearRtRicSpiral(self, center: Hex, radius: int) -> list[Hex]:
298 result: list[Hex] = [center]
299 for k in range(1, radius + 1):
300 result += self.oRanNearRtRicRing(center, k)