handoverlab 2.3.0__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. {handoverlab-2.3.0 → handoverlab-2.4.0}/CHANGELOG.md +61 -1
  2. {handoverlab-2.3.0 → handoverlab-2.4.0}/CITATION.cff +1 -1
  3. {handoverlab-2.3.0 → handoverlab-2.4.0}/PKG-INFO +9 -4
  4. {handoverlab-2.3.0 → handoverlab-2.4.0}/README.md +8 -3
  5. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/calibration-3gpp.md +56 -2
  6. handoverlab-2.4.0/docs/comparison.md +199 -0
  7. handoverlab-2.4.0/docs/guides/ai-mobility.md +182 -0
  8. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/scheduler.md +5 -3
  9. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/suburban-o2i.md +3 -2
  10. handoverlab-2.4.0/docs/guides/ue-beams.md +93 -0
  11. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/performance.md +41 -0
  12. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/standard-compliance.md +47 -2
  13. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/user_guide.md +1 -1
  14. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/verification.md +2 -1
  15. {handoverlab-2.3.0 → handoverlab-2.4.0}/mkdocs.yml +3 -0
  16. {handoverlab-2.3.0 → handoverlab-2.4.0}/pyproject.toml +1 -1
  17. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/__init__.py +1 -1
  18. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/antenna.py +50 -3
  19. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/extended.py +114 -4
  20. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/config.py +63 -3
  21. handoverlab-2.4.0/src/handoverlab/engine/_kernels.py +238 -0
  22. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/core.py +3 -0
  23. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/extended.py +57 -5
  24. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/scheduler.py +125 -0
  25. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/rules/__init__.py +6 -4
  26. handoverlab-2.4.0/src/handoverlab/rules/predict.py +588 -0
  27. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/seeds.py +13 -11
  28. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/standard.py +1 -0
  29. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/__init__.py +5 -3
  30. handoverlab-2.4.0/src/handoverlab/verify/aimobility.py +56 -0
  31. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/calibration.py +171 -14
  32. handoverlab-2.4.0/src/handoverlab/verify/data/r1_2506406.csv +607 -0
  33. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/learning.py +5 -0
  34. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab.egg-info/PKG-INFO +9 -4
  35. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab.egg-info/SOURCES.txt +9 -0
  36. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/data/public_api.json +1 -0
  37. handoverlab-2.4.0/tests/test_ai_mobility.py +123 -0
  38. handoverlab-2.4.0/tests/test_calibration.py +167 -0
  39. handoverlab-2.4.0/tests/test_sched_kernel.py +130 -0
  40. handoverlab-2.4.0/tests/test_ue_beams.py +162 -0
  41. handoverlab-2.3.0/src/handoverlab/engine/_kernels.py +0 -78
  42. handoverlab-2.3.0/tests/test_calibration.py +0 -81
  43. {handoverlab-2.3.0 → handoverlab-2.4.0}/.zenodo.json +0 -0
  44. {handoverlab-2.3.0 → handoverlab-2.4.0}/CODE_OF_CONDUCT.md +0 -0
  45. {handoverlab-2.3.0 → handoverlab-2.4.0}/CONTRIBUTING.md +0 -0
  46. {handoverlab-2.3.0 → handoverlab-2.4.0}/LICENSE +0 -0
  47. {handoverlab-2.3.0 → handoverlab-2.4.0}/MANIFEST.in +0 -0
  48. {handoverlab-2.3.0 → handoverlab-2.4.0}/SECURITY.md +0 -0
  49. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/RELEASING.md +0 -0
  50. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/calibration.md +0 -0
  51. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/add-scenario.md +0 -0
  52. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/beams-layers.md +0 -0
  53. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/buffers.md +0 -0
  54. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/daps-ltm.md +0 -0
  55. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/dashboard.md +0 -0
  56. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/dual-connectivity.md +0 -0
  57. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/export-event-logs.md +0 -0
  58. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/fading.md +0 -0
  59. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/high-speed-train.md +0 -0
  60. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/highway.md +0 -0
  61. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/indoor-rural.md +0 -0
  62. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/learning-rule.md +0 -0
  63. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/many-cores.md +0 -0
  64. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/mro.md +0 -0
  65. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/ntn.md +0 -0
  66. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/radio-maps.md +0 -0
  67. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/reproduce.md +0 -0
  68. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/guides/upper-mid-band.md +0 -0
  69. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/calibration_38901.png +0 -0
  70. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/dashboard-charts.png +0 -0
  71. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/dashboard-compare.png +0 -0
  72. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/dashboard-where.png +0 -0
  73. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/dashboard.png +0 -0
  74. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/ntn-beams.png +0 -0
  75. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/radio-map.png +0 -0
  76. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/report-comparison.png +0 -0
  77. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/report-tuning.png +0 -0
  78. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/images/ssb-beams.png +0 -0
  79. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/index.md +0 -0
  80. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/migration-2.0.md +0 -0
  81. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/config.md +0 -0
  82. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/engine.md +0 -0
  83. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/eventlog.md +0 -0
  84. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/gui.md +0 -0
  85. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/index.md +0 -0
  86. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/mapfile.md +0 -0
  87. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/ntn.md +0 -0
  88. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/rules.md +0 -0
  89. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/scenarios.md +0 -0
  90. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/simulate.md +0 -0
  91. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/stability.md +0 -0
  92. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/stats.md +0 -0
  93. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/studies.md +0 -0
  94. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/testing.md +0 -0
  95. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/api/verify.md +0 -0
  96. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/cli.md +0 -0
  97. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference/metrics.md +0 -0
  98. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/reference-study.md +0 -0
  99. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/dense-urban-2layer.md +0 -0
  100. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/dense-urban-2layer.svg +0 -0
  101. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/fr3-urban-15ghz.md +0 -0
  102. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/fr3-urban-15ghz.svg +0 -0
  103. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/highway-tr37885-30ghz.md +0 -0
  104. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/highway-tr37885-30ghz.svg +0 -0
  105. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/highway-tr37885-4ghz.md +0 -0
  106. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/highway-tr37885-4ghz.svg +0 -0
  107. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/hst-fr2-28ghz.md +0 -0
  108. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/hst-fr2-28ghz.svg +0 -0
  109. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/indoor-office-4ghz.md +0 -0
  110. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/indoor-office-4ghz.svg +0 -0
  111. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/ns3-urban-3.5ghz.md +0 -0
  112. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/ns3-urban-3.5ghz.svg +0 -0
  113. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/ntn-leo600-2ghz.md +0 -0
  114. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/ntn-leo600-2ghz.svg +0 -0
  115. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/open-area-10ghz.md +0 -0
  116. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/open-area-10ghz.svg +0 -0
  117. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/rural-700mhz.md +0 -0
  118. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/rural-700mhz.svg +0 -0
  119. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/smoke.md +0 -0
  120. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/smoke.svg +0 -0
  121. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/suburban-sma-7ghz.md +0 -0
  122. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/suburban-sma-7ghz.svg +0 -0
  123. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/urban-grid-10ghz.md +0 -0
  124. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/urban-grid-10ghz.svg +0 -0
  125. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/urban-grid-28ghz-beams.md +0 -0
  126. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/urban-grid-28ghz-beams.svg +0 -0
  127. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/urban-macro-tr37885-4ghz.md +0 -0
  128. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/scenarios/urban-macro-tr37885-4ghz.svg +0 -0
  129. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/stability.md +0 -0
  130. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/time-step.md +0 -0
  131. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/tutorials/first-run.md +0 -0
  132. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/tutorials/own-rule.md +0 -0
  133. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/tutorials/reading-the-report.md +0 -0
  134. {handoverlab-2.3.0 → handoverlab-2.4.0}/docs/tutorials/tuning-study.md +0 -0
  135. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/compare_a3_cho.py +0 -0
  136. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/open_area.toml +0 -0
  137. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/radio_map.py +0 -0
  138. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/smoke.yaml +0 -0
  139. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/speed_rule.py +0 -0
  140. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/street_grid.yaml +0 -0
  141. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/study_reference.yaml +0 -0
  142. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/study_reference_explore.yaml +0 -0
  143. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/study_smoke.yaml +0 -0
  144. {handoverlab-2.3.0 → handoverlab-2.4.0}/examples/traffic_models.py +0 -0
  145. {handoverlab-2.3.0 → handoverlab-2.4.0}/setup.cfg +0 -0
  146. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/__main__.py +0 -0
  147. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/__init__.py +0 -0
  148. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/fading.py +0 -0
  149. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/l2s.py +0 -0
  150. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/ntn.py +0 -0
  151. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/pathloss.py +0 -0
  152. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/radiomap.py +0 -0
  153. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/channel/source.py +0 -0
  154. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/cli.py +0 -0
  155. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/__init__.py +0 -0
  156. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/batch.py +0 -0
  157. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/buffers.py +0 -0
  158. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/dual.py +0 -0
  159. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/invariants.py +0 -0
  160. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/metrics.py +0 -0
  161. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/engine/procedures.py +0 -0
  162. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/eventlog.py +0 -0
  163. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/gui/__init__.py +0 -0
  164. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/gui/app.py +0 -0
  165. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/gui/logic.py +0 -0
  166. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/io.py +0 -0
  167. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/layout.py +0 -0
  168. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/linklevel.py +0 -0
  169. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/mapfile.py +0 -0
  170. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/measurement.py +0 -0
  171. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/mobility.py +0 -0
  172. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/py.typed +0 -0
  173. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/requirements.py +0 -0
  174. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/rules/base.py +0 -0
  175. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/rules/builtin.py +0 -0
  176. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/rules/dqn.py +0 -0
  177. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/rules/mro.py +0 -0
  178. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/__init__.py +0 -0
  179. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/dense-urban-2layer.yaml +0 -0
  180. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/fr3-urban-15ghz.yaml +0 -0
  181. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/highway-tr37885-30ghz.yaml +0 -0
  182. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/highway-tr37885-4ghz.yaml +0 -0
  183. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/hst-fr2-28ghz.yaml +0 -0
  184. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/indoor-office-4ghz.yaml +0 -0
  185. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/ns3-urban-3.5ghz.yaml +0 -0
  186. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/ntn-leo600-2ghz.yaml +0 -0
  187. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/open-area-10ghz.yaml +0 -0
  188. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/rural-700mhz.yaml +0 -0
  189. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/smoke.yaml +0 -0
  190. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/suburban-sma-7ghz.yaml +0 -0
  191. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/urban-grid-10ghz.yaml +0 -0
  192. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/urban-grid-28ghz-beams.yaml +0 -0
  193. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/scenarios/cards/urban-macro-tr37885-4ghz.yaml +0 -0
  194. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/simulate.py +0 -0
  195. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/stability.py +0 -0
  196. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/stats.py +0 -0
  197. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/__init__.py +0 -0
  198. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/config.py +0 -0
  199. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/report.py +0 -0
  200. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/runner.py +0 -0
  201. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/status.py +0 -0
  202. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/store.py +0 -0
  203. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/study.py +0 -0
  204. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/studies/tuning.py +0 -0
  205. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/testing.py +0 -0
  206. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/traffic.py +0 -0
  207. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/data/golden.json +0 -0
  208. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/data/golden_1x.json +0 -0
  209. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/data/ns3_urban_a3.json +0 -0
  210. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/data/r1_165974.csv +0 -0
  211. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/engine_checks.py +0 -0
  212. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/extended.py +0 -0
  213. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/fading.py +0 -0
  214. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/golden.py +0 -0
  215. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/highway.py +0 -0
  216. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/ns3.py +0 -0
  217. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/ntn.py +0 -0
  218. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/radio.py +0 -0
  219. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/report.py +0 -0
  220. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/scenarios.py +0 -0
  221. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/stored.py +0 -0
  222. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/verify/values.py +0 -0
  223. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab/world.py +0 -0
  224. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab.egg-info/dependency_links.txt +0 -0
  225. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab.egg-info/entry_points.txt +0 -0
  226. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab.egg-info/requires.txt +0 -0
  227. {handoverlab-2.3.0 → handoverlab-2.4.0}/src/handoverlab.egg-info/top_level.txt +0 -0
  228. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/conftest.py +0 -0
  229. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/data/bh6_reference.json +0 -0
  230. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/data/bh6_wide.json +0 -0
  231. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/data/make_bh6_reference.py +0 -0
  232. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/data/make_bh6_wide.py +0 -0
  233. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/helpers.py +0 -0
  234. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_batch.py +0 -0
  235. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_beams_layers.py +0 -0
  236. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_buffers.py +0 -0
  237. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_channel_detail.py +0 -0
  238. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_cltm.py +0 -0
  239. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_config_cli.py +0 -0
  240. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_contract.py +0 -0
  241. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_determinism.py +0 -0
  242. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_dqn.py +0 -0
  243. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_engine_triggers.py +0 -0
  244. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_eventlog.py +0 -0
  245. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_fading.py +0 -0
  246. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_gui.py +0 -0
  247. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_highway.py +0 -0
  248. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_highway_tr37885.py +0 -0
  249. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_hst_dc.py +0 -0
  250. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_indoor_rural.py +0 -0
  251. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_invariants.py +0 -0
  252. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_levels_status_extend.py +0 -0
  253. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_lm_model.py +0 -0
  254. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_mapfile.py +0 -0
  255. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_measurement.py +0 -0
  256. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_mro.py +0 -0
  257. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_ntn.py +0 -0
  258. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_pathloss.py +0 -0
  259. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_protocol_3gpp.py +0 -0
  260. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_readme_boundaries.py +0 -0
  261. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_regression_bh6.py +0 -0
  262. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_regression_bh6_wide.py +0 -0
  263. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_rrc_detail.py +0 -0
  264. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_rules_rc2.py +0 -0
  265. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_scenarios.py +0 -0
  266. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_scenarios_230.py +0 -0
  267. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_scheduler.py +0 -0
  268. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_signalling_energy.py +0 -0
  269. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_stability.py +0 -0
  270. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_stats.py +0 -0
  271. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_study.py +0 -0
  272. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_tools.py +0 -0
  273. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_traffic.py +0 -0
  274. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_tuning.py +0 -0
  275. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_v111.py +0 -0
  276. {handoverlab-2.3.0 → handoverlab-2.4.0}/tests/test_verify.py +0 -0
  277. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/compare_fingerprints.py +0 -0
  278. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/make_beam_figure.py +0 -0
  279. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/make_calibration_figure.py +0 -0
  280. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/make_ntn_figure.py +0 -0
  281. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/make_radiomap_figure.py +0 -0
  282. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/make_readme_images.py +0 -0
  283. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/mkdocs_hooks.py +0 -0
  284. {handoverlab-2.3.0 → handoverlab-2.4.0}/tools/release_check.py +0 -0
@@ -7,6 +7,65 @@ All notable changes to this project are documented in this file. The format foll
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.4.0] - 2026-10-22
11
+
12
+ ### Added
13
+
14
+ - 7 GHz large-scale calibration (TR 38.901 V19.5.0 clause 7.8.1, Table 7.8-1A) in the `verify` group
15
+ `calibration`: UMa and UMi at 7 GHz, UMa and UMi at 6 GHz with the updated model, and SMa with ISD 1299 m and
16
+ 1732 m (35 m sites with a mechanical downtilt of 95 / 92 deg through Eqs. 7.1-7 and 7.1-8, 20 % of the users
17
+ in cars with the car penetration loss, 80 % in residential and commercial buildings over their floors with the
18
+ low-loss A model), compared with the companies of 3GPP R1-2506406 (RAN1 #122; mean and range in
19
+ `verify/data/r1_2506406.csv`). Pre-registered result (30 000 users, seed 1): every percentile 5-95 % lies
20
+ inside the company range (18 of 18 case-metric pairs pass, 342 of 342 percentiles); the largest distance from
21
+ the company mean is 1.65-2.88 dB, so the second criterion (at most 1.5 dB) fails for all six cases. It is
22
+ reported as a note. The checks against R1-165974 are unchanged. `simulate_drops` takes the IRR-glass loss of
23
+ the case's reference when `irr_glass` is not given (unchanged for the old cases).
24
+ - Compiled slot scheduler: with `run.backend: numba` (`pip install handoverlab[fast]`) the slots of
25
+ `protocol.scheduler` are played by a compiled loop (`handoverlab.engine._kernels.sched_slots`). The MCS
26
+ look-ups, logarithms and block error probabilities still come from the NumPy functions of the reference loop
27
+ (per-interval tables), and the loop uses only basic arithmetic in the reference order, so every result is
28
+ bit-identical to the NumPy loop (`tests/test_sched_kernel.py`, which also runs the loop's logic as plain Python
29
+ without Numba). On the ns-3 card the engine time with the scheduler drops by a factor of 8 to 60 (case and machine load) (about 3 times the rate model instead of 50-80 times; see `docs/performance.md`). The NumPy loop stays the reference and the default and runs in debug mode.
30
+ - UE receive beams as an option of the beam model (`radio.beams.ue_panels` 1, 2 or 4, off by default): UE panels
31
+ of TR 38.802 V14.2.0 Table A.2.1-4 (Config 1: two panels 180 deg apart, Config 2: four at 90 deg; `ue_panel`
32
+ [M, N] = [2, 4] at half a wavelength, one polarisation) with the element of Table A.2.1-8 (model 1, 5 dBi;
33
+ = ITU-R M.2412-0 Table 11), `ue_beams` DFT receive beams per panel over `ue_beam_span_deg`, bearing uniform
34
+ per UE (`ue_orientation: random`) or along the direction of travel (`heading`). Measurements use the best
35
+ receive beam of the best panel (`ue_rx: best`; TS 38.215 5.1.1 receiver branches) or a sweep over the beams,
36
+ one per L1 instant, with the highest of the last samples reported (`sweep`); data, RLM, beam failure
37
+ detection and recovery and the interference use the serving receive beam. The FR2 time scaling of the sweep
38
+ was already in `protocol.meas_periods: ts38133` (Mmeas_period_w/o_gaps = 24, TS 38.133 V19.6.0 9.2.5.1) and is
39
+ not applied twice; `sweep` is refused with `ts38133`. New random stream `ue_beams`. Not combined with
40
+ `protocol.dc`. With the option off every result is unchanged. Guide: `docs/guides/ue-beams.md`.
41
+ - AI/ML-based mobility after 3GPP TR 38.744 V19.0.1 (Release 19) as an optional rule, `a3_pred` (NumPy only, off
42
+ unless a run names it): prediction of the L3 cell-level RSRP of a cell from its own past L3 results (RRM
43
+ sub-use case 2), in case A (prediction window ahead; handover on the predicted Event A3, handover model
44
+ option 2 with the preparation started at the report) and case B (measurement skipping with MRRT =
45
+ skip / (skip + 1), L3 filtering options 1-3, Event A3 on the measured-and-predicted series, option 3).
46
+ Predictors: sample and hold (the non-AI baseline of TR 38.744 clause 5.1) and a ridge-regression
47
+ autoregressive model trained on runs of training seeds (`handoverlab.rules.predict.fit_predictor`,
48
+ `collect`, JSON weights), or a user object. Statistics after a run (`PredA3.stats`, `Recorder`): prediction
49
+ accuracy per horizon against the fully measured L3 result, MRRT, and the counters n1, n2, n3 and F1 score of
50
+ the indirect A3 event prediction (clause 5.3.1). With `act: false` and in case B without skipping the rule
51
+ gives the event log of `a3`. `handoverlab verify --only learning` gained four checks (P1-P4). Guide
52
+ `docs/guides/ai-mobility.md` with the evaluation against TR 38.744 and what is not modelled (RLF
53
+ prediction, frequency- and spatial-domain prediction, beam-level prediction, option 1, LCM); compliance rows
54
+ in `docs/standard-compliance.md`. Pre-registered evaluation (FR1 case B, FR2 case A): ridge more accurate
55
+ than sample and hold, errors rising with speed, PW and MRRT as TR 38.744 observes; MRRT 50 % costs
56
+ +0.7-0.9 percentage points of HOF rate; option 2 cuts the HOF rate from 2.4 % to 0.3 % but with 55 % more
57
+ attempts and three times the ping-pongs, and sample and hold does the same; generalization criterion G2
58
+ failed. Every existing result is unchanged.
59
+
60
+ ### Documentation
61
+
62
+ - `docs/comparison.md`: HandoverLab next to ns-3 with 5G-LENA and the mmWave module, Simu5G, the Vienna 5G System
63
+ Level Simulator, the MATLAB 5G Toolbox, OpenAirInterface and Sionna on the points that matter for handover
64
+ studies (A3, CHO, DAPS, LTM, radio-link failure, dual connectivity, NTN, beams, fast fading and link-to-system
65
+ mapping, scheduler, speed and scale, licence, language, last release, validation against 3GPP). Every cell
66
+ about another tool cites its official documentation, repository or paper (accessed 2026-10-22); facts not
67
+ found are marked "not stated"; a section lists where the other tools are stronger.
68
+
10
69
  ## [2.3.0] - 2026-10-22
11
70
 
12
71
  ### Added
@@ -1005,7 +1064,8 @@ First alpha release (stage 1: the core simulator).
1005
1064
  - Documentation: README, user guide, contribution guide, citation file; CI on Linux, Windows and
1006
1065
  macOS with Python 3.9-3.12.
1007
1066
 
1008
- [Unreleased]: https://github.com/mjs19971997/handoverlab/compare/v2.3.0...HEAD
1067
+ [Unreleased]: https://github.com/mjs19971997/handoverlab/compare/v2.4.0...HEAD
1068
+ [2.4.0]: https://github.com/mjs19971997/handoverlab/compare/v2.3.0...v2.4.0
1009
1069
  [2.3.0]: https://github.com/mjs19971997/handoverlab/compare/v2.2.0...v2.3.0
1010
1070
  [2.2.0]: https://github.com/mjs19971997/handoverlab/compare/v2.1.0...v2.2.0
1011
1071
  [2.1.0]: https://github.com/mjs19971997/handoverlab/compare/v2.0.0...v2.1.0
@@ -11,7 +11,7 @@ abstract: >-
11
11
  measurement chain, a radio-link failure model, an outcome label for every handover attempt,
12
12
  a plug-in interface for handover rules, equal-budget tuning studies with paired statistics,
13
13
  and verification against hand-computed values, golden event-log fingerprints and ns-3 / 5G-LENA.
14
- version: "2.3.0"
14
+ version: "2.4.0"
15
15
  doi: 10.5281/zenodo.23409131
16
16
  identifiers:
17
17
  - type: doi
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: handoverlab
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: System-level handover simulator for 5G-Advanced and beyond-5G research
5
5
  Author: Mostafa Jalili Sanjarani, Yasser Elmi Sola
6
6
  License-Expression: MIT
@@ -193,11 +193,11 @@ the clause-by-clause detail is in [standard compliance](https://github.com/mjs19
193
193
  |---|---|---|---|
194
194
  | Layouts | `street_grid` (TR 37.885 urban grid), `open_area`, `highway` (TR 37.885 / TR 36.885, wrap-around), `indoor` (TR 38.901 office), `ntn` (one LEO satellite, TR 38.821); explicit site lists | sites on the pavement with small cells (urban cards); the TR 37.885 urban macro grid without wrap-around (`urban-macro-tr37885-4ghz`) | several satellites |
195
195
  | Channel | TR 38.901 path loss and LOS (UMi, UMa, RMa, SMa, InH), LOS from buildings, spatially consistent LOS and shadowing, car and O2I building penetration loss, radio maps from a file (clause 8), TR 38.811 for the satellite | received power per site and step with a slow time-varying component; indoor users keep the LOS state and shadowing of their position; optional TDL fast fading with effective SINRs (clause 7.7.2, since 2.2.0) | CDL and the full fast-fading model of clause 7.5, MIMO |
196
- | Beams and carriers | SSB beams per sector, cell quality from beams, beam failure detection and recovery, several carriers with gaps and Event A5; dual connectivity (NR-DC: SN addition, PSCell change, SN release, SCG failure; option since 2.3.0) | the TR 38.901 antenna element and DFT beams; isotropic UE; the SCG as one PSCell with a full-buffer share | UE-side beamforming, conditional PSCell change, fast MCG recovery |
196
+ | Beams and carriers | SSB beams per sector, cell quality from beams, beam failure detection and recovery, several carriers with gaps and Event A5; dual connectivity (NR-DC: SN addition, PSCell change, SN release, SCG failure; option since 2.3.0) | the TR 38.901 antenna element and DFT beams; isotropic UE unless UE receive panels are set (option since 2.4.0); the SCG as one PSCell with a full-buffer share | UE transmit beams and polarisation, conditional PSCell change, fast MCG recovery |
197
197
  | Mobility | street-following vehicles (60 km/h, two lanes), highway lanes at 70/140 km/h, a train at 350 km/h (TR 38.854), random waypoints, pedestrians | constant speed per user | handheld rotation and body blockage |
198
198
  | Traffic and load | constant rates per 5QI, full buffer, periodic, FTP model 3; cell load drives interference | rate from SINR (Shannon-type mapping), no scheduler | slot scheduler, HARQ, RLC/PDCP, TCP and applications |
199
199
  | Measurements | L1 samples with error, TS 38.331 L3 filter, TS 38.133 measurement periods and gaps (option) | wideband RSRP; SS-RSRP per resource element with beams/carriers | RSRQ, CSI reporting |
200
- | Procedures | baseline (A3), CHO, DAPS, LTM, conditional LTM, CHO with D1/D2 for satellites, A3/A5 between carriers; rules `a3`, `a3a5`, `a3_mro`, `a3_bandit`, `dqn`, `cho`, `cho_d2`, `daps`, `ltm`, `cltm` | fixed preparation, command and execution delays; re-establishment always succeeds after a fixed outage | condEventT1, RACH-less NTN handover, Xn signalling in detail |
200
+ | Procedures | baseline (A3), CHO, DAPS, LTM, conditional LTM, CHO with D1/D2 for satellites, A3/A5 between carriers; rules `a3`, `a3a5`, `a3_mro`, `a3_bandit`, `dqn`, `a3_pred`, `cho`, `cho_d2`, `daps`, `ltm`, `cltm` | fixed preparation, command and execution delays; re-establishment always succeeds after a fixed outage | condEventT1, RACH-less NTN handover, Xn signalling in detail |
201
201
  | Failure model | Qout/Qin with windows, N310/N311/T310, T304, command received during T310, re-establishment, link-monitoring restart | Qout/Qin as SINR thresholds (TR 36.839 values) instead of the BLER of a hypothetical PDCCH | BLER-based link monitoring; absolute failure rates are not calibrated: compare rules with each other |
202
202
  | Time | 10 ms step by default (`protocol.step_s`); the effect of the step is measured in [time step](https://github.com/mjs19971997/handoverlab/blob/main/docs/time-step.md) | events rounded to the step | sub-slot timing |
203
203
 
@@ -218,7 +218,8 @@ networks with small cells 50-300 m apart. Three paths lead beyond 5G:
218
218
  - **Non-terrestrial networks**: a LEO satellite with earth-moving beams (TR 38.811, TR 38.821) and conditional
219
219
  handover with condEventD2 (TS 38.331 Release 18).
220
220
  - **Learning-based mobility**: the rule interface gives a rule every measurement and the outcome of every
221
- attempt; `a3_bandit` and `dqn` are examples, `a3_mro` the fair tuned baseline.
221
+ attempt; `a3_bandit` and `dqn` are examples, `a3_mro` the fair tuned baseline, and `a3_pred` follows the
222
+ RRM measurement prediction of TR 38.744 (Release 19).
222
223
 
223
224
  6G itself is at the stage of requirements: TR 38.914 V20.1.0 (Release 20, last changed at RAN #113 in September
224
225
  2026) sets scenarios and key performance requirements but specifies no handover procedure, timer or measurement
@@ -434,6 +435,10 @@ the pages are plain Markdown in [docs/](https://github.com/mjs19971997/handoverl
434
435
  - [Scenario cards](https://github.com/mjs19971997/handoverlab/tree/main/docs/scenarios): the built-in scenarios with the source of every parameter.
435
436
  - [Verification](https://github.com/mjs19971997/handoverlab/blob/main/docs/verification.md), [failure-model calibration](https://github.com/mjs19971997/handoverlab/blob/main/docs/calibration.md) and
436
437
  [performance](https://github.com/mjs19971997/handoverlab/blob/main/docs/performance.md).
438
+ - [Comparison with other simulators](https://github.com/mjs19971997/handoverlab/blob/main/docs/comparison.md): ns-3 with 5G-LENA
439
+ and the mmWave module, Simu5G, the Vienna 5G System Level Simulator, the MATLAB 5G Toolbox, OpenAirInterface
440
+ and Sionna on handover procedures, failure model, NTN, beams, PHY abstraction, scheduler, scale and validation,
441
+ each cell with its source, including where the other tools are stronger.
437
442
  - [Changelog](https://github.com/mjs19971997/handoverlab/blob/main/CHANGELOG.md), [contribution guide](https://github.com/mjs19971997/handoverlab/blob/main/CONTRIBUTING.md) and [releasing](https://github.com/mjs19971997/handoverlab/blob/main/docs/RELEASING.md).
438
443
 
439
444
  ## Roadmap
@@ -135,11 +135,11 @@ the clause-by-clause detail is in [standard compliance](https://github.com/mjs19
135
135
  |---|---|---|---|
136
136
  | Layouts | `street_grid` (TR 37.885 urban grid), `open_area`, `highway` (TR 37.885 / TR 36.885, wrap-around), `indoor` (TR 38.901 office), `ntn` (one LEO satellite, TR 38.821); explicit site lists | sites on the pavement with small cells (urban cards); the TR 37.885 urban macro grid without wrap-around (`urban-macro-tr37885-4ghz`) | several satellites |
137
137
  | Channel | TR 38.901 path loss and LOS (UMi, UMa, RMa, SMa, InH), LOS from buildings, spatially consistent LOS and shadowing, car and O2I building penetration loss, radio maps from a file (clause 8), TR 38.811 for the satellite | received power per site and step with a slow time-varying component; indoor users keep the LOS state and shadowing of their position; optional TDL fast fading with effective SINRs (clause 7.7.2, since 2.2.0) | CDL and the full fast-fading model of clause 7.5, MIMO |
138
- | Beams and carriers | SSB beams per sector, cell quality from beams, beam failure detection and recovery, several carriers with gaps and Event A5; dual connectivity (NR-DC: SN addition, PSCell change, SN release, SCG failure; option since 2.3.0) | the TR 38.901 antenna element and DFT beams; isotropic UE; the SCG as one PSCell with a full-buffer share | UE-side beamforming, conditional PSCell change, fast MCG recovery |
138
+ | Beams and carriers | SSB beams per sector, cell quality from beams, beam failure detection and recovery, several carriers with gaps and Event A5; dual connectivity (NR-DC: SN addition, PSCell change, SN release, SCG failure; option since 2.3.0) | the TR 38.901 antenna element and DFT beams; isotropic UE unless UE receive panels are set (option since 2.4.0); the SCG as one PSCell with a full-buffer share | UE transmit beams and polarisation, conditional PSCell change, fast MCG recovery |
139
139
  | Mobility | street-following vehicles (60 km/h, two lanes), highway lanes at 70/140 km/h, a train at 350 km/h (TR 38.854), random waypoints, pedestrians | constant speed per user | handheld rotation and body blockage |
140
140
  | Traffic and load | constant rates per 5QI, full buffer, periodic, FTP model 3; cell load drives interference | rate from SINR (Shannon-type mapping), no scheduler | slot scheduler, HARQ, RLC/PDCP, TCP and applications |
141
141
  | Measurements | L1 samples with error, TS 38.331 L3 filter, TS 38.133 measurement periods and gaps (option) | wideband RSRP; SS-RSRP per resource element with beams/carriers | RSRQ, CSI reporting |
142
- | Procedures | baseline (A3), CHO, DAPS, LTM, conditional LTM, CHO with D1/D2 for satellites, A3/A5 between carriers; rules `a3`, `a3a5`, `a3_mro`, `a3_bandit`, `dqn`, `cho`, `cho_d2`, `daps`, `ltm`, `cltm` | fixed preparation, command and execution delays; re-establishment always succeeds after a fixed outage | condEventT1, RACH-less NTN handover, Xn signalling in detail |
142
+ | Procedures | baseline (A3), CHO, DAPS, LTM, conditional LTM, CHO with D1/D2 for satellites, A3/A5 between carriers; rules `a3`, `a3a5`, `a3_mro`, `a3_bandit`, `dqn`, `a3_pred`, `cho`, `cho_d2`, `daps`, `ltm`, `cltm` | fixed preparation, command and execution delays; re-establishment always succeeds after a fixed outage | condEventT1, RACH-less NTN handover, Xn signalling in detail |
143
143
  | Failure model | Qout/Qin with windows, N310/N311/T310, T304, command received during T310, re-establishment, link-monitoring restart | Qout/Qin as SINR thresholds (TR 36.839 values) instead of the BLER of a hypothetical PDCCH | BLER-based link monitoring; absolute failure rates are not calibrated: compare rules with each other |
144
144
  | Time | 10 ms step by default (`protocol.step_s`); the effect of the step is measured in [time step](https://github.com/mjs19971997/handoverlab/blob/main/docs/time-step.md) | events rounded to the step | sub-slot timing |
145
145
 
@@ -160,7 +160,8 @@ networks with small cells 50-300 m apart. Three paths lead beyond 5G:
160
160
  - **Non-terrestrial networks**: a LEO satellite with earth-moving beams (TR 38.811, TR 38.821) and conditional
161
161
  handover with condEventD2 (TS 38.331 Release 18).
162
162
  - **Learning-based mobility**: the rule interface gives a rule every measurement and the outcome of every
163
- attempt; `a3_bandit` and `dqn` are examples, `a3_mro` the fair tuned baseline.
163
+ attempt; `a3_bandit` and `dqn` are examples, `a3_mro` the fair tuned baseline, and `a3_pred` follows the
164
+ RRM measurement prediction of TR 38.744 (Release 19).
164
165
 
165
166
  6G itself is at the stage of requirements: TR 38.914 V20.1.0 (Release 20, last changed at RAN #113 in September
166
167
  2026) sets scenarios and key performance requirements but specifies no handover procedure, timer or measurement
@@ -376,6 +377,10 @@ the pages are plain Markdown in [docs/](https://github.com/mjs19971997/handoverl
376
377
  - [Scenario cards](https://github.com/mjs19971997/handoverlab/tree/main/docs/scenarios): the built-in scenarios with the source of every parameter.
377
378
  - [Verification](https://github.com/mjs19971997/handoverlab/blob/main/docs/verification.md), [failure-model calibration](https://github.com/mjs19971997/handoverlab/blob/main/docs/calibration.md) and
378
379
  [performance](https://github.com/mjs19971997/handoverlab/blob/main/docs/performance.md).
380
+ - [Comparison with other simulators](https://github.com/mjs19971997/handoverlab/blob/main/docs/comparison.md): ns-3 with 5G-LENA
381
+ and the mmWave module, Simu5G, the Vienna 5G System Level Simulator, the MATLAB 5G Toolbox, OpenAirInterface
382
+ and Sionna on handover procedures, failure model, NTN, beams, PHY abstraction, scheduler, scale and validation,
383
+ each cell with its source, including where the other tools are stronger.
379
384
  - [Changelog](https://github.com/mjs19971997/handoverlab/blob/main/CHANGELOG.md), [contribution guide](https://github.com/mjs19971997/handoverlab/blob/main/CONTRIBUTING.md) and [releasing](https://github.com/mjs19971997/handoverlab/blob/main/docs/RELEASING.md).
380
385
 
381
386
  ## Roadmap
@@ -81,6 +81,58 @@ distribution, at most 0.12 dB below the smallest company value: the SIR of Hando
81
81
  0.5 dB below the industry mean there, which is on the conservative side. `handoverlab verify`
82
82
  passes a case when every percentile lies inside the company range widened by 0.5 dB.
83
83
 
84
+ ## 7 GHz: Table 7.8-1A against R1-2506406 (since 2.4.0)
85
+
86
+ **Summary.** TR 38.901 V19.5.0 adds Table 7.8-1A to clause 7.8.1: UMa, UMi-Street Canyon and suburban macro
87
+ (SMa, ISD 1299 m and 1732 m) at 7 GHz, plus UMa and UMi at 6 GHz again "with updated channel modeling". The
88
+ companies reported their CDFs in the 3GPP contribution **R1-2506406** (RAN1 #122, Bengaluru, August 2025,
89
+ InterDigital and ZTE, "Calibration Results for 7 - 24 GHz SI";
90
+ [3GPP server](https://www.3gpp.org/ftp/tsg_ran/WG1_RL1/TSGR1_122/Docs/R1-2506406.zip); large-scale workbook
91
+ `Calibration_LS_v35`, based on TR 38.901 V19.0.0). The criteria were fixed before the first run: every
92
+ percentile 5-95 % inside the company range widened by 0.5 dB (C1, the rule of the cases above), and the
93
+ largest distance from the company mean at most 1.5 dB per case (C2). Result, 30 000 users per case, seed 1:
94
+ **C1 passes for all 18 case-metric pairs (342 of 342 percentiles strictly inside the range); C2 fails for all
95
+ six cases (largest distance 1.65-2.88 dB).** `handoverlab verify` runs C1 as checks and C2 as notes in the
96
+ group `calibration`.
97
+
98
+ **The reference.** `src/handoverlab/verify/data/r1_2506406.csv` keeps, in the format of `r1_165974.csv`, the
99
+ mean, the smallest and the largest company value and the number of companies per case, metric and percentile;
100
+ the mean equals the workbook's own mean column. Companies with complete columns: 16 (coupling loss) / 15
101
+ (SINR, SIR) at 6 GHz; 17 / 16 for UMa and UMi at 7 GHz (Huawei, InterDigital, Samsung, ZTE, CATT, Lenovo,
102
+ Apple, Nokia, Ericsson, OPPO, MediaTek, Intel, Sharp, Spreadtrum, LGE, ETRI, Xiaomi; Spreadtrum gave the
103
+ coupling loss only); 17 / 16 for SMa 1299 m (with vivo, without ETRI); 13 / 12 for SMa 1732 m.
104
+
105
+ **The drop.** UMa and UMi as above (Table 7.8-1), with the IRR-glass loss of V19.5.0 (25.4 + 0.11 f dB) because
106
+ the companies worked with Release 19; at 7 GHz 49 dBm (UMa) and 44 dBm (UMi) with 20 MHz, the 6 GHz values of
107
+ Table 7.8-1, which Table 7.8-1A leaves unchanged for these two scenarios. SMa:
108
+
109
+ | Item | Setting | Source |
110
+ |---|---|---|
111
+ | Layout | 19 sites, 3 sectors, ISD 1299 m or 1732 m, BS 35 m, geographical wrap-around, minimum 2D distance 35 m (to d2D-out) | Tables 7.2-5, 7.8-1A |
112
+ | Antenna | element of Table 7.3-1 and 10 vertical elements (one port) without electrical tilt, the panel tilted mechanically to 95 deg (ISD 1299 m) or 92 deg (ISD 1732 m): the angles are taken into the antenna's local coordinates with Eqs. 7.1-7 and 7.1-8 | Tables 7.3-1, 7.8-1A; clause 7.1.3 |
113
+ | Users | 20 % outdoors (in cars, 1.5 m) with the car penetration loss N(9 dB, 5 dB) of non-metallic windows; 80 % indoors, 90 % of them in residential buildings (1.5 or 4.5 m), 10 % in commercial buildings (1.5 ... 13.5 m), uniform over the floors | Tables 7.2-5, 7.8-1A; clause 7.4.3.2 |
114
+ | O2I loss | low-loss A model (30 % glass, 70 % plywood, sigma_P 4.4 dB); d2D-in = minimum of two uniform variables up to 10 m (residential) or 25 m (commercial) | clause 7.4.3.1, Tables 7.4.3-1, 7.4.3-2 |
115
+ | Path loss, LOS, shadowing | the SMa models of `handoverlab.channel.pathloss` (Table 7.4.1-1; LOS probability of Table 7.4.2-1 without vegetation); shadowing 4 dB (LOS below d_BP), 6 dB (LOS beyond), 8 dB (NLOS), 8 dB for indoor users | Tables 7.4.1-1, 7.4.2-1, 7.5-6 Part-4 |
116
+ | Link budget | 49 dBm, 20 MHz, UT noise figure 9 dB, isotropic UT, attachment to the highest coupling gain | Tables 7.8-1, 7.8-1A |
117
+
118
+ Results (median HandoverLab / company mean; percentiles 5-95 % strictly inside the range; largest distance
119
+ from the mean):
120
+
121
+ | Case | Coupling loss [dB] | SINR [dB] | SIR [dB] | C1 | C2 (largest distance) |
122
+ |---|---|---|---|---|---|
123
+ | UMa-6 GHz | 119.9 / 121.0; 19/19; 1.65 | 5.5 / 5.6; 19/19; 1.34 | 8.0 / 8.0; 19/19; 0.17 | pass | fail (1.65) |
124
+ | UMi-6 GHz | 111.9 / 112.1; 19/19; 2.88 | 5.1 / 5.2; 19/19; 1.35 | 6.8 / 6.6; 19/19; 0.53 | pass | fail (2.88) |
125
+ | UMa-7 GHz | 121.7 / 122.4; 19/19; 1.78 | 5.0 / 5.0; 19/19; 0.90 | 7.9 / 7.9; 19/19; 0.29 | pass | fail (1.78) |
126
+ | UMi-7 GHz | 113.8 / 113.3; 19/19; 2.43 | 4.7 / 4.8; 19/19; 1.63 | 6.7 / 6.6; 19/19; 0.30 | pass | fail (2.43) |
127
+ | SMa-7 GHz, ISD 1299 m | 103.5 / 104.3; 19/19; 1.31 | 5.9 / 5.7; 19/19; 1.69 | 5.9 / 5.9; 19/19; 1.57 | pass | fail (1.69) |
128
+ | SMa-7 GHz, ISD 1732 m | 109.2 / 111.3; 19/19; 2.24 | 6.3 / 5.9; 19/19; 1.07 | 6.4 / 6.6; 19/19; 0.32 | pass | fail (2.24) |
129
+
130
+ Where the distance comes from: for UMa and UMi the coupling loss of the best users (75-95 %, close to a site)
131
+ is 1.6-2.9 dB lower than the company mean, and at UMi 7 GHz also at 5-10 %; the medians are within 1.1 dB.
132
+ For SMa 1732 m the coupling loss is about 2.1 dB lower than the mean over most of the distribution. The
133
+ company spread is large here (at the median, from 106.5 dB to 129.4 dB for SMa 1732 m), so the mean is a soft
134
+ target, but C2 was fixed before the run and is reported as it came. No parameter was changed after the run.
135
+
84
136
  ## What this calibration covers, and what it does not
85
137
 
86
138
  - It covers the **radio model**: the path-loss formulas, the LOS probabilities, the shadowing, the
@@ -98,8 +150,8 @@ passes a case when every percentile lies inside the company range widened by 0.5
98
150
  ## Repeat it
99
151
 
100
152
  ```bash
101
- handoverlab verify --only calibration # 10 000 users per case, a few seconds
102
- handoverlab verify --only calibration --full # 30 000 users per case, the table above
153
+ handoverlab verify --only calibration # 10 000 users per case, under a minute
154
+ handoverlab verify --only calibration --full # 30 000 users per case, the tables above
103
155
  python tools/make_calibration_figure.py # docs/images/calibration_38901.png
104
156
  ```
105
157
 
@@ -110,4 +162,6 @@ case = cal.CalScenario("UMa", 6.0)
110
162
  res = cal.simulate_drops(case, n_users=30000, seed=1)
111
163
  for c in cal.compare(case, res):
112
164
  print(c.metric, c.inside.sum(), "of", len(c.percentiles), "inside, largest distance", c.max_dev_db)
165
+
166
+ case = cal.CalScenario("SMa", 7.0, isd_m=1299.0, reference="R1-2506406") # compared with R1-2506406
113
167
  ```
@@ -0,0 +1,199 @@
1
+ # Comparison with other simulators
2
+
3
+ This page sets HandoverLab 2.4.0 next to other open or widely used 5G simulators and emulators, on the points
4
+ that matter for handover and mobility studies. It is meant to help you pick the right tool for a question, not
5
+ to rank tools: most of them were built for other questions, and several are far more detailed than HandoverLab
6
+ in layers that HandoverLab abstracts.
7
+
8
+ **How the table was made.** Every cell about another tool comes from that project's own documentation,
9
+ repository (README, docs, source tree, release notes) or its peer-reviewed paper; the source labels in brackets
10
+ point to the [list of sources](#sources), all accessed on 2026-10-22. **"not stated"** means the fact was not found
11
+ in those sources; it does not prove that the feature is absent, and a later release may add it. Corrections are
12
+ welcome as issues. The HandoverLab column follows the code and the pages of this site for version 2.4.0.
13
+
14
+ Tools compared (latest release found on 2026-10-22):
15
+
16
+ | Tool | Kind | Latest release | Licence | Language |
17
+ |---|---|---|---|---|
18
+ | HandoverLab | system-level, procedure-centred, time-stepped | 2.4.0 (2026-10-22) | MIT | Python (optional Numba kernel) |
19
+ | ns-3 with 5G-LENA (`nr` module) | packet-level, end-to-end, discrete-event | v5.1 (2026-08-06, ns-3.48) [L5] | GPLv2 [L6] | C++ [L6] |
20
+ | ns-3 mmWave module (NYU / UniPD) | packet-level, end-to-end, discrete-event | v8.0 (2024-06-26, ns-3.42) [M2] | GPL-2.0 [M1] | C++ [M1] |
21
+ | Simu5G (OMNeT++ / INET) | packet-level, end-to-end, discrete-event; real-time emulation | 1.8.0 (2026-10-07) [S2] | LGPL-3.0 [S7] | C++ and NED [S1] |
22
+ | Vienna 5G System Level Simulator | system-level, link abstraction from link-level curves | 1.4 (October 2023) [V3, V4] | academic use only, non-commercial [V5] | MATLAB [V2, V3] |
23
+ | MATLAB 5G Toolbox, system-level part | system-level with abstract or full PHY | R2026b (2026-09-24) [W12] | proprietary; nrGNB / nrUE also need the Wireless Network Toolbox since R2026a [W3, W13] | MATLAB |
24
+ | OpenAirInterface 5G RAN | real-time protocol stack (emulator with RF simulator, or real radios) | v3.0.0 (October 2026) [O4] | CSSL v1.0 (code) [O1] | C [O1] |
25
+ | NVIDIA Sionna (PHY, SYS, RT) | link-level library with a system-level part (SYS), GPU | v2.2.0 (2026-09-29) [N2] | Apache-2.0 [N1] | Python (PyTorch since 2.0.0) [N2] |
26
+
27
+ ## Handover and mobility procedures
28
+
29
+ | Tool | Event A3 / RRC handover | CHO | DAPS | LTM | Radio-link failure | Dual connectivity |
30
+ |---|---|---|---|---|---|---|
31
+ | HandoverLab 2.4.0 | yes: report, preparation, command, execution; A5 between carriers; a rule on predicted measurements after TR 38.744 ([AI/ML mobility](guides/ai-mobility.md)) | yes (Rel-16, up to 8 candidates; D1/D2 for NTN) | yes | yes, and conditional LTM | Qout/Qin as SINR thresholds with windows (or the MIESM effective SINR of the hypothetical PDCCH with fading), N310/N311/T310, T304, command during T310, re-establishment after a fixed outage; absolute failure rates are not calibrated | NR-DC as an option: SN addition, PSCell change, SN release, SCG failure; no EN-DC |
32
+ | ns-3 5G-LENA v5.1 | yes: X2-based, intra- and inter-frequency, A3 and A2-A4 algorithms, CIO; TTT scaling and ping-pong guards in v5.1 [L2, L3, L5] | not stated | not stated | not stated | Qout/Qin from the hypothetical-PDCCH BLER, N310/N311/T310, re-establishment; optional TR 36.839 handover-failure model (v5.1) [L2, L4, L5] | no: "out of scope and is future work" [L3] |
33
+ | ns-3 mmWave v8.0 | mmWave secondary-cell switch coordinated by the LTE eNB (SINR difference with fixed or dynamic TTT), not an A3 configuration as such [M1, M4, M5] | not stated | not stated | not stated | mmWave outage by an SINR threshold; T310/N310: not stated [M4] | LTE-mmWave DC (LTE master, mmWave secondary) [M1, M5]; NR-DC: not stated |
34
+ | Simu5G 1.8.0 | yes: Xn-prepared handover on a measurement report with the best cell, hysteresis on RSSI; A3 with TTT: not stated [S3, S4] | not stated | not stated | not stated | RLF when an RLC AM PDU exceeds its retransmission limit, RRC re-establishment (T311 = 0 disables it by default); T310/N310: not stated [S2] | EN-DC and NE-DC with split bearers [S1, S6]; NR-DC: not stated |
35
+ | Vienna 5G SLS 1.4 | no handover procedure described; cell association by received power or SINR, fixed per segment [V1] | not stated | not stated | not stated | not stated; "we omit the implementation of the complete protocol stack" [V1] | not stated |
36
+ | MATLAB 5G Toolbox R2026b | not stated; UE mobility models exist, the mobility example uses one gNB [W4, W6, W7] | not stated | not stated | not stated | not stated; the node stack is traffic, RLC, MAC and PHY [W5] | not stated; carrier aggregation since R2026b [W10] |
37
+ | OpenAirInterface v3.0.0 | yes: A3 or manual triggers, intra-/inter-frequency, F1 inter-DU and N2 inter-gNB [O2, O3, O4] | not stated | not stated | not stated | RLF declared by the MAC after a number of PUSCH DTX, RRC re-establishment; T310/N310: not stated [O4, O6] | EN-DC (NSA "unstable (only one UE connection)") and NR-DC [O2, O4] |
38
+ | Sionna v2.2.0 | no: the SYS tutorial excludes handover, users attach to the nearest base station [N6] | not stated | not stated | not stated | not stated | not stated |
39
+
40
+ ## Radio, beams and PHY abstraction
41
+
42
+ | Tool | NTN | Beams | Fast fading and link-to-system mapping | Scheduler |
43
+ |---|---|---|---|---|
44
+ | HandoverLab 2.4.0 | one LEO satellite with earth-moving beams (TR 38.811, TR 38.821), CHO with D2; no several satellites, Doppler or earth-fixed beams ([NTN guide](guides/ntn.md)) | SSB beams per sector from the TR 38.901 element and DFT beams, cell quality from beams, beam failure detection and recovery; UE receive beams optional (1, 2 or 4 panels, [UE beams](guides/ue-beams.md)), isotropic UE by default; no MIMO ([beams](guides/beams-layers.md)) | off by default (large-scale channel with a slow time-varying part); option: TDL-A to TDL-E with MIESM for link monitoring and a capacity-equivalent SINR for the rate; no CDL ([fading](guides/fading.md)) | by default a rate model without a scheduler; option: slot scheduler RR or PF with MCS, TBS and HARQ (base engine only; with `run.backend: numba` 11-59 times faster than its NumPy loop, bit-identical) ([scheduler](guides/scheduler.md)) |
45
+ | ns-3 5G-LENA v5.1 | NTN channel (TR 38.811, from ns-3 mainline [L9]) and a LEO mobility example [L1, L2] | ideal and SRS-based realistic beamforming; beam management "Simplified model; no SSB blocks" [L1]; quasi-omni beams in the RRC / handover context [L3] | TR 38.901 with fast fading; EESM-based PHY abstraction with SINR-BLER tables [L1, L8] | PF, RR, MR, QoS-aware, RL-based; OFDMA and TDMA [L1] |
46
+ | ns-3 mmWave v8.0 | TR 38.811 channel inherited from ns-3.42; no NTN protocol features stated [M2] | SVD- and DFT-based beamforming; NR beam tracking listed as future work [M1, M3] | TR 38.901 channel, ray-tracing and measured traces; EESM error model from 5G-LENA [M1, M3] | flexible-TTI RR, PF, max-rate, max-weight [M1] |
47
+ | Simu5G 1.8.0 | not in the official release; separate third-party work exists [S10] | not stated; antenna-gain link budget only [S1] | path loss, LOS and shadowing of TR 36.814 / 36.873 / 38.901 with Jakes or Rayleigh fading; reception from SINR and BLER curves [S5, S6] | MAX C/I, PF, DRR, QoS-aware PF [S1] |
48
+ | Vienna 5G SLS 1.4 | not stated | precoding and MIMO (CLSM / OLSM, MU-MIMO); no beam-management procedure described [V1, V2] | small-scale fading per slot (TR 38.901 CDL, PDP models, QuaDRiGa interface); post-equalisation SINR mapped to BLER with tables from the Vienna link-level simulator [V1, V2] | RR, best CQI, weighted RR, QoS-aware, ZF MU-MIMO [V2] |
49
+ | MATLAB 5G Toolbox R2026b | system-level LEO transparent-payload example with static satellite and UEs, no handover (R2026b) [W8] | system-level example with P-2 beam measurement and reporting, without SSB sweeping [W9] | CDL, TR 38.901 system-level channel or custom; abstract PHY (RBIR mapping and lookup tables) or full PHY [W2, W4, W5] | RR, PF, best CQI and custom schedulers [W2] |
50
+ | OpenAirInterface v3.0.0 | GEO and LEO transparent satellites; RF simulator with LEO delay and Doppler [O5, O10] | basic FR2 beam management; analog beamforming; beam gains in the RF simulator [O4, O7, O8] | full PHY on time-domain samples; channel simulator with TR 36.873 / 38.901 models; no abstraction needed [O8, O9] | proportional fair [O2, O6] |
51
+ | Sionna v2.2.0 | not stated; the official 3GPP channel page lists TDL, CDL, UMi, UMa, RMa, InH and InF [N7] | TR 38.901 panel arrays; beam management: not stated [N6] | TR 38.901 TDL, CDL, UMi, UMa, RMa, InH, InF; PHY abstraction with EESM and BLER tables [N4, N7] | PF for single-user MIMO; link adaptation and power control [N3, N5] |
52
+
53
+ ## Speed, scale and validation
54
+
55
+ | Tool | Speed and scale | Validation against 3GPP |
56
+ |---|---|---|
57
+ | HandoverLab 2.4.0 | one process: 2 rules, 40 users, 76 cells, 60 s simulated in 10-15 s on a modest virtual machine (1.11.0 timings, [performance](performance.md)); many rules share one world; no published figures for thousands of nodes | large-scale calibration of TR 38.901 clause 7.8.1 against the 21 companies of R1-165974 (325 of 342 percentiles inside the range) and at 7 GHz against R1-2506406 (all 342 percentiles inside the range, 1.7-2.9 dB from the company mean, [details](calibration-3gpp.md)); handover counts against ns-3 / 5G-LENA; failure levels differ from ns-3 ([calibration](calibration.md)); clause-by-clause [standard compliance](standard-compliance.md) |
58
+ | ns-3 5G-LENA v5.1 | runtime numbers: not stated for the module; a MIMO channel speed-up of up to 16 times is reported in a WNS3 paper [L11]; the calibration scenario has 12 gNBs and 120 UEs [L10] | calibrated in 3GPP outdoor reference scenarios (SIMPAT 2022) [L7]; calibration examples for RP-180524 [L2]; mobility checked against TR 36.839 (v5.1) [L5] |
59
+ | ns-3 mmWave v8.0 | not stated | not stated (examples "verify its correct functioning" [M6]) |
60
+ | Simu5G 1.8.0 | background cells and UEs for large scenarios; real-time emulation of "hundreds of simulated users and tens of cells" on one desktop [S1, S9] | PHY abstraction validated in 3GPP-based scenarios [S8]; fingerprint regression tests [S1] |
61
+ | Vienna 5G SLS 1.4 | "more than 7000 users" in less than 16 GB RAM for 100 slots; runs split over cores or a cluster [V1] | not stated (TR 38.901 channels implemented; no calibration reported) [V1] |
62
+ | MATLAB 5G Toolbox R2026b | no measured runtimes published; a full-PHY example with 19 sites of 3 sectors and 20 UEs per cell can need "several hundred gigabytes" of memory [W2, W14] | InH SINR CDF against RP-180524 and dense urban against R1-1715251 [W11] |
63
+ | OpenAirInterface v3.0.0 | real time; "up to 100 UEs" (v3.0.0) [O4]; 55 UEs in the stress test of the paper [O10] | not stated (CI over 4G, 5G NSA and SA) [O10] |
64
+ | Sionna v2.2.0 | GPU acceleration; runtime numbers: not stated [N1] | TR 38.901 channel models "Updated and calibrated" (v2.1.0) and calibration metrics in SYS [N2] |
65
+
66
+ ## Where the other tools are stronger
67
+
68
+ - **Full protocol stacks and packets.** ns-3 with 5G-LENA or the mmWave module and Simu5G simulate every packet
69
+ through RLC, PDCP, RRC, the core network, transport and applications [L10, M6, S6]. End-to-end latency,
70
+ TCP behaviour during a handover, or application quality can be studied there and not in HandoverLab, which
71
+ has no transport layer or applications (it has an optional PDCP buffer model at handover).
72
+ - **Real systems.** OpenAirInterface runs the real protocol stack in real time, with commercial UEs and core
73
+ networks [O1, O3, O10]; results from it include implementation effects that no simulator has.
74
+ - **PHY detail.** MATLAB can switch the same network to a waveform-level full PHY [W4]; the Vienna simulator
75
+ takes its BLER curves from a link-level simulator with several waveforms and codes [V1]; Sionna offers a
76
+ differentiable link-level chain on GPUs and a ray tracer [N1]. HandoverLab has no MIMO and no CDL channel.
77
+ - **Scale.** The Vienna simulator reports thousands of nodes [V1]; Simu5G emulates tens of cells in real time
78
+ [S9]. HandoverLab runs in one Python process per world and is sized for tens of cells and users per run.
79
+ - **Packet-level handover against the 3GPP mobility study.** 5G-LENA v5.1 can be checked against the TR 36.839
80
+ handover-failure curves [L5], which matters because HandoverLab's absolute failure rates are not calibrated
81
+ ([calibration](calibration.md)).
82
+
83
+ ## Where HandoverLab differs
84
+
85
+ - The Rel-16 to Rel-19 mobility procedures (CHO, DAPS, LTM, conditional LTM, CHO with D1/D2) sit side by side
86
+ behind one rule interface; none of them is stated in the sources of the other tools above.
87
+ - Every compared rule runs on the same world per seed (paired comparison), and the cost of each procedure
88
+ (signalling, prepared cells, interruption, energy) is measured next to its benefit.
89
+ - The price is abstraction: received power per step with a slow time-varying part by default, SINR thresholds
90
+ for link monitoring, fixed procedure delays and a fixed re-establishment outage. The
91
+ [model boundaries](https://github.com/mjs19971997/handoverlab#model-boundaries) and
92
+ [standard compliance](standard-compliance.md) say what this supports.
93
+
94
+ ## Sources
95
+
96
+ All accessed on 2026-10-22.
97
+
98
+ **HandoverLab:** the pages linked above and `CHANGELOG.md` of 2.4.0.
99
+
100
+ **ns-3 5G-LENA**
101
+
102
+ - [L1] 5G-LENA features: <https://5g-lena.cttc.es/features/>
103
+ - [L2] `nr` release notes: <https://gitlab.com/cttc-lena/nr/-/raw/master/RELEASE_NOTES.md>
104
+ - [L3] `nr` RRC layer documentation: <https://gitlab.com/cttc-lena/nr/-/raw/master/doc/source/rrc-layer.rst>
105
+ - [L4] `nr` source, UE RRC and PHY (master branch): <https://gitlab.com/cttc-lena/nr/-/raw/master/model/nr-ue-rrc.cc>,
106
+ <https://gitlab.com/cttc-lena/nr/-/raw/master/model/nr-ue-phy.cc>
107
+ - [L5] 5G-LENA v5.1 announcement: <https://5g-lena.cttc.es/blog/36/>
108
+ - [L6] `nr` documentation: <https://cttc-lena.gitlab.io/nr/html/>
109
+ - [L7] K. Koutlia, B. Bojovic, Z. Ali, S. Lagén, "Calibration of the 5G-LENA system level simulator in 3GPP
110
+ reference scenarios", Simulation Modelling Practice and Theory 119 (2022) 102580,
111
+ <https://doi.org/10.1016/j.simpat.2022.102580>
112
+ - [L8] S. Lagén et al., "New radio physical layer abstraction for system-level simulations of 5G networks",
113
+ IEEE ICC 2020, <https://doi.org/10.1109/ICC40277.2020.9149444>
114
+ - [L9] M. Sandri et al., "Implementation of a channel model for non-terrestrial networks in ns-3", WNS3 2023,
115
+ <https://doi.org/10.1145/3592149.3592158>
116
+ - [L10] N. Patriciello et al., "An E2E simulator for 5G NR networks", Simulation Modelling Practice and Theory 96
117
+ (2019) 101933, <https://doi.org/10.1016/j.simpat.2019.101933>
118
+ - [L11] M. Pagin et al., "Improving the efficiency of MIMO simulations in ns-3", WNS3 2023,
119
+ <https://doi.org/10.1145/3592149.3592167>
120
+
121
+ **ns-3 mmWave module**
122
+
123
+ - [M1] Repository and README: <https://github.com/nyuwireless-unipd/ns3-mmwave>
124
+ - [M2] Releases: <https://github.com/nyuwireless-unipd/ns3-mmwave/releases>
125
+ - [M3] Module documentation: <https://github.com/nyuwireless-unipd/ns3-mmwave/blob/new-handover/src/mmwave/doc/mmwave-doc.md>
126
+ - [M4] eNB and UE RRC source: <https://github.com/nyuwireless-unipd/ns3-mmwave/blob/new-handover/src/lte/model/lte-enb-rrc.cc>,
127
+ <https://github.com/nyuwireless-unipd/ns3-mmwave/blob/new-handover/src/lte/model/lte-ue-rrc.cc>
128
+ - [M5] M. Polese et al., "Improved handover through dual connectivity in 5G mmWave mobile networks", IEEE JSAC
129
+ 35(9), 2017, <https://doi.org/10.1109/JSAC.2017.2720338>
130
+ - [M6] M. Mezzavilla et al., "End-to-end simulation of 5G mmWave networks", IEEE Communications Surveys &
131
+ Tutorials 20(3), 2018, <https://doi.org/10.1109/COMST.2018.2828880>
132
+
133
+ **Simu5G**
134
+
135
+ - [S1] Repository and README: <https://github.com/Unipisa/Simu5G>
136
+ - [S2] Releases (1.6.0, 1.7.0, 1.8.0): <https://github.com/Unipisa/Simu5G/releases>
137
+ - [S3] What's new: <https://github.com/Unipisa/Simu5G/blob/master/WHATSNEW.md>
138
+ - [S4] UE connection control: <https://github.com/Unipisa/Simu5G/blob/master/src/simu5g/stack/rrc/ConnectionControlUe.ned>
139
+ - [S5] Stochastic channel model: <https://github.com/Unipisa/Simu5G/blob/master/src/simu5g/stack/phy/channelmodel/StochasticChannelModel.ned>
140
+ - [S6] Simu5G site and overview: <https://simu5g.org/>, <https://simu5g.org/users-guide/overview>
141
+ - [S7] Licence: <https://github.com/Unipisa/Simu5G/blob/master/LICENSE.md>
142
+ - [S8] G. Nardini et al., "Simu5G: an OMNeT++ library for end-to-end performance evaluation of 5G networks",
143
+ IEEE Access 8, 2020, <https://doi.org/10.1109/ACCESS.2020.3028550>
144
+ - [S9] G. Nardini, G. Stea, A. Virdis, "Scalable real-time emulation of 5G networks with Simu5G", IEEE Access 9,
145
+ 2021, <https://doi.org/10.1109/ACCESS.2021.3123873>
146
+ - [S10] LEON, a LEO handover simulator built on OMNeT++, INET and Simu5G, DroNet 2024,
147
+ <https://doi.org/10.1145/3661810.3663470>
148
+
149
+ **Vienna 5G System Level Simulator**
150
+
151
+ - [V1] M. K. Müller et al., "Flexible multi-node simulation of cellular mobile communications: the Vienna 5G
152
+ System Level Simulator", EURASIP J. Wireless Commun. Netw. 2018:227, <https://doi.org/10.1186/s13638-018-1238-7>
153
+ - [V2] List of features, v1.4: <https://www.tuwien.at/etit/tc/wp-content/uploads/2023/11/listoffeatures-v1-4.pdf>
154
+ - [V3] Simulator page: <https://www.tuwien.at/etit/tc/vienna-simulators/vienna-5g-simulators/>
155
+ - [V4] Release 1.4 announcement: <https://vccsforum.nt.tuwien.ac.at/t/new-release-v1-4-vienna-5g-sl-simulator/297>
156
+ - [V5] Licence agreement: <https://www.tuwien.at/etit/tc/wp-content/uploads/2022/06/license-agreement-5g-sl.pdf>
157
+
158
+ **MATLAB 5G Toolbox**
159
+
160
+ - [W1] System-level simulation: <https://www.mathworks.com/help/5g/system-level-simulation.html>
161
+ - [W2] Overview of system-level simulation: <https://www.mathworks.com/help/5g/ug/overview-system-level-simulation-in-5g-network-analysis.html>
162
+ - [W3] `nrGNB`: <https://www.mathworks.com/help/5g/ref/nrgnb.html>
163
+ - [W4] `nrUE`: <https://www.mathworks.com/help/5g/ref/nrue.html>
164
+ - [W5] Composition of NR nodes: <https://www.mathworks.com/help/5g/ug/composition-of-nr-nodes.html>
165
+ - [W6] `addMobility`: <https://www.mathworks.com/help/5g/ref/nrue.addmobility.html>
166
+ - [W7] Simulate mobility of a UE node: <https://www.mathworks.com/help/5g/ug/simulate-ue-mobility-in-5g-network.html>
167
+ - [W8] NR NTN system performance with a transparent-payload LEO satellite:
168
+ <https://www.mathworks.com/help/5g/ug/nr-ntn-system-performance-evaluation-with-transparent-payload-leo-satellite.html>
169
+ - [W9] NR cell performance with beam management:
170
+ <https://www.mathworks.com/help/5g/ug/nr-cell-performance-evaluation-with-beam-management.html>
171
+ - [W10] Carrier aggregation in system-level simulation:
172
+ <https://www.mathworks.com/help/5g/ug/carrier-aggregation-in-5g-system-level-simulation.html>
173
+ - [W11] Evaluate 3GPP indoor reference scenario: <https://www.mathworks.com/help/5g/ug/evaluate-3gpp-indoor-reference-scenario.html>
174
+ - [W12] Release 2026b announcement: <https://www.mathworks.com/company/newsroom/mathworks-introduces-release-2026b-of-matlab-and-simulink.html>
175
+ - [W13] R2026a product transition: <https://www.mathworks.com/products/new_products/r2026a-transition.html>
176
+ - [W14] Run 5G system-level simulations on AWS: <https://www.mathworks.com/help/5g/ug/run-5g-system-level-simulations-on-aws-cloud.html>
177
+
178
+ **OpenAirInterface**
179
+
180
+ - [O1] README: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/README.md>
181
+ - [O2] Feature set: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/doc/FEATURE_SET.md>
182
+ - [O3] Handover tutorial: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/doc/handover-tutorial.md>
183
+ - [O4] Changelog: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/CHANGELOG.md>
184
+ - [O5] NTN configuration: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/doc/ntn-configuration.md>
185
+ - [O6] MAC usage: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/doc/MAC/mac-usage.md>
186
+ - [O7] Analog beamforming: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/doc/analog_beamforming.md>
187
+ - [O8] RF simulator: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/radio/rfsimulator/README.md>
188
+ - [O9] Channel simulation: <https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md>
189
+ - [O10] F. Kaltenberger et al., Computer Networks (2025) 111410, <https://doi.org/10.1016/j.comnet.2025.111410>
190
+
191
+ **NVIDIA Sionna**
192
+
193
+ - [N1] Repository and documentation: <https://github.com/NVlabs/sionna>, <https://nvlabs.github.io/sionna/>
194
+ - [N2] Releases (v2.0.0, v2.1.0, v2.2.0): <https://github.com/NVlabs/sionna/releases>
195
+ - [N3] Sionna SYS: <https://nvlabs.github.io/sionna/sys/index.html>
196
+ - [N4] `PHYAbstraction`: <https://nvlabs.github.io/sionna/sys/api/sionna.sys.PHYAbstraction.html>
197
+ - [N5] `PFSchedulerSUMIMO`: <https://nvlabs.github.io/sionna/sys/api/sionna.sys.PFSchedulerSUMIMO.html>
198
+ - [N6] SYS end-to-end tutorial: <https://nvlabs.github.io/sionna/sys/tutorials/notebooks/End-to-End_Example.html>
199
+ - [N7] 3GPP channel models: <https://nvlabs.github.io/sionna/phy/api/channel/wireless/3gpp.html>