code: def ecef2geodetic(
      x,
      y,
      z,
      ell: Ellipsoid = None,
      deg: bool = True,
  ) -> tuple:
      """
      convert ECEF (meters) to geodetic coordinates
  
      Parameters
      ----------
      x
          target x ECEF coordinate (meters)
      y
          target y ECEF coordinate (meters)
      z
          target z ECEF coordinate (meters)
      ell : Ellipsoid, optional
            reference ellipsoid
      deg : bool, optional
            degrees input/output  (False: radians in/out)
  
      Returns
      -------
      lat
             target geodetic latitude
      lon
             target geodetic longitude
      alt
           target altitude above geodetic ellipsoid (meters)
  
      based on:
      You, Rey-Jer. (2000). Transformation of Cartesian to Geodetic Coordinates without Iterations.
      Journal of Surveying Engineering. doi: 10.1061/(ASCE)0733-9453
      """
  
      if ell is None:
          ell = Ellipsoid.from_name("wgs84")
  
      try:
          x = asarray(x)
          y = asarray(y)
          z = asarray(z)
      except NameError:
          pass
  
      r = sqrt(x**2 + y**2 + z**2)
  
      E = sqrt(ell.semimajor_axis**2 - ell.semiminor_axis**2)
  
      # eqn. 4a
      u = sqrt(
          0.5 * (r**2 - E**2)
          + 0.5 * hypot(r**2 - E**2, 2 * E * z)
      )
  
      Q = hypot(x, y)
  
      huE = hypot(u, E)
  
      # eqn. 4b
      try:
          Beta = empty_like(r)
          ibad = isclose(u, 0) | isclose(Q, 0)
          Beta[~ibad] = atan(
              huE[~ibad] / u[~ibad] * z[~ibad] / Q[~ibad]
          )
          iz = ibad & isclose(z, 0)
          i1 = ibad & ~iz & (z > 0)
          i2 = ibad & ~iz & ~i1
  
          Beta[iz] = 0
          Beta[i1] = pi / 2
          Beta[i2] = -pi / 2
      except NameError:
          try:
              with warnings.catch_warnings(record=True):
                  warnings.simplefilter("error")
                  Beta = atan(huE / u * z / Q)
          except (ArithmeticError, RuntimeWarning):
              if isclose(z, 0):
                  Beta = 0
              elif z > 0:
                  Beta = pi / 2
              else:
                  Beta = -pi / 2
  
      # eqn. 13
      dBeta = (
          (ell.semiminor_axis * u - ell.semimajor_axis * huE + E**2)
          * sin(Beta)
      ) / (
          ell.semimajor_axis * huE * 1 / cos(Beta) - E**2 * cos(Beta)
      )
  
      Beta += dBeta
  
      # eqn. 4c
      # %% final output
      lat = atan(ell.semimajor_axis / ell.semiminor_axis * tan(Beta))
  
      try:
          # patch latitude for float32 precision loss
          lim_pi2 = pi / 2 - finfo(dBeta.dtype).eps
          lat = where(Beta >= lim_pi2, pi / 2, lat)
          lat = where(Beta <= -lim_pi2, -pi / 2, lat)
      except NameError:
          pass
  
      lon = atan2(y, x)
  
      # eqn. 7
      cosBeta = cos(Beta)
      try:
          # patch altitude for float32 precision loss
          cosBeta = where(Beta >= lim_pi2, 0, cosBeta)
          cosBeta = where(Beta <= -lim_pi2, 0, cosBeta)
      except NameError:
          pass
  
      alt = hypot(
          z - ell.semiminor_axis * sin(Beta),
          Q - ell.semimajor_axis * cosBeta,
      )
  
      # inside ellipsoid?
      inside = (
          x**2 / ell.semimajor_axis**2
          + y**2 / ell.semimajor_axis**2
          + z**2 / ell.semiminor_axis**2
          < 1
      )
  
      try:
          if inside.any():
              # avoid all false assignment bug
              alt[inside] = -alt[inside]
      except (TypeError, AttributeError):
          if inside:
              alt = -alt
  
      if deg:
          lat = degrees(lat)
          lon = degrees(lon)
  
      return lat, lon, alt
  
file_path: pymap3d/src/pymap3d/ecef.py
imports: from __future__ import annotations
  import warnings
  from datetime import datetime
  from math import pi
  from .ellipsoid import Ellipsoid
  from .mathfun import atan, atan2, cos, degrees, hypot, isclose, radians, sin, sqrt, tan
  from .utils import sanitize
label_desc: Use image node_id 2 for calling a global function with example usage: ecef2geodetic(x, y, z, ell, deg) and returns: lat,  lon,  alt