From 08db8fbd04428b057f71a14d0ec799aca550e7a8 Mon Sep 17 00:00:00 2001 From: JB Lovland Date: Wed, 29 Nov 2023 09:32:38 +0100 Subject: [PATCH] CLN: Port x_rotation_conv.c to python --- src/clib/xtg/libxtg.h | 2 - src/clib/xtg/x_rotation_conv.c | 101 --------------------------------- src/xtgeo/common/_angles.py | 29 ++++++++++ src/xtgeo/common/calc.py | 26 ++++----- tests/test_common/test_calc.py | 32 +++++++++++ 5 files changed, 72 insertions(+), 118 deletions(-) delete mode 100644 src/clib/xtg/x_rotation_conv.c create mode 100644 src/xtgeo/common/_angles.py diff --git a/src/clib/xtg/libxtg.h b/src/clib/xtg/libxtg.h index 9f8281543..b4a0915cb 100644 --- a/src/clib/xtg/libxtg.h +++ b/src/clib/xtg/libxtg.h @@ -178,8 +178,6 @@ double x_avg_angles(double *swig_np_dbl_in_v1, // *angles long n_swig_np_dbl_in_v1); // nsize, -double -x_rotation_conv(double ain, int aimode, int mode, int option); double x_tetrahedron_volume(double *swig_np_dbl_inplaceflat_v1, diff --git a/src/clib/xtg/x_rotation_conv.c b/src/clib/xtg/x_rotation_conv.c deleted file mode 100644 index 8162c4ea1..000000000 --- a/src/clib/xtg/x_rotation_conv.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - ****************************************************************************** - * - * NAME: - * x_rotation_convert.c - * - * - * DESCRIPTION: - * Transforms different rotation schemes. Ie. to transform from radians - * azimuth to degrees anticlock from x: - * deg = z_rotation_conv(0.343, 3, 0, 0, 1) - * - * ARGUMENTS: - * ain i Input angle - * ainmode i Input angle mode: - * 0 degrees, anti-clock from X - * 1 radians, anti-clock from X - * 2 degrees, clock from Y (azimuth) - * 3 radians, clock from Y (azimuth) - * mode i Mode of returning angle (same codes as ainmode) - * option i Options flag for later usage - * - * RETURNS: - * Transformed angle. - * - * TODO/ISSUES/BUGS: - * UNFINISHED! All combinations of conversion are not finished yet - * - * LICENCE: - * cf. XTGeo LICENSE - ****************************************************************************** - */ -#include "libxtg.h" -#include "libxtg_.h" - -double -x_rotation_conv(double ain, int ainmode, int mode, int option) -{ - /* locals */ - double result = 0.0; - - /* - * ------------------------------------------------------------------------ - * Some checks - * ------------------------------------------------------------------------ - */ - - if (ainmode == 0 || ainmode == 2) { - if (ain < -360 || ain > 360) { - return -9; - } - } - - if (ainmode == 1 || ainmode == 3) { - if (ain < -2 * PI || ain > 2 * PI) { - return -9; - } - } - - /* - * ------------------------------------------------------------------------ - * Use degrees when comptuting - * ------------------------------------------------------------------------ - */ - if (ainmode == 1 || ainmode == 3) - ain = ain * 180.0 / PI; - - /* - * ------------------------------------------------------------------------ - * Compute - * ------------------------------------------------------------------------ - */ - - /* from angle to azimuth */ - if (ainmode <= 1 && mode >= 2) { - result = -ain + 90; - if (result > 360) - result = result - 360; - if (ainmode == 1) - result = result * PI / 180.0; - } - - /* convert degrees azimuth angle to degrees normal angle */ - if (ainmode >= 2 && mode <= 1) { - result = 450 - ain; - if (result > 360) - result = result - 360; - if (ainmode == 3) - result = result * PI / 180.0; - } - - /* convert radians azimuth angle to degrees normal angle */ - if (ainmode == 3 && mode == 0) { - ain = ain * 180 / PI; - result = 450 - ain; - if (result > 360) - result = result - 360; - } - - return result; -} diff --git a/src/xtgeo/common/_angles.py b/src/xtgeo/common/_angles.py new file mode 100644 index 000000000..1e59c231d --- /dev/null +++ b/src/xtgeo/common/_angles.py @@ -0,0 +1,29 @@ +from math import degrees, radians + + +def _deg_angle2azimuth(deg: float) -> float: + """Converts an angle from X-axis anti-clockwise orientation + to Y-axis clockwise azimuth. + """ + return (-deg + 90) % 360 + + +def _deg_azimuth2angle(deg: float) -> float: + """Converts azimuth from Y-axis clockwise orientation to X-axis + anti-clockwise angle. + """ + return (450 - deg) % 360 + + +def _rad_angle2azimuth(rad: float) -> float: + """Converts an angle from X-axis anti-clockwise orientation to Y-axis clockwise + azimuth in radians. + """ + return radians(_deg_angle2azimuth(degrees(rad))) + + +def _rad_azimuth2angle(deg: float) -> float: + """Converts azimuth from Y-axis clockwise orientation to X-axis anti-clockwise + angle in radians. + """ + return radians(_deg_azimuth2angle(degrees(deg))) diff --git a/src/xtgeo/common/calc.py b/src/xtgeo/common/calc.py index 7b91fc96f..5fb9262f4 100644 --- a/src/xtgeo/common/calc.py +++ b/src/xtgeo/common/calc.py @@ -8,7 +8,7 @@ import numpy as np from xtgeo import XTGeoCLibError, _cxtgeo -from xtgeo.common import XTGeoDialog, null_logger +from xtgeo.common import XTGeoDialog, _angles, null_logger xtg = XTGeoDialog() logger = null_logger(__name__) @@ -207,13 +207,11 @@ def angle2azimuth( Return: Azimuth angle (in degrees or radian) """ - nmode1 = 0 - nmode2 = 2 - if mode == "radians": - nmode1 += 1 - nmode2 += 1 - - return _cxtgeo.x_rotation_conv(inangle, nmode1, nmode2, 0) + return ( + _angles._deg_angle2azimuth(inangle) + if mode == "degrees" + else _angles._rad_angle2azimuth(inangle) + ) def azimuth2angle( @@ -232,13 +230,11 @@ def azimuth2angle( Return: Angle (in degrees or radians) """ - nmode1 = 2 - nmode2 = 0 - if mode == "radians": - nmode1 += 1 - nmode2 += 1 - - return _cxtgeo.x_rotation_conv(inangle, nmode1, nmode2, 0) + return ( + _angles._deg_azimuth2angle(inangle) + if mode == "degrees" + else _angles._rad_azimuth2angle(inangle) + ) def tetrehedron_volume(vertices: Sequence[float]) -> float: diff --git a/tests/test_common/test_calc.py b/tests/test_common/test_calc.py index fd804bccf..2506c28fd 100644 --- a/tests/test_common/test_calc.py +++ b/tests/test_common/test_calc.py @@ -4,6 +4,8 @@ import numpy as np import pytest +from hypothesis import given +from hypothesis import strategies as st import xtgeo import xtgeo.common.calc as xcalc @@ -190,6 +192,36 @@ def test_azimuth2angle(): assert res == 120 +@given( + x=st.floats( + min_value=0, + max_value=180, + allow_infinity=False, + allow_nan=False, + ) +) +def test_angle2azimuth_azimuth2angle_deg(x: float) -> None: + assert ( + pytest.approx(xcalc.azimuth2angle(xcalc.angle2azimuth(x, "degrees"), "degrees")) + == x + ) + + +@given( + x=st.floats( + min_value=0, + max_value=math.pi, + allow_infinity=False, + allow_nan=False, + ) +) +def test_angle2azimuth_azimuth2angle_rad(x: float) -> None: + assert ( + pytest.approx(xcalc.azimuth2angle(xcalc.angle2azimuth(x, "radians"), "radians")) + == x + ) + + def test_averageangle(): """Test finding an average angle"""