diff --git a/boule/_ellipsoid.py b/boule/_ellipsoid.py index bd8f9847..e880442a 100644 --- a/boule/_ellipsoid.py +++ b/boule/_ellipsoid.py @@ -7,6 +7,7 @@ """ Module for defining and setting the reference ellipsoid. """ +import textwrap from warnings import warn import attr @@ -82,13 +83,21 @@ class Ellipsoid: ... flattening=1 / 298.257223563, ... geocentric_grav_const=3986004.418e8, ... angular_velocity=7292115e-11, - ... reference=( - ... "Hofmann-Wellenhof, B., & Moritz, H. (2006). Physical Geodesy " - ... "(2nd, corr. ed. 2006 edition ed.). Wien ; New York: Springer." - ... ), + ... reference="Hofmann-Wellenhof & Moritz (2006)", + ... comments="This is the same as the boule WGS84 ellipsoid.", ... ) >>> print(ellipsoid) # doctest: +ELLIPSIS - Ellipsoid(name='WGS84', ...) + WGS84 - World Geodetic System 1984 + Oblate ellipsoid: + • Semimajor axis: 6378137 m + • Flattening: 0.0033528106647474805 + • GM: 398600441800000.0 m³/s² + • Angular velocity: 7.292115e-05 rad/s + Source: + Hofmann-Wellenhof & Moritz (2006) + Comments: + This is the same as the boule WGS84 ellipsoid. + >>> print(ellipsoid.long_name) World Geodetic System 1984 @@ -411,6 +420,29 @@ def gravity_pole(self): ) return result + def __str__(self): + s = self.name + " - " + self.long_name + "\n" + s += "Oblate ellipsoid:\n" + s += f" • Semimajor axis: {self.semimajor_axis} m\n" + s += f" • Flattening: {self.flattening}\n" + s += f" • GM: {self.geocentric_grav_const} m³/s²\n" + s += f" • Angular velocity: {self.angular_velocity} rad/s" + if self.reference is not None: + s += "\nSource:" + for ref in self.reference.splitlines(): + s += "\n" + textwrap.fill( + ref, width=72, initial_indent=2 * " ", subsequent_indent=4 * " " + ) + if self.comments is not None: + s += "\nComments:\n" + s += textwrap.fill( + self.comments, + width=72, + initial_indent=2 * " ", + subsequent_indent=2 * " ", + ) + return s + def geocentric_radius(self, latitude, geodetic=True): r""" Radial distance from the center of the ellipsoid to its surface. diff --git a/boule/_realizations.py b/boule/_realizations.py index 6989d0c9..614b4281 100644 --- a/boule/_realizations.py +++ b/boule/_realizations.py @@ -23,7 +23,7 @@ reference=( "Wieczorek, MA (2015). 10.05 - Gravity and Topography of the Terrestrial " "Planets, Treatise of Geophysics (Second Edition); Elsevier. " - "doi:10.1016/B978-0-444-53802-4.00169-X" + "https://doi.org/10.1016/B978-0-444-53802-4.00169-X" ), ) @@ -35,11 +35,12 @@ angular_velocity=1.2400141739494342e-06, reference=( "Radius: Maia, J. (2024). Spherical harmonic models of the shape of " - "Mercury [Data set]. Zenodo. https://doi.org/10.5281/zenodo.10809345; " + "Mercury [Data set]. Zenodo. https://doi.org/10.5281/zenodo.10809345" + "\n" "GM, angular velocity: Mazarico, E., et al. (2014), The gravity field, " "orientation, and ephemeris of Mercury from MESSENGER observations " "after three years in orbit, J. Geophys. Res. Planets, 119, " - "2417-2436, doi:10.1002/2014JE004675." + "2417-2436. https://doi.org/10.1002/2014JE004675" ), ) @@ -52,7 +53,7 @@ reference=( "Wieczorek, MA (2015). 10.05 - Gravity and Topography of the Terrestrial " "Planets, Treatise of Geophysics (Second Edition); Elsevier. " - "doi:10.1016/B978-0-444-53802-4.00169-X" + "https://doi.org/10.1016/B978-0-444-53802-4.00169-X" ), ) @@ -65,7 +66,7 @@ angular_velocity=7292115e-11, reference=( "Hofmann-Wellenhof, B., & Moritz, H. (2006). Physical Geodesy " - "(2nd, corr. ed. 2006 edition ed.). Wien ; New York: Springer." + "(2nd, corr. ed. 2006 edition ed.). Wien; New York: Springer." ), ) @@ -79,7 +80,7 @@ angular_velocity=7292115e-11, reference=( "Hofmann-Wellenhof, B., & Moritz, H. (2006). Physical Geodesy " - "(2nd, corr. ed. 2006 edition ed.). Wien ; New York: Springer." + "(2nd, corr. ed. 2006 edition ed.). Wien; New York: Springer." ), ) @@ -106,7 +107,7 @@ reference=( "Wieczorek, MA (2015). 10.05 - Gravity and Topography of the Terrestrial " "Planets, Treatise of Geophysics (Second Edition); Elsevier. " - "doi:10.1016/B978-0-444-53802-4.00169-X" + "https://doi.org/10.1016/B978-0-444-53802-4.00169-X" ), ) @@ -120,8 +121,8 @@ reference=( "Ardalan, A. A., Karimi, R., & Grafarend, E. W. (2009). A New Reference " "Equipotential Surface, and Reference Ellipsoid for the Planet Mars. " - "Earth, Moon, and Planets, 106(1), 1. " - "doi:10.1007/s11038-009-9342-7" + "Earth, Moon, and Planets, 106, 1-13. " + "https://doi.org/10.1007/s11038-009-9342-7" ), ) @@ -135,7 +136,8 @@ reference=( "Semimajor axis, flattening: Park, R. S., et al. (2019). High-resolution " "shape model of Ceres from stereophotoclinometry using Dawn Imaging Data. " - "Icarus, 319, 812–827. https://doi.org/10.1016/j.icarus.2018.10.024; " + "Icarus, 319, 812–827. https://doi.org/10.1016/j.icarus.2018.10.024" + "\n" "GM, angular velocity: Konopliv, A. S., et al. (2018). The Ceres gravity " "field, spin pole, rotation period and orbit from the Dawn radiometric " "tracking and optical data. Icarus, 299, 411–429. " @@ -189,10 +191,12 @@ reference=( "Semi-axis: Thomas, P. C., et al. (1998). The Shape of Io from Galileo " "Limb Measurements. Icarus, 135(1), 175–180. " - "https://doi.org/10.1006/icar.1998.5987; " + "https://doi.org/10.1006/icar.1998.5987" + "\n" "GM: Anderson, J. D., et al. (2001). Io's gravity field and interior " "structure. J. Geophys. Res., 106, 32963–32969. " - "https://doi.org/10.1029/2000JE001367; " + "https://doi.org/10.1029/2000JE001367" + "\n" "Angular velocity: R. A. Jacobson (2021), The Orbits of the Regular " "Jovian Satellites and the Orientation of the Pole of Jupiter, personal " "communication to Horizons/NAIF. Accessed via JPL Solar System " @@ -213,10 +217,11 @@ "Semi-axis: Nimmo, F., et al. (2007). The global shape of Europa: " "Constraints on lateral shell thickness variations. Icarus, 191(1), " "183–192. https://doi.org/10.1016/j.icarus.2007.04.021" - "https://doi.org/10.1006/icar.1998.5987; " + "\n" "GM: Anderson, J. D., et al. (1998). Europa's differentiated internal " "structure: Inferences from four Galileo encounters. Science, 281, " - "2019–2022. https://doi.org/10.1126/science.281.5385.2019; " + "2019–2022. https://doi.org/10.1126/science.281.5385.2019" + "\n" "Angular velocity: R. A. Jacobson (2021), The Orbits of the Regular " "Jovian Satellites and the Orientation of the Pole of Jupiter, personal " "communication to Horizons/NAIF. Accessed via JPL Solar System " @@ -236,10 +241,12 @@ reference=( "Semi-axis: Zubarev, A., et al. (2015). New Ganymede control point " "network and global shape model. Planetary and Space Science, 117, " - "246–249. https://doi.org/10.1016/j.pss.2015.06.022; " + "246–249. https://doi.org/10.1016/j.pss.2015.06.022" + "\n" "GM: Gomez Casajus, L., et al. (2022). Gravity Field of Ganymede After " "the Juno Extended Mission. Geophysical Research Letters, 49(24), " - "e2022GL099475, doi:10.1029/2022GL099475.; " + "e2022GL099475. https://doi.org/doi:10.1029/2022GL099475" + "\n" "Angular velocity: R. A. Jacobson (2021), The Orbits of the Regular " "Jovian Satellites and the Orientation of the Pole of Jupiter, personal " "communication to Horizons/NAIF. Accessed via JPL Solar System " @@ -257,7 +264,8 @@ reference=( "Radius, GM: Anderson, J. D., et al. (2001). Shape, mean radius, gravity " "field, and interior structure of Callisto. Icarus, 153(1), 157–161. " - "https://doi.org/10.1006/icar.2001.6664; " + "https://doi.org/10.1006/icar.2001.6664" + "\n" "Angular velocity: Satellites and the Orientation of the Pole of Jupiter, " "personal communication to Horizons/NAIF. Accessed via JPL Solar " "System Dynamics, https://ssd.jpl.nasa.gov, JUP365." @@ -290,10 +298,12 @@ reference=( "Semi-axis: Corlies, P., et al. (2017). Titan’s Topography and Shape at " "the End of the Cassini Mission. Geophysical Research Letters, 44(23), " - "11,754-11,761. https://doi.org/10.1002/2017GL075518; " + "11,754-11,761. https://doi.org/10.1002/2017GL075518" + "\n" "GM: Durante, D., et al. (2019). Titan’s gravity field and interior " "structure after Cassini. Icarus, 326, 123–132. " - "https://doi.org/10.1016/j.icarus.2019.03.003; " + "https://doi.org/10.1016/j.icarus.2019.03.003" + "\n" "Angular velocity: Jacobson, R. (2022). The Orbits of the Main Saturnian " "Satellites, the Saturnian System Gravity Field, and the Orientation " "of Saturn's Pole. The Astronomical Journal, 164, 199. " @@ -313,10 +323,11 @@ reference=( "Radius: Nimmo, et al. (2017). Mean radius and shape of Pluto and Charon " "from New Horizons images. Icarus, 287, 12–29. " - "https://doi.org/10.1016/j.icarus.2016.06.027; " + "https://doi.org/10.1016/j.icarus.2016.06.027" + "\n" "GM, angular velocity: Brozović, M., et al. (2015). The orbits and masses of " "satellites of Pluto. Icarus, 246, 317–329. " - "https://doi.org/10.1016/j.icarus.2014.03.015; " + "https://doi.org/10.1016/j.icarus.2014.03.015" ), ) @@ -329,9 +340,10 @@ reference=( "Radius: Nimmo, et al. (2017). Mean radius and shape of Pluto and Charon " "from New Horizons images. Icarus, 287, 12–29. " - "https://doi.org/10.1016/j.icarus.2016.06.027; " + "https://doi.org/10.1016/j.icarus.2016.06.027" + "\n" "GM, angular velocity: Brozović, M., et al. (2015). The orbits and masses of " "satellites of Pluto. Icarus, 246, 317–329. " - "https://doi.org/10.1016/j.icarus.2014.03.015; " + "https://doi.org/10.1016/j.icarus.2014.03.015" ), ) diff --git a/boule/_sphere.py b/boule/_sphere.py index 3cd4d288..f1f2bc79 100644 --- a/boule/_sphere.py +++ b/boule/_sphere.py @@ -7,6 +7,7 @@ """ Define the reference sphere (ellipsoid with 0 flattening). """ +import textwrap from warnings import warn import attr @@ -75,24 +76,34 @@ class Sphere: >>> sphere = Sphere( ... name="Moon", - ... long_name="That's no moon", - ... radius=1, - ... geocentric_grav_const=2, - ... angular_velocity=0.5, + ... long_name="Moon Spheroid", + ... radius=1737151, + ... geocentric_grav_const=4902800070000.0, + ... angular_velocity=2.6617073e-06, + ... reference="Wieczorek (2015)", + ... comments="This is the same as the boule Moon2015 spheroid." ... ) >>> print(sphere) # doctest: +ELLIPSIS - Sphere(name='Moon', ...) + Moon - Moon Spheroid + Spheroid: + • Radius: 1737151 m + • GM: 4902800070000.0 m³/s² + • Angular velocity: 2.6617073e-06 rad/s + Source: + Wieczorek (2015) + Comments: + This is the same as the boule Moon2015 spheroid. + >>> print(sphere.long_name) - That's no moon + Moon Spheroid - The sphere defines semi-axis, flattening, and some eccentricities similar - to :class:`~bould.Ellipsoid` for compatibility with the coordinate - conversion functions of pymap3d: + The sphere defines semi-axess, flattening, and some eccentricities similar + to :class:`~bould.Ellipsoid` for compatibility: >>> print(sphere.semiminor_axis) - 1 + 1737151 >>> print(sphere.semimajor_axis) - 1 + 1737151 >>> print(sphere.first_eccentricity) 0 >>> print(sphere.eccentricity) @@ -102,23 +113,23 @@ class Sphere: >>> print(sphere.thirdflattening) 0 >>> print(sphere.mean_radius) - 1 + 1737151 >>> print(sphere.semiaxes_mean_radius) - 1 + 1737151 >>> print(f"{sphere.volume_equivalent_radius:.1f} m") - 1.0 m - >>> print(f"{sphere.volume:.10f} m³") - 4.1887902048 m³ - >>> print(f"{sphere.area:.10f} m²") - 12.5663706144 m² + 1737151.0 m + >>> print(f"{sphere.volume:.12e} m³") + 2.195843181718e+19 m³ + >>> print(f"{sphere.area:.12e} m²") + 3.792145613798e+13 m² >>> print(sphere.area_equivalent_radius) - 1 + 1737151 >>> print(f"{sphere.mass:.12e} kg") - 2.996568928577e+10 kg + 7.345789176393e+22 kg >>> print(f"{sphere.mean_density:.0f} kg/m³") - 7153781359 kg/m³ + 3345 kg/m³ >>> print(f"{sphere.reference_normal_gravitational_potential:.3f} m²/s²") - 2.000 m²/s² + 2822322.337 m²/s² """ @@ -289,6 +300,28 @@ def reference_normal_gravitational_potential(self): """ return self.geocentric_grav_const / self.radius + def __str__(self): + s = self.name + " - " + self.long_name + "\n" + s += "Spheroid:\n" + s += f" • Radius: {self.radius} m\n" + s += f" • GM: {self.geocentric_grav_const} m³/s²\n" + s += f" • Angular velocity: {self.angular_velocity} rad/s" + if self.reference is not None: + s += "\nSource:" + for ref in self.reference.splitlines(): + s += "\n" + textwrap.fill( + ref, width=72, initial_indent=2 * " ", subsequent_indent=4 * " " + ) + if self.comments is not None: + s += "\nComments:\n" + s += textwrap.fill( + self.comments, + width=72, + initial_indent=2 * " ", + subsequent_indent=2 * " ", + ) + return s + def normal_gravity(self, latitude, height, si_units=False): r""" Normal gravity of the sphere at the given latitude and height. diff --git a/boule/_triaxialellipsoid.py b/boule/_triaxialellipsoid.py index c1ab8a4e..35c1a377 100644 --- a/boule/_triaxialellipsoid.py +++ b/boule/_triaxialellipsoid.py @@ -7,6 +7,7 @@ """ Define a reference triaxial ellipsoid. """ +import textwrap from warnings import warn import attr @@ -84,22 +85,31 @@ class TriaxialEllipsoid: We can define an ellipsoid by setting the 5 key numerical parameters: >>> ellipsoid = TriaxialEllipsoid( - ... name="VESTA", + ... name="Vesta", ... long_name="Vesta Triaxial Ellipsoid", - ... semimajor_axis=286_300, - ... semimedium_axis=278_600, - ... semiminor_axis=223_200, - ... geocentric_grav_const=1.729094e10, - ... angular_velocity=326.71050958367e-6, - ... reference=( - ... "Russell, C. T., Raymond, C. A., Coradini, A., McSween, " - ... "H. Y., Zuber, M. T., Nathues, A., et al. (2012). Dawn at " - ... "Vesta: Testing the Protoplanetary Paradigm. Science. " - ... "doi:10.1126/science.1219381" - ... ), + ... semimajor_axis=280_413, + ... semimedium_axis=274_572, + ... semiminor_axis=231_253, + ... geocentric_grav_const=17.288e9, + ... angular_velocity=3.267e-4, + ... semimajor_axis_longitude=8.29, + ... reference="Karimi et al. (2017)", + ... comments="This is the same as the VestaTriaxial2017 ellipsoid." ... ) >>> print(ellipsoid) # doctest: +ELLIPSIS - TriaxialEllipsoid(name='VESTA', ...) + Vesta - Vesta Triaxial Ellipsoid + Triaxial ellipsoid: + • Semimajor axis: 280413 m + • Semimedium axis: 274572 m + • Semiminor axis: 231253 m + • Semimajor axis longitude: 8.29° + • GM: 17288000000.0 m³/s² + • Angular velocity: 0.0003267 rad/s + Source: + Karimi et al. (2017) + Comments: + This is the same as the VestaTriaxial2017 ellipsoid. + >>> print(ellipsoid.long_name) Vesta Triaxial Ellipsoid @@ -107,21 +117,21 @@ class TriaxialEllipsoid: parameters: >>> print(f"{ellipsoid.mean_radius:.0f} m") - 259813 m + 260344 m >>> print(f"{ellipsoid.semiaxes_mean_radius:.0f} m") - 262700 m + 262079 m >>> print(f"{ellipsoid.area:.10e} m²") - 8.6562393883e+11 m² + 8.6210266337e+11 m² >>> print(f"{ellipsoid.area_equivalent_radius:0.0f} m") - 262458 m + 261924 m >>> print(f"{ellipsoid.volume_equivalent_radius:.0f} m") - 261115 m + 261124 m >>> print(f"{ellipsoid.mass:.10e} kg") - 2.5906746775e+20 kg + 2.5902341819e+20 kg >>> print(f"{ellipsoid.mean_density:.0f} kg/m³") - 3474 kg/m³ + 3473 kg/m³ >>> print(f"{ellipsoid.volume * 1e-9:.0f} km³") - 74573626 km³ + 74581373 km³ """ @@ -325,6 +335,31 @@ def meridional_flattening(self): """ return (self.semimajor_axis - self.semiminor_axis) / self.semimajor_axis + def __str__(self): + s = self.name + " - " + self.long_name + "\n" + s += "Triaxial ellipsoid:\n" + s += f" • Semimajor axis: {self.semimajor_axis} m\n" + s += f" • Semimedium axis: {self.semimedium_axis} m\n" + s += f" • Semiminor axis: {self.semiminor_axis} m\n" + s += f" • Semimajor axis longitude: {self.semimajor_axis_longitude}°\n" + s += f" • GM: {self.geocentric_grav_const} m³/s²\n" + s += f" • Angular velocity: {self.angular_velocity} rad/s" + if self.reference is not None: + s += "\nSource:" + for ref in self.reference.splitlines(): + s += "\n" + textwrap.fill( + ref, width=72, initial_indent=2 * " ", subsequent_indent=4 * " " + ) + if self.comments is not None: + s += "\nComments:\n" + s += textwrap.fill( + self.comments, + width=72, + initial_indent=2 * " ", + subsequent_indent=2 * " ", + ) + return s + def geocentric_radius(self, longitude, latitude): r""" Radial distance from the center of the ellipsoid to its surface.