Skip to content

Commit

Permalink
Merge pull request #213 from bluescarni/pr/heyoka_updates
Browse files Browse the repository at this point in the history
Updates for latest heyoka
  • Loading branch information
bluescarni authored Jan 2, 2025
2 parents 04743c0 + 8d45292 commit b005b6c
Show file tree
Hide file tree
Showing 21 changed files with 145 additions and 194 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE)
endif()

project(heyoka.py VERSION 7.0.1 LANGUAGES CXX C)
project(heyoka.py VERSION 7.2.0 LANGUAGES CXX C)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/yacma")

Expand Down Expand Up @@ -124,7 +124,7 @@ find_package(fmt REQUIRED CONFIG)
message(STATUS "fmt version: ${fmt_VERSION}")

# heyoka.
find_package(heyoka 7.0.0 REQUIRED CONFIG)
find_package(heyoka 7.2.0 REQUIRED CONFIG)

# Python.

Expand Down
13 changes: 13 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
Changelog
=========

7.2.0 (2025-01-02)
------------------

Changes
~~~~~~~

- Clarify that epochs and dates have to be provided to the SGP4
propagator in the UTC scale of time
(`#213 <https://github.com/bluescarni/heyoka.py/pull/213>`__).
- heyoka.py now requires version 7.2.0 of the
heyoka C++ library
(`#213 <https://github.com/bluescarni/heyoka.py/pull/213>`__).

7.0.1 (2024-12-29)
------------------

Expand Down
2 changes: 1 addition & 1 deletion doc/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Dependencies
heyoka.py has several Python and C++ dependencies. On the C++ side, heyoka.py depends on:

* the `heyoka C++ library <https://github.com/bluescarni/heyoka>`__,
version 7.0.x (**mandatory**),
version 7.2.x (**mandatory**),
* the `Boost <https://www.boost.org/>`__ C++ libraries (**mandatory**),
* the `{fmt} <https://fmt.dev/latest/index.html>`__ library (**mandatory**),
* the `TBB <https://github.com/oneapi-src/oneTBB>`__ library (**mandatory**),
Expand Down
16 changes: 3 additions & 13 deletions doc/notebooks/sgp4_propagator.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,7 @@
"id": "1e3ec1fa-1c09-46f7-a8fe-f6da4c33edb2",
"metadata": {},
"source": [
"{py:func}`~heyoka.model.sgp4_propagator()` takes as only mandatory input argument the list of satellites, here represented as ``Satrec`` objects from the [sgp4 Python module](https://pypi.org/project/sgp4/). The list of satellites can alternatively be passed as a NumPy 2D array containing the GPE data for all satellites (see the documentation). {py:func}`~heyoka.model.sgp4_propagator()` returns a propagator object, by default of type {py:func}`~heyoka.model.sgp4_propagator_dbl()` (i.e., a double-precision propagator). You can also request a single-precision propagator via the {ref}`fp_type keyword argument <api_common_kwargs_fp_type>`.\n",
"\n",
"(tut_sgp4_propagator_epochs)=\n",
"\n",
"## A caveat on epochs and scales of time\n",
"\n",
"When an {py:func}`~heyoka.model.sgp4_propagator()` is constructed from a list of ``Satrec`` objects, the satellite epochs are represented as UTC Julian dates. Consequently, UTC Julian dates must also be used when specifying the {ref}`propagation epochs <tut_sgp4_scalar_propagation>`. The use of UTC Julian dates comes with an important caveat: UTC days do not constitute a uniform scale of time due to the potential presence of [leap seconds](https://en.wikipedia.org/wiki/Leap_second). As a consequence, if the time interval between the satellite epoch and the propagation epoch includes a leap second, the result of the propagation will be slightly wrong.\n",
"\n",
"Considering that the last leap second was added in 2016 and that leap seconds may be phased out altogether by 2035, this quirk should not manifest itself when using contemporary GPE data. For the purpose of this tutorial we will thus ignore the leap seconds issue altogether.\n",
"\n",
"If precise propagation across leap seconds is required, one should construct an {py:func}`~heyoka.model.sgp4_propagator()` not via a list of ``Satrec`` objects, but instead using the second overload which takes as input the GPE data as a NumPy 2D array. The GPE epochs in the array should be represented as Julian dates in a continuous scale of time such as [TAI](https://en.wikipedia.org/wiki/International_Atomic_Time). Similarly, the propagation epochs should be provided as Julian dates in the same scale of time. We recommend to use of a library such as [Astropy](https://docs.astropy.org/en/stable/time/index.html) to convert between UTC epochs and TAI Julian dates."
"{py:func}`~heyoka.model.sgp4_propagator()` takes as only mandatory input argument the list of satellites, here represented as ``Satrec`` objects from the [sgp4 Python module](https://pypi.org/project/sgp4/). The list of satellites can alternatively be passed as a NumPy 2D array containing the GPE data for all satellites (see the documentation). {py:func}`~heyoka.model.sgp4_propagator()` returns a propagator object, by default of type {py:func}`~heyoka.model.sgp4_propagator_dbl()` (i.e., a double-precision propagator). You can also request a single-precision propagator via the {ref}`fp_type keyword argument <api_common_kwargs_fp_type>`."
]
},
{
Expand Down Expand Up @@ -263,7 +253,7 @@
"source": [
"Julian dates are represented via the {py:attr}`~heyoka.model.sgp4_propagator_dbl.jdtype` type, which is a {ref}`structured NumPy datatype<numpy:defining-structured-types>` consisting of\n",
"two floating-point fields, the first one called ``jd`` and representing a Julian date, the second one called ``frac`` representing a fractional correction to ``jd`` (so that the full\n",
"Julian date is ``jd + frac``). Remember that, since we constructed the propagator from a list of ``Satrec`` objects, the Julian dates are to be provided in the UTC time scale.\n",
"Julian date is ``jd + frac``). Julian dates must be provided in the UTC scale of time, following the [SOFA](http://www.iausofa.org/)/[ERFA](https://github.com/liberfa/erfa/) convention of handling leap seconds via slightly longer/shorter days. We highly recommend the use of a library such as [Astropy](https://docs.astropy.org/en/stable/time/index.html) to convert between calendar days and UTC Julian dates.\n",
"\n",
"Although in principle we could propagate each satellite to a different date, here we will be propagating *all* satellites to the same Julian date:"
]
Expand Down Expand Up @@ -1206,7 +1196,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
"version": "3.13.1"
}
},
"nbformat": 4,
Expand Down
15 changes: 9 additions & 6 deletions heyoka/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ def from_sympy(ex, s_dict={}):

if not isinstance(ex, Basic):
raise TypeError(
"The 'ex' parameter must be a sympy expression but it is of type {} instead"
.format(type(ex))
"The 'ex' parameter must be a sympy expression but it is of type {} instead".format(
type(ex)
)
)

if not isinstance(s_dict, dict):
Expand Down Expand Up @@ -215,8 +216,9 @@ def set_serialization_backend(name):

if not name in _s11n_backend_map:
raise ValueError(
"The serialization backend '{}' is not valid. The valid backends are: {}"
.format(name, list(_s11n_backend_map.keys()))
"The serialization backend '{}' is not valid. The valid backends are: {}".format(
name, list(_s11n_backend_map.keys())
)
)

new_backend = _s11n_backend_map[name]
Expand Down Expand Up @@ -289,8 +291,9 @@ def is_iterable(x):
return _ensemble_propagate_process(tp, ta, arg, n_iter, gen, **kwargs)

raise ValueError(
"The parallelisation algorithm must be one of {}, but '{}' was provided instead"
.format(allowed_algos, algo)
"The parallelisation algorithm must be one of {}, but '{}' was provided instead".format(
allowed_algos, algo
)
)


Expand Down
17 changes: 6 additions & 11 deletions heyoka/_test_batch_integrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,7 @@ def __call__(self, ta):
ta.propagate_for(fp_t(10.0), callback=broken_cb())
self.assertTrue(
"The call operator of a step callback is expected to return a boolean,"
" but a value of type"
in str(cm.exception)
" but a value of type" in str(cm.exception)
)

# Callback with pre_hook().
Expand Down Expand Up @@ -321,8 +320,7 @@ def __call__(self, ta):
ta.propagate_until(fp_t(10.0), callback=broken_cb())
self.assertTrue(
"The call operator of a step callback is expected to return a boolean,"
" but a value of type"
in str(cm.exception)
" but a value of type" in str(cm.exception)
)

# Callback with pre_hook().
Expand Down Expand Up @@ -713,17 +711,15 @@ def test_propagate_grid(self):
self.assertTrue(
"Invalid grid passed to the propagate_grid() method of a batch"
" integrator: the expected number of dimensions is 2, but the input"
" array has a dimension of 1"
in str(cm.exception)
" array has a dimension of 1" in str(cm.exception)
)

with self.assertRaises(ValueError) as cm:
ta.propagate_grid(np.array([[1, 2], [3, 4]], dtype=fp_t))
self.assertTrue(
"Invalid grid passed to the propagate_grid() method of a batch"
" integrator: the shape must be (n, 4) but the number of columns is 2"
" instead"
in str(cm.exception)
" instead" in str(cm.exception)
)

# Run a simple scalar/batch comparison.
Expand All @@ -747,7 +743,7 @@ def test_propagate_grid(self):
self.assertTrue(bres[0] is None)

for idx, cur_ta in enumerate(tas):
cur_ta.propagate_until(grid[0, idx]),
(cur_ta.propagate_until(grid[0, idx]),)

sres = [
tas[0].propagate_grid(grid[:, 0]),
Expand Down Expand Up @@ -842,8 +838,7 @@ def __call__(self, ta):
ta.propagate_grid(grid, callback=broken_cb())
self.assertTrue(
"The call operator of a step callback is expected to return a boolean,"
" but a value of type"
in str(cm.exception)
" but a value of type" in str(cm.exception)
)

# Callback with pre_hook().
Expand Down
Loading

0 comments on commit b005b6c

Please sign in to comment.