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 import network_generation.model.python.hexagon as Hexagon
18 from network_generation.model.python.cube import Cube
19 from network_generation.model.python.hexagon import Hex
22 class SpiralRadiusProfile:
23 def __init__(self, data: [dict[str, dict] | None] = None):
24 self._oRanSmoSpiralRadiusOfNearRtRics = (
25 data.get("oRanSmoSpiralRadiusOfNearRtRics", 1) if data else 1
27 self._oRanNearRtRicSpiralRadiusOfOCus = (
28 data.get("oRanNearRtRicSpiralRadiusOfOCus", 1) if data else 1
30 self._oRanCuSpiralRadiusOfODus = (
31 data.get("oRanCuSpiralRadiusOfODus", 1) if data else 1
33 self._oRanDuSpiralRadiusOfTowers = (
34 data.get("oRanDuSpiralRadiusOfTowers", 1) if data else 1
39 return f"{self._oRanDuSpiralRadiusOfTowers}{self._oRanCuSpiralRadiusOfODus}{self._oRanNearRtRicSpiralRadiusOfOCus}{self._oRanSmoSpiralRadiusOfNearRtRics}"
42 def count(self) -> int:
48 for ru in range(self._oRanDuSpiralRadiusOfTowers + 1):
49 towers = towers + 6 * ru
51 for du in range(self._oRanCuSpiralRadiusOfODus + 1):
54 for cu in range(self._oRanNearRtRicSpiralRadiusOfOCus + 1):
57 for ric in range(self._oRanSmoSpiralRadiusOfNearRtRics + 1):
60 return towers * dus * cus * rics
63 def oRanSmoSpiralRadiusOfNearRtRics(self) -> int:
64 return self._oRanSmoSpiralRadiusOfNearRtRics
66 @oRanSmoSpiralRadiusOfNearRtRics.setter
67 def oRanSmoSpiralRadiusOfNearRtRics(self, value: int):
68 self._oRanSmoSpiralRadiusOfNearRtRics = value
71 def oRanNearRtRicSpiralRadiusOfOCus(self) -> int:
72 return self._oRanNearRtRicSpiralRadiusOfOCus
74 @oRanNearRtRicSpiralRadiusOfOCus.setter
75 def oRanNearRtRicSpiralRadiusOfOCus(self, value: int):
76 self._oRanNearRtRicSpiralRadiusOfOCus = value
79 def oRanCuSpiralRadiusOfODus(self) -> int:
80 return self._oRanCuSpiralRadiusOfODus
82 @oRanCuSpiralRadiusOfODus.setter
83 def oRanCuSpiralRadiusOfODus(self, value: int):
84 self._oRanCuSpiralRadiusOfODus = value
87 def oRanDuSpiralRadiusOfTowers(self) -> int:
88 return self._oRanDuSpiralRadiusOfTowers
90 @oRanDuSpiralRadiusOfTowers.setter
91 def oRanDuSpiralRadiusOfTowers(self, value: int):
92 self._oRanDuSpiralRadiusOfTowers = value
95 def sectors(self) -> int:
99 def sectors(self, value: int):
100 self._sectors = value
103 def nrDuCellsPerSector(self) -> int:
104 return self._nrDuCellsPerSector
106 @nrDuCellsPerSector.setter
107 def nrDuCellsPerSector(self, value: int):
108 self._nrDuCellsPerSector: int = value
110 def oRanDuDirections(self) -> list[Hex]:
111 q: int = 2 * self._oRanDuSpiralRadiusOfTowers + 1
112 r: int = -self._oRanDuSpiralRadiusOfTowers - 1
123 def oRanDuNeighbor(self, cube: Cube, direction: int):
124 return Hexagon.hex_add(cube, self.oRanDuDirections()[direction])
126 def oRanDuRing(self, center: Hex, radius: int) -> list[Hex]:
129 "Invalid radius. The radius around the hex center must be greater than 0 rings."
131 results: list[Hex] = []
132 hex: Hex = Hexagon.hex_add(
133 center, Hexagon.hex_scale(self.oRanDuDirections()[4], radius)
136 for j in range(radius):
138 hex = self.oRanDuNeighbor(hex, i)
141 def oRanDuSpiral(self, o_ran_du_center: Hex, radius: int) -> list[Hex]:
142 result: list[Hex] = [o_ran_du_center]
143 for k in range(1, radius + 1):
144 result.extend(self.oRanDuRing(o_ran_du_center, k))
147 def oRanCuDirections(self) -> list[Hex]:
149 2 * self.oRanCuSpiralRadiusOfODus
151 * self.oRanCuSpiralRadiusOfODus
152 * self.oRanDuSpiralRadiusOfTowers
153 + self.oRanDuSpiralRadiusOfTowers
157 self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus
169 def oRanCuNeighbor(self, cube: Hex, direction: int) -> list[Hex]:
170 return Hexagon.hex_add(cube, self.oRanCuDirections()[direction])
172 def oRanCuRing(self, center: Hex, radius: int):
175 "Invalid radius. The radius around the hex center must be greater than 0 rings."
178 results: list[Hex] = []
179 hex: Hex = Hexagon.hex_add(
180 center, Hexagon.hex_scale(self.oRanCuDirections()[4], radius)
183 for j in range(radius):
185 hex = self.oRanCuNeighbor(hex, i)
188 def oRanCuSpiral(self, center: Hex, radius: int) -> list[Hex]:
189 result: list[Hex] = [center]
190 for k in range(1, radius + 1):
191 result += self.oRanCuRing(center, k)
194 def oRanNearRtRicDirections(self) -> list[Hex]:
196 2 * self.oRanCuSpiralRadiusOfODus
198 * self.oRanCuSpiralRadiusOfODus
199 * self.oRanDuSpiralRadiusOfTowers
200 + self.oRanDuSpiralRadiusOfTowers
204 self.oRanDuSpiralRadiusOfTowers - self.oRanCuSpiralRadiusOfODus
207 q: int = 3 * q0 - self.oRanNearRtRicSpiralRadiusOfOCus
208 r: int = -r0 - self.oRanNearRtRicSpiralRadiusOfOCus
210 profile_id: str = self.id[0 : len(self.id) - 1]
211 if profile_id in {"111", "112", "113", "114"}:
212 q: int = 21 + 14 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
213 r: int = -7 * self.oRanNearRtRicSpiralRadiusOfOCus
214 elif profile_id in {"121", "122", "123", "124"}:
215 q: int = 25 + 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
216 r: int = 9 + 10 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
217 elif profile_id in {"131", "132"}:
218 q: int = 49 + 30 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
219 r: int = -21 - 34 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
220 elif profile_id == "133":
223 elif profile_id == "134":
226 elif profile_id in {"211", "212", "213", "214"}:
227 q: int = 34 + 23 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
228 r: int = -10 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
229 elif profile_id in {"221", "222", "223", "224"}:
230 q: int = 57 + 38 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
231 r: int = -19 * self.oRanNearRtRicSpiralRadiusOfOCus
232 elif profile_id in {"231", "232", "233", "234"}:
233 q: int = 80 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
234 r: int = -28 * self.oRanNearRtRicSpiralRadiusOfOCus - 1
235 elif profile_id in {"241", "242", "243", "244"}:
236 q: int = 103 + 68 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
237 r: int = -39 * self.oRanNearRtRicSpiralRadiusOfOCus + 2 * (
238 self.oRanNearRtRicSpiralRadiusOfOCus - 1
240 elif profile_id in {"311", "312", "313", "314"}:
241 q: int = 47 + 32 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
242 r: int = -11 - 13 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
243 elif profile_id in {"321", "322", "323", "324"}:
244 q: int = 79 + 53 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
245 r: int = -24 - 25 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
246 elif profile_id in {"331", "332", "333", "334"}:
247 q: int = 111 + 75 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
248 r: int = -37 - 37 * (self.oRanNearRtRicSpiralRadiusOfOCus - 1)
250 # Handle the default case or raise a warning
263 def oRanNearRtRicNeighbor(self, cube: Hex, direction: int):
264 return Hexagon.hex_add(cube, self.oRanNearRtRicDirections()[direction])
266 def oRanNearRtRicRing(self, center: Hex, radius: int) -> list[Hex]:
269 "Invalid radius. The radius around the hex center must be greater than 0 rings."
272 results: list[Hex] = []
273 hex: Hex = Hexagon.hex_add(
275 Hexagon.hex_scale(self.oRanNearRtRicDirections()[4], radius),
278 for j in range(radius):
280 hex = self.oRanNearRtRicNeighbor(hex, i)
283 def oRanNearRtRicSpiral(self, center: Hex, radius: int) -> list[Hex]:
284 result: list[Hex] = [center]
285 for k in range(1, radius + 1):
286 result += self.oRanNearRtRicRing(center, k)