[Git][debian-gis-team/pytroll-schedule][upstream] New upstream version 0.7.5

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Aug 10 18:04:26 BST 2025



Antonio Valentino pushed to branch upstream at Debian GIS Project / pytroll-schedule


Commits:
2776a7a1 by Antonio Valentino at 2025-08-09T10:20:23+00:00
New upstream version 0.7.5
- - - - -


9 changed files:

- CHANGELOG.md
- pyproject.toml
- trollsched/__init__.py
- trollsched/drawing.py
- trollsched/satpass.py
- trollsched/schedule.py
- trollsched/tests/test_satpass.py
- trollsched/tests/test_schedule.py
- trollsched/writers.py


Changes:

=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,32 @@
+## Version 0.7.5 (2025/06/12)
+
+### Issues Closed
+
+* [Issue 103](https://github.com/pytroll/pytroll-schedule/issues/103) - Add write the metno xml schedule
+* [Issue 101](https://github.com/pytroll/pytroll-schedule/issues/101) - The generation of metno xml file failes with AttributeError in main
+
+In this release 2 issues were closed.
+
+###############################################################################
+## Version 0.7.3 (2025/04/30)
+
+### Issues Closed
+
+* [Issue 99](https://github.com/pytroll/pytroll-schedule/issues/99) - Build sometimes allocates 24 GB of RAM ([PR 100](https://github.com/pytroll/pytroll-schedule/pull/100) by [@mraspaud](https://github.com/mraspaud))
+* [Issue 96](https://github.com/pytroll/pytroll-schedule/issues/96) - Add fengyun3f mersi-3
+* [Issue 65](https://github.com/pytroll/pytroll-schedule/issues/65) - Mapping in collections is depricated since 3.3 and removed in 3.10
+
+In this release 3 issues were closed.
+
+### Pull Requests Merged
+
+#### Bugs fixed
+
+* [PR 100](https://github.com/pytroll/pytroll-schedule/pull/100) - Fix test running long ([99](https://github.com/pytroll/pytroll-schedule/issues/99))
+
+In this release 1 pull request was closed.
+
+
 ###############################################################################
 ## Version 0.7.2 (2025/01/08)
 


=====================================
pyproject.toml
=====================================
@@ -37,6 +37,9 @@ compare_scheds = "trollsched.compare:run"
 
 [project.optional-dependencies]
 doc = ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-apidoc"]
+test = [
+    "pytest>=8.3.5",
+]
 
 [build-system]
 requires = ["hatchling", "hatch-vcs"]


=====================================
trollsched/__init__.py
=====================================
@@ -56,7 +56,9 @@ SATELLITE_NAMES = {"npp": "Suomi NPP",
                    "noaa21": "NOAA-21",
                    "noaa22": "NOAA-22",
                    "fengyun3d": "FY-3D",
-                   "fengyun3c": "FY-3C"
+                   "fengyun3c": "FY-3C",
+                   "fengyun3e": "FY-3E",
+                   "fengyun3f": "FY-3F"
                    }
 
 INSTRUMENT = {"Suomi NPP": "viirs",
@@ -80,6 +82,7 @@ VIIRS_PLATFORM_NAMES = ["SUOMI NPP", "SNPP",
 MERSI_PLATFORM_NAMES = ["FENGYUN 3C", "FENGYUN-3C", "FY-3C"]
 MERSI2_PLATFORM_NAMES = ["FENGYUN 3D", "FENGYUN-3D", "FY-3D",
                          "FENGYUN 3E", "FENGYUN-3E", "FY-3E"]
+MERSI3_PLATFORM_NAMES = ["FENGYUN 3F", "FENGYUN-3F", "FY-3F"]
 
 SATELLITE_MEOS_TRANSLATION = {"NOAA 19": "NOAA_19",
                               "NOAA 18": "NOAA_18",


=====================================
trollsched/drawing.py
=====================================
@@ -25,6 +25,7 @@
 import logging
 import logging.handlers
 import os
+from tempfile import gettempdir
 
 import matplotlib as mpl
 import numpy as np
@@ -47,7 +48,7 @@ if not BASEMAP_NOT_CARTOPY:
         "CARTOPY_PRE_EXISTING_DATA_DIR", cartopy.config["pre_existing_data_dir"])
 
 
-class MapperBasemap(object):
+class MapperBasemap:
     """A class to generate nice plots with basemap."""
 
     def __init__(self, **proj_info):
@@ -74,13 +75,15 @@ class MapperBasemap(object):
         self.map.drawparallels(np.arange(-90, 90, 30))
 
     def __enter__(self):
+        """Enter the mapper context."""
         return self.map
 
     def __exit__(self, etype, value, tb):
+        """Exit the mapper context."""
         pass
 
 
-class MapperCartopy(object):
+class MapperCartopy:
     """A class to generate nice plots with Cartopy."""
 
     def __init__(self, **proj_info):
@@ -127,24 +130,24 @@ class MapperCartopy(object):
         fill_dark_side(self._ax, time=utctime, color=color, alpha=alpha)
 
     def __call__(self, *args):
+        """Call the mapper."""
         return args
 
     def __enter__(self):
+        """Enter the mapper context."""
         return self
 
     def __exit__(self, etype, value, tb):
+        """Exit the mapper context."""
         pass
 
 
-if BASEMAP_NOT_CARTOPY:
-    Mapper = MapperBasemap
-else:
-    Mapper = MapperCartopy
+Mapper = MapperBasemap if BASEMAP_NOT_CARTOPY else MapperCartopy
 
 
 def save_fig(pass_obj,
              poly=None,
-             directory="/tmp/plots",
+             directory=None,
              overwrite=False,
              labels=None,
              extension=".png",
@@ -167,6 +170,8 @@ def save_fig(pass_obj,
     logger.debug("Save fig " + str(pass_obj))
     rise = pass_obj.risetime.strftime("%Y%m%d%H%M%S")
     fall = pass_obj.falltime.strftime("%Y%m%d%H%M%S")
+    if directory is None:
+        directory = os.path.join(gettempdir(), "plots")
     if not os.path.exists(directory):
         logger.debug("Create plot dir " + directory)
         os.makedirs(directory)
@@ -247,8 +252,10 @@ def main():
     from trollsched.satpass import get_next_passes
 
     passes = get_next_passes(["noaa 19", "suomi npp"], datetime.now(), 24, (16, 58, 0))
+
+    directory = os.path.join(gettempdir(), "plots")
     for p in passes:
-        save_fig(p, directory="/tmp/plots/")
+        save_fig(p, directory=directory)
 
 
 if __name__ == "__main__":


=====================================
trollsched/satpass.py
=====================================
@@ -44,6 +44,7 @@ from pyresample.boundary import AreaDefBoundary
 from trollsched import (
     JPSS_TLE_NAMES,
     MERSI2_PLATFORM_NAMES,
+    MERSI3_PLATFORM_NAMES,
     MERSI_PLATFORM_NAMES,
     MIN_PASS,
     NUMBER_OF_FOVS,
@@ -172,6 +173,9 @@ class Pass(SimplePass):
             elif "mersi-2" in instrument:
                 logger.warning("Instrument is a sequence! Assume mersi-2...")
                 instrument = "mersi-2"
+            elif "mersi-3" in instrument:
+                logger.warning("Instrument is a sequence! Assume mersi-3...")
+                instrument = "mersi-3"
             else:
                 raise TypeError("Instrument is a sequence! Don't know which one to choose!")
 
@@ -578,6 +582,8 @@ def get_next_passes(satellites,
                 instrument = "mersi"
             elif sat.name.upper() in MERSI2_PLATFORM_NAMES:
                 instrument = "mersi-2"
+            elif sat.name.upper() in MERSI3_PLATFORM_NAMES:
+                instrument = "mersi-3"
             else:
                 instrument = "unknown"
 


=====================================
trollsched/schedule.py
=====================================
@@ -137,7 +137,11 @@ class Station:
             logger.info("Done!")
 
         if opts.metno_xml:
-            generate_metno_xml_file(build_filename("file_metno_xml", pattern, pattern_args), allpasses,
+            generate_metno_xml_file(build_filename("file_metno_xml_all", pattern, pattern_args), allpasses,
+                                    self.coords, start_time + timedelta(hours=sched.start),
+                                    start_time + timedelta(hours=sched.forward), self.id, sched.center_id,
+                                    report_mode=True)
+            generate_metno_xml_file(build_filename("file_metno_xml", pattern, pattern_args), schedule,
                                     self.coords, start_time + timedelta(hours=sched.start),
                                     start_time + timedelta(hours=sched.forward), self.id, sched.center_id,
                                     report_mode=True)


=====================================
trollsched/tests/test_satpass.py
=====================================
@@ -372,6 +372,13 @@ class TestSwathBoundary:
         cov = mypass.area_coverage(self.euron1)
         assert cov == pytest.approx(0.786836, 1e-5)
 
+        tstart = datetime.strptime("2025-03-03T11:53:01", "%Y-%m-%dT%H:%M:%S")
+        tend = tstart + timedelta(seconds=60*12.2)
+        tle1 = "1 57490U 23111A   25061.77275788  .00000196  00000+0  11297-3 0  9996"
+        tle2 = "2 57490  98.7372 134.1450 0001865  84.6719 275.4671 14.20001545 81964"
+        mypass = Pass("FENGYUN 3F", tstart, tend, instrument="mersi-3", tle1=tle1, tle2=tle2, frequency=100)
+        cov = mypass.area_coverage(self.euron1)
+        assert cov == pytest.approx(0.70125, 1e-5)
 
     def test_arctic_is_not_antarctic(self):
         """Test that artic and antarctic are not mixed up."""


=====================================
trollsched/tests/test_schedule.py
=====================================
@@ -45,7 +45,7 @@ class TestTools:
                 self.risetime = rise
                 self.falltime = fall
 
-        ref_time = datetime.utcnow()
+        ref_time = datetime(2020, 1, 1, 18, 0)
         passes = [MyPass(ref_time, ref_time + timedelta(minutes=10)),
                   MyPass(ref_time + timedelta(minutes=10.01),
                          ref_time + timedelta(minutes=20))]
@@ -314,6 +314,39 @@ class TestAll:
             assert (metopa_passes[0].uptime - datetime(2018, 12, 4, 9, 17, 48, 530484)).seconds == 0
             assert (metopa_passes[0].risetime - datetime(2018, 12, 4, 9, 17, 21, 644605)).seconds == 0
 
+    def test_write_metno_xml(self, tmp_path):
+        """Test that writing pass list in metno xml format work as expected."""
+        from datetime import timezone
+        from trollsched.writers import generate_metno_xml_file
+        import defusedxml.ElementTree as ET
+
+        with open(tmp_path / "tle.file", "wt") as f:
+            f.write(self.satellites[0].upper() + "\n")
+            f.write(self.tles[self.satellites[0]]['line1'] + "\n")
+            f.write(self.tles[self.satellites[0]]['line2'] + "\n")
+            f.close()
+
+            allpasses = get_next_passes(self.satellites, self.utctime,
+                                        4, (16, 58, 0), tle_file=str(tmp_path / "tle.file"))
+            coords = (10, 60, 0.1)
+            written_test_file = generate_metno_xml_file(tmp_path / "test.xml", allpasses,
+                                                        coords, self.utctime,
+                                                        self.utctime + timedelta(hours=5), "id", "center_id",
+                                                        report_mode=True)
+            # Read back to test content
+            tree = ET.parse(written_test_file)
+            root = tree.getroot()
+            assert root.find('properties/project').text == 'Pytroll'
+            assert root.find('properties/type').text == 'report'
+            assert root.find('properties/station').text == 'id'
+            assert root.find('properties/requested-by').text == 'center_id'
+            assert root.find('properties/file-start').text == '2018-11-28T10:00:00'
+            assert root.find('properties/file-end').text == '2018-11-28T15:00:00'
+            expected_aos = ['20181128105342', '20181128123444']
+            expected_los = ['20181128110906', '20181128124925']
+            for overpass, exp_aos, exp_los in zip(root.iter("pass"), expected_aos, expected_los):
+                assert overpass.attrib["aos"] == exp_aos
+                assert overpass.attrib["los"] == exp_los
 
 euron1 = """euron1:
   description: Northern Europe - 1km
@@ -372,7 +405,7 @@ def test_pyorbitals_platform_name(tmp_path):
     with open(config_file, "w") as fd:
         fd.write(yaml.dump(config))
 
-    run(["-c", os.fspath(config_file), "-x", "-t", os.fspath(tle_file)])
+    run(["-c", os.fspath(config_file), "-x", "-t", os.fspath(tle_file), "-s", "2024-03-30T15:00"])
     assert sched_file in tmp_path.iterdir()
 
 
@@ -436,10 +469,12 @@ def test_schedule_avoid(tmp_path):
 
     start_time = datetime(2024, 5, 8, 0, 0, 0)
     run(["-c", os.fspath(config_file), "-x", "-v", "-t", os.fspath(tle_file),
-         "--start-time", start_time.strftime("%Y-%m-%dT%H:%M:%S"), "--avoid", os.fspath(avoid_file)])
+         "--start-time", start_time.strftime("%Y-%m-%dT%H:%M:%S"),
+         "--avoid", os.fspath(avoid_file)])
     assert sched_file in tmp_path.iterdir()
 
     sched_file_passes = get_passes_from_xml_file([sched_file])
     avoid_file_passes = get_passes_from_xml_file([avoid_file])
     for avoid_pass in avoid_file_passes:
         assert avoid_pass not in sched_file_passes
+


=====================================
trollsched/writers.py
=====================================
@@ -41,7 +41,7 @@ def generate_sch_file(output_file, overpasses, coords):
 
 def generate_metno_xml_file(output_file, allpasses, coords, start, end, station_name, center_id, report_mode=False):
     """Generate a meto xml file."""
-    import defusedxml.ElementTree as ET
+    from xml.etree import ElementTree as ET  # noqa
 
     reqtime = datetime.utcnow()
     time_format = "%Y-%m-%dT%H:%M:%S"



View it on GitLab: https://salsa.debian.org/debian-gis-team/pytroll-schedule/-/commit/2776a7a13519ec12d8d5b972e1ff2a15bebff86a

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pytroll-schedule/-/commit/2776a7a13519ec12d8d5b972e1ff2a15bebff86a
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/20250810/1546c417/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list