Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce NTIA fix on Isolated ridge (optional. OFF for now) #895

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/harness/reference_models/propagation/ehata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ The modification relates mostly to:
between 3km and 15km (due to an issue in original formulas), and to use
terrain strictly included within the 3km and 15km range.

A E-Hata correction about isolated ridge correction is also provided with a
second argument, by specifying: `SetWinnfForumExtensions(True, True)`.
By default this correction is OFF (`=False`).

In addition all the code has been ported to use double instead of float, using
a global #define in `ehata.h`. This allows much more consistent results across existing
or future implementations.
Expand Down
4 changes: 2 additions & 2 deletions src/harness/reference_models/propagation/ehata/ehata.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
' python setup.py build_ext -i')


def SetWinnForumExtensions(on):
def SetWinnForumExtensions(on, isolated_ridge_corr=False):
"""Activates/Deactivate the Winnforum extensions.
By default they are ON.
"""
ehata_its.SetWinnForumExtensions(on)
ehata_its.SetWinnForumExtensions(on, isolated_ridge_corr)

def ExtendedHata(its_elev, freq_mhz, height_tx, height_rx, region_code):
"""Computes the E-Hata propagation path loss.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@ static PyObject* MedianBasicPropLoss(PyObject* self, PyObject* args) {
static PyObject* SetWinnForumExtensions(PyObject* self, PyObject* args) {

PyObject *val = NULL;
if (!PyArg_ParseTuple(args, "O:ehata_its_SetWinnForumExtensions",
&val)) {
PyObject *isolated_ridge_corr = NULL;
if (!PyArg_ParseTuple(args, "OO:ehata_its_SetWinnForumExtensions",
&val, &isolated_ridge_corr)) {
return NULL;
}
bool on = PyObject_IsTrue(val);
bool do_isolated_ridge_corr = PyObject_IsTrue(isolated_ridge_corr);

SetWinnForumExtensions(on);
SetWinnForumExtensions(on, do_isolated_ridge_corr);

Py_RETURN_NONE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

// Activation of the WinnForum modifications
bool _WinnForum_Extensions = true; // on by default
void SetWinnForumExtensions(bool on)
bool _do_isolated_ridge_v2_corr = false; // off by default
void SetWinnForumExtensions(bool on, bool isolated_ridge_v2_corr)
{
_WinnForum_Extensions = on;
_do_isolated_ridge_v2_corr = isolated_ridge_v2_corr;
}

// Definition of the profile distance calculation routine - see ehata.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,59 @@
* d1_hzn__km : horizon distance, in kilometers
* d2_hzn__km : horizon distance, in kilometers
* h_edge__meter : intermediate value
* do_v2_corr: apply correction v3.2. See https://github.com/NTIA/ehata/pull/13
* Return:
* [double] : correction factor
*/
double IsolatedRidgeCorrectionFactor(double d1_hzn__km, double d2_hzn__km, double h_edge__meter)
double IsolatedRidgeCorrectionFactor(double d1_hzn__km, double d2_hzn__km,
double h_edge__meter)
{
double d_1__km[3] = { 15.0, 30.0, 60.0 };
double d_2__km[9] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };

// points from Figure 31, Okumura
// points from Figure 31, Okumura, at corresponding d2 distances
double curve_data[3][9] =
{ { 4.0, -13.0, -17.5, -17.5, -15.0, -12.5, -10.0, -8.0, -6.0 }, // C curve : d1 <= 15 km
{ 12.0, -8.5, -13.0, -12.0, -10.0, -8.0, -6.5, -5.0, -4.0 }, // B curve : d1 <= 30 km
{ 20.0, -4.0, -6.5, -6.0, -4.5, -3.5, -2.5, -2.0, -1.0 } }; // A curve : d1 <= 60 km

// normalized ridge height factor
double alpha = sqrt(h_edge__meter / 200.0); // Eq 1, Okumura, alpha = 0.07 * sqrt(h)
// Eq 1, Okumura, alpha = 0.07 * sqrt(h)
// Note: 0.07 is approx sqrt (1/ 200), with 200 being the normalization height
double alpha = sqrt(h_edge__meter / 200.0);

int id1 = 0;
if (d1_hzn__km >= d_1__km[1])
id1 = 1;
int id2 = 0;

// select the first d2 curve distance that is <= to actual path d2 distance
int id2 = 0;
while (id2 < 7 && d2_hzn__km > d_2__km[id2 + 1])
id2 = id2 + 1;

// c1 is value on "lower" curve in Figure 31, Okumura, relative to d1 - either curve B or C
// c2 is value on "upper" curve in Figure 31, Okumura, relative to d1 - either curve A or B
double c1 = curve_data[id1][id2] + (curve_data[id1][id2 + 1] - curve_data[id1][id2]) * (d2_hzn__km - d_2__km[id2]) / (d_2__km[id2 + 1] - d_2__km[id2]);
double c2 = curve_data[id1 + 1][id2] + (curve_data[id1 + 1][id2 + 1] - curve_data[id1 + 1][id2]) * (d2_hzn__km - d_2__km[id2]) / (d_2__km[id2 + 1] - d_2__km[id2]);

return alpha * (c1 + (c2 - c1) * (d1_hzn__km - d_1__km[id1]) / (d_1__km[id1 + 1] - d_1__km[id1]));
if (!_do_isolated_ridge_v2_corr) {
return alpha * (c1 + (c2 - c1) * (d1_hzn__km - d_1__km[id1]) / (d_1__km[id1 + 1] - d_1__km[id1]));
} else {
// compute isolated ridge correction factor, K_im, from Figure 31, Okumura
double K_im;
if (d1_hzn__km <= 15) // clamp to curve C
K_im = c1;
else if (d1_hzn__km >= 60) // clamp to curve A
K_im = c2;
else // interpolate between curves
K_im = (c1 + (c2 - c1) * (d1_hzn__km - d_1__km[id1]) / (d_1__km[id1 + 1] - d_1__km[id1]));

// clamp K_im asymptote value to 0 dB (to avoid causing a non-physical gain from occuring)
// allow the gain to occur for portion of the curve with d2 distances close to or equal to 0 km
if (d2_hzn__km > 2)
K_im = MIN(K_im, 0);

// apply conversion factor to account for ridge height, Figure 32, Okumura
double L_iso__db = alpha * K_im;
return L_iso__db;
}
}
3 changes: 2 additions & 1 deletion src/harness/reference_models/propagation/ehata/its/ehata.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
// ******* WinnForum extension *******
// Activate the Winnforum extensions
extern bool _WinnForum_Extensions; // default is ON
void SetWinnForumExtensions(bool on);
extern bool _do_isolated_ridge_v2_corr; // default is OFF
void SetWinnForumExtensions(bool on, bool isolated_ridge_v2_corr);

// Function to get the distance in meters from a profile:
// the `pfl` profile store the number of points and the step between
Expand Down