[Git][debian-gis-team/pyorbital][master] 5 commits: New upstream version 1.10.0

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sat Apr 12 08:51:40 BST 2025



Antonio Valentino pushed to branch master at Debian GIS Project / pyorbital


Commits:
f4cad134 by Antonio Valentino at 2025-04-12T06:49:25+00:00
New upstream version 1.10.0
- - - - -
4400de35 by Antonio Valentino at 2025-04-12T06:49:26+00:00
Update upstream source from tag 'upstream/1.10.0'

Update to upstream version '1.10.0'
with Debian dir d11b84e5882e114e173cd2ef0696781c61a90506
- - - - -
ff4793fa by Antonio Valentino at 2025-04-12T06:51:25+00:00
New upstream release

- - - - -
f2b148e4 by Antonio Valentino at 2025-04-12T07:50:20+00:00
Fix patch syntax

- - - - -
a756c632 by Antonio Valentino at 2025-04-12T07:50:21+00:00
Set distribution to unstable

- - - - -


17 changed files:

- .github/workflows/ci.yaml
- .github/workflows/deploy-sdist.yaml
- .pre-commit-config.yaml
- CHANGELOG.md
- debian/changelog
- debian/patches/0002-Reproducible-build.patch
- doc/source/index.rst
- pyorbital/etc/platforms.txt
- pyorbital/geoloc.py
- pyorbital/geoloc_example.py
- pyorbital/geoloc_instrument_definitions.py
- pyorbital/orbital.py
- pyorbital/tests/test_aiaa.py
- pyorbital/tests/test_astronomy.py
- pyorbital/tests/test_geoloc.py
- pyorbital/tests/test_orbital.py
- pyorbital/tests/test_tlefile.py


Changes:

=====================================
.github/workflows/ci.yaml
=====================================
@@ -93,7 +93,7 @@ jobs:
         uses: codecov/codecov-action at v5
         with:
           flags: unittests
-          file: ./coverage.xml
+          files: ./coverage.xml
           env_vars: OS,PYTHON_VERSION,UNSTABLE
 
       - name: Coveralls Parallel


=====================================
.github/workflows/deploy-sdist.yaml
=====================================
@@ -21,7 +21,7 @@ jobs:
 
       - name: Publish package to PyPI
         if: github.event.action == 'published'
-        uses: pypa/gh-action-pypi-publish at v1.12.3
+        uses: pypa/gh-action-pypi-publish at v1.12.4
         with:
           user: __token__
           password: ${{ secrets.pypi_password }}


=====================================
.pre-commit-config.yaml
=====================================
@@ -3,7 +3,7 @@ fail_fast: false
 repos:
   - repo: https://github.com/astral-sh/ruff-pre-commit
     # Ruff version.
-    rev: 'v0.8.1'
+    rev: 'v0.11.4'
     hooks:
       - id: ruff
   - repo: https://github.com/pre-commit/pre-commit-hooks
@@ -15,12 +15,12 @@ repos:
       - id: check-yaml
         args: [--unsafe]
   - repo: https://github.com/PyCQA/bandit
-    rev: '1.8.0' # Update me!
+    rev: '1.8.3' # Update me!
     hooks:
       - id: bandit
         args: [--ini, .bandit]
   - repo: https://github.com/pre-commit/mirrors-mypy
-    rev: 'v1.13.0'  # Use the sha / tag you want to point at
+    rev: 'v1.15.0'  # Use the sha / tag you want to point at
     hooks:
       - id: mypy
         additional_dependencies:
@@ -30,7 +30,7 @@ repos:
           - types-requests
         args: ["--python-version", "3.10", "--ignore-missing-imports"]
   - repo: https://github.com/pycqa/isort
-    rev: 5.13.2
+    rev: 6.0.1
     hooks:
       - id: isort
         language_version: python3


=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,26 @@
+## Version 1.10.0 (2025/04/10)
+
+### Issues Closed
+
+* [Issue 184](https://github.com/pytroll/pyorbital/issues/184) - avhrr_gac instrument definition is broken ([PR 185](https://github.com/pytroll/pyorbital/pull/185) by [@oembury](https://github.com/oembury))
+
+In this release 1 issue was closed.
+
+### Pull Requests Merged
+
+#### Bugs fixed
+
+* [PR 185](https://github.com/pytroll/pyorbital/pull/185) - Fix avhrr gac geometry ([184](https://github.com/pytroll/pyorbital/issues/184))
+
+#### Features added
+
+* [PR 188](https://github.com/pytroll/pyorbital/pull/188) - Cleanup for #185
+* [PR 186](https://github.com/pytroll/pyorbital/pull/186) - Support yaw arrays for ScanGeometry with same broadcasting as roll / pitch
+* [PR 177](https://github.com/pytroll/pyorbital/pull/177) - Fix datetime imports
+
+In this release 4 pull requests were closed.
+
+
 ## Version 1.9.2 (2024/12/12)
 
 ### Pull Requests Merged


=====================================
debian/changelog
=====================================
@@ -1,17 +1,17 @@
-pyorbital (1.9.2-2) UNRELEASED; urgency=medium
+pyorbital (1.10.0-1) unstable; urgency=medium
 
   [ Bas Couwenberg ]
-  * Team upload.
   * Bump Standards-Version to 4.7.2, no changes.
 
   [ Antonio Valentino ]
+  * New upstream release.
   * Update dates in d/copyright.
   * debian/patches:
     - Drop 0002-Fix-broken-test-on-i386.patch
       (didn't actually solve the issue on i386).
     - Renumber remaining patches.
 
- -- Bas Couwenberg <sebastic at debian.org>  Thu, 20 Mar 2025 06:18:31 +0100
+ -- Antonio Valentino <antonio.valentino at tiscali.it>  Sat, 12 Apr 2025 07:47:20 +0000
 
 pyorbital (1.9.2-1) unstable; urgency=medium
 


=====================================
debian/patches/0002-Reproducible-build.patch
=====================================
@@ -3,7 +3,6 @@ Date: Sat, 7 Dec 2024 10:48:29 +0000
 Subject: Make the build reproducible
 
 Last-Update: 2024-12-04
-
 Forwarded: not-needed
 ---
  doc/source/conf.py | 5 +++--


=====================================
doc/source/index.rst
=====================================
@@ -114,10 +114,10 @@ Computing satellite position
 The orbital module enables computation of satellite position and velocity at a specific time:
 
     >>> from pyorbital.orbital import Orbital
-    >>> from datetime import datetime
+    >>> import datetime as dt
     >>> # Use current TLEs from the internet:
     >>> orb = Orbital("Suomi NPP")
-    >>> now = datetime.utcnow()
+    >>> now = dt.datetime.now(dt.timezone.utc)
     >>> # Get normalized position and velocity of the satellite:
     >>> orb.get_position(now)
     (array([-0.20015267,  0.09001458,  1.10686756]),
@@ -131,9 +131,9 @@ Use actual TLEs to increase accuracy
 ------------------------------------
 
     >>> from pyorbital.orbital import Orbital
-    >>> from datetime import datetime
+    >>> import datetime as dt
     >>> orb = Orbital("Suomi NPP")
-    >>> dtobj = datetime(2015,2,7,3,0)
+    >>> dtobj = dt.datetime(2015,2,7,3,0)
     >>> orb.get_lonlatalt(dtobj)
     (152.11564698762811, 20.475251739329622, 829.37355785502211)
 
@@ -158,8 +158,8 @@ Computing astronomical parameters
 The astronomy module enables computation of certain parameters of interest for satellite remote sensing for instance the Sun-zenith angle:
 
     >>> from pyorbital import astronomy
-    >>> from datetime import datetime
-    >>> utc_time = datetime(2012, 5, 15, 15, 45)
+    >>> import datetime as dt
+    >>> utc_time = dt.datetime(2012, 5, 15, 15, 45)
     >>> lon, lat = 12, 56
     >>> astronomy.sun_zenith_angle(utc_time, lon, lat)
     62.685986438071602


=====================================
pyorbital/etc/platforms.txt
=====================================
@@ -19,6 +19,7 @@ DMSP-F18 35951
 DMSP-F19 39630
 EOS-Aqua 27424
 EOS-Aura 28376
+EOS-6 (OCEANSAT-3) 54361
 EOS-Terra 25994
 FY-2D 29640
 FY-2E 33463
@@ -74,7 +75,9 @@ NOAA-18 28654
 NOAA-19 33591
 NOAA-20 43013
 NOAA-21 54234
+OTB-3-GAZELLE 54023
 RadarSat-2 32382
+SARAL 39086
 Sentinel-1A 39634
 Sentinel-1B 41456
 Sentinel-2A 40697


=====================================
pyorbital/geoloc.py
=====================================
@@ -118,6 +118,9 @@ class ScanGeometry(object):
         # then around y
         xy_rotated = qrotate(x_rotated, y, self.fovs[1] + pitch)
         # then around z
+        if np.shape(yaw):
+            # If we have an array then need to use the same broadcasting as x/y rotation
+            yaw = np.broadcast_to(yaw, self.fovs[0].shape)
         return qrotate(xy_rotated, nadir, yaw)
 
     def times(self, start_of_scan):
@@ -274,8 +277,8 @@ if __name__ == "__main__":
     noaa18_tle1 = "1 28654U 05018A   11284.35271227  .00000478  00000-0  28778-3 0  9246"
     noaa18_tle2 = "2 28654  99.0096 235.8581 0014859 135.4286 224.8087 14.11526826329313"
 
-    from datetime import datetime
-    t = datetime(2011, 10, 12, 13, 45)
+    import datetime as dt
+    t = dt.datetime(2011, 10, 12, 13, 45)
 
     # edge and centre of an avhrr scanline
     # sgeom = ScanGeometry([(-0.9664123687741623, 0),


=====================================
pyorbital/geoloc_example.py
=====================================
@@ -22,7 +22,7 @@
 
 """Simple usage for geoloc."""
 
-from datetime import datetime
+import datetime as dt
 
 import matplotlib.pyplot as plt
 import numpy as np
@@ -35,7 +35,7 @@ tle1 = "1 33591U 09005A   12345.45213434  .00000391  00000-0  24004-3 0  6113"
 tle2 = "2 33591 098.8821 283.2036 0013384 242.4835 117.4960 14.11432063197875"
 
 # Choosing a specific time, this should be relatively close to the issue date of the TLE
-t = datetime(2012, 12, 12, 4, 16, 1, 575000)
+t = dt.datetime(2012, 12, 12, 4, 16, 1, 575000)
 # this is the number of full scan rotations
 scans_nb = 10
 # we take only every 40th point for plotting clarity


=====================================
pyorbital/geoloc_instrument_definitions.py
=====================================
@@ -37,6 +37,8 @@ different pixels.
 Both scan angles and scan times are then combined into a ScanGeometry object.
 """
 
+import warnings
+
 import numpy as np
 
 from pyorbital.geoloc import ScanGeometry
@@ -82,6 +84,8 @@ def avhrr_gac(scan_times, scan_points,
     Source: NOAA KLM User's Guide, Appendix J
     http://www.ncdc.noaa.gov/oa/pod-guide/ncdc/docs/klm/html/j/app-j.htm
     """
+    warnings.warn("avhrr_gac is replaced with avhrr_from_times or avhrr_gac_from_times",
+                  DeprecationWarning)
     try:
         offset = np.array([(t - scan_times[0]).seconds +
                            (t - scan_times[0]).microseconds / 1000000.0 for t in scan_times])
@@ -100,6 +104,63 @@ def avhrr_gac(scan_times, scan_points,
              + np.expand_dims(offset, 1))
     return ScanGeometry(avhrr_inst, times)
 
+
+def avhrr_from_times(scan_times, scan_points, scan_angle=55.37):
+    """Definition of the avhrr instrument.
+
+    Source: NOAA KLM User's Guide, Appendix J
+    http://www.ncdc.noaa.gov/oa/pod-guide/ncdc/docs/klm/html/j/app-j.htm
+
+    :scan_times: Observation times (datetime object)
+    :scan_points: Across track pixel positions
+    :scan_angle: Maximum scan angle of the outermost FOV
+    """
+    offset = np.array([(t - scan_times[0]).total_seconds() for t in scan_times])
+    scan_points = np.asanyarray(scan_points)
+    scans_nb = len(offset)
+
+    avhrr_inst = np.vstack([(scan_points / 1023.5 - 1) * np.deg2rad(-scan_angle),
+                            np.zeros(len(scan_points))])
+
+    avhrr_inst = np.tile(avhrr_inst[:, np.newaxis, :], [1, scans_nb, 1])
+    # building the corresponding times array
+    times = (np.tile(scan_points * 0.000025, [scans_nb, 1])
+             + np.expand_dims(offset, 1))
+    return ScanGeometry(avhrr_inst, times)
+
+
+def avhrr_gac_from_times(scan_times, scan_points, scan_angle=55.37):
+    """Definition of the avhrr instrument, gac version.
+
+    Source: NOAA KLM User's Guide, Appendix J
+    http://www.ncdc.noaa.gov/oa/pod-guide/ncdc/docs/klm/html/j/app-j.htm
+
+    :scan_times: Observation times (datetime object)
+    :scan_points: Across track pixel positions
+    :scan_angle: Maximum scan angle of the outermost FOV
+    """
+    offset = np.array([(t - scan_times[0]).total_seconds() for t in scan_times])
+    scan_points = np.asanyarray(scan_points)
+    scans_nb = len(offset)
+
+    # The AVHRR swath is +/- 55.4 degrees, which puts the outermost FOV at
+    #   55.4 * 1023.5 / 1024 = 55.373
+    # GAC pixels are the average of four FOVs with sampling: ..1111.2222.----.NNNN..
+    # so we need to reduce the scan_angle by a factor (1023.5 - 3.5) / 1023.5
+    # to calculate the GAC pixel centres
+    gac_angle = scan_angle * (1023.5 - 3.5) / 1023.5
+
+    avhrr_inst = np.vstack([(scan_points / 204 - 1) * np.deg2rad(-gac_angle),
+                            np.zeros(len(scan_points))])
+
+    avhrr_inst = np.tile(
+        avhrr_inst[:, np.newaxis, :], [1, np.int32(scans_nb), 1])
+    # building the corresponding times array
+    times = (np.tile(scan_points * 0.000125, [scans_nb, 1])
+             + np.expand_dims(offset, 1))
+    return ScanGeometry(avhrr_inst, times)
+
+
 ################################################################
 # avhrr, all pixels
 


=====================================
pyorbital/orbital.py
=====================================
@@ -24,9 +24,9 @@
 
 """Module for computing the orbital parameters of satellites."""
 
+import datetime as dt
 import logging
 import warnings
-from datetime import datetime, timedelta, timezone
 from functools import partial
 
 import numpy as np
@@ -353,7 +353,7 @@ class Orbital(object):
 
         """
         # every minute
-        times = utc_time + np.array([timedelta(minutes=minutes)
+        times = utc_time + np.array([dt.timedelta(minutes=minutes)
                                      for minutes in range(length * 60)])
         elev = self.get_observer_look(times, lon, lat, alt)[1] - horizon
         zcs = np.where(np.diff(np.sign(elev)))[0]
@@ -364,7 +364,7 @@ class Orbital(object):
         elev_inv_func = partial(self._elevation_inv, utc_time, lon, lat, alt, horizon)
         for guess in zcs:
             horizon_mins = _get_root(elev_func, guess, guess + 1.0, tol=tol / 60.0)
-            horizon_time = utc_time + timedelta(minutes=horizon_mins)
+            horizon_time = utc_time + dt.timedelta(minutes=horizon_mins)
             if elev[guess] < 0:
                 risetime = horizon_time
                 risemins = horizon_mins
@@ -377,7 +377,7 @@ class Orbital(object):
                 int_end = min(len(elev), int(np.ceil(fallmins) + 1))
                 middle = int_start + np.argmax(elev[int_start:int_end])
                 highest = utc_time + \
-                    timedelta(minutes=_get_max_parab(
+                    dt.timedelta(minutes=_get_max_parab(
                         elev_inv_func,
                         max(risemins, middle - 1), min(fallmins, middle + 1),
                         tol=tol / 60.0
@@ -401,14 +401,14 @@ class Orbital(object):
         if "precision" in kwargs:
             precision = kwargs["precision"]
         else:
-            precision = timedelta(seconds=0.001)
+            precision = dt.timedelta(seconds=0.001)
         if "max_iterations" in kwargs:
             nmax_iter = kwargs["max_iterations"]
         else:
             nmax_iter = 100
 
         sec_step = 0.5
-        t_step = timedelta(seconds=sec_step / 2.0)
+        t_step = dt.timedelta(seconds=sec_step / 2.0)
 
         # Local derivative:
         def fprime(timex):
@@ -418,7 +418,7 @@ class Orbital(object):
                                          obslon, obslat, 0.0)[1]
             return el0, (abs(el1) - abs(el0)) / sec_step
 
-        tx0 = utc_time - timedelta(seconds=1.0)
+        tx0 = utc_time - dt.timedelta(seconds=1.0)
         tx1 = utc_time
         idx = 0
         # eps = 500.
@@ -431,11 +431,11 @@ class Orbital(object):
             # var_scale = np.abs(np.sin(fpr[0] * np.pi/180.))
             # var_scale = np.sqrt(var_scale)
             var_scale = np.abs(fpr[0])
-            tx1 = tx0 - timedelta(seconds=(eps * var_scale * fpr[1]))
+            tx1 = tx0 - dt.timedelta(seconds=(eps * var_scale * fpr[1]))
             idx = idx + 1
             # print idx, tx0, tx1, var_scale, fpr
             if abs(tx1 - utc_time) < precision and idx < 2:
-                tx1 = tx1 + timedelta(seconds=1.0)
+                tx1 = tx1 + dt.timedelta(seconds=1.0)
 
         if abs(tx1 - tx0) <= precision and idx < nmax_iter:
             return tx1
@@ -445,7 +445,7 @@ class Orbital(object):
     def utc2local(self, utc_time):
         """Convert UTC to local time."""
         lon, _, _ = self.get_lonlatalt(utc_time)
-        return utc_time + timedelta(hours=lon * 24 / 360.0)
+        return utc_time + dt.timedelta(hours=lon * 24 / 360.0)
 
     def get_equatorial_crossing_time(self, tstart, tend, node="ascending", local_time=False,
                                      rtol=1E-9):
@@ -502,7 +502,7 @@ class Orbital(object):
         except ValueError:
             # Bisection did not converge
             return None
-        tcross = np.datetime64(int(tcross), time_unit).astype(datetime)
+        tcross = np.datetime64(int(tcross), time_unit).astype(dt.datetime)
 
         # Convert UTC to local time
         if local_time:
@@ -514,7 +514,7 @@ class Orbital(object):
     def _elevation(self, utc_time, lon, lat, alt, horizon, minutes):
         """Compute the elevation."""
         return self.get_observer_look(utc_time +
-                                      timedelta(minutes=np.float64(minutes)),
+                                      dt.timedelta(minutes=np.float64(minutes)),
                                       lon, lat, alt)[1] - horizon
 
 
@@ -1228,8 +1228,8 @@ def _get_tz_unaware_utctime(utc_time):
     The input *utc_time* is either a timezone unaware object assumed to be in
     UTC, or a timezone aware datetime object in UTC.
     """
-    if isinstance(utc_time, datetime):
-        if utc_time.tzinfo and utc_time.tzinfo != timezone.utc:
+    if isinstance(utc_time, dt.datetime):
+        if utc_time.tzinfo and utc_time.tzinfo != dt.timezone.utc:
             raise ValueError("UTC time expected! Parsing a timezone aware datetime object requires it to be UTC!")
         return utc_time.replace(tzinfo=None)
 
@@ -1275,11 +1275,11 @@ if __name__ == "__main__":
     obs_alt = 0.02
     o = Orbital(satellite="METOP-B")
 
-    t_start = datetime.now()
-    t_stop = t_start + timedelta(minutes=20)
+    t_start = dt.datetime.now()
+    t_stop = t_start + dt.timedelta(minutes=20)
     t = t_start
     while t < t_stop:
-        t += timedelta(seconds=15)
+        t += dt.timedelta(seconds=15)
         lon, lat, alt = o.get_lonlatalt(t)
         lon, lat = np.rad2deg((lon, lat))
         az, el = o.get_observer_look(t, obs_lon, obs_lat, obs_alt)


=====================================
pyorbital/tests/test_aiaa.py
=====================================
@@ -26,9 +26,9 @@
 # TODO: right formal unit tests.
 from __future__ import print_function, with_statement
 
+import datetime as dt
 import os
 import unittest
-from datetime import datetime
 
 import numpy as np
 
@@ -63,7 +63,7 @@ def get_results(satnumber, delay):
                 if delay == 0:
                     utc_time = None
                 else:
-                    utc_time = datetime.strptime(sline[-1], "%H:%M:%S.%f")
+                    utc_time = dt.datetime.strptime(sline[-1], "%H:%M:%S.%f")
                     utc_time = utc_time.replace(year=int(sline[-4]),
                                                 month=int(sline[-3]),
                                                 day=int(sline[-2]))


=====================================
pyorbital/tests/test_astronomy.py
=====================================
@@ -23,7 +23,7 @@
 """Unit testing the Astronomy methods and functions."""
 
 
-from datetime import datetime
+import datetime as dt
 
 import dask.array as da
 import numpy as np
@@ -60,16 +60,16 @@ class TestAstronomy:
     """Testing the Astronomy class."""
 
     @pytest.mark.parametrize(
-        ("dt", "exp_jdays", "exp_j2000"),
+        ("dat", "exp_jdays", "exp_j2000"),
         [
-            (datetime(2000, 1, 1, 12, 0), 2451545.0, 0),
-            (datetime(2009, 10, 8, 14, 30), 2455113.1041666665, 3568.1041666666665),
+            (dt.datetime(2000, 1, 1, 12, 0), 2451545.0, 0),
+            (dt.datetime(2009, 10, 8, 14, 30), 2455113.1041666665, 3568.1041666666665),
         ]
     )
-    def test_jdays(self, dt, exp_jdays, exp_j2000):
+    def test_jdays(self, dat, exp_jdays, exp_j2000):
         """Test julian day functions."""
-        assert astr.jdays(dt) == exp_jdays
-        assert astr.jdays2000(dt) == exp_j2000
+        assert astr.jdays(dat) == exp_jdays
+        assert astr.jdays2000(dat) == exp_j2000
 
     @pytest.mark.parametrize(
         ("lon", "lat", "exp_theta"),
@@ -98,7 +98,7 @@ class TestAstronomy:
         if array_construct is None and dtype is not None:
             pytest.skip(reason="Xarray dependency unavailable")
 
-        time_slot = datetime(2011, 9, 23, 12, 0)
+        time_slot = dt.datetime(2011, 9, 23, 12, 0)
         abs_tolerance = 1e-8
         if dtype is not None:
             lon = array_construct([lon], dtype=dtype)
@@ -117,7 +117,7 @@ class TestAstronomy:
 
     def test_sun_earth_distance_correction(self):
         """Test the sun-earth distance correction."""
-        utc_time = datetime(2022, 6, 15, 12, 0, 0)
+        utc_time = dt.datetime(2022, 6, 15, 12, 0, 0)
         corr = astr.sun_earth_distance_correction(utc_time)
         corr_exp = 1.0156952156742332
         assert corr == pytest.approx(corr_exp, abs=1e-8)


=====================================
pyorbital/tests/test_geoloc.py
=====================================
@@ -23,12 +23,23 @@
 """Test the geoloc module."""
 
 
-from datetime import datetime
+import datetime as dt
 
 import numpy as np
 
 from pyorbital.geoloc import ScanGeometry, geodetic_lat, qrotate, subpoint
-from pyorbital.geoloc_instrument_definitions import amsua, ascat, atms, avhrr, hirs4, mhs, slstr_nadir, viirs
+from pyorbital.geoloc_instrument_definitions import (
+    amsua,
+    ascat,
+    atms,
+    avhrr,
+    avhrr_from_times,
+    avhrr_gac_from_times,
+    hirs4,
+    mhs,
+    slstr_nadir,
+    viirs,
+)
 
 
 class TestQuaternion:
@@ -97,6 +108,14 @@ class TestGeoloc:
         expected = np.array([0.0, 0.0, -1.0])
         np.testing.assert_allclose(result, expected, rtol=1e-8, atol=1e-8)
 
+        # Check if we can pass an array for yaw
+        vec = instrument.vectors(pos, vel, yaw=[0])
+
+        result = vec[:, 0, 1]
+        expected = np.array([0.0, 0.0, -1.0])
+        np.testing.assert_allclose(result, expected, rtol=1e-8, atol=1e-8)
+
+
         # minus sin because we use trigonometrical direction of angles
         result = vec[:, 0, 0]
         expected = np.array([0, -np.sin(np.deg2rad(10)), -np.cos(np.deg2rad(10))])
@@ -108,7 +127,7 @@ class TestGeoloc:
 
         # Test times
 
-        start_of_scan = np.datetime64(datetime(2014, 1, 8, 11, 30))
+        start_of_scan = np.datetime64(dt.datetime(2014, 1, 8, 11, 30))
         times = instrument.times(start_of_scan)
 
         assert times[0, 1] == start_of_scan
@@ -174,6 +193,52 @@ class TestGeolocDefs:
         np.testing.assert_allclose(np.rad2deg(avh.fovs[0]),
                                    np.array([[10, 0, -10]]))
 
+    def test_avhrr_from_times(self):
+        """Test generating the avhrr from times."""
+        avh = avhrr_from_times([dt.datetime(2000,1,1,0,0,0)], [0, 1023.5, 2047])
+        result = np.rad2deg(avh.fovs[0])
+        expected = np.array([[55.37, 0, -55.37]])
+        np.testing.assert_allclose(result, expected, rtol=1e-7, atol=1e-7)
+        result = avh.times(dt.date(2000,1,1))
+        expected = ((np.array([[0, 1023.5, 2047]]) * 25000).astype("timedelta64[ns]")
+                    + np.datetime64("2000-01-01T00:00:00"))
+        np.testing.assert_equal(result, expected)
+
+        avh = avhrr_from_times([dt.datetime(2000,1,1,0,0,0)], np.array([0, 1023.5, 2047]), 10)
+        np.testing.assert_allclose(np.rad2deg(avh.fovs[0]),
+                                   np.array([[10, 0, -10]]))
+
+        avh = avhrr_from_times([dt.datetime(2000,1,1,0,0,0), dt.datetime(2000,1,1,0,1,0)],
+                    [0, 2047])
+        times = avh.times(dt.datetime(2001,1,1))
+        expected = (np.array([[0,51175000],[60000000000, 60051175000]]).astype("timedelta64[ns]")
+                    + np.datetime64("2001-01-01"))
+        np.testing.assert_equal(times, expected)
+
+
+    def test_avhrr_gac_from_times(self):
+        """Test getting avhrr gac from times."""
+        avh = avhrr_gac_from_times([dt.datetime(2000,1,1,0,0,0)], [0, 204, 408])
+        result = np.rad2deg(avh.fovs[0])
+        expected = np.array([[55.180655, 0, -55.180655]])
+        np.testing.assert_allclose(result, expected, rtol=1e-7, atol=1e-7)
+        result = avh.times(dt.date(2000,1,1))
+        expected = ((np.array([[0, 204, 408]]) * 125000).astype("timedelta64[ns]")
+                    + np.datetime64("2000-01-01T00:00:00"))
+        np.testing.assert_equal(result, expected)
+
+        avh = avhrr_gac_from_times([dt.datetime(2000,1,1,0,0,0)], np.array([0, 204, 408]), 10)
+        np.testing.assert_allclose(np.rad2deg(avh.fovs[0]),
+                                   np.array([[9.965804, 0, -9.965804]]))
+
+        avh = avhrr_gac_from_times([dt.datetime(2000,1,1,0,0,0), dt.datetime(2000,1,1,0,1,0)],
+                    [0, 408])
+        times = avh.times(dt.datetime(2001,1,1))
+        expected = (np.array([[0,51000000],[60000000000, 60051000000]]).astype("timedelta64[ns]")
+                    + np.datetime64("2001-01-01"))
+        np.testing.assert_equal(times, expected)
+
+
     def test_viirs(self):
         """Test the definition of the viirs instrument."""
         geom = viirs(1, np.array([0, 3200, 6399]))


=====================================
pyorbital/tests/test_orbital.py
=====================================
@@ -22,8 +22,8 @@
 
 """Test the geoloc orbital."""
 
+import datetime as dt
 import unittest
-from datetime import datetime, timedelta, timezone
 from unittest import mock
 
 import numpy as np
@@ -44,7 +44,7 @@ class Test(unittest.TestCase):
                                     "-.00000112  00000-0 -32693-4 0   772",
                               line2="2 37849  98.7026 317.8811 0001845  "
                                     "92.4533 267.6830 14.19582686 11574")
-        dobj = datetime(2012, 1, 18, 8, 4, 19)
+        dobj = dt.datetime(2012, 1, 18, 8, 4, 19)
         orbnum = sat.get_orbit_number(dobj)
         assert orbnum == 1163
 
@@ -55,7 +55,7 @@ class Test(unittest.TestCase):
                                     ".00021906  00000-0  28403-3 0  8652",
                               line2="2 25544  51.6361  13.7980 0004256  "
                                     "35.6671  59.2566 15.58778559250029")
-        d = datetime(2003, 3, 23, 0, 3, 22)
+        d = dt.datetime(2003, 3, 23, 0, 3, 22)
         lon, lat, alt = sat.get_lonlatalt(d)
         expected_lon = -68.199894472013213
         expected_lat = 23.159747677881075
@@ -71,7 +71,7 @@ class Test(unittest.TestCase):
                                     ".00021906  00000-0  28403-3 0  8652",
                               line2="2 25544  51.6361  13.7980 0004256  "
                                     "35.6671  59.2566 15.58778559250029")
-        d = datetime(2003, 3, 23, 0, 3, 22)
+        d = dt.datetime(2003, 3, 23, 0, 3, 22)
         az, el = sat.get_observer_look(d, -84.39733, 33.775867, 0)
         expected_az = 122.45169655331965
         expected_el = 1.9800219611255456
@@ -85,7 +85,7 @@ class Test(unittest.TestCase):
                                     ".00000092  00000-0  62081-4 0  5221",
                               line2="2 29499  98.6804 312.6735 0001758 "
                                     "111.9178 248.2152 14.21501774254058")
-        d = datetime(2011, 9, 14, 5, 30)
+        d = dt.datetime(2011, 9, 14, 5, 30)
         assert sat.get_orbit_number(d) == 25437
 
     def test_orbit_num_non_an(self):
@@ -105,8 +105,8 @@ class Test(unittest.TestCase):
                                     ".00000048  00000-0  43679-4 0  4334",
                               line2="2 37849  98.7444   1.0588 0001264  "
                                     "63.8791 102.8546 14.19528338 69643")
-        t1 = datetime(2013, 3, 2, 22, 2, 25)
-        t2 = datetime(2013, 3, 2, 22, 2, 26)
+        t1 = dt.datetime(2013, 3, 2, 22, 2, 25)
+        t2 = dt.datetime(2013, 3, 2, 22, 2, 26)
         on1 = sat.get_orbit_number(t1)
         on2 = sat.get_orbit_number(t2)
         assert on1 == 6973
@@ -125,9 +125,9 @@ class Test(unittest.TestCase):
                 "89.8714 270.2713 14.34246429 90794"
 
         orb = orbital.Orbital("IRIDIUM 7 [+]", line1=line1, line2=line2)
-        d = datetime(2018, 3, 7, 3, 30, 15)
+        d = dt.datetime(2018, 3, 7, 3, 30, 15)
         res = orb.get_next_passes(d, 1, 170.556, -43.368, 0.5, horizon=40)
-        assert abs(res[0][2] - datetime(2018, 3, 7, 3, 48, 13, 178439)) < timedelta(seconds=0.01)
+        assert abs(res[0][2] - dt.datetime(2018, 3, 7, 3, 48, 13, 178439)) < dt.timedelta(seconds=0.01)
 
     def test_get_next_passes_tricky(self):
         """Check issue #34 for reference."""
@@ -138,12 +138,12 @@ class Test(unittest.TestCase):
             "157.6344 202.5362 15.23132245036381"
 
         orb = orbital.Orbital("LEMUR-2-BROWNCOW", line1=line1, line2=line2)
-        d = datetime(2018, 9, 8)
+        d = dt.datetime(2018, 9, 8)
 
         res = orb.get_next_passes(d, 72, -8.174163, 51.953319, 0.05, horizon=5)
 
-        assert abs(res[0][2] - datetime(2018, 9, 8, 9, 5, 46, 375248)) < timedelta(seconds=0.01)
-        assert abs(res[-1][2] - datetime(2018, 9, 10, 22, 15, 3, 143469)) < timedelta(seconds=0.01)
+        assert abs(res[0][2] - dt.datetime(2018, 9, 8, 9, 5, 46, 375248)) < dt.timedelta(seconds=0.01)
+        assert abs(res[-1][2] - dt.datetime(2018, 9, 10, 22, 15, 3, 143469)) < dt.timedelta(seconds=0.01)
 
         assert len(res) == 15
 
@@ -153,7 +153,7 @@ class Test(unittest.TestCase):
         line2 = "2 28654  99.0035 147.6583 0014816 159.4931 200.6838 14.12591533816498"
 
         orb = orbital.Orbital("NOAA 18", line1=line1, line2=line2)
-        t = datetime(2021, 3, 9, 22)
+        t = dt.datetime(2021, 3, 9, 22)
         next_passes = orb.get_next_passes(t, 1, -15.6335, 27.762, 0.)
         rise, fall, max_elevation = next_passes[0]
         assert rise < max_elevation < fall
@@ -167,7 +167,7 @@ class Test(unittest.TestCase):
                                     ".00000017  00000-0  27793-4 0  9819",
                               line2="2 29499  98.6639 121.6164 0001449  "
                                     "71.9056  43.3132 14.21510544330271")
-        assert sat.utc2local(datetime(2009, 7, 1, 12)) == datetime(2009, 7, 1, 9)
+        assert sat.utc2local(dt.datetime(2009, 7, 1, 12)) == dt.datetime(2009, 7, 1, 9)
 
     @mock.patch("pyorbital.orbital.Orbital.utc2local")
     @mock.patch("pyorbital.orbital.Orbital.get_orbit_number")
@@ -187,21 +187,21 @@ class Test(unittest.TestCase):
                                     "71.9056  43.3132 14.21510544330271")
 
         # Ascending node
-        res = sat.get_equatorial_crossing_time(tstart=datetime(2009, 7, 1, 12),
-                                               tend=datetime(2009, 7, 1, 13))
-        exp = datetime(2009, 7, 1, 12, 38, 12)
-        assert res - exp < timedelta(seconds=0.01)
+        res = sat.get_equatorial_crossing_time(tstart=dt.datetime(2009, 7, 1, 12),
+                                               tend=dt.datetime(2009, 7, 1, 13))
+        exp = dt.datetime(2009, 7, 1, 12, 38, 12)
+        assert res - exp < dt.timedelta(seconds=0.01)
 
         # Descending node
-        res = sat.get_equatorial_crossing_time(tstart=datetime(2009, 7, 1, 12),
-                                               tend=datetime(2009, 7, 1, 14, 0),
+        res = sat.get_equatorial_crossing_time(tstart=dt.datetime(2009, 7, 1, 12),
+                                               tend=dt.datetime(2009, 7, 1, 14, 0),
                                                node="descending")
-        exp = datetime(2009, 7, 1, 13, 38, 12)
-        assert res - exp < timedelta(seconds=0.01)
+        exp = dt.datetime(2009, 7, 1, 13, 38, 12)
+        assert res - exp < dt.timedelta(seconds=0.01)
 
         # Conversion to local time
-        res = sat.get_equatorial_crossing_time(tstart=datetime(2009, 7, 1, 12),
-                                               tend=datetime(2009, 7, 1, 14),
+        res = sat.get_equatorial_crossing_time(tstart=dt.datetime(2009, 7, 1, 12),
+                                               tend=dt.datetime(2009, 7, 1, 14),
                                                local_time=True)
         assert res == "local_time"
 
@@ -211,7 +211,7 @@ class TestGetObserverLook(unittest.TestCase):
 
     def setUp(self):
         """Set up the test environment."""
-        self.t = datetime(2018, 1, 1, 0, 0, 0)
+        self.t = dt.datetime(2018, 1, 1, 0, 0, 0)
         self.sat_lon = np.array([[-89.5, -89.4, -89.5, -89.4],
                                  [-89.3, -89.2, -89.3, -89.2]])
         self.sat_lat = np.array([[45.5, 45.4, 45.5, 45.4],
@@ -315,7 +315,7 @@ class TestGetObserverLookNadir(unittest.TestCase):
           2 error for xarray with numpy
         """
         rng = np.random.RandomState(125)
-        self.t = datetime(2018, 1, 1, 0, 0, 0)
+        self.t = dt.datetime(2018, 1, 1, 0, 0, 0)
         self.sat_lon = 360 * rng.rand(100) - 180
         self.sat_lat = 180 * rng.rand(100) - 90
         self.sat_alt = rng.rand(100) + 850
@@ -408,13 +408,13 @@ class TestRegressions(unittest.TestCase):
         orb = Orbital("Suomi-NPP",
                       line1="1 37849U 11061A   19292.84582509  .00000011  00000-0  25668-4 0  9997",
                       line2="2 37849  98.7092 229.3263 0000715  98.5313 290.6262 14.19554485413345")
-        orb.get_next_passes(datetime(2019, 10, 21, 16, 0, 0), 12, 123.29736, -13.93763, 0)
+        orb.get_next_passes(dt.datetime(2019, 10, 21, 16, 0, 0), 12, 123.29736, -13.93763, 0)
         warnings.filterwarnings("default")
 
 
 @pytest.mark.parametrize("dtime",
-                         [datetime(2024, 6, 25, 11, 0, 18),
-                          datetime(2024, 6, 25, 11, 5, 0, 0, timezone.utc),
+                         [dt.datetime(2024, 6, 25, 11, 0, 18),
+                          dt.datetime(2024, 6, 25, 11, 5, 0, 0, dt.timezone.utc),
                           np.datetime64("2024-06-25T11:10:00.000000")
                           ]
                          )
@@ -431,7 +431,7 @@ def test_get_last_an_time_scalar_input(dtime):
 
 
 @pytest.mark.parametrize("dtime",
-                         [datetime(2024, 6, 25, 11, 5, 0, 0, timezone(timedelta(hours=1))),
+                         [dt.datetime(2024, 6, 25, 11, 5, 0, 0, dt.timezone(dt.timedelta(hours=1))),
                           ]
                          )
 def test_get_last_an_time_wrong_input(dtime):


=====================================
pyorbital/tests/test_tlefile.py
=====================================
@@ -20,7 +20,7 @@
 """Test TLE file reading, TLE downloading and stroging TLEs to database."""
 
 
-import datetime
+import datetime as dt
 import logging
 import os
 import time
@@ -405,8 +405,8 @@ class TLETest(unittest.TestCase):
         assert tle.id_launch_piece.strip() == "A"
         assert tle.epoch_year == "08"
         assert tle.epoch_day == 264.51782528
-        epoch = (datetime.datetime(2008, 1, 1)
-                 + datetime.timedelta(days=264.51782528 - 1))
+        epoch = (dt.datetime(2008, 1, 1)
+                 + dt.timedelta(days=264.51782528 - 1))
         assert tle.epoch == epoch
         assert tle.mean_motion_derivative == -2.182e-05
         assert tle.mean_motion_sec_derivative == 0.0
@@ -774,7 +774,7 @@ class TestSQLiteTLE(unittest.TestCase):
         # TLE
         assert data[0][1] == "\n".join((LINE1, LINE2))
         # Date when the data were added should be close to current time
-        date_added = datetime.datetime.strptime(data[0][2], ISO_TIME_FORMAT)
+        date_added = dt.datetime.strptime(data[0][2], ISO_TIME_FORMAT)
         now = _utcnow()
         assert (now - date_added).total_seconds() < 1.0
         # Source of the data
@@ -786,7 +786,7 @@ class TestSQLiteTLE(unittest.TestCase):
         res = self.db.db.execute(f"select * from '{satid:d}'")  # noseq
         data = res.fetchall()
         assert len(data) == 1
-        date_added2 = datetime.datetime.strptime(data[0][2], ISO_TIME_FORMAT)
+        date_added2 = dt.datetime.strptime(data[0][2], ISO_TIME_FORMAT)
         assert date_added == date_added2
         # Source of the data
         assert data[0][3] == "foo"



View it on GitLab: https://salsa.debian.org/debian-gis-team/pyorbital/-/compare/a73b71915e506386f57adffcb3849477dbcb23aa...a756c6320eb84285503640e56d02054e8f11c75c

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyorbital/-/compare/a73b71915e506386f57adffcb3849477dbcb23aa...a756c6320eb84285503640e56d02054e8f11c75c
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20250412/0961fe51/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list