openntn 2.0.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 (116) hide show
  1. openntn-2.0.0/CHANGELOG.md +1558 -0
  2. openntn-2.0.0/LICENSE +21 -0
  3. openntn-2.0.0/LICENSE-APACHE +202 -0
  4. openntn-2.0.0/MANIFEST.in +6 -0
  5. openntn-2.0.0/PKG-INFO +312 -0
  6. openntn-2.0.0/README.md +275 -0
  7. openntn-2.0.0/openntn/__init__.py +34 -0
  8. openntn-2.0.0/openntn/antenna.py +966 -0
  9. openntn-2.0.0/openntn/channel_coefficients.py +1246 -0
  10. openntn-2.0.0/openntn/dense_urban.py +156 -0
  11. openntn-2.0.0/openntn/dense_urban_scenario.py +247 -0
  12. openntn-2.0.0/openntn/lsp.py +635 -0
  13. openntn-2.0.0/openntn/models/CDL-A.json +40 -0
  14. openntn-2.0.0/openntn/models/CDL-B.json +43 -0
  15. openntn-2.0.0/openntn/models/CDL-C.json +36 -0
  16. openntn-2.0.0/openntn/models/CDL-D.json +42 -0
  17. openntn-2.0.0/openntn/models/Dense_Urban_LOS_Ka_band_DL.json +517 -0
  18. openntn-2.0.0/openntn/models/Dense_Urban_LOS_Ka_band_UL.json +517 -0
  19. openntn-2.0.0/openntn/models/Dense_Urban_LOS_S_band_DL.json +518 -0
  20. openntn-2.0.0/openntn/models/Dense_Urban_LOS_S_band_UL.json +517 -0
  21. openntn-2.0.0/openntn/models/Dense_Urban_NLOS_Ka_band_DL.json +529 -0
  22. openntn-2.0.0/openntn/models/Dense_Urban_NLOS_Ka_band_UL.json +529 -0
  23. openntn-2.0.0/openntn/models/Dense_Urban_NLOS_S_band_DL.json +529 -0
  24. openntn-2.0.0/openntn/models/Dense_Urban_NLOS_S_band_UL.json +529 -0
  25. openntn-2.0.0/openntn/models/Sub_Urban_LOS_Ka_band_DL.json +518 -0
  26. openntn-2.0.0/openntn/models/Sub_Urban_LOS_Ka_band_UL.json +517 -0
  27. openntn-2.0.0/openntn/models/Sub_Urban_LOS_S_band_DL.json +518 -0
  28. openntn-2.0.0/openntn/models/Sub_Urban_LOS_S_band_UL.json +518 -0
  29. openntn-2.0.0/openntn/models/Sub_Urban_NLOS_Ka_band_DL.json +531 -0
  30. openntn-2.0.0/openntn/models/Sub_Urban_NLOS_Ka_band_UL.json +532 -0
  31. openntn-2.0.0/openntn/models/Sub_Urban_NLOS_S_band_DL.json +531 -0
  32. openntn-2.0.0/openntn/models/Sub_Urban_NLOS_S_band_UL.json +531 -0
  33. openntn-2.0.0/openntn/models/TDL-A.json +13 -0
  34. openntn-2.0.0/openntn/models/TDL-A30.json +31 -0
  35. openntn-2.0.0/openntn/models/TDL-B.json +15 -0
  36. openntn-2.0.0/openntn/models/TDL-B100.json +31 -0
  37. openntn-2.0.0/openntn/models/TDL-C.json +13 -0
  38. openntn-2.0.0/openntn/models/TDL-C300.json +31 -0
  39. openntn-2.0.0/openntn/models/TDL-D.json +15 -0
  40. openntn-2.0.0/openntn/models/Urban_LOS_Ka_band_DL.json +518 -0
  41. openntn-2.0.0/openntn/models/Urban_LOS_Ka_band_UL.json +517 -0
  42. openntn-2.0.0/openntn/models/Urban_LOS_S_band_DL.json +518 -0
  43. openntn-2.0.0/openntn/models/Urban_LOS_S_band_UL.json +517 -0
  44. openntn-2.0.0/openntn/models/Urban_NLOS_Ka_band_DL.json +530 -0
  45. openntn-2.0.0/openntn/models/Urban_NLOS_Ka_band_UL.json +530 -0
  46. openntn-2.0.0/openntn/models/Urban_NLOS_S_band_DL.json +533 -0
  47. openntn-2.0.0/openntn/models/Urban_NLOS_S_band_UL.json +530 -0
  48. openntn-2.0.0/openntn/models/__init__.py +4 -0
  49. openntn-2.0.0/openntn/rays.py +1029 -0
  50. openntn-2.0.0/openntn/sub_urban.py +156 -0
  51. openntn-2.0.0/openntn/sub_urban_scenario.py +247 -0
  52. openntn-2.0.0/openntn/system_level_channel.py +530 -0
  53. openntn-2.0.0/openntn/system_level_scenario.py +1209 -0
  54. openntn-2.0.0/openntn/urban.py +156 -0
  55. openntn-2.0.0/openntn/urban_scenario.py +245 -0
  56. openntn-2.0.0/openntn/utils.py +1822 -0
  57. openntn-2.0.0/openntn.egg-info/PKG-INFO +312 -0
  58. openntn-2.0.0/openntn.egg-info/SOURCES.txt +114 -0
  59. openntn-2.0.0/openntn.egg-info/dependency_links.txt +1 -0
  60. openntn-2.0.0/openntn.egg-info/requires.txt +8 -0
  61. openntn-2.0.0/openntn.egg-info/top_level.txt +1 -0
  62. openntn-2.0.0/pyproject.toml +76 -0
  63. openntn-2.0.0/setup.cfg +4 -0
  64. openntn-2.0.0/tests/Link_Budget_test.py +129 -0
  65. openntn-2.0.0/tests/antenna_pattern_test.py +196 -0
  66. openntn-2.0.0/tests/antenna_polarization_test.py +78 -0
  67. openntn-2.0.0/tests/atmosphere_test.py +39 -0
  68. openntn-2.0.0/tests/compile_test.py +176 -0
  69. openntn-2.0.0/tests/conftest.py +34 -0
  70. openntn-2.0.0/tests/coupling_loss_test.py +112 -0
  71. openntn-2.0.0/tests/device_comparison_test.py +251 -0
  72. openntn-2.0.0/tests/device_test.py +136 -0
  73. openntn-2.0.0/tests/differentiable_topology_test.py +220 -0
  74. openntn-2.0.0/tests/faraday_rotation_test.py +163 -0
  75. openntn-2.0.0/tests/gas_attenuation_test.py +207 -0
  76. openntn-2.0.0/tests/gpu_device_test.py +161 -0
  77. openntn-2.0.0/tests/indoor_test.py +82 -0
  78. openntn-2.0.0/tests/input_checks_test.py +186 -0
  79. openntn-2.0.0/tests/known_issues_test.py +268 -0
  80. openntn-2.0.0/tests/los_ray_test.py +203 -0
  81. openntn-2.0.0/tests/lsp_correlation_test.py +210 -0
  82. openntn-2.0.0/tests/lsp_spatial_correlation_test.py +244 -0
  83. openntn-2.0.0/tests/model_parameters_test.py +331 -0
  84. openntn-2.0.0/tests/module_names_test.py +21 -0
  85. openntn-2.0.0/tests/platform_test.py +219 -0
  86. openntn-2.0.0/tests/plotting_test.py +75 -0
  87. openntn-2.0.0/tests/public_api_test.py +187 -0
  88. openntn-2.0.0/tests/random_numbers_test.py +65 -0
  89. openntn-2.0.0/tests/ray_angles_test.py +389 -0
  90. openntn-2.0.0/tests/readme_quickstart_test.py +43 -0
  91. openntn-2.0.0/tests/reference_elevation_test.py +101 -0
  92. openntn-2.0.0/tests/reference_outputs/dense_urban.npz +0 -0
  93. openntn-2.0.0/tests/reference_outputs/environment.json +13 -0
  94. openntn-2.0.0/tests/reference_outputs/sub_urban.npz +0 -0
  95. openntn-2.0.0/tests/reference_outputs/urban.npz +0 -0
  96. openntn-2.0.0/tests/reference_outputs_test.py +391 -0
  97. openntn-2.0.0/tests/satellite_doppler_test.py +137 -0
  98. openntn-2.0.0/tests/scintillation_test.py +219 -0
  99. openntn-2.0.0/tests/spec_tables/tr38811_v15.4.0.json +1097 -0
  100. openntn-2.0.0/tests/statistical_checks.py +84 -0
  101. openntn-2.0.0/tests/step_10_test.py +59 -0
  102. openntn-2.0.0/tests/step_11_test.py +925 -0
  103. openntn-2.0.0/tests/step_12_test.py +157 -0
  104. openntn-2.0.0/tests/step_1_test.py +866 -0
  105. openntn-2.0.0/tests/step_2_test.py +424 -0
  106. openntn-2.0.0/tests/step_3_test.py +144 -0
  107. openntn-2.0.0/tests/step_4_1_test.py +281 -0
  108. openntn-2.0.0/tests/step_4_2_test.py +340 -0
  109. openntn-2.0.0/tests/step_4_3_test.py +1589 -0
  110. openntn-2.0.0/tests/step_5_test.py +334 -0
  111. openntn-2.0.0/tests/step_6_test.py +175 -0
  112. openntn-2.0.0/tests/step_7_test.py +137 -0
  113. openntn-2.0.0/tests/step_8_test.py +67 -0
  114. openntn-2.0.0/tests/step_9_test.py +95 -0
  115. openntn-2.0.0/tests/topology_in_place_test.py +153 -0
  116. openntn-2.0.0/tests/topology_orientations_test.py +108 -0
@@ -0,0 +1,1558 @@
1
+ # Changelog
2
+
3
+ The format follows [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/).
4
+
5
+ ## [2.0.0] - 2026-10-26
6
+
7
+ First release of OpenNTN for Sionna 2.x, which is built on PyTorch: the package
8
+ `openntn`, installed from PyPI with `pip install openntn`, whose channel models give the
9
+ results of 2.0.0a4 and 2.0.0rc1. Against the versions for Sionna 1.x and 0.19, its
10
+ classes and functions take and return PyTorch tensors, its corrections of the models
11
+ change simulation results (the first section lists them), its three example notebooks
12
+ run with Sionna 2.x and PyTorch, and it adds a description of the models
13
+ (`docs/model.md`), a migration guide (`docs/migration.md`) and the citation metadata
14
+ (`CITATION.cff`). Since 2.0.0rc1 the metadata of the distribution has the development
15
+ status "5 - Production/Stable", and the tests of two test files that failed on a GPU are
16
+ fixed; the package is unchanged.
17
+
18
+ This entry collects the changes since the versions for Sionna 1.x and 0.19, which are
19
+ OpenNTN 1.0.0 and 0.19.0 as to their models: each item ends with the pre-releases whose
20
+ sections below describe it in full, with its measured effect and its conditions, apart
21
+ from the fix of the tests, which is new in this version. A change that concerns only the
22
+ pre-releases, such as a defect that one pre-release brought and a later one fixed, is
23
+ described only in their sections.
24
+
25
+ ### Changes that affect simulation results
26
+
27
+ - Random numbers: every random number is drawn with PyTorch from the generators of
28
+ Sionna 2.x instead of with TensorFlow, so the same seed gives other realizations,
29
+ which also differ between the CPU and a GPU and between eager and compiled calls, and
30
+ single precision rounds some quantities differently; the statistics of the results do
31
+ not change. Affected earlier versions: the versions for Sionna 0.19 and 1.x. See
32
+ 2.0.0rc1.
33
+ - Shadow fading applied once: on every link the shadow fading reaches the channel only
34
+ as the large scale parameter SF of TR 38.901 V16.1.0, clause 7.5, step 4, with σ_SF
35
+ and the correlations of TR 38.811 V15.4.0 (eq. (6.6-4), Tables 6.7.2-1a to 6.7.2-8b),
36
+ where a second draw in the basic path loss gave about √2 times σ_SF and remained with
37
+ `enable_shadow_fading=False`. Affected earlier versions: the versions for Sionna 0.19
38
+ and 1.x, and 2.0.0a1. See 2.0.0a2.
39
+ - Correlation of the large scale parameters: they are correlated first across the UTs
40
+ and then across the parameters of each link, in the Cholesky order of TR 38.901
41
+ V16.1.0, clause 7.5, step 4 (TR 38.811 V15.4.0, clause 6.7.2), where the reversed
42
+ order left links with UTs of the same link state within the correlation distances
43
+ without the cross-correlations of the tables. Affected earlier versions: the versions
44
+ for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
45
+ - UTs at the same location: UTs at one location in the horizontal plane, in one link
46
+ state and batch example, share their large scale parameters, as the correlation
47
+ exp(-d/d_corr) of TR 38.901 V16.1.0, clause 7.5, step 4, is 1 at d = 0; its singular
48
+ matrix gave the UTs after them too large a variance and NaN gradients (2.0.0a1), NaN
49
+ parameters (the version for Sionna 1.x) or a result that depends on TensorFlow (the
50
+ version for Sionna 0.19). Affected earlier versions: 2.0.0a1; the versions for Sionna
51
+ 0.19 and 1.x build the same singular correlation for such UTs. See 2.0.0a2.
52
+ - Elevation angles midway between two reference angles: at exactly 25°, 45°, 65° and 85°
53
+ every table takes the higher reference angle, where the rounding of ties to the even
54
+ number took the lower one; TR 38.811 V15.4.0, clauses 6.6.1 and 6.6.2, takes the
55
+ nearest reference angle and gives no rule for an angle midway between two. Affected
56
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
57
+ - Ray offset angles: on every link ray 16 of every cluster lies at -1.1481 times the
58
+ intra-cluster angle spread, as in TR 38.901 V16.1.0, Table 7.5-3 (TR 38.811 V15.4.0,
59
+ clause 6.7.2), instead of -0.1481 times. Affected earlier versions: the versions for
60
+ Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
61
+ - Cluster elimination: on every link, clusters with less than -25 dB power compared with
62
+ the strongest cluster get zero power, as TR 38.901 V16.1.0, clause 7.5, step 6,
63
+ removes them (TR 38.811 V15.4.0, clause 6.7.2), where they were kept; the shapes of
64
+ the outputs stay, and the other powers are not renormalized. Affected earlier
65
+ versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
66
+ - Angular scaling factors: C_phi^NLOS and C_theta^NLOS follow the number of clusters at
67
+ the elevation angle, as in TR 38.811 V15.4.0, Tables 6.7.2-1aa and 6.7.2-1ab, where
68
+ each parameter file held one pair for all angles; this concerns urban LOS links at
69
+ 10°, urban NLOS and sub-urban LOS links at 70° to 90° and sub-urban NLOS links at 60°
70
+ to 90°, and the files no longer have the keys `CPhiNLoS` and `CThetaNLoS`. Affected
71
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
72
+ - Random signs and ray coupling per link: the signs X_n of the cluster angles and the
73
+ coupling of the rays (TR 38.901 V16.1.0, clause 7.5, steps 7 and 8; TR 38.811 V15.4.0,
74
+ clause 6.7.2) are drawn for each link, where all UTs of a satellite shared them, which
75
+ correlated their angles in simulations with more than one UT per satellite. Affected
76
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
77
+ - Ray coupling in the two strongest clusters: on every link their rays are coupled
78
+ within the sub-clusters of TR 38.901 V16.1.0, Table 7.5-5, as clause 7.5, step 8,
79
+ requires (TR 38.811 V15.4.0, clause 6.7.2), where they were coupled across the whole
80
+ cluster; the cluster powers and delays and the mean power of a link do not change.
81
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See
82
+ 2.0.0a2.
83
+ - LOS arrival direction: the zenith angle of arrival of the LOS ray is 180° minus the
84
+ zenith angle of departure, as in TR 38.901 V16.1.0, clause 7.5, step 1c (TR 38.811
85
+ V15.4.0, eq. (6.8-1b)), where the zenith angle of departure plus 180° put the arrival
86
+ direction 180° minus twice the elevation angle off; this concerns every LOS link
87
+ through the antenna pattern, the array phases and the Doppler shift at the UT.
88
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See
89
+ 2.0.0a2.
90
+ - Sign of the LOS propagation phase: the LOS ray contains exp(-j2π d3D/λ0), as in
91
+ TR 38.901 V16.1.0, eq. (7.5-29), and TR 38.811 V15.4.0, eq. (6.8-1b), instead of
92
+ exp(+j2π d3D/λ0); single realizations of LOS links change, the statistics do not.
93
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See
94
+ 2.0.0a2.
95
+ - LOS propagation phase in single precision: the phase 2π d3D/λ0, with d3D of TR 38.811
96
+ V15.4.0, eq. (6.6-3), is computed in double precision and reduced modulo 2π before the
97
+ cast, where single precision made it random; this concerns the first-path and the
98
+ total power of single LOS links in single precision, not their distributions. Affected
99
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1, in single
100
+ precision, their default precision. See 2.0.0a2.
101
+ - Zenith angle of departure offset: mu_offset,ZOD of TR 38.901 V16.1.0, eq. (7.5-19), is
102
+ 0, as the tables of TR 38.811 V15.4.0, clause 6.7.2, have no offset row, where NLOS
103
+ links took the expression of TR 38.901 Table 7.5-9 (rural macro cell), in radians
104
+ added to degrees; the cluster zenith angles of NLOS links at the satellite change
105
+ little. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
106
+ See 2.0.0a2.
107
+ - Sub-urban NLOS, Ka band, uplink, 80°: the mean of lg ZSD is -3.20, as in TR 38.811
108
+ V15.4.0, Table 6.7.2-6b, instead of -3.30, which made the median ZSD and the zenith
109
+ spread of the rays within each cluster at the satellite or aerial platform too small;
110
+ as the departure spreads of a satellite are zero in both directions (the item on the
111
+ departure spreads at the satellite in the uplink), the corrected value acts on the
112
+ uplink of aerial platforms. Affected earlier versions: the versions for Sionna 0.19
113
+ and 1.x, and 2.0.0a1. See 2.0.0a2.
114
+ - Urban NLOS, Ka band: the cluster ASA at 30°, 40° and 50° is 16.4°, 17.86° and 19.74°,
115
+ as in TR 38.811 V15.4.0, Table 6.7.2-4b, instead of 18.14°, 16.04° and 17.86° in both
116
+ directions, which made the spread of the rays within each cluster on the UT side too
117
+ large at 30° and too small at 40° and 50°. Affected earlier versions: the versions for
118
+ Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
119
+ - Departure spreads at the satellite in the uplink: NOTE 8 of TR 38.811 V15.4.0, Tables
120
+ 6.7.2-1a to 6.7.2-8b, by which the departure angle spreads of a satellite are zero,
121
+ applies in both directions, where only the downlink parameter files applied it; the
122
+ files hold the tables as printed, so aerial platforms take their spreads in both
123
+ directions, where the downlink files gave them zero. This concerns the uplink of
124
+ satellites and both directions of aerial platforms. Affected earlier versions: the
125
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
126
+ - Cluster azimuth spread at the satellite: every ray leaves a satellite in the azimuth
127
+ of its cluster, as NOTE 8 of TR 38.811 V15.4.0, Tables 6.7.2-1a to 6.7.2-8b, makes the
128
+ departure angle spreads of a satellite zero, where the rays of the urban scenario left
129
+ at the AOD of their cluster plus c_ASD α_m (TR 38.901 V16.1.0, eq. (7.5-13)); this
130
+ concerns the urban links of satellites, as the other tables print c_ASD = 0, and not
131
+ aerial platforms. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and
132
+ 2.0.0a1. See 2.0.0a2.
133
+ - Satellite Doppler shift: the Doppler shift due to the motion of the satellite has the
134
+ factor R/(R+h) of TR 38.811 V15.4.0, clauses 6.7.1 and 6.9.2, without which it was
135
+ (R+h)/R times too large, and a geostationary satellite, which induced one, induces
136
+ none, as clause 5.3.2.3 states; this concerns the phase over time of every satellite
137
+ link with the Doppler shift enabled. Affected earlier versions: the versions for
138
+ Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
139
+ - Satellites from 160 km to below 600 km: the Doppler shift due to the motion of the
140
+ satellite applies to them, where it applied from 600 km on; the Faraday rotation of
141
+ TR 38.811 V15.4.0, clause 6.8.2, given for a spaceborne BS above the ionosphere, still
142
+ applies from 600 km, the lowest satellite altitude of TR 38.811. Affected earlier
143
+ versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
144
+ - Faraday rotation in the uplink: uplink paths to a satellite from 600 km are rotated in
145
+ the direction of the downlink, as seen from the earth station (ITU-R P.618-13,
146
+ section 4), between the scatterers and the satellite, where the field of the UT was
147
+ rotated before the scatterers and in the opposite direction (TR 38.811 V15.4.0,
148
+ eqs. (6.8-1a) and (6.8-1b), are written for the downlink); this changes the power
149
+ between single elements and, through scatterers, over two orthogonal elements at the
150
+ satellite. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and
151
+ 2.0.0a1 to 2.0.0a3. See 2.0.0a4.
152
+ - Default atmosphere: the defaults of `temperature` and `atmospheric_pressure` are those
153
+ of the reference atmosphere of TR 38.811 V15.4.0, clause 6.6.4 (288.15 K and
154
+ 1013.25 hPa), where they were 273 K and 1020 hPa, and the gas loss takes
155
+ t = T - 273.15 in degrees Celsius, where T - 273 was used; this concerns the gas loss
156
+ of every link. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and
157
+ 2.0.0a1. See 2.0.0a2.
158
+ - Gas attenuation: the gas loss of every link follows Annex 2 of ITU-R P.676-10 as
159
+ printed (eqs. (22a) to (23d) and (25a) to (28); TR 38.811 V15.4.0, eq. (6.6-8)), with
160
+ the pressure of clause 6.6.4 as the dry air pressure, where it used curve fits up to
161
+ 54 GHz, with two coefficients that no revision prints, followed no revision above
162
+ 54 GHz and took the pressure as the total pressure. Affected earlier versions: the
163
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
164
+ - Atmospheric parameters of `set_topology`: a value of `latitude`,
165
+ `atmospheric_pressure`, `temperature` or `water_vapor_density` persists until it is
166
+ passed again and, passed without new topology tensors, recomputes the gas and
167
+ scintillation losses (TR 38.811 V15.4.0, clauses 6.6.4 and 6.6.6), where every call
168
+ reset the values that it did not pass and only a new topology recomputed the losses;
169
+ the `set_topology` method of the models takes them, where it raised `TypeError`.
170
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1. See
171
+ 2.0.0a2.
172
+ - Tropospheric scintillation: in the Ka band the loss is the value of TR 38.811 V15.4.0,
173
+ Table 6.6.6.2.1-1, at the nearest reference elevation angle, as clause 6.6.6.2.1
174
+ specifies above 6 GHz, where it was the fade depth of ITU-R P.618-13 exceeded 0.01 %
175
+ of the time instead of the 1 % of the table, computed from atmospheric and antenna
176
+ parameters; this concerns every link in the Ka band. Affected earlier versions: the
177
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
178
+ - Ionospheric scintillation: in the S band, satellite links get A_IS of TR 38.811
179
+ V15.4.0, clause 6.6.6.1.4, only for UTs within 20° of the magnetic equator, by
180
+ `latitude` of `set_topology` (by default 47°, which gives 0 dB), and links to aerial
181
+ platforms get none, as Table 6.10.1-1 gives the scintillation as negligible for UAS,
182
+ where A_IS applied at every latitude and to every platform. Affected earlier versions:
183
+ the versions for Sionna 0.19 and 1.x and 2.0.0a1, and for aerial platforms within 20°
184
+ of the magnetic equator 2.0.0a2 and 2.0.0a3. See 2.0.0a2 and 2.0.0a4.
185
+ - Antenna element pattern `"dlp"`: it includes the maximum directional gain of 5 dBi of
186
+ R1-1802551, Table 2, which TR 38.811 V15.4.0, clause 6.4.2, uses, where its maximum
187
+ was 0 dBi; this concerns every channel with `"dlp"` elements, at either end. Affected
188
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3. See
189
+ 2.0.0a4.
190
+ - Antenna arrays with `polarization="dual"` and `polarization_type="VH"`: the two
191
+ elements of each pair have the slant angles 0° and 90°, as in TR 38.901 V16.1.0,
192
+ clause 7.3.2, and R1-1802551, Table 1 (TR 38.811 V15.4.0, clause 6.4.2), where they
193
+ had the -45° and +45° of `"cross"`; this concerns every such array, at either end, but
194
+ not the power summed over a pair. Affected earlier versions: the versions for Sionna
195
+ 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3. See 2.0.0a4.
196
+ - UT orientations of `generate_uts_topology` and `gen_single_sector_topology`: every UT
197
+ faces the satellite or aerial platform, as the generators intend and their docstrings
198
+ now state, where the UTs at negative x faced away from it (`atan` of y/x instead of
199
+ the angle of (x, y)); this concerns such UTs with a directional antenna element, about
200
+ a third of the UTs of `generate_uts_topology` with `drop_area="cell"`. Affected
201
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3. See
202
+ 2.0.0a4.
203
+
204
+ ### Added
205
+
206
+ - The argument `device`, by default `sionna.phy.config.device`, of `DenseUrban`,
207
+ `Urban`, `SubUrban`, their scenarios and `SystemLevelScenario`, of the antenna classes
208
+ and `ChannelCoefficientsGenerator`, and of nine functions of `openntn.utils`; the
209
+ antenna arrays of a model must be built on its device. See 2.0.0a3 and 2.0.0rc1.
210
+ - The argument `aperture_radius` of `AntennaElement`, `PanelArray`, `Antenna` and
211
+ `AntennaArray`, the radius of the pattern `"aperture"` of TR 38.811 V15.4.0, clause
212
+ 6.4.1, in wavelengths, by default 10, the radius that the pattern used before. See
213
+ 2.0.0a4.
214
+ - The optional argument `strongest_cluster_indices` of `Rays`. See 2.0.0a2.
215
+ - `openntn.__version__`, the version of the installed distribution. See 2.0.0rc1.
216
+ - The optional dependencies `test`, what the test suite of the source distribution
217
+ needs. See 2.0.0rc1.
218
+ - `docs/model.md`, the description of the channel models. See 2.0.0rc1.
219
+ - `docs/migration.md`, a guide for the users of the versions for Sionna 1.x and 0.19.
220
+ See 2.0.0rc1.
221
+ - `CITATION.cff`, the citation metadata of the software. See 2.0.0rc1.
222
+ - `example/BER_sims_results.npz` and `example/ML_based_SIMO_receiver_results.npz`, the
223
+ results of the full runs of `BER_sims.ipynb` and `ML_based_SIMO_receiver.ipynb`. See
224
+ 2.0.0rc1.
225
+
226
+ ### Changed
227
+
228
+ - The package is built on PyTorch and Sionna 2.x: its classes and functions take and
229
+ return PyTorch tensors of the same shapes instead of TensorFlow tensors, and its
230
+ objects are objects of Sionna 2.x, with the attributes `dtype` (instead of `rdtype`),
231
+ `cdtype` and `device`. Affected earlier versions: the versions for Sionna 0.19 and
232
+ 1.x. See 2.0.0rc1.
233
+ - Import name `openntn`, instead of the module `tr38811` that the installation scripts
234
+ of the earlier versions linked into Sionna. See 2.0.0a1.
235
+ - Installation: `pip install openntn` installs the package from PyPI with PyTorch, NumPy
236
+ and Matplotlib, for Sionna 2.x (`sionna>=2.0.1,<3.0`) and Python 3.11 or later,
237
+ without TensorFlow, and changes no file of Sionna; the link and the line
238
+ `from . import tr38811` that the earlier installation scripts added to Sionna remain
239
+ in such an environment, as `openntn` neither needs nor removes them. Affected earlier
240
+ versions: the versions for Sionna 0.19 and 1.x. See 2.0.0a1 and 2.0.0rc1.
241
+ - The licence is declared as `MIT AND Apache-2.0`: the files derived from Sionna are
242
+ under the Apache License 2.0, all other files under the MIT License, and both licence
243
+ texts are included. See 2.0.0a1.
244
+ - The source distribution contains `CHANGELOG.md`, and the metadata of the distribution
245
+ name the changelog, have keywords and the development status "5 - Production/Stable"
246
+ ("4 - Beta" in 2.0.0rc1) and list Louis Lagona and Tim Düe as authors. See 2.0.0rc1.
247
+ - For users of the version for Sionna 0.19: the argument `precision`, `"single"` or
248
+ `"double"`, by default `sionna.phy.config.precision`, replaces the TensorFlow `dtype`,
249
+ and a call with `dtype` raises `TypeError`; the property `dtype` of the scenarios is
250
+ the real data type, and the antenna classes, `ChannelCoefficientsGenerator`,
251
+ `LSPGenerator`, `RaysGenerator` and `SystemLevelScenario` are objects of Sionna 2.x
252
+ instead of plain classes. Affected earlier version: the version for Sionna 0.19. See
253
+ 2.0.0rc1.
254
+ - Counts such as `num_ant`, `batch_size` and `num_ut` are Python ints instead of
255
+ TensorFlow integer tensors, and the antenna indices of `PanelArray` are `torch.int64`.
256
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x. See 2.0.0rc1.
257
+ - `Topology`, `LSP` and `Rays` are plain classes, and the abstract methods of
258
+ `SystemLevelScenario` are no longer enforced. Affected earlier versions: the version
259
+ for Sionna 1.x (the three classes) and the versions for Sionna 0.19 and 1.x (the
260
+ abstract methods). See 2.0.0rc1.
261
+ - `openntn.channel_coefficients`, `openntn.lsp` and `openntn.rays` define `__all__`, so
262
+ a star import binds only their two classes. Affected earlier versions: the versions
263
+ for Sionna 0.19 and 1.x. See 2.0.0rc1.
264
+ - Inputs and edge cases: `set_topology` converts the topology tensors to the precision
265
+ and device of the model and accepts NumPy arrays, `AntennaElement.field` takes only
266
+ PyTorch tensors, and several functions of `openntn.utils` treat edge cases otherwise.
267
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x. See 2.0.0rc1.
268
+ - Graph execution: `torch.compile` takes the place of `tf.function`; `set_topology` runs
269
+ eagerly, outside the compiled function, so code that traced it calls it before, and
270
+ the call of the models compiles without graph breaks and with CUDA graphs recorded
271
+ once per shape of the topology, as `set_topology` writes the tensors that it derives
272
+ from the topology in place: they are buffers of the model, and the next `set_topology`
273
+ of the same shapes overwrites a tensor taken from it, so clone it to keep its values.
274
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x. See 2.0.0a3, 2.0.0a4
275
+ and 2.0.0rc1.
276
+ - A model stays on the device and in the precision of its construction: moved or cast,
277
+ for example with `.to()`, `.cuda()` or `.double()`, it raises `ValueError` in its next
278
+ `set_topology` or call. Affected earlier versions: 2.0.0a3, whose call raised it only
279
+ after the last `set_topology`, and 2.0.0a1 and 2.0.0a2, which had no such check. See
280
+ 2.0.0a3 and 2.0.0a4.
281
+ - Antenna arrays built in another precision than the model raise a `ValueError` that
282
+ names both precisions. Affected earlier versions: 2.0.0a1 to 2.0.0a3; the versions for
283
+ Sionna 0.19 and 1.x raised an `InvalidArgumentError` of TensorFlow. See 2.0.0a4.
284
+ - The parameters of `set_topology` after `latitude` are keyword-only, so a call in the
285
+ earlier order, with `lwc` and `rain_rate` after `latitude`, raises `TypeError`, where
286
+ 2.0.0a2 to 2.0.0a4 gave their values to the unchecked `atmospheric_pressure` and
287
+ `temperature`. Affected earlier versions: the versions for Sionna 0.19 and 1.x and
288
+ 2.0.0a1, whose scenarios take these parameters by position in the earlier order, and
289
+ 2.0.0a2 to 2.0.0a4, whose scenarios and models take them by position. See 2.0.0rc1.
290
+ - `enable_pathloss` and `enable_shadow_fading` must be `True` or `False`, otherwise
291
+ `TypeError`, where any value was taken by its truth value. Affected earlier versions:
292
+ the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a4. See 2.0.0rc1.
293
+ - `always_generate_lsp` and `doppler_enabled` must be `True` or `False`
294
+ (`doppler_enabled` of `set_topology` also `None`), otherwise `TypeError`, also when a
295
+ call passes the average street width and building height of the earlier versions by
296
+ position. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1
297
+ to 2.0.0a3. See 2.0.0a4.
298
+ - Invalid inputs, such as an elevation angle outside 10° to 90° or a carrier frequency
299
+ outside 1.9 GHz to 4 GHz and 19 GHz to 40 GHz, raise `ValueError` instead of
300
+ `AssertionError`, also under `python -O`, which removed the checks; a `ut_array` or
301
+ `bs_array` of another type raises `TypeError`. Affected earlier versions: the versions
302
+ for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3. See 2.0.0a4.
303
+ - `AntennaPanel.polarization` replaces the misspelt `AntennaPanel.porlarization`,
304
+ without an alias. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and
305
+ 2.0.0a1 to 2.0.0a3. See 2.0.0a4.
306
+ - `Topology` takes the argument `los_phase`, which the scenarios provide; code that
307
+ builds a `Topology` itself has to pass it. See 2.0.0a2.
308
+ - `set_topology` raises `ValueError` unless `bs_loc` holds one satellite (160 km to
309
+ 35 786 km) or aerial platform (8 km to 50 km) at the same height in every batch
310
+ example; before, a second BS made the channel call fail, and with heights that
311
+ differed across the batch the 3D distance, the path loss and the switches of the
312
+ satellite took the height of the first batch example, as in the versions for Sionna
313
+ 0.19 and 1.x and 2.0.0a1. See 2.0.0a2.
314
+ - `set_topology` raises `ValueError` for a `latitude` outside -90° to 90°, the latitude
315
+ of the UTs relative to the magnetic equator, where any value was accepted and had no
316
+ effect. See 2.0.0a2.
317
+ - `basic_pathloss` of the scenarios is the free space path loss plus the clutter loss of
318
+ NLOS links, without the shadow fading draw of its own that it had, as in the versions
319
+ for Sionna 0.19 and 1.x and 2.0.0a1. See 2.0.0a2.
320
+ - `set_topology` raises `ValueError` for indoor UTs, as the models have neither the
321
+ building entry loss of TR 38.811 V15.4.0, clause 6.6.3, nor clusters for them, where
322
+ their channel coefficients were NaN. Affected earlier versions: 2.0.0a1, and the
323
+ versions for Sionna 0.19 and 1.x. See 2.0.0a2.
324
+ - The three notebooks of `example/` run with Sionna 2.x, PyTorch and `openntn`; with
325
+ `OPENNTN_NOTEBOOK_MODE` unset, `BER_sims.ipynb` and `ML_based_SIMO_receiver.ipynb`
326
+ load their stored results, `full` computes the full runs and `reduced` runs short
327
+ ones. See 2.0.0rc1.
328
+ - `BER_sims.ipynb` takes the noise variance of `ebnodb2no` without the factor of the
329
+ bits per symbol, so that its curves lie 3.01 dB to the left of those of the earlier
330
+ notebook. See 2.0.0rc1.
331
+ - `ML_based_SIMO_receiver.ipynb` evaluates the receiver from -10 to 0 dB, where the
332
+ earlier notebook evaluated it from -5 to 0 dB. See 2.0.0rc1.
333
+ - Seven changes of the notebooks: `BER_sims.ipynb` points the antenna of the satellite
334
+ at the UT, generates the topology at the elevation angle of the model and decodes
335
+ log-likelihood ratios in cell 7; `ML_based_SIMO_receiver.ipynb` evaluates the receiver
336
+ beside the baselines with perfect CSI and with LS channel estimation and writes its
337
+ weights with `numpy.savez`; `channel_response.ipynb` generates the topologies at the
338
+ elevation angles of the models and places the geostationary satellite at 35 786 km
339
+ instead of 36 000 km. See 2.0.0rc1.
340
+ - Other changes of the notebooks: the device, single precision and the seed 42 in their
341
+ first code cell, in `BER_sims.ipynb` the batch size and the limits of the notebook for
342
+ Sionna 1.x, in `channel_response.ipynb` no Doppler sweep of the condition number and
343
+ other figures, and texts that describe what the code computes. See 2.0.0rc1.
344
+
345
+ ### Removed
346
+
347
+ - `TDL` and `CDL`, with their modules; the link-level models NTN-TDL and NTN-CDL of
348
+ TR 38.811 V15.4.0, clause 6.9, are not implemented, and their parameter files stay in
349
+ `openntn/models`. See 2.0.0a2.
350
+ - The rain and cloud attenuation of TR 38.811 V15.4.0, clause 6.6.5, which no model
351
+ computed: the scenario property `additional_pathloss` and
352
+ `utils.compute_pathloss_additional`. See 2.0.0a2.
353
+ - The parameters `lwc` and `rain_rate` of `set_topology` and the scenario properties of
354
+ the same names, which had no effect. See 2.0.0a2.
355
+ - The parameters `relative_humidity`, `diameter_earth_antenna` and `antenna_efficiency`
356
+ of `set_topology` and the scenario properties of the same names, which had no effect;
357
+ a call that passes one of the five removed parameters raises `TypeError`. See 2.0.0a2.
358
+ - The arguments `average_street_width` and `average_building_height` of the models and
359
+ their scenarios and the scenario properties of the same names, which no computation
360
+ used. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to
361
+ 2.0.0a3. See 2.0.0a4.
362
+ - `compute_pathloss_basic`, `compute_pathloss_entry`, `compute_pathloss_gas` and
363
+ `compute_pathloss_scintilation` of `openntn.utils` as public functions; the properties
364
+ of the scenarios give the path loss terms. Affected earlier versions: the versions for
365
+ Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3. See 2.0.0a4.
366
+ - `utils.compute_stallite_doppler`, which nothing used. See 2.0.0a2.
367
+ - `utils.gen_single_sector_topology_interferers`, which failed in every scenario. See
368
+ 2.0.0a2.
369
+ - The unused model data files. See 2.0.0a1.
370
+ - `example/Example_NTN_sim.pkl`, replaced by `example/BER_sims_results.npz`. See
371
+ 2.0.0rc1.
372
+
373
+ ### Fixed
374
+
375
+ - The seed of Sionna alone fixes every random number of a simulation on one device, as
376
+ all are drawn from the generators of Sionna 2.x, where the earlier versions drew most
377
+ of them from the global generator of TensorFlow, which that seed does not seed.
378
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x. See 2.0.0rc1.
379
+ - `precision="double"` works throughout, where `gen_single_sector_topology`,
380
+ `set_topology` and other functions of the version for Sionna 1.x raised an error of
381
+ TensorFlow. Affected earlier version: the version for Sionna 1.x; the version for
382
+ Sionna 0.19 was not checked. See 2.0.0rc1.
383
+ - The distribution installs only the package `openntn`, where the `setup.py` of the
384
+ earlier versions also listed their tests as a top-level package `test`. Affected
385
+ earlier versions: the versions for Sionna 0.19 and 1.x (by their `setup.py`; they were
386
+ not built). See 2.0.0rc1.
387
+ - The gradients of `matrix_ut_distance_2d` and of the large scale parameters with
388
+ respect to the UT locations are finite, where the square root of the zero distance of
389
+ a UT to itself made them NaN; no simulation result changes. Affected earlier versions:
390
+ 2.0.0a1, and the versions for Sionna 0.19 and 1.x. See 2.0.0a2.
391
+ - Documentation of the scenario properties: `doppler_enabled` describes the flag that
392
+ switches the Doppler shift due to the motion of the satellite, where it had the
393
+ description of the antenna efficiency, and `gas_pathloss`, `scintillation_pathloss`,
394
+ `entry_pathloss` and `free_space_pathloss` cite TR 38.811 V15.4.0, where they cited
395
+ TR 38.901, clause 7.4.1; no result changes. Affected earlier versions: the versions
396
+ for Sionna 0.19 and 1.x, and 2.0.0a1. See 2.0.0a2.
397
+ - Documentation: the docstrings name `openntn`, the current paths of Sionna and the
398
+ arguments of the signatures; no result changes. Affected earlier versions: 2.0.0a1 to
399
+ 2.0.0a3; the versions for Sionna 0.19 and 1.x have the same texts, apart from the
400
+ module paths. See 2.0.0a4.
401
+ - Documentation: corrected docstrings, for example that of
402
+ `SystemLevelScenario.los_zoa`, which gives the zenith angle of arrival of the LOS path
403
+ as 180° minus its zenith angle of departure, where it said "considered 90 degrees"; no
404
+ result changes. Affected earlier versions: 2.0.0a1 to 2.0.0a4; the versions for Sionna
405
+ 0.19 and 1.x have the same texts, apart from the arguments `precision` and `device`.
406
+ See 2.0.0rc1.
407
+ - The messages of the checks of the panel spacings of `PanelArray` spell "Panel" where
408
+ they said "Pannel". Affected earlier versions: the versions for Sionna 0.19 and 1.x,
409
+ and 2.0.0a1 to 2.0.0a4. See 2.0.0rc1.
410
+ - The tests in `tests/topology_orientations_test.py` and the test `test_dlp_pattern` in
411
+ `tests/antenna_pattern_test.py` failed on a GPU, where Sionna's default device is
412
+ `cuda:0`: they converted tensors on the GPU to NumPy arrays without moving them to
413
+ the CPU. The package is not affected. Affected earlier versions: 2.0.0a4 and
414
+ 2.0.0rc1, whose source distributions contain these tests.
415
+
416
+ ## [2.0.0rc1] - 2026-10-21
417
+
418
+ Release candidate of OpenNTN 2.0.0 for Sionna 2.x, whose channel models give the results
419
+ of 2.0.0a4: it adds a description of the models (`docs/model.md`), a migration guide for
420
+ the users of the versions for Sionna 1.x and 0.19 (`docs/migration.md`) and the citation
421
+ metadata (`CITATION.cff`), ports the three example notebooks to Sionna 2.x and PyTorch,
422
+ takes the parameters of `set_topology` after `latitude` by keyword only, and accepts
423
+ only `True` or `False` for `enable_pathloss` and `enable_shadow_fading`.
424
+
425
+ The entries of this section also complete the sections of 2.0.0a1 to 2.0.0a4: an entry
426
+ that names a pre-release, such as "since 2.0.0a1", describes a change that this
427
+ pre-release brought and its section does not list.
428
+
429
+ ### Changes that affect simulation results
430
+
431
+ - Random numbers: since 2.0.0a1 the package draws every random number with PyTorch,
432
+ from the generators of Sionna 2.x, instead of with TensorFlow, so the same seed gives
433
+ other realizations of every random quantity: the UT drops of the topology generators,
434
+ the LOS states, the large scale parameters, the cluster delays, powers and angles, the
435
+ ray coupling, the cross-polarization ratios, the initial phases and the direction of
436
+ the orbit. The move to PyTorch changed neither the number nor the order nor the
437
+ distributions of the draws; the corrections listed in the sections of the
438
+ pre-releases change some of them. The realizations also depend on where they are
439
+ drawn: the same seed gives other realizations on the CPU than on a GPU, and a call
440
+ compiled with `torch.compile` draws other random numbers than an eager call, unless
441
+ `torch._inductor.config.fallback_random` is set. In single precision, some
442
+ intermediate quantities are rounded differently, because they are now computed in
443
+ double precision before the cast or by the kernels of PyTorch, for example the cosine
444
+ of the elevation angle in the satellite speed, the Faraday rotation angle, the
445
+ constant of the free space path loss, the Bessel function of the pattern `"aperture"`
446
+ and the antenna positions, so results in single precision can differ within rounding
447
+ (the size of these differences was not measured). None of these differences changes
448
+ the statistics of the results. With the versions for Sionna 0.19 and 1.x, the seed of
449
+ Sionna alone did not fix the random numbers (see "Fixed"). Affected earlier versions:
450
+ the versions for Sionna 0.19 and 1.x.
451
+
452
+ ### Added
453
+
454
+ - `example/BER_sims_results.npz` and `example/ML_based_SIMO_receiver_results.npz`, the
455
+ results of the full runs of `BER_sims.ipynb` and `ML_based_SIMO_receiver.ipynb` with
456
+ their metadata (the seed, the versions, the date, the device, the precision, the
457
+ parameters and the run times), as NumPy arrays read with
458
+ `numpy.load(..., allow_pickle=False)`.
459
+ - The argument `device` of `AntennaElement`, `AntennaPanel`, `PanelArray`, `Antenna`,
460
+ `AntennaArray` and `ChannelCoefficientsGenerator`, and of the functions
461
+ `subcarrier_frequencies`, `time_frequency_vector`, `sample_bernoulli`,
462
+ `drop_uts_in_sector`, `set_3gpp_scenario_parameters`, `generate_uts_topology`,
463
+ `gen_single_sector_topology`, `exp_corr_mat` and `one_ring_corr_mat` of
464
+ `openntn.utils`: the device on which they create their tensors, by default
465
+ `sionna.phy.config.device`. The antenna arrays of a model must be built on the device
466
+ of the model (see 2.0.0a3). Since 2.0.0a1; the versions for Sionna 0.19 and 1.x have
467
+ no such argument, as TensorFlow places the tensors itself.
468
+ - `openntn.__version__`, the version of the installed distribution, read from its
469
+ metadata; in a source tree that is not installed it is `"0+unknown"`. Since 2.0.0a1;
470
+ the versions for Sionna 0.19 and 1.x have no `__version__`.
471
+ - The optional dependencies `test`, installed with `pip install openntn[test]`: what
472
+ the test suite of the source distribution needs, pytest since 2.0.0a1 and mpmath
473
+ since 2.0.0a2.
474
+ - `docs/model.md`, the scope, the conventions and the limits of the channel models: what
475
+ they implement of TR 38.811 and TR 38.901, where they take a side and what they leave
476
+ out, with their calibration against TR 38.821 V16.2.0 and their speed on a GPU.
477
+ - `docs/migration.md`, a guide for the users of the versions for Sionna 1.x and 0.19:
478
+ the package and its import, the installation, PyTorch tensors, precision, device and
479
+ random numbers, the removed and renamed names, the arguments by keyword and the checks
480
+ of the inputs, the results that change and why, and the example notebooks.
481
+ - `CITATION.cff`, the citation metadata of the software in the Citation File Format
482
+ 1.2.0, with the paper that presents the framework among its references.
483
+
484
+ ### Changed
485
+
486
+ - The package is built on PyTorch and Sionna 2.x: since 2.0.0a1 its classes and
487
+ functions take and return PyTorch tensors (`torch.Tensor`) instead of TensorFlow
488
+ tensors, with the same shapes, for example the topology tensors of `set_topology` and
489
+ the path coefficients and delays of a call of `DenseUrban`, `Urban` and `SubUrban`,
490
+ so the code around them has to use PyTorch and Sionna 2.x as well. Its objects are
491
+ objects of Sionna 2.x: the real data type is the attribute `dtype` instead of
492
+ `rdtype`, the complex one is `cdtype` as before, and the attribute `device` is new;
493
+ an invalid precision raises the error of Sionna 2.x ("Invalid precision") instead of
494
+ "'precision' must be 'single' or 'double'". Affected earlier versions: the versions
495
+ for Sionna 0.19 and 1.x, which are built on TensorFlow (for the version for Sionna
496
+ 0.19, see also the entry for its users below).
497
+ - Graph execution: `torch.compile` takes the place of TensorFlow's `tf.function`.
498
+ `set_topology` runs eagerly, outside the compiled function, and the call of
499
+ `DenseUrban`, `Urban` and `SubUrban` can be compiled, without graph breaks since
500
+ 2.0.0a3 and with CUDA graphs across topologies of the same shapes since 2.0.0a4 (see
501
+ "Fixed" in these versions). The versions for Sionna 0.19 and 1.x could run
502
+ `set_topology` inside a function traced by `tf.function`, as the earlier
503
+ `BER_sims.ipynb` did; such code has to call `set_topology` before the compiled
504
+ function. Affected earlier versions: the versions for Sionna 0.19 and 1.x.
505
+ - For users of the version for Sionna 0.19: the classes take the argument `precision`,
506
+ `"single"` or `"double"`, instead of a TensorFlow `dtype`, as in the version for
507
+ Sionna 1.x: `AntennaElement`, `AntennaPanel`, `PanelArray`, `Antenna`, `AntennaArray`,
508
+ `ChannelCoefficientsGenerator`, `DenseUrban`, `Urban`, `SubUrban`, their scenarios and
509
+ `SystemLevelScenario`, and so do the functions `subcarrier_frequencies`,
510
+ `time_frequency_vector`, `drop_uts_in_sector`, `set_3gpp_scenario_parameters`,
511
+ `generate_uts_topology`, `gen_single_sector_topology`, `exp_corr_mat` and
512
+ `one_ring_corr_mat` of `openntn.utils`; a call with `dtype` raises `TypeError`.
513
+ Without `precision`, they take `sionna.phy.config.precision`, which sets the
514
+ precision of every object at once. The property `dtype` of the scenarios is the real
515
+ data type (`torch.float32` or `torch.float64`) instead of the complex TensorFlow
516
+ dtype, which is now `cdtype`. `AntennaElement`, `AntennaPanel`, `PanelArray` (and with
517
+ it `Antenna` and `AntennaArray`), `ChannelCoefficientsGenerator`, `LSPGenerator`,
518
+ `RaysGenerator` and `SystemLevelScenario` are objects of Sionna 2.x, PyTorch modules
519
+ with a precision and a device, instead of plain classes (an abstract base class in
520
+ the case of `SystemLevelScenario`, see the entry on its abstract methods). Since
521
+ 2.0.0a1. Affected earlier version: the version for Sionna 0.19; the version for
522
+ Sionna 1.x took `precision` already.
523
+ - The parameters of `set_topology` after `latitude` are taken by keyword only:
524
+ `atmospheric_pressure`, `temperature` and `water_vapor_density` of `DenseUrban`,
525
+ `Urban`, `SubUrban` and their scenarios, and `doppler_enabled` of the scenarios. A
526
+ call that passes them by position raises `TypeError`; `latitude` stays the eighth
527
+ parameter, its position in the scenarios of all earlier versions. In the versions for
528
+ Sionna 0.19 and 1.x and in 2.0.0a1, the `set_topology` method of the scenarios took
529
+ `lwc` and `rain_rate` by position after `latitude`. Since their removal in 2.0.0a2, a
530
+ call written for that order gave their values to `atmospheric_pressure` and
531
+ `temperature`, which are not checked: with a liquid water content of 0.5 g/m³ and a
532
+ rain rate of 100 mm/h, for example, the gas loss was computed for 0.5 hPa and 100 K,
533
+ 2.1180 dB instead of 0.5156 dB at 20 GHz and 30° (dense urban, downlink, 600 km), and
534
+ a rain rate of 10 mm/h made `set_topology` fail with an `OverflowError` in the gas
535
+ loss (computed with the code of 2.0.0a4). Such a call now raises `TypeError`, and so
536
+ does a call that passes the atmospheric parameters by position in the order of
537
+ 2.0.0a2 to 2.0.0a4, which has to name them. Affected earlier versions: the versions
538
+ for Sionna 0.19 and 1.x and 2.0.0a1, whose scenarios take these parameters by position
539
+ in the earlier order, and 2.0.0a2 to 2.0.0a4, whose scenarios and models take them by
540
+ position.
541
+ - `enable_pathloss` and `enable_shadow_fading` of `DenseUrban`, `Urban`, `SubUrban` and
542
+ their scenarios must be `True` or `False`; other values raise `TypeError`. Before, any
543
+ value was accepted and taken by its truth value. Affected earlier versions: the
544
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a4, which accept any value.
545
+ - Counts are Python ints instead of TensorFlow integer tensors: the properties
546
+ `num_rows` and `num_cols` of `AntennaPanel` and `PanelArray`, `num_rows_per_panel`,
547
+ `num_cols_per_panel`, `num_panels`, `num_panels_ant` and `num_ant` of `PanelArray`
548
+ (and of `Antenna` and `AntennaArray`), and `batch_size`, `num_ut`, `num_bs`,
549
+ `num_clusters_los`, `num_clusters_nlos` and `num_clusters_max` of the scenarios. The
550
+ antenna indices `ant_ind_pol1` and `ant_ind_pol2` of `PanelArray` are `torch.int64`
551
+ instead of `tf.int32`. Since 2.0.0a1. Affected earlier versions: the versions for
552
+ Sionna 0.19 and 1.x.
553
+ - `Topology`, `LSP` and `Rays` are plain classes, without the attributes of Sionna's
554
+ `Object`, from which the version for Sionna 1.x derived them. The abstract methods of
555
+ `SystemLevelScenario` are no longer enforced, as it derives from Sionna's `Object`, a
556
+ PyTorch module, instead of an abstract base class: a subclass that lacks one is built
557
+ without an error and fails when the method is used. Since 2.0.0a1. Affected earlier
558
+ versions: the version for Sionna 1.x (the three classes) and the versions for Sionna
559
+ 0.19 and 1.x (the abstract methods).
560
+ - The modules `openntn.channel_coefficients`, `openntn.lsp` and `openntn.rays` define
561
+ `__all__`, so a star import binds only their two classes, for example `LSP` and
562
+ `LSPGenerator` from `openntn.lsp`; it also bound the names that the module imported,
563
+ such as `tf`. Since 2.0.0a1. Affected earlier versions: the versions for Sionna 0.19
564
+ and 1.x.
565
+ - Accepted inputs and edge cases: `set_topology` converts the topology tensors to the
566
+ precision and device of the model and accepts NumPy arrays; `AntennaElement.field`
567
+ takes PyTorch tensors of any floating precision and device, but no Python numbers or
568
+ NumPy arrays; `deg_2_rad`, `rad_2_deg` and `wrap_angle_0_360` accept Python numbers
569
+ and tensors of any precision; `drop_uts_in_sector` and `gen_single_sector_topology`
570
+ accept integer heights; `sample_bernoulli` no longer takes a TensorFlow dtype as its
571
+ precision; `exp_corr_mat` raises `ValueError` for a coefficient of magnitude 1 or
572
+ more instead of an error of TensorFlow, and no longer rejects a NaN coefficient;
573
+ `time_lag_discrete_time_channel` returns Python ints and computes its ceiling in
574
+ double precision (one sample more where the product lies just above an integer);
575
+ with `normalize=True`, `cir_to_ofdm_channel` and `cir_to_time_channel` leave a link
576
+ whose energy is NaN unnormalized, where the division made every coefficient of such
577
+ a link NaN, and the first takes its frequencies only as a PyTorch tensor, cast to the
578
+ precision and device of the delays; `time_to_ofdm_channel` returns a response with
579
+ more taps than the FFT size instead of an error. Since 2.0.0a1. Affected earlier
580
+ versions: the versions for Sionna 0.19 and 1.x.
581
+ - Installation: `pip install openntn` installs the package with its dependencies and
582
+ changes no file of Sionna (since 2.0.0a1). The installation scripts of the versions
583
+ for Sionna 0.19 and 1.x linked their package into Sionna, as `sionna.channel.tr38811`
584
+ or `sionna.phy.channel.tr38811`, and added the line `from . import tr38811` to the
585
+ `__init__.py` of Sionna's channel package; `openntn` neither needs nor removes this
586
+ link and this line, which remain in an environment with such an installation (the
587
+ line until Sionna is reinstalled). The distribution declares PyTorch, NumPy and
588
+ Matplotlib as dependencies besides Sionna 2.x, with the lower bounds of Sionna 2.0.1;
589
+ it needs neither TensorFlow nor `importlib_resources`, which the earlier versions
590
+ imported without declaring it. Affected earlier versions: the versions for Sionna
591
+ 0.19 and 1.x.
592
+ - The source distribution contains `CHANGELOG.md`. The metadata of the distribution
593
+ names the changelog among the project URLs, has keywords and the development status
594
+ "4 - Beta", and lists Louis Lagona and Tim Düe as authors, in this order.
595
+ - The three notebooks of `example/`, `channel_response.ipynb`, `BER_sims.ipynb` and
596
+ `ML_based_SIMO_receiver.ipynb`, run with Sionna 2.x and PyTorch, with the channel
597
+ models, the antennas and the topology generator of `openntn`, instead of TensorFlow
598
+ and `sionna.phy.channel.tr38811`. The environment variable `OPENNTN_NOTEBOOK_MODE`,
599
+ read in their first code cell, sets what they compute: unset, `BER_sims.ipynb` and
600
+ `ML_based_SIMO_receiver.ipynb` load their stored results and `channel_response.ipynb`
601
+ runs with its own batch sizes; `full`, the full runs, which for
602
+ `ML_based_SIMO_receiver.ipynb` include the training of the receiver and need a GPU;
603
+ `reduced`, short runs with small batches that write no file.
604
+ - `BER_sims.ipynb` computes the noise variance with `ebnodb2no` for the Eb/N0 per
605
+ information bit, without the factor of the bits per symbol by which the earlier
606
+ notebook multiplied it: the noise variance at an Eb/N0 of x dB is that of the earlier
607
+ notebook at x + 3.01 dB, so that by this change its curves lie 3.01 dB to the left of
608
+ those of the earlier notebook (its BER at x is the earlier BER at x + 3.01 dB).
609
+ - `ML_based_SIMO_receiver.ipynb` trains the receiver on Eb/N0 drawn from [-5, 0.5) dB,
610
+ as before, and evaluates it from -10 to 0 dB in steps of 0.5 dB; the earlier notebook
611
+ evaluated it from -5 to 0 dB.
612
+ - Seven changes of the notebooks. `BER_sims.ipynb` points the antenna of the satellite
613
+ at the UT instead of the nadir: with the topology at 50°, the nadir would put the UT
614
+ 40° off the boresight of the pattern `"aperture"`, at -44.64 dB (in the earlier
615
+ notebook, whose UTs lay at 80°, 10° off, at -30.54 dB); the channel is normalized, so
616
+ this changes the BER only through the polarization. It generates the topology at the
617
+ elevation angle of the model, 50°, where the earlier notebook took the default of the
618
+ generator, 80°, and it decodes log-likelihood ratios in the single transmission of
619
+ its cell 7, where the earlier notebook fed the decoder hard decisions and printed a
620
+ coded BER of 0.478 (0.0776 with the version for Sionna 0.19); its BER simulations stay
621
+ uncoded, with hard decisions. `ML_based_SIMO_receiver.ipynb` evaluates the receiver
622
+ beside the two baselines with perfect CSI and with LS channel estimation, and writes
623
+ the weights once, after the training, as float32 arrays with `numpy.savez`, where the
624
+ earlier notebooks pickled them. `channel_response.ipynb` generates the topologies at
625
+ the elevation angles of the models, where the earlier notebook took 90° or the
626
+ default of the generator, 80°, beside models at other angles, and places the
627
+ geostationary satellite at 35 786 km, the altitude of TR 38.811 V15.4.0, Table 4.5-1,
628
+ instead of 36 000 km, which the models reject since 2.0.0a2.
629
+ - Other changes of the notebooks: their first code cell sets the device, single
630
+ precision and the seed 42, so that runs on one device repeat their results, apart from
631
+ a training of the receiver on a GPU (the earlier notebooks set no seed);
632
+ `BER_sims.ipynb` simulates each point with a batch size of 16, at most 1000
633
+ iterations and at most 1000 block errors, as the notebook for Sionna 1.x did, where
634
+ the notebook for Sionna 0.19 took 128, 1 000 000 and 10 000; `channel_response.ipynb`
635
+ no longer sweeps the condition number over the Doppler shift (it took one time
636
+ sample, at t = 0, where the Doppler shift has no effect, so its figure showed random
637
+ variation only), leaves the paths without power out of its figures, shows the
638
+ condition numbers as empirical distribution functions with their medians and plots
639
+ every time sample; and the texts of the three notebooks describe what the code
640
+ computes and what its results show.
641
+
642
+ ### Removed
643
+
644
+ - `example/Example_NTN_sim.pkl`, the pickled results of the earlier `BER_sims.ipynb`,
645
+ replaced by `example/BER_sims_results.npz`.
646
+
647
+ ### Fixed
648
+
649
+ - The seed of Sionna alone now fixes every random number of a simulation on one device:
650
+ since 2.0.0a1 the package draws all of them from the generators of Sionna 2.x, which
651
+ `sionna.phy.config.seed` seeds (see "Changes that affect simulation results"). The
652
+ seed of Sionna 1.x (`sionna.phy.config.seed`) and that of Sionna 0.19
653
+ (`sionna.config.seed`) seed Sionna's own generators, but not TensorFlow's global
654
+ generator. The version for Sionna 1.x drew only the large scale parameters and its
655
+ Bernoulli draws, such as the LOS states, from Sionna's generator, the version for
656
+ Sionna 0.19 only the LOS states, and both drew every other random number from
657
+ TensorFlow's global generator: the UT drops, the cluster delays, powers, signs and
658
+ angles, the ray coupling, the cross-polarization ratios, the initial phases, the
659
+ direction of the orbit and the shadow fading of the basic path loss. Their results
660
+ therefore changed from run to run under the same seed of Sionna; a run of these
661
+ versions repeats its random numbers only when `tf.random.set_seed` is set as well
662
+ (read from the code of these versions and of Sionna 0.19.2, 1.0.1 and 1.2.1).
663
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x.
664
+ - Double precision: `precision="double"` works throughout (since 2.0.0a1), as the
665
+ reference outputs of the test suite, computed in double precision, show. In the
666
+ version for Sionna 1.x several functions combined float32 tensors with float64 ones,
667
+ among them `gen_single_sector_topology` and `set_topology`, which therefore raised an
668
+ error of TensorFlow in double precision (computed with Sionna 1.2.1 and TensorFlow
669
+ 2.19.0), so that simulations ran in single precision, its default, only. Affected
670
+ earlier version: the version for Sionna 1.x; the version for Sionna 0.19, which takes
671
+ a TensorFlow dtype, was not checked.
672
+ - The distribution installs only the package `openntn` (since 2.0.0a1); the tests are
673
+ part of the source distribution only. The `setup.py` of the versions for Sionna 0.19
674
+ and 1.x took its packages from `find_packages()`, which also lists the folder of their
675
+ tests as a top-level package `test`, a name that Python's standard library uses for
676
+ its own tests. Affected earlier versions: the versions for Sionna 0.19 and 1.x (by
677
+ their `setup.py`; they were not built).
678
+ - Documentation: the docstring of `SystemLevelChannel` describes its argument
679
+ `precision`, which the model does not use, as in Sionna, since it takes the precision
680
+ and the device of its scenario; the docstrings of the argument `precision` of
681
+ `DenseUrban`, `Urban`, `SubUrban`, their scenarios and `SystemLevelScenario` say that
682
+ the antenna arrays must be built in that precision; the docstring of
683
+ `SystemLevelScenario.los_zoa` gives the zenith angle of arrival of the LOS path, 180°
684
+ minus its zenith angle of departure, where it said "considered 90 degrees"; those of
685
+ `los_probability` of the scenarios give its shape [batch size, number of BSs, number
686
+ of UTs]; that of `drop_uts_in_sector` describes its drop, within ± `isd`/2 in x and in
687
+ y around one point at the elevation angle of the BS, where it described the sector
688
+ drop of Sionna and `isd` as the distance between two adjacent BSs, and its arguments
689
+ `elevation_angle` and `device`; the module `openntn` no longer calls itself a
690
+ sub-package of Sionna; the docstrings of `PanelArray`, `time_to_ofdm_channel`,
691
+ `drop_uts_in_sector`, `relocate_uts`, `generate_uts_topology` and
692
+ `gen_single_sector_topology` no longer refer to figures of Sionna's documentation,
693
+ which the package does not have; that of `relocate_uts` describes the indexing of the
694
+ sectors in words; the entries `panel_vertical_spacing` and `panel_horizontal_spacing`
695
+ of `PanelArray` compare the spacings with the height and the width of a panel, as its
696
+ checks do, where they had height and width swapped; and the summary of
697
+ `gen_single_sector_topology` places its BS above the origin and its UTs around one
698
+ point, where it said that the UTs are dropped uniformly in a cell sector. No result
699
+ changes. Affected earlier versions: 2.0.0a1 to 2.0.0a4; the versions for Sionna 0.19
700
+ and 1.x have the same texts, apart from the argument `precision`, which the version
701
+ for Sionna 0.19 does not take (it takes a TensorFlow `dtype`), and the argument
702
+ `device`, which neither takes.
703
+ - The messages of the checks of the panel spacings of `PanelArray` spell "Panel" where
704
+ they said "Pannel". Affected earlier versions: the versions for Sionna 0.19 and 1.x,
705
+ and 2.0.0a1 to 2.0.0a4.
706
+
707
+ ## [2.0.0a4] - 2026-10-19
708
+
709
+ Fourth pre-release of OpenNTN for Sionna 2.x: its corrections change simulation results
710
+ (the first section names them), and the interface changes, with a renamed property,
711
+ private path loss functions, removed arguments and checks of the inputs that raise
712
+ `ValueError` or `TypeError`.
713
+
714
+ ### Changes that affect simulation results
715
+
716
+ - Ionospheric scintillation of aerial platforms: links to an aerial platform (8 km to
717
+ 50 km) below 6 GHz no longer get the ionospheric scintillation loss of TR 38.811
718
+ V15.4.0, clause 6.6.6.1.4; its Table 6.10.1-1 gives the scintillation as negligible
719
+ for the deployment of UAS including HAPS below 6 GHz, whose links stay below the
720
+ ionosphere. Within 20° of the magnetic equator such links got 2.2 dB at 2 GHz
721
+ (1.93 dB at 2.185 GHz); at higher latitudes, the default of 47° included, the loss
722
+ was already 0. Satellites keep the loss. Affected earlier versions: 2.0.0a2 and
723
+ 2.0.0a3; the versions for Sionna 0.19 and 1.x and 2.0.0a1 gave the loss at every
724
+ latitude, also to platforms at the heights of aerial platforms, which they accepted
725
+ without a check.
726
+ - Antenna element pattern `"dlp"`: it now includes the maximum directional gain of
727
+ 5 dBi that R1-1802551, Table 2, gives for the element of the co-phased dual linearly
728
+ polarized UE array, which TR 38.811 V15.4.0, clause 6.4.2, uses. Its maximum was
729
+ 0 dBi, so every path of a channel with `"dlp"` elements was 5 dB too weak for each end
730
+ that uses them, 10 dB with `"dlp"` at both ends (computed with this version); the
731
+ element `"38.901"` already included its 8 dBi. Affected earlier versions: the
732
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3.
733
+ - The UTs of `generate_uts_topology` and `gen_single_sector_topology` now face the
734
+ satellite or aerial platform, as the generators intend: the bearing of a UT at
735
+ negative x was off by 180° (`atan` of y/x instead of the angle of (x, y)), so its
736
+ boresight pointed away from the platform, 180° minus twice the elevation angle off
737
+ the line of sight. This concerns UTs with a directional antenna element: with the
738
+ element `"38.901"` their gain toward the platform was -22 dBi instead of +8 dBi at
739
+ elevation angles up to 30° and -3.5 dBi at 60°. `generate_uts_topology` with
740
+ `drop_area="cell"` places about a third of the UTs at negative x;
741
+ `gen_single_sector_topology` does so on average for at most about 0.6 % of the UTs at
742
+ 600 km and elevation angles up to 80°, but for up to a fifth at 20 km and a third at
743
+ 8 km at 80°, where the loss was 1 to 2 dB on average (computed with this version). At
744
+ 90° nothing changes. Their docstrings now state the orientations that they set: the
745
+ BS facing the nadir and each UT facing the BS; they said that the UT orientations
746
+ were random and that the BS faced the centre of the sector. Affected earlier
747
+ versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3.
748
+ - Dual-polarized antenna arrays with `polarization_type="VH"`: the two elements of each
749
+ pair now have the slant angles 0° and 90°, a vertically and a horizontally polarized
750
+ element, as in TR 38.901 V16.1.0, clause 7.3.2 (polarization model 2) and the "X-pol
751
+ (0/+90 degree)" configuration of its clause 7.8.2, and as R1-1802551, Table 1, gives
752
+ for the UE arrays of TR 38.811 V15.4.0, clause 6.4.2. They had the slant angles -45°
753
+ and +45°, those of `polarization_type="cross"`, because the constructor tested the
754
+ wrong argument. This concerns every `PanelArray`, `Antenna` and `AntennaArray` built
755
+ with `polarization="dual"` and `polarization_type="VH"`, at the satellite, the aerial
756
+ platform or the UT, in all scenarios, bands, directions and link states. The power of
757
+ each element of such a pair changes; the power summed over the two elements of a pair
758
+ does not. In the characterization outputs of the test suite, a satellite array of
759
+ four such pairs and a vertically polarized UT element, the power per antenna pair
760
+ changed by up to 32 dB, the power summed over the satellite's elements by less than
761
+ 1e-14 relative (computed with this version). Affected earlier versions: the versions
762
+ for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3.
763
+ - Faraday rotation in the uplink: the polarization of uplink paths to a satellite from
764
+ 600 km is now rotated in the same direction as on the downlink, as seen from the earth
765
+ station, as ITU-R P.618-13, section 4, states, and between the scatterers near the UT
766
+ and the satellite, as on the downlink. Before, the uplink rotated the UT's field
767
+ before the scatterers and in the opposite direction (TR 38.811 V15.4.0, eqs. (6.8-1a)
768
+ and (6.8-1b), are written for the downlink). The rotation is 108°/f² (f in GHz;
769
+ 6.75° to 29.9° in the S band, 0.07° to 0.30° in the Ka band). This changes the power
770
+ between single elements (by tens of dB, without a bound near a polarization null on a
771
+ LOS path) and, for the paths through scatterers, the power that the satellite
772
+ collects over two orthogonal elements, which no longer depends on the rotation (it
773
+ did by up to 13 dB for single paths); the power over two orthogonal elements at
774
+ either end of a LOS path does not change (computed with this version). Affected
775
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3.
776
+
777
+ ### Added
778
+
779
+ - The argument `aperture_radius` of `AntennaElement`, `PanelArray`, `Antenna` and
780
+ `AntennaArray`: the radius a of the circular aperture of the element pattern
781
+ `"aperture"` of TR 38.811 V15.4.0, clause 6.4.1, in multiples of the wavelength, as
782
+ the element spacings of `PanelArray`. For an aperture of diameter D at the carrier
783
+ frequency f, a = D f/(2c), with c the speed of light; the 2 m of TR 38.821 V16.2.0,
784
+ Table 6.1.1.1-1, at 2 GHz give a = 6.67. It defaults to 10, the radius of Figure
785
+ 6.4.1-1 of TR 38.811, which the pattern always used before, so results do not change;
786
+ the other patterns do not use it. A value that is a bool or not a real number raises
787
+ `TypeError`, one that is not positive and finite `ValueError`.
788
+
789
+ ### Changed
790
+
791
+ - A model moved to another device or cast to another precision, for example with
792
+ `.to()`, `.cuda()` or `.double()`, now raises `ValueError` in every order:
793
+ `set_topology` checks the device and the precision of its tensors first, as the call
794
+ already did after the last `set_topology`. Before, a model moved or cast before
795
+ `set_topology` or between two topologies failed with an error from PyTorch in
796
+ `set_topology` or in the call, such as "Tensor on device meta is not on the expected
797
+ device cpu!" or "expected scalar type ComplexFloat but found Double". Affected
798
+ earlier version: 2.0.0a3; 2.0.0a1 and 2.0.0a2 had no such check.
799
+ - `AntennaPanel.polarization` replaces the misspelt `AntennaPanel.porlarization`,
800
+ which is removed without an alias. The property returns the polarization of the
801
+ panel, `"single"` or `"dual"`, under the name of the same property of Sionna's
802
+ `AntennaPanel` and of `PanelArray`. Affected earlier versions: the versions for
803
+ Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3, which have only `porlarization`.
804
+ - `always_generate_lsp` of `DenseUrban`, `Urban` and `SubUrban`, and `doppler_enabled`
805
+ of these models, of their scenarios, of the `set_topology` method of the scenarios
806
+ and of `Topology`, must be `True` or `False` (`None` in `set_topology`, which keeps
807
+ the flag); other values raise `TypeError`. Before, any value was accepted and taken
808
+ by its truth value. The arguments `average_street_width` and
809
+ `average_building_height`, which came before them, are removed (see "Removed"), so a
810
+ call that passes the arguments of the earlier versions by position would otherwise
811
+ take the street width as one of the flags; it now raises `TypeError`. Affected
812
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3,
813
+ which accept any value.
814
+ - Invalid inputs raise `ValueError` instead of `AssertionError`, also under
815
+ `python -O`, which removed these checks, so that the invalid inputs went on
816
+ unchecked: an elevation angle outside 10° to 90°, a carrier frequency outside 1.9 GHz
817
+ to 4 GHz and 19 GHz to 40 GHz, a `direction` other than `"uplink"` and `"downlink"`,
818
+ and arrays whose carrier frequency differs from that of the model (`DenseUrban`,
819
+ `Urban`, `SubUrban` and their scenarios); a first `set_topology` that leaves out one
820
+ of the topology tensors; the element pattern of `AntennaElement`; the polarization of
821
+ `AntennaPanel`, `PanelArray`, `Antenna` and `AntennaArray`, the polarization type of
822
+ the last three, and panel spacings of `PanelArray` that do not exceed the panel size;
823
+ the properties `ant_pol2`, `ant_ind_pol2` and `ant_pos_pol2` of a single-polarized
824
+ array; the scenario of `set_3gpp_scenario_parameters` and
825
+ `gen_single_sector_topology`; and the drop area of `generate_uts_topology`. A
826
+ `ut_array` or `bs_array` that is not a `PanelArray`, `Antenna` or `AntennaArray`
827
+ raises `TypeError` instead of `AssertionError`, as an argument of the wrong type. The
828
+ conditions and the messages are those of the earlier checks. Under `python -O`, a
829
+ model at an elevation angle of 5° or at 6 GHz, for example, was built without an
830
+ error (the code before this change). Affected earlier versions: the versions for
831
+ Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3, which check these inputs with `assert`.
832
+ - Antenna arrays built in another precision than the model raise a `ValueError` that
833
+ names both precisions. Before, the check of the carrier frequencies failed with its
834
+ message on the frequencies or, at a frequency whose wavelength both precisions hold
835
+ exactly, such as 2 398 339 664 Hz (0.125 m), the model was built and its call failed
836
+ with an error from PyTorch. Affected earlier versions: 2.0.0a1 to 2.0.0a3; the
837
+ versions for Sionna 0.19 and 1.x raised an `InvalidArgumentError` of TensorFlow on
838
+ the data types (computed with TensorFlow 2.18.1 and 2.19.0).
839
+
840
+ ### Removed
841
+
842
+ - The path loss functions `compute_pathloss_basic`, `compute_pathloss_entry`,
843
+ `compute_pathloss_gas` and `compute_pathloss_scintilation` of `openntn.utils` are no
844
+ longer public. They take a scenario of the package, such as a `DenseUrbanScenario`,
845
+ and store their results in its tensors, so only the scenarios use them, in
846
+ `set_topology`. The path loss terms stay available as the properties
847
+ `basic_pathloss`, `gas_pathloss`, `scintillation_pathloss`, `entry_pathloss` and
848
+ `free_space_pathloss` of the scenarios. Affected earlier versions: the versions for
849
+ Sionna 0.19 and 1.x, and 2.0.0a1 to 2.0.0a3, whose `utils` module has them.
850
+ - The arguments `average_street_width` and `average_building_height` of `DenseUrban`,
851
+ `Urban`, `SubUrban` and their scenarios, and the scenario properties of the same
852
+ names: no computation used them. TR 38.811 has no such parameters; the models took
853
+ them over from the rural macro model (RMa) of TR 38.901 in Sionna, whose path loss
854
+ uses them. A call that passes one of them by name raises `TypeError`; for a call by
855
+ position, see "Changed". Affected earlier versions: the versions for Sionna 0.19 and
856
+ 1.x, and 2.0.0a1 to 2.0.0a3, which accept them.
857
+
858
+ ### Fixed
859
+
860
+ - With `torch.compile(mode="reduce-overhead")`, which captures the call of
861
+ `DenseUrban`, `Urban` and `SubUrban` as CUDA graphs, a new topology of the same
862
+ shapes no longer makes the next call record its graphs again: `set_topology` now
863
+ writes the tensors that it derives from the topology (the means and standard
864
+ deviations of the large scale parameters, the ZOD offset, the path loss terms, the
865
+ cluster mask and the large scale parameters drawn with the topology) into the
866
+ existing tensors when their shapes stay the same and no gradients are involved, as it
867
+ already did for the topology itself. Before, it replaced up to 13 of the inputs of
868
+ the captured graphs, and PyTorch recorded and kept one more set of graphs after every
869
+ new topology. Measured on an RTX 4090 with torch 2.14.1 (DenseUrban at 2 GHz, 8 and
870
+ 64 topologies of the same shapes): one recording in all instead of one per topology,
871
+ and the first call after `set_topology` as fast as the next calls, 0.44 to 1.93 ms
872
+ (computed with this version). A topology with another batch size still records new
873
+ graphs, which PyTorch keeps. The results are unchanged. The tensors derived from the
874
+ topology are now buffers of the model and appear in its `state_dict()`. A tensor
875
+ taken from the model after `set_topology`, such as the path loss terms or the means
876
+ of the large scale parameters, is now overwritten by the next `set_topology` of the
877
+ same shapes, as the topology tensors already were; clone it to keep its values.
878
+ Affected earlier versions: 2.0.0a1 to 2.0.0a3; the versions for Sionna 0.19 and 1.x
879
+ are built on TensorFlow and are not affected.
880
+ - Documentation: the docstrings referred to the classes of this package in the module
881
+ `sionna.phy.channel.tr38811`, which does not exist with the package `openntn`, and to
882
+ `sionna.ofdm.ResourceGrid` instead of `sionna.phy.ofdm.ResourceGrid`. The examples of
883
+ `DenseUrban`, `Urban`, `SubUrban` and `gen_single_sector_topology` built the model
884
+ without the required `elevation_angle`, the last one with an argument `o2i_model` that
885
+ no model takes, and the signatures at the top of the docstrings of the models left out
886
+ `elevation_angle` and `doppler_enabled`. The docstrings of the models and their
887
+ scenarios named the antenna arrays `rx_array` and `tx_array` instead of `ut_array` and
888
+ `bs_array`, those of the scenarios described `always_generate_lsp`, which only the
889
+ models take, and those of the models named the first input of the call
890
+ `num_time_steps` instead of `num_time_samples`. The argument `doppler_enabled` of the
891
+ models, their scenarios, `SystemLevelScenario` and its `set_topology` had no
892
+ description. `set_3gpp_scenario_parameters` and `gen_single_sector_topology`
893
+ described a parameter `min_bs_ut_dist` that they do not take, `exp_corr_mat` a
894
+ parameter `dtype` instead of `precision` and `device`, and `time_to_ofdm_channel` its
895
+ parameter `rg` as `resource_grid`; `AntennaPanel` described its property
896
+ `horizontal_spacing` as the vertical spacing. They now name `openntn`, the current
897
+ paths of Sionna and the arguments of the signatures, and describe `doppler_enabled`.
898
+ No result changes. Affected earlier versions: 2.0.0a1 to 2.0.0a3; the versions for
899
+ Sionna 0.19 and 1.x have the same texts, apart from the module paths, which named the
900
+ module that their installation linked into Sionna.
901
+
902
+ ## [2.0.0a3] - 2026-10-13
903
+
904
+ Third pre-release of OpenNTN for Sionna 2.x: the models take the argument `device`, and
905
+ `torch.compile` captures their channel generation without graph breaks; the simulation
906
+ results are unchanged.
907
+
908
+ ### Added
909
+
910
+ - The argument `device` of `DenseUrban`, `Urban`, `SubUrban`, their scenarios and
911
+ `SystemLevelScenario`: the device on which the model creates its tensors and
912
+ computes, for example `"cuda:0"`. It defaults to `sionna.phy.config.device` at the
913
+ construction, the device that the models took before. The antenna arrays `ut_array`
914
+ and `bs_array` must be built on the same device (the argument `device` of the
915
+ antenna classes); otherwise the construction raises `ValueError`. Before, Sionna
916
+ 2.0.1 accepted such an array, and Sionna 2.2.0 raised a `ValueError` of its own with
917
+ the same text. `set_topology` now draws the random LOS states on the device of the
918
+ model; before, it drew them on the device in `sionna.phy.config.device` at the time
919
+ of the call, which failed when that was not the device of the model (2.0.0a1 and
920
+ 2.0.0a2).
921
+
922
+ ### Changed
923
+
924
+ - A model that was moved to another device or cast to another precision after its last
925
+ `set_topology`, for example with `.to()`, `.cuda()` or `.double()`, raises
926
+ `ValueError` when it is called: the message names the device and the precision of the
927
+ construction and those of the tensors, and advises to build the model with the device
928
+ and precision it is to use. The models stay on the device and in the precision of
929
+ their construction, as Sionna's models do: `.to()` moves or casts the registered
930
+ tensors, but not the device and the precision of the model and its parts. Before, the
931
+ call failed inside the channel generation with a `RuntimeError` such as "Tensor on
932
+ device cpu is not on the expected device meta!" after a move, or "expected scalar
933
+ type Double but found ComplexFloat" after a cast to double precision. A model moved
934
+ or cast at another point, before `set_topology` or before a new topology, still fails
935
+ with an error from PyTorch, in `set_topology` or in the call.
936
+
937
+ ### Fixed
938
+
939
+ - `torch.compile` captures the channel generation of `DenseUrban`, `Urban` and
940
+ `SubUrban` without graph breaks, also with `fullgraph=True`, and the results are
941
+ unchanged. The Faraday rotation of TR 38.811 V15.4.0, clause 6.8.2, converted its
942
+ angle ψ = 108°/f², with f in GHz (eq. (6.8-2)), from a tensor to a Python number in
943
+ every call, and `DenseUrban` held its number of rays per cluster, 20, as a tensor,
944
+ which the generation of the rays converted to a Python number to use it as a slice
945
+ bound. With the code of 2.0.0a2, `torch._dynamo.explain` found 11 graph breaks in a
946
+ call of `Urban` or `SubUrban` and 19 in a call of `DenseUrban` (20 with
947
+ `always_generate_lsp=True`), in both link directions and both precisions, and
948
+ `fullgraph=True` failed. The angle is now computed once, when the model is built, and
949
+ the number of rays per cluster is the integer 20 in the three models. Affected earlier
950
+ versions: 2.0.0a1 and 2.0.0a2; the versions for Sionna 0.19 and 1.x are built on
951
+ TensorFlow and are not affected.
952
+ - With 2.0.0a2, on a machine with a CUDA GPU, 7 cases of
953
+ `tests/differentiable_topology_test.py` and `tests/lsp_spatial_correlation_test.py`
954
+ failed, because the tests built tensors on the CPU: defects of the tests, not of the
955
+ package. The tests now build these tensors on the device of the topology.
956
+ `tests/lsp_spatial_correlation_test.py` now reads the parameter files through the
957
+ installed package, so that it also runs against an installed package. No result of the
958
+ package changes. Affected earlier version: 2.0.0a2.
959
+
960
+ ## [2.0.0a2] - 2026-10-12
961
+
962
+ Second pre-release of OpenNTN for Sionna 2.x. Its corrections change simulation results;
963
+ they are listed first, each with the earlier versions it affects.
964
+
965
+ ### Changes that affect simulation results
966
+
967
+ Elevation angles in these entries are the reference angles of TR 38.811 (10° to 90° in
968
+ steps of 10°); the models use the parameters of the reference angle nearest to the
969
+ elevation angle.
970
+
971
+ - Ray offset angles: ray 16 of every cluster is now placed at -1.1481 times the
972
+ intra-cluster angle spread, as in TR 38.901 V16.1.0, Table 7.5-3, which TR 38.811
973
+ V15.4.0, clause 6.7.2, uses; it was placed at -0.1481 times that spread. This
974
+ concerns the azimuth and zenith angles of arrival and departure of every cluster, in
975
+ all scenarios, link states, bands and directions. With the wrong value the 20 offsets
976
+ had a mean of 0.050 instead of 0 and a standard deviation of 0.966 instead of 1.000,
977
+ so the rays of each cluster were shifted by 0.05 times the intra-cluster spread and
978
+ their spread was 3.4 % too small (computed from the table). Affected earlier
979
+ versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
980
+ - Sub-urban NLOS, Ka band, uplink, 80°: the mean of lg ZSD is now -3.20, as in TR
981
+ 38.811 V15.4.0, Table 6.7.2-6b; the parameter file held -3.30. The median ZSD (the
982
+ zenith spread on the satellite side) and the zenith spread of the rays within each
983
+ cluster on that side (TR 38.901 V16.1.0, eq. (7.5-20)) were 21 % too small:
984
+ 10^-3.30 instead of 10^-3.20 degrees, that is 0.00050° instead of 0.00063°. Affected
985
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
986
+ - Urban NLOS, Ka band: the cluster ASA (c_ASA) at 30°, 40° and 50° is now 16.4°, 17.86°
987
+ and 19.74°, as in TR 38.811 V15.4.0, Table 6.7.2-4b; the parameter files of both
988
+ directions held 18.14°, 16.04° and 17.86°. The azimuth spread of the rays within each
989
+ cluster on the UT side was 11 % too large at 30° and 10 % too small at 40° and 50°.
990
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
991
+ - Angular scaling factors: the factors C_phi^NLOS and C_theta^NLOS now follow the
992
+ number of clusters of the link state at the elevation angle, as in TR 38.811 V15.4.0,
993
+ Tables 6.7.2-1aa and 6.7.2-1ab, with the numbers of clusters of Tables 6.7.2-3a to
994
+ 6.7.2-6b (TR 38.901 V16.1.0, clause 7.5, step 7: "a scaling factor related to the
995
+ total number of clusters"). Each parameter file held one pair of factors for all
996
+ elevation angles, so the factors of another number of clusters were used for urban
997
+ LOS links at 10° (4 clusters, the factors of 3 used), urban NLOS and sub-urban LOS
998
+ links at 70° to 90° (2 clusters, the factors of 3 used) and sub-urban NLOS links at
999
+ 60° to 90° (3 clusters, the factors of 4 used), in both bands and both directions;
1000
+ dense urban is not affected. The cluster angles of TR 38.901 eqs. (7.5-9) and
1001
+ (7.5-14) are divided by these factors: they were 0.74 times (azimuth) and 0.72 times
1002
+ (zenith) their specified size where 2 clusters apply, 0.87 and 0.85 times for
1003
+ sub-urban NLOS links at 60° to 90°, and 1.15 and 1.17 times for urban LOS links at
1004
+ 10°. The factors are now tables in the code; the keys `CPhiNLoS` and `CThetaNLoS`
1005
+ were removed from the parameter files. Affected earlier versions: the versions for
1006
+ Sionna 0.19 and 1.x, and 2.0.0a1.
1007
+ - Atmospheric parameters of `set_topology` (`latitude`, `atmospheric_pressure`,
1008
+ `temperature`, `water_vapor_density`): a value now persists until it is passed again,
1009
+ as the `set_topology` documentation states, and a value passed without new topology
1010
+ tensors recomputes the gas and scintillation losses (TR 38.811 V15.4.0, clauses 6.6.4
1011
+ and 6.6.6) without drawing anything else again. Before, every call reset the
1012
+ parameters it did not pass to their defaults, and the losses were recomputed only
1013
+ together with a new topology. The `set_topology` method of `DenseUrban`, `Urban` and
1014
+ `SubUrban` now accepts these parameters and forwards them to the scenario; it raised a
1015
+ `TypeError` before. The default temperature and pressure are now those of the
1016
+ reference atmosphere of clause 6.6.4 (see the entry on the default atmosphere).
1017
+ `latitude` decides the ionospheric scintillation loss (see the entry on the
1018
+ ionospheric scintillation). The parameters `lwc`, `rain_rate`, `relative_humidity`,
1019
+ `diameter_earth_antenna` and `antenna_efficiency`, which had no effect and which the
1020
+ scenario reset in the same way, are removed (see "Removed"). This concerns every
1021
+ simulation that sets atmospheric parameters. For example, at 30° in the urban
1022
+ scenario, a temperature of 300 K instead of the default changes the gas loss from
1023
+ 0.0728 dB to 0.0654 dB at 2.2 GHz and from 0.5156 dB to 0.4939 dB at 20 GHz (computed
1024
+ with this version); where earlier versions had reset a value or not applied it, they
1025
+ used the defaults instead. Affected earlier versions: the versions for Sionna 0.19 and
1026
+ 1.x, and 2.0.0a1.
1027
+ - Cluster elimination: clusters with less than -25 dB power compared with the
1028
+ strongest cluster of their link are now removed, as in TR 38.901 V16.1.0, clause
1029
+ 7.5, step 6, which TR 38.811 V15.4.0, clause 6.7.2, uses; before, all clusters were
1030
+ kept with their own delays and angles. The threshold applies to the cluster powers of
1031
+ TR 38.901 eq. (7.5-6) on LOS and NLOS links, before the LOS specular component is
1032
+ added. A removed cluster gets zero power, so the shapes of the outputs do not
1033
+ change, and the remaining powers are not renormalized. This concerns all scenarios,
1034
+ link states, bands and directions. In 10,000 links per scenario, link state and
1035
+ elevation angle (S band, downlink, computed with 2.0.0a1), 0.6 % to 21 % of the links
1036
+ had at least one such cluster. A removed cluster has less than 10^-2.5 (0.32 %) of
1037
+ the power of the strongest cluster, so the cluster power of a link is now lower by
1038
+ less than 0.32 %, 0.63 % or 0.94 % (0.014 dB, 0.028 dB or 0.042 dB) with 2, 3 or 4
1039
+ clusters; on LOS links the specular component is not affected, so the power of the
1040
+ link falls by less. Affected earlier versions: the versions for Sionna 0.19 and 1.x,
1041
+ and 2.0.0a1.
1042
+ - LOS arrival direction: the zenith angle of arrival of the LOS ray is now 180° minus
1043
+ the zenith angle of departure, so that the LOS arrival direction is the reversed
1044
+ departure direction, as in TR 38.901 V16.1.0, clause 7.5, step 1c, and clause 7.1,
1045
+ which TR 38.811 V15.4.0, clause 6.7.2 and eq. (6.8-1b), uses. It was the zenith angle
1046
+ of departure plus 180°, which together with the azimuth angle of arrival points at
1047
+ the elevation of the satellite but in the opposite azimuth: the arrival direction was
1048
+ off by 180° minus twice the elevation angle, that is by 160°, 120° and 60° at 10°,
1049
+ 30° and 60°, and correct only at 90°. This concerns the LOS ray of every LOS link,
1050
+ in all scenarios, bands and directions: the antenna pattern at the UT, the phases
1051
+ across a UT antenna array, and the Doppler shift of the LOS ray due to the motion of
1052
+ the UT. With one 38.901 element at the UT and a 1 x 4 dual-polarized 38.901 panel at
1053
+ the satellite, the mean power of the first path (the LOS ray and the first cluster)
1054
+ was 10.0 dB, 12.7 dB and 9.0 dB too low at 10°, 30° and 60°, in both directions
1055
+ (dense urban, S band, 1000 forced LOS links, path loss and shadow fading off,
1056
+ computed); with one element with an isotropic pattern at the UT the power does not
1057
+ change. The zenith angles of arrival of the clusters keep their distribution,
1058
+ because TR 38.901 eq. (7.5-18) reflects them into [0°, 180°]; their realizations
1059
+ change. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1060
+ - Sign of the LOS propagation phase: the LOS ray now contains exp(-j2π d3D/λ0), as in
1061
+ TR 38.901 V16.1.0, eq. (7.5-29), and TR 38.811 V15.4.0, eq. (6.8-1b); it contained
1062
+ exp(+j2π d3D/λ0). The minus sign is the one consistent with the Doppler term of the
1063
+ same equation: when a UT moves towards the satellite, d3D shrinks and -2π d3D/λ0
1064
+ grows at the rate of the Doppler phase. This concerns every
1065
+ LOS link, in all scenarios, bands and directions. The statistics do not change,
1066
+ because the phases of the rays of the first cluster, to which the LOS ray is added,
1067
+ are uniformly distributed; single realizations of the channel coefficients of LOS
1068
+ links change. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and
1069
+ 2.0.0a1.
1070
+ - LOS propagation phase in single precision: the phase 2π d3D/λ0 of the LOS ray is now
1071
+ computed in double precision and reduced modulo 2π before the cast to the model
1072
+ precision, with d3D of TR 38.811 V15.4.0, eq. (6.6-3), evaluated in double precision
1073
+ in a form without cancellation, and with the carrier frequency as given (in single
1074
+ precision, 30 GHz, for example, is not representable). Before, d3D and the phase were
1075
+ computed in the model precision. In single precision one unit in the last place of
1076
+ d3D at 600 km (6.25 cm) is 0.4 to 6 wavelengths between 2 and 30 GHz, and d3D was off
1077
+ by up to 0.77 m at 600 km (0.5 m at 90°), so the phase was off by up to 3.1 rad, that
1078
+ is random. The LOS ray is added coherently to the first cluster, so the first-path
1079
+ power and the total power of single LOS links were affected; their distributions
1080
+ were not. The phase is now within 1e-6 rad of the specified value in single and
1081
+ double precision; for elevation angles from 10° to 90° in steps of 0.5°, 600 km and
1082
+ carrier frequencies of 2.0, 2.2, 2.5, 3.0, 3.5, 4.0, 20, 22.5, 25, 27.5 and 30 GHz,
1083
+ the largest errors are 4.3e-7 rad in single and 2.3e-7 rad in double precision
1084
+ (computed). `distance_3d` is within half a unit in the last place in single
1085
+ precision and within 2 units in double precision (600 km, steps of 0.25°,
1086
+ computed). In double precision the results change only within rounding.
1087
+ This concerns every LOS link in single precision, in all scenarios, bands and
1088
+ directions. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and
1089
+ 2.0.0a1, in single precision, their default precision.
1090
+ - Zenith angle of departure offset: the offset mu_offset,ZOD of TR 38.901 V16.1.0,
1091
+ eq. (7.5-19), is now 0 for every link. TR 38.811 V15.4.0, clause 6.7.2, replaces the
1092
+ parameter tables of TR 38.901 with its own tables, which have no offset row. Before,
1093
+ NLOS links used the expression of TR 38.901 Table 7.5-9 (rural macro cell,
1094
+ arctan((35 - 3.5)/d_2D) - arctan((35 - 1.5)/d_2D)) in all three scenarios, computed
1095
+ in radians and added to angles in degrees. This concerns the zenith angles of the
1096
+ clusters of NLOS links at the satellite, in all scenarios, bands and directions; LOS
1097
+ links had no offset. Because the zenith spread of the clusters at the satellite is
1098
+ zero, the offset was the whole deviation of these clusters from the LOS zenith
1099
+ direction: less than 6e-6° at elevation angles of 10° to 60° (horizontal UT
1100
+ distances of 346 km and more) and at most 0.031° at 90°, for a UT 32 m from the point
1101
+ below the satellite (computed from the expression). The clusters of NLOS links are
1102
+ now centred on the LOS zenith direction at the satellite. The effect on the channel
1103
+ is small: of the reference outputs of the test suite (600 km), only the per-antenna
1104
+ powers of urban NLOS links at 90° changed by more than a relative 1e-5. Affected
1105
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1106
+ - Random signs and ray coupling per link: the random sign X_n of the cluster angles
1107
+ (TR 38.901 V16.1.0, clause 7.5, step 7, eqs. (7.5-11), (7.5-16) and (7.5-19)) and the
1108
+ random coupling of the rays within a cluster (step 8) are now drawn for each link
1109
+ between a satellite and a UT, as TR 38.901 defines them; TR 38.811 V15.4.0, clause
1110
+ 6.7.2, uses this procedure unchanged. Before, both were drawn once per satellite and
1111
+ shared by all its UTs, so the clusters of all UTs of a satellite had the same signs of
1112
+ their angle offsets and the same pairing of ray angles. This concerns simulations
1113
+ with more than one UT per satellite, in all scenarios, link states, bands and
1114
+ directions: the angles of different UTs were correlated, which matters for
1115
+ multi-user and interference studies. For example, for two UTs in the dense urban
1116
+ scenario (S band, 30°, 2000 drops), the sign of the AOA offset of a cluster (other
1117
+ than the strongest) agreed in 69 % (NLOS) to 76 % (LOS) of the clusters instead of
1118
+ 50 %, and on average 14 to 16 of the 20 rays of a cluster had the same position in
1119
+ the AOA order instead of 1 (computed with the earlier version). The statistics of a
1120
+ single link do not change. Because more random numbers are drawn, the realizations
1121
+ of the cluster angles, of the ray coupling and of the random variables drawn after
1122
+ them (cross-polarization ratios, initial phases) change for every link. Affected
1123
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1124
+ - Ray coupling in the two strongest clusters: the rays of the two strongest clusters
1125
+ of a link are now coupled within the sub-clusters of TR 38.901 V16.1.0, Table 7.5-5,
1126
+ as clause 7.5, step 8, requires ("within a cluster n, or within a sub-cluster in the
1127
+ case of two strongest clusters"), and step 11 splits the same two clusters into
1128
+ sub-clusters (eq. (7.5-26)); TR 38.811 V15.4.0, clause 6.7.2, uses these steps
1129
+ unchanged. The two strongest clusters are those with the largest powers of eq.
1130
+ (7.5-6) after the cluster elimination. Before, the rays of every cluster were coupled
1131
+ across the whole cluster, so a sub-cluster, at its own delay, carried angle offsets
1132
+ drawn from all 20 rays of its cluster instead of those that Table 7.5-5 assigns to
1133
+ it, and step 11 sorted the clusters again, which could select a different second
1134
+ cluster when fewer than two clusters of a link have non-zero power (34 of 2100
1135
+ sampled links in the sub-urban scenario, LOS, S band, 30°). This concerns all
1136
+ scenarios, link states, bands and directions. The angular spread of each sub-cluster
1137
+ now follows Table 7.5-5: the rms ray offsets of the sub-clusters R1, R2 and R3 are
1138
+ 0.987, 1.006 and 1.025 times the intra-cluster spread (computed from Tables 7.5-3
1139
+ and 7.5-5), where before they were random around 1; the total angular spread of a
1140
+ cluster, the cluster powers and delays and the mean power of a link do not
1141
+ change. Realizations of the channel coefficients change for every link; no
1142
+ additional random numbers are drawn. Affected earlier versions: the versions for
1143
+ Sionna 0.19 and 1.x, and 2.0.0a1.
1144
+ - Correlation of the large scale parameters: the large scale parameters (delay
1145
+ spread, angular spreads, Ricean K-factor, shadow fading) are now generated as TR
1146
+ 38.901 V16.1.0, clause 7.5, step 4, prescribes, which TR 38.811 V15.4.0, clause
1147
+ 6.7.2, uses with its own tables: with the procedure of clause 3.3.1 of WINNER II
1148
+ D1.1.2 (TR 38.901 reference [14]), which first correlates each parameter spatially
1149
+ across the UTs, with the correlation exp(-d/d_corr) of its correlation distance,
1150
+ and then applies the square root of the cross-correlation matrix of the parameters
1151
+ to each link, with the Cholesky decomposition in the order [SF, K, DS, ASD, ASA,
1152
+ ZSD, ZSA] that step 4 specifies. Before, the cross-correlation was applied first and
1153
+ the spatial correlation second, so the order of the Cholesky decomposition had no
1154
+ effect, and the parameters of one link did not have the cross-correlations of the
1155
+ tables when other UTs of the same link state were within the correlation distances
1156
+ (12 m to 50 m in the TR 38.811 tables of the three scenarios). This concerns all
1157
+ scenarios, link states, bands and directions. For example, for two UTs 20 m apart
1158
+ (dense urban, LOS, S band, downlink, 30°, 20,000 drops, computed), the correlation
1159
+ between the logarithms of the zenith spreads of arrival of the two UTs is now 0.507
1160
+ instead of 0.265, of the azimuth spreads of arrival 0.440 instead of 0.268 and of the
1161
+ delay spreads 0.473 instead of 0.512, against 0.505, 0.435 and 0.473 computed from the
1162
+ tables; the shadow fading and the K-factor keep their correlations exp(-d/d_corr),
1163
+ 0.582 and 0.189 (measured 0.587 and 0.191). In the same setting, for the second of two
1164
+ UTs 5 m apart, the cross-correlation between its zenith spread of arrival and its
1165
+ shadow fading was -0.776 instead of -0.800 of the table (the first had -0.805). For
1166
+ UTs that are far apart compared with the correlation distances the statistics do not
1167
+ change. The realizations of all large scale parameters change for every link, and with
1168
+ them the cluster delays and powers; the path losses and the link states do not change.
1169
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1170
+ - Satellites from 160 km to below 600 km: the Doppler shift due to the motion of the
1171
+ satellite now applies to every satellite, that is to every platform from 160 km to
1172
+ 35 786 km, as the zero departure spreads at the satellite (NOTE 8 of TR 38.811
1173
+ V15.4.0, Tables 6.7.2-1a to 6.7.2-8b) did before; it applied from 600 km on. The
1174
+ Faraday rotation of clause 6.8.2 still applies from 600 km on, as in the earlier
1175
+ versions: the clause gives it "In case of propagation for spaceborne BS above the
1176
+ ionosphere", and 600 km is the lowest satellite altitude of TR 38.811 (Table 4.5-1,
1177
+ LEO; Table 5.1-1, non-GEO down to 600 km), while a lower satellite flies within the F
1178
+ region of the ionosphere, below much of its electron content. This concerns satellites
1179
+ from 160 km to below 600 km, in all scenarios, link states, bands and directions:
1180
+ their channel coefficients now contain the phase drift of the satellite Doppler shift.
1181
+ TR 38.811, clause 3.1, places LEO satellites from 500 km on; the models accept
1182
+ satellites from 160 km, very low orbits included. Results at 600 km and above and of
1183
+ aerial platforms (8 km to 50 km) do not change. Affected earlier versions: the
1184
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1185
+ - Satellite Doppler shift: the Doppler shift due to the motion of the satellite is now
1186
+ f_c (v_sat/c) (R/(R+h)) cos(α) cos(2πU), with the speed v_sat of a circular orbit at
1187
+ the height h, the radius R of the Earth, the elevation angle α and U uniform per batch
1188
+ example (the direction of the orbit relative to the UTs, as before); its largest value
1189
+ is the shift of TR 38.811 V15.4.0, clauses 6.7.1 and 6.9.2, f_d = (v_sat/c) (R/(R+h))
1190
+ cos(α) f_c. The factor R/(R+h) was missing, so the shift was (R+h)/R times too large:
1191
+ by 9.4 % at 600 km, 18.8 % at 1200 km and 157 % at 10 000 km. At 10° the largest shift
1192
+ was 24.84 ppm of the carrier frequency at 600 km and 23.84 ppm at 1200 km and is now
1193
+ 22.70 ppm and 20.06 ppm (TR 38.821 V16.2.0, Table 6.1.1.1-8, gives 24 ppm and 20 ppm
1194
+ as the maximum Doppler shifts for elevation angles of at least 10°). A geostationary
1195
+ satellite (35 786 km) now induces no Doppler shift, as TR 38.811, clause 5.3.2.3,
1196
+ states ("the Geostationary satellite is fixed and therefore no Doppler shift is
1197
+ induced except that due to possible UE motion"); it had up to 10.1 ppm, 202 kHz at
1198
+ 20 GHz. As in clause 5.3.4.3, the rotation of the Earth is neglected. This concerns
1199
+ the phase of the channel coefficients over time on every satellite link with the
1200
+ Doppler shift enabled, in all scenarios, link states, bands and directions; powers,
1201
+ delays and angles do not change, and of the reference outputs of the test suite only
1202
+ the time correlations changed. Affected earlier versions: the versions for Sionna 0.19
1203
+ and 1.x, and 2.0.0a1.
1204
+ - Departure spreads at the satellite in the uplink: NOTE 8 of TR 38.811 V15.4.0, Tables
1205
+ 6.7.2-1a to 6.7.2-8b ("For satellite (e.g.GEO/LEO), the departure angle spreads are
1206
+ zeros, i.e. µlgASD and µlgZSD are –∞, and corresponding standard deviations are
1207
+ zeros"), now applies to satellites in both directions, with zero cross-correlations of
1208
+ ASD and ZSD with the other large scale parameters, as the downlink parameter files had
1209
+ it. The satellite is the departure end of the rays as the generator draws them in both
1210
+ directions, so the ASD and ZSD of the uplink are spreads at the satellite as well.
1211
+ Before, only the downlink parameter files applied the note: in the uplink the large
1212
+ scale parameters ASD and ZSD took the values of the tables (medians of up to 0.78° and
1213
+ 0.09°), the rays of each cluster kept the intra-cluster zenith spread (3/8)·10^µlgZSD
1214
+ of TR 38.901 V16.1.0, eq. (7.5-20), at the satellite (rays up to 0.07° from their
1215
+ cluster), and the cross-correlations with ASD and ZSD entered the generation of the
1216
+ other large scale parameters, whose realizations therefore change (their distribution
1217
+ per link does not). The parameter files now hold the tables as printed, and the models
1218
+ apply the note for satellites (160 km to 35 786 km). Aerial platforms (8 km to 50 km)
1219
+ now take the spreads of the tables in both directions; in the downlink the parameter
1220
+ files had given them zero spreads. This concerns the uplink of satellites and both
1221
+ directions of aerial platforms, in all scenarios, link states and bands. Affected
1222
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1223
+ - Cluster azimuth spread at the satellite: every ray now leaves a satellite in the
1224
+ azimuth of its cluster, that is in the LOS direction. TR 38.811 V15.4.0, NOTE 8 of
1225
+ Tables 6.7.2-1a to 6.7.2-8b, makes the departure angle spreads of a satellite zero,
1226
+ and clause 6.9.1 states for the link-level models derived from this model that "the
1227
+ azimuth and elevation angular spreads of departure, ASD and ZSD, can be considered
1228
+ zero, and all cluster AOD and ZOD angles the same". Before, the rays of the urban
1229
+ scenario left the satellite at the AOD of their cluster plus c_ASD α_m (TR 38.901
1230
+ V16.1.0, eq. (7.5-13), applied to the departure), with the cluster ASD c_ASD of the
1231
+ urban Tables 6.7.2-3a to 6.7.2-4b (0.08° to 6.63°) and the offsets α_m of Table 7.5-3:
1232
+ up to 14.3° in azimuth at 90°, and up to 0.74° from the LOS direction (urban NLOS, S
1233
+ band, 70°; computed). Seen from a satellite at 600 km, a scatterer 1 km from the UT is
1234
+ at most 0.03° (10°) to 0.1° (90°) off the direction of the UT. The dense urban and
1235
+ sub-urban tables print c_ASD = 0, so only urban links of satellites (160 km to
1236
+ 35 786 km) are affected, in both directions, link states and bands; aerial platforms
1237
+ keep the c_ASD of the tables. In the reference outputs of the test suite (600 km), the
1238
+ power of single urban links changed by up to 0.79 dB and the power per antenna pair by
1239
+ up to 0.07 times the largest of its configuration (NLOS, 90°); the total power of a
1240
+ configuration of six links changed by less than 0.1 dB. Affected earlier versions: the
1241
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1242
+ - Default atmosphere: the defaults of `temperature` and `atmospheric_pressure` are now
1243
+ the mean annual global reference atmosphere of TR 38.811 V15.4.0, clause 6.6.4 ("For
1244
+ all UEs, [...] T = 288.15 K, p = 1013.25 hPa, ρ = 7.5 g/m³"). The defaults were 273 K
1245
+ and 1020 hPa, and the formulas of ITU-R P.676 and P.618-13 that took the temperature
1246
+ in degrees Celsius used T - 273 instead of T - 273.15. The gas loss of this version,
1247
+ by ITU-R P.676-10, takes t = T - 273.15 (see "Gas attenuation"), and the scintillation
1248
+ loss no longer uses the temperature (see "Tropospheric scintillation"). With the gas
1249
+ formulas of the earlier versions, the defaults give a lower gas loss, for example
1250
+ 0.2056 dB instead of 0.2405 dB at 2.2 GHz and 10°, 1.4779 dB instead of 1.5711 dB at
1251
+ 20 GHz and 10°, 1.4019 dB instead of 1.5941 dB at 30 GHz and 10°, and 0.2434 dB
1252
+ instead of 0.2768 dB at 30 GHz and 90° (urban, 600 km, computed). Where the
1253
+ temperature was set, the conversion alone changes the gas loss of these formulas at
1254
+ 288.15 K by at most 0.0031 dB in the bands that the models accept (at 40 GHz and 10°,
1255
+ 1013.25 hPa, 7.5 g/m³). This concerns the gas loss in all scenarios, link states,
1256
+ bands and directions; the scintillation loss no longer depends on the temperature.
1257
+ Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1258
+ - Gas attenuation: the gas loss now follows Annex 2 of ITU-R P.676-10 (09/2013) as
1259
+ printed: the specific attenuation of dry air of eqs. (22a) to (22u), every branch from
1260
+ 1 GHz to 350 GHz, that of water vapour of eqs. (23a) to (23d), the equivalent heights
1261
+ of eqs. (25a) to (25e), (26a) and (26b), and the slant path of eqs. (27) and (28)
1262
+ with TR 38.811 V15.4.0, eq. (6.6-8). The atmospheric pressure is the dry air pressure
1263
+ p, as clause 6.6.4 calls its 1013.25 hPa; Annex 2 takes the total pressure p + e, with
1264
+ the water vapour partial pressure e = ρT/216.7 (Annex 1, eq. (4)), and the temperature
1265
+ t = T - 273.15 in degrees Celsius. Clause 6.6.4 takes "The method of Annex 2 in ITU-R
1266
+ P.676" without a version, and clause 2 makes the latest version apply to such a
1267
+ reference ("For a non-specific reference, the latest version applies."). P.676-10 is
1268
+ the last revision whose Annex 2 gives the specific attenuations and the equivalent
1269
+ heights in closed form, the form of the earlier versions; with the reference
1270
+ atmosphere of clause 6.6.4 the revision in force, P.676-13 (08/2022), gives at 10° in
1271
+ the bands that the models accept between 0.2738 dB more (22.41 GHz; 0.2663 dB more at
1272
+ 22.74 GHz, outside the 0.5 GHz around the water vapour line at 22.235 GHz that clause
1273
+ 6.6.4 excludes from the method) and 0.0676 dB less (40 GHz) (computed). Before, the
1274
+ loss used curve fits in the form of Annex 2 of P.676-6 to P.676-10 up to 54 GHz, with
1275
+ two coefficients of the water vapour equivalent height that no revision prints (-8.1
1276
+ and 1.5, where P.676-6 to P.676-11 print -8.6 and 1.58), and followed no revision
1277
+ above 54 GHz: from 54 GHz to 66 GHz it used expressions of P.676-5, one of them with
1278
+ the factor of another equation, and from 66 GHz to 120 GHz the dry-air term of eq.
1279
+ (22e) lacked the factor f² rp² 10^-3 and had 1.15 ξ5 in the exponent of (f - 66)
1280
+ instead of added to its power. The second made the zenith loss of dry air jump from
1281
+ 10.8 dB at 65.9 GHz to 985 dB at 66.1 GHz, and together they made the attenuation
1282
+ 1.6 % to 7.4 % of the printed value from 69 GHz to 120 GHz (dry air, zenith, 288.15 K,
1283
+ 1013.25 hPa, computed with the earlier formulas). Above 120 GHz dry air did not
1284
+ attenuate, the limit of eq. (25e) on the equivalent height of dry air was missing, and
1285
+ the atmospheric pressure was taken as the total pressure. With the reference
1286
+ atmosphere of clause 6.6.4 and at 10°, the loss changes against the earlier formulas
1287
+ with t = T - 273.15 by +0.0040 dB at 2 GHz, +0.0041 dB at 2.2 GHz, +0.0068 dB at
1288
+ 20 GHz (1.4846 dB instead of 1.4779 dB) and +0.0186 dB at 30 GHz (1.4205 dB instead of
1289
+ 1.4019 dB); in the bands that the models accept (1.9 GHz to 4 GHz and 19 GHz to
1290
+ 40 GHz) the change lies between -0.0112 dB (22.29 GHz; -0.0089 dB at 22.74 GHz,
1291
+ outside the excluded range) and +0.0384 dB (40 GHz), relative between -0.37 %
1292
+ (22.25 GHz) and +2.04 % (3.75 GHz), mostly from the dry reading of the pressure
1293
+ (computed). In dB the change scales with 1/sin of the elevation angle. This concerns
1294
+ all scenarios, link states, bands and directions. `utils.compute_pathloss_gas` raises
1295
+ `ValueError` for carrier frequencies outside 1 GHz to 350 GHz, the range of Annex 2;
1296
+ the models accept only the S and Ka bands. As clause 6.6.4 states, the method does not
1297
+ apply to UE altitudes above 10 km and to frequencies within 0.5 GHz of the centres of
1298
+ resonance lines; the models do not check either. Affected earlier versions: the
1299
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1300
+ - Tropospheric scintillation: in the Ka band the scintillation loss is now the value of
1301
+ TR 38.811 V15.4.0, Table 6.6.6.2.1-1, at the reference elevation angle nearest to the
1302
+ elevation angle: 1.08 dB at 10°, 0.48 dB at 20°, 0.30 dB at 30°, 0.22 dB at 40°,
1303
+ 0.17 dB at 50°, 0.13 dB at 60° and 0.12 dB from 70° to 90°, as clause 6.6.6.2.1
1304
+ specifies ("As baseline for system-level simulations above 6 GHz, the fading due to
1305
+ scintillation PL_S is equal to the tropospheric attenuation level at 99% of the time
1306
+ derived from Figure 6.6.6.2.1-1 and summarized in Table 6.6.6.2.1-1"). The table is
1307
+ given for 20 GHz in Toulouse; it is used at every carrier frequency from 6 GHz on, as
1308
+ TR 38.821 V16.2.0 uses it at 20 GHz and 30 GHz (Tables 6.1.3.2-1 and 6.1.3.3-1). An
1309
+ elevation angle midway between two reference angles takes the higher one. Before, the
1310
+ loss was the fade depth of ITU-R P.618-13, section 2.4.1, exceeded 0.01 % of the time,
1311
+ where the table gives the depth exceeded 1 % of the time; by that method the depth
1312
+ exceeded 0.01 % of the time is 2.40 times the depth exceeded 1 %. It was computed at
1313
+ the elevation angle itself, from the temperature, the relative humidity and the
1314
+ diameter and efficiency of the Earth-stationed antenna. That computation also
1315
+ evaluated the effective path length of eq. (41) of P.618-13 as
1316
+ 2h_L/sqrt(sin²θ + 2.35·10^-4 + sin θ) instead of
1317
+ 2h_L/(sqrt(sin²θ + 2.35·10^-4) + sin θ), which changed the loss by -1.85 % at 10° and
1318
+ by +6.68 % at 90° (20 GHz, the default antenna, computed). With the defaults of the
1319
+ earlier versions the loss was 1.5507 dB, 0.4090 dB and 0.1660 dB at 20 GHz and 10°,
1320
+ 30° and 90°, and 1.8943 dB at 30 GHz and 10° (urban, 600 km, computed); it is now
1321
+ 1.08 dB, 0.30 dB, 0.12 dB and 1.08 dB. This concerns the scintillation loss of every
1322
+ link in the Ka band, in all scenarios, link states and directions; it no longer
1323
+ depends on the atmospheric parameters (see "Removed"). Affected earlier versions: the
1324
+ versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1325
+ - Ionospheric scintillation: in the S band the scintillation loss is now the ionospheric
1326
+ scintillation A_IS of TR 38.811 V15.4.0, clause 6.6.6.1.4, only for UTs within 20° of
1327
+ the magnetic equator, and 0 dB at higher latitudes, as the clause specifies ("For
1328
+ system-level simulations below 6 GHz, PL_S is equal to A_IS from Equation (6.6-13) for
1329
+ latitudes of maximum ±20°. For latitudes between ±20° and ±60° of latitude, PL_S = 0.
1330
+ [...] the choice of PL_S = 0 is also applied for latitude above ±60°."). The latitude
1331
+ is the `latitude` of `set_topology`, the latitude of the UTs relative to the magnetic
1332
+ equator, around which the clause places the region of the model; its default of 47°
1333
+ gives 0 dB, as the calibration of TR 38.821 V16.2.0 assumes (Table 6.1.1.1-5, NOTE 2:
1334
+ "the ionospheric scintillation loss shall be considered equal to zero (i.e., the UEs
1335
+ are located between 20 and 60 degrees of latitude)"). Before,
1336
+ A_IS = 1.1 (f/4 GHz)^-1.5/√2 dB applied at every latitude, and `latitude` had no
1337
+ effect. This concerns the scintillation loss of every link in the S band, in all
1338
+ scenarios, link states and directions: with the default latitude it is now 0 dB
1339
+ instead of 2.2 dB at 2 GHz and 1.9069 dB at 2.2 GHz; within 20° of the magnetic
1340
+ equator it is unchanged. Affected earlier versions: the versions for Sionna 0.19 and
1341
+ 1.x, and 2.0.0a1.
1342
+ - Shadow fading applied once: the shadow fading now reaches the channel once, as the
1343
+ large scale parameter SF of TR 38.901 V16.1.0, clause 7.5, step 4, which step 12
1344
+ applies to the channel coefficients. TR 38.811 V15.4.0, clause 6.6.2, eq. (6.6-4),
1345
+ writes one shadow fading term SF ~ N(0, σ_SF²) into the basic path loss, with σ_SF of
1346
+ Tables 6.6.2-1 to 6.6.2-3, and Tables 6.7.2-1a to 6.7.2-8b give the cross-correlations
1347
+ of this shadow fading with the other large scale parameters and its correlation
1348
+ distance, which only the large scale parameter carries. Before, the basic path loss
1349
+ contained a second shadow fading draw per link, independent of the first and without
1350
+ these correlations, so the shadow fading applied to the channel had about √2 times
1351
+ σ_SF and weaker correlations, and with `enable_shadow_fading=False` the draw in the
1352
+ basic path loss remained. In the urban scenario (S band, downlink, 50°, 600 km, 4000
1353
+ links with one UT each, LOS and NLOS forced, computed), the standard deviation of the
1354
+ applied shadow fading is now 4.05 dB (LOS) and 6.08 dB (NLOS) instead of 5.60 dB and
1355
+ 8.57 dB (Table 6.6.2-2: 4 dB and 6 dB); its correlation with lg DS is now -0.411 and
1356
+ -0.214 instead of -0.273 and -0.126 (Tables 6.7.2-3a and 6.7.2-4a: -0.4 and -0.21),
1357
+ and with lg ZSA -0.776 and -0.356 instead of -0.528 and -0.271 (the tables give -0.8
1358
+ and -0.38; with the limit of ZSA to 52° of step 4 the expected values are -0.771 and
1359
+ -0.348); with `enable_shadow_fading=False` it is now 0 dB instead of a standard
1360
+ deviation of 4.07 dB and 6.09 dB. Because two draws per link fewer are made, the
1361
+ realizations of the large scale parameters, and with them of the cluster delays and
1362
+ powers, change for every link; their statistics do not change, and neither do the link
1363
+ states. This concerns all scenarios, link states, bands and directions. Affected
1364
+ earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1365
+ - Elevation angles midway between two reference angles: an elevation angle of 25°, 45°,
1366
+ 65° or 85° now takes the values of the higher reference angle, 30°, 50°, 70° or 90°,
1367
+ in every table: the LOS probability, the shadow fading and the clutter loss, the large
1368
+ scale parameters, the number of clusters and the cluster parameters. TR 38.811
1369
+ V15.4.0, clauses 6.6.1 and 6.6.2, takes the reference angle nearest to the elevation
1370
+ angle and gives no rule for an angle midway between two; the models now take the
1371
+ higher one in every lookup. Before, Python's rounding of ties to the even number took
1372
+ the lower angle, 20°, 40°, 60° or 80°, at these four angles (the tropospheric
1373
+ scintillation table of this version already took the higher one); 15°, 35°, 55° and
1374
+ 75° took the higher angle and still do. For example, at 25° the LOS probability of the
1375
+ urban scenario is now 0.493 instead of 0.386, and the clutter loss of the urban NLOS
1376
+ links in the S band 29.0 dB instead of 30.9 dB (the values of Tables 6.6.1-1 and
1377
+ 6.6.2-2 at 30° and 20°). This concerns simulations at exactly 25°, 45°, 65° or 85°, in
1378
+ all scenarios, link states, bands and directions; other elevation angles do not
1379
+ change. Affected earlier versions: the versions for Sionna 0.19 and 1.x, and 2.0.0a1.
1380
+ - UTs at the same location: two or more UTs at the same location in the horizontal plane
1381
+ and in the same link state, in one batch example, made the spatial correlation of the
1382
+ large scale parameters (delay spread, angular spreads, Ricean K-factor, shadow fading)
1383
+ of that batch example singular, because the correlation exp(-d/d_corr) of TR 38.901
1384
+ V16.1.0, clause 7.5, step 4, which TR 38.811 V15.4.0, clause 6.7.2, uses, is 1 at the
1385
+ distance d = 0. Its Cholesky factorization then stopped without an error at the second
1386
+ of these UTs and left unfactored entries in the rows of the UTs after them, so the UTs
1387
+ listed after them in that batch example got large scale parameters with a log-domain
1388
+ variance above the specified one: 1 + 2c^2 times it in the case measured, a UT after
1389
+ two co-located UTs with the correlation c to them; for the shadow fading of a UT 7.6 m
1390
+ away (dense urban, LOS, S band, downlink, 30°, double precision, computed) 2.33 times,
1391
+ a standard deviation 1.53 times the specified one. Where rounding left a pivot just
1392
+ above 0 instead, mostly in single precision, the factorization continued past these
1393
+ UTs or stopped at a later one. The gradients of the large scale parameters of that
1394
+ batch example with respect to the UT locations were NaN. Now UTs at one location in
1395
+ one state share their large scale parameters, as the correlation exp(-d/d_corr) = 1 at
1396
+ d = 0 requires and as in the procedure of clause 3.3.1 of WINNER II D1.1.2, which step
1397
+ 4 uses, where such UTs read the same grid node; every UT has the specified
1398
+ distribution, and the gradients are finite. This concerns topologies with such UTs,
1399
+ whatever their heights (the distance is measured in the horizontal plane), in all
1400
+ scenarios, link states, bands and directions; random drops practically never place
1401
+ two UTs at one location. Topologies without them are unchanged bit for bit. Affected
1402
+ earlier versions: 2.0.0a1. The versions for Sionna 0.19 and 1.x build the same
1403
+ singular correlation for such UTs. The version for Sionna 1.x factors it with the
1404
+ Cholesky decomposition of TensorFlow, which returns NaN for it without an error
1405
+ (computed with TensorFlow 2.18.1 and 2.19.0 on the CPU), so that every UT of such a
1406
+ batch example got NaN large scale parameters, also with only two UTs at one location;
1407
+ the version for Sionna 0.19 takes a symmetric matrix square root, whose result for
1408
+ such UTs depends on TensorFlow.
1409
+
1410
+ ### Added
1411
+
1412
+ - `Rays` takes the optional argument `strongest_cluster_indices`, the indices of the two
1413
+ strongest clusters of each link, whose rays are coupled within the sub-clusters and
1414
+ which the channel coefficients split into sub-clusters; `RaysGenerator` sets it. Code
1415
+ that constructs `Rays` directly can omit it; the two clusters with the largest powers
1416
+ are then split, as before.
1417
+
1418
+ ### Changed
1419
+
1420
+ - `Topology` takes the new argument `los_phase`, the LOS propagation phase per link,
1421
+ which `ChannelCoefficientsGenerator` uses for the LOS ray; the scenarios provide it
1422
+ as `los_phase`, and the channel models pass it. Code that constructs a `Topology`
1423
+ directly has to pass it.
1424
+ - `set_topology` now checks the platform and raises `ValueError` unless `bs_loc` holds
1425
+ one BS at the same height in every batch example, either a satellite from 160 km to
1426
+ 35 786 km or an aerial platform from 8 km to 50 km. TR 38.811 V15.4.0, clause 3.1,
1427
+ places aerial platforms at 8 km to 50 km and LEO satellites from 500 km on; the models
1428
+ accept satellites from 160 km, very low orbits included. Table 4.5-1 gives typical
1429
+ altitudes (LEO 600 km to 1500 km, MEO 7000 km to 20 000 km, GEO 35 786 km),
1430
+ Table 5.1-1 the reference deployments (GEO, non-GEO down to 600 km, UAS 8 km to
1431
+ 50 km). The models simulate one platform with one nominal elevation angle per call.
1432
+ Before, `set_topology` accepted every input: with a second BS the channel call failed,
1433
+ with heights that differed across the batch the 3D distance, the path loss and the
1434
+ switches of the satellite took the height of the first batch example for every
1435
+ example, and any height was used as given. The versions for Sionna 0.19 and 1.x and
1436
+ 2.0.0a1 use the height of the first batch example in the same way.
1437
+ - `utils.compute_pathloss_gas` raises `ValueError` for carrier frequencies outside 1 GHz
1438
+ to 350 GHz, the range of Annex 2 of ITU-R P.676-10 (see "Gas attenuation").
1439
+ - `set_topology` raises `ValueError` for a `latitude` outside -90° to 90°, and a
1440
+ `latitude` passed without new topology tensors now recomputes the scintillation loss.
1441
+ `latitude` is documented as the latitude of the UTs relative to the magnetic equator
1442
+ (see "Ionospheric scintillation"); before, any value was accepted, and it had no
1443
+ effect.
1444
+ - `basic_pathloss` of the scenarios is now the free space path loss plus, for NLOS
1445
+ links, the clutter loss, without a shadow fading term; the shadow fading is the large
1446
+ scale parameter SF, which step 12 applies (see "Shadow fading applied once"). Before,
1447
+ `basic_pathloss` contained a shadow fading draw of its own, as in the versions for
1448
+ Sionna 0.19 and 1.x and 2.0.0a1.
1449
+ - `set_topology` raises `ValueError` if a UT is indoor (`in_state` `True`), before
1450
+ anything is stored; the models accept outdoor UTs only, for satellites and aerial
1451
+ platforms. TR 38.811 V15.4.0 considers only outdoor UTs for satellites (clause 6.1.2:
1452
+ "Only outdoor conditions are considered for satellite operations"; Table 5.1-1: "100%
1453
+ Outdoors" for the satellite deployments) and indoor UTs as well for aerial platforms
1454
+ (clause 6.1.2: "additional indoor conditions are also considered for HAPS";
1455
+ Table 5.1-1: "Indoor and Outdoor" for UAS including HAPS), but the models have neither
1456
+ the building entry loss of clause 6.6.3 nor clusters for indoor UTs. Before, indoor
1457
+ UTs were accepted, but all their clusters were masked, so their channel coefficients
1458
+ were NaN (dense urban, 2 GHz, downlink, 30°, 600 km, LOS and NLOS forced, computed
1459
+ with the code before this change: every coefficient of an indoor UT), and no building
1460
+ entry loss applied. The indoor probability of the topology generators was already
1461
+ forced to 0; its documentation now says that the argument is ignored. Affected earlier
1462
+ versions: 2.0.0a1, and the versions for Sionna 0.19 and 1.x, which have the same code
1463
+ for indoor UTs.
1464
+
1465
+ ### Removed
1466
+
1467
+ - `utils.compute_stallite_doppler`, which nothing used: it returned the carrier
1468
+ frequency plus the Doppler shift of TR 38.811 V15.4.0, clauses 6.7.1 and 6.9.2, which
1469
+ the channel now applies (see "Changes that affect simulation results").
1470
+ - `TDL` and `CDL`, with their modules `openntn.tdl` and `openntn.cdl`: placeholders that
1471
+ raised `NotImplementedError` when constructed (in the versions for Sionna 0.19 and 1.x
1472
+ they were copies of the TR 38.901 models marked as not working). The link-level models
1473
+ NTN-TDL and NTN-CDL of TR 38.811 V15.4.0, clause 6.9, are not implemented in this
1474
+ version; their parameter files stay in `openntn/models`, and Sionna's `TDL` and `CDL`
1475
+ of TR 38.901 are unchanged.
1476
+ - The rain and cloud attenuation of TR 38.811 V15.4.0, clause 6.6.5: the scenario
1477
+ property `additional_pathloss` (it raised `AttributeError`, because no model computed
1478
+ the attenuation) and `utils.compute_pathloss_additional`, which failed when called.
1479
+ The models follow the baseline of clause 6.6.5, "For system-level simulations, the
1480
+ baseline is to consider clear sky conditions only", as before.
1481
+ - The parameters `lwc` and `rain_rate` of `set_topology` and the scenario properties of
1482
+ the same names: only the rain and cloud attenuation read them, which no model applied,
1483
+ so they had no effect.
1484
+ - The parameters `relative_humidity`, `diameter_earth_antenna` and `antenna_efficiency`
1485
+ of `set_topology` and the scenario properties of the same names: only the computation
1486
+ of the tropospheric scintillation by ITU-R P.618-13 read them, and the scintillation
1487
+ loss now follows TR 38.811 V15.4.0, Table 6.6.6.2.1-1 (see "Tropospheric
1488
+ scintillation"), so they had no effect. A call that passes one of the five removed
1489
+ parameters raises `TypeError`; the scenario of 2.0.0a1 and of the versions for Sionna
1490
+ 0.19 and 1.x accepted them.
1491
+ - `utils.gen_single_sector_topology_interferers`, which failed in every scenario. The
1492
+ models simulate one satellite or aerial platform per call (see "Changed");
1493
+ `utils.gen_single_sector_topology` generates the topology of one sector.
1494
+
1495
+ ### Fixed
1496
+
1497
+ - `set_topology` no longer modifies the tensors passed to it. The scenario kept the
1498
+ topology tensors (UT and BS locations, orientations, UT velocities, indoor state) as
1499
+ its own storage when they already had the model's data type and device, and a later
1500
+ call wrote its values into them, so a tensor passed in an earlier call changed. The
1501
+ scenario now keeps copies, through which gradients with respect to the tensors
1502
+ passed still flow. The outputs for given inputs are unchanged; results change only
1503
+ for scripts that used such a tensor again after a later `set_topology` call.
1504
+ Affected earlier version: 2.0.0a1; the versions for Sionna 0.19 and 1.x are not
1505
+ affected.
1506
+ - Repeated `set_topology` calls with topology tensors that require gradients: every call
1507
+ now works, and the quantities of the scenario, for example the 2D distances and the
1508
+ LOS angles, stay differentiable with respect to the tensors of that call. Before, the
1509
+ scenario wrote the values of a later call into the tensors it had stored in the first
1510
+ call, which carried the graph of that call, so the backward pass of the second
1511
+ differentiable call failed with "Trying to backward through the graph a second time",
1512
+ and after a differentiable call the stored tensors kept requiring gradients in calls
1513
+ without gradients. Calls without gradients still write in place, so that the stored
1514
+ tensors keep their addresses. The path coefficients and delays of the channel models
1515
+ are detached, as before and as in Sionna; their documentation now says so. Affected
1516
+ earlier version: 2.0.0a1; the versions for Sionna 0.19 and 1.x are not affected.
1517
+ - Gradients with respect to the UT locations of the scenario property
1518
+ `matrix_ut_distance_2d`, the distances between the UTs in the horizontal plane, and of
1519
+ the large scale parameters, whose spatial correlation is computed from these
1520
+ distances, were NaN in the x and y coordinate of every UT: the distance of a UT to
1521
+ itself, which is always 0, was taken as a square root, whose derivative at 0 is
1522
+ infinite. They are now finite: the distance of a UT to itself has the derivative 0,
1523
+ and the distances are unchanged bit for bit. For example, with the dense urban
1524
+ scenario at 2.2 GHz, downlink, 30°, 600 km and 2 batch examples with 3 UTs each, the
1525
+ gradient of the sum of the distances was NaN in 12 of the 18 entries of the UT
1526
+ locations, and so were the gradients of the delay spread, the angular spreads, the
1527
+ Ricean K-factor and the shadow fading. This concerns users who differentiate with
1528
+ respect to the UT locations through these quantities; the path coefficients and delays
1529
+ are detached and not affected, and no simulation result changes. Affected earlier
1530
+ versions: 2.0.0a1, and the versions for Sionna 0.19 and 1.x, which compute the
1531
+ distances between the UTs in the same way.
1532
+ - The test suite now checks the data files of the NTN-CDL and NTN-TDL models in
1533
+ `openntn/models` against TR 38.811 V15.4.0, Tables 6.9.1-1 to 6.9.1-4 and 6.9.2-1 to
1534
+ 6.9.2-4, value by value; it called them TR 38.901 profiles without TR 38.811 values.
1535
+ The files equal the tables; no model of the package reads them.
1536
+ - Documentation of the scenario properties: `doppler_enabled` had the description of the
1537
+ antenna efficiency; it now states that the flag switches the Doppler shift due to the
1538
+ motion of the satellite, while the Doppler shift due to the motion of the UTs is
1539
+ always applied. `gas_pathloss`, `scintillation_pathloss` and `entry_pathloss` called
1540
+ themselves the basic path loss of TR 38.901, clause 7.4.1; they now name the gas
1541
+ attenuation (TR 38.811 V15.4.0, clause 6.6.4, eq. (6.6-8)), the scintillation loss
1542
+ (clause 6.6.6) and the building entry loss (clause 6.6.3). `free_space_pathloss` now
1543
+ cites eq. (6.6-2) of TR 38.811 instead of TR 38.901, clause 7.4.1. No result changes.
1544
+ Affected earlier versions (the same texts): the versions for Sionna 0.19 and 1.x, and
1545
+ 2.0.0a1.
1546
+
1547
+ ## [2.0.0a1] - 2026-10-07
1548
+
1549
+ First pre-release of OpenNTN for Sionna 2.x, which is built on PyTorch.
1550
+
1551
+ - Import name `openntn` (`import openntn`), instead of the module `tr38811` that the
1552
+ installation scripts of the earlier versions linked into Sionna.
1553
+ - Installation with pip from PyPI (`pip install openntn`) instead of `install.sh`.
1554
+ - Sionna 2.x is required (`sionna>=2.0.1,<3.0`), with Python 3.11 or later.
1555
+ - The licence is declared as `MIT AND Apache-2.0`: files derived from Sionna are under
1556
+ the Apache License 2.0, all other files under the MIT License. Both licence texts are
1557
+ included.
1558
+ - The unused model data files were removed.