Skip to content

Commit

Permalink
Merge branch 'main' into add-noaa21
Browse files Browse the repository at this point in the history
# Conflicts:
#	.stickler.yml
  • Loading branch information
Adam.Dybbroe committed Apr 29, 2024
2 parents f7f55df + 4fb9ff6 commit 0e1319e
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 166 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: ["3.8", "3.9", "3.10"]
python-version: ["3.10", "3.11", "3.12"]
experimental: [false]
steps:
- name: Checkout source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -29,7 +29,7 @@ jobs:
run: |
pytest --cov=trollsched trollsched/tests --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
env_vars: PYTHON_VERSION
2 changes: 1 addition & 1 deletion .stickler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ files:
ignore:
- 'docs/Makefile'
- 'docs/make.bat'

34 changes: 33 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
###############################################################################
## Version 0.7.1 (2024/02/16)


### Pull Requests Merged

#### Features added

* [PR 85](https://github.com/pytroll/pytroll-schedule/pull/85) - Update CI Python versions
* [PR 84](https://github.com/pytroll/pytroll-schedule/pull/84) - Update versioneer

In this release 2 pull requests were closed.

## Version 0.7.0 (2023/06/21)

### Issues Closed

* [Issue 74](https://github.com/pytroll/pytroll-schedule/issues/74) - numpy 1.24.0 np.bool removed needs cleanup ([PR 72](https://github.com/pytroll/pytroll-schedule/pull/72) by [@mraspaud](https://github.com/mraspaud))
* [Issue 68](https://github.com/pytroll/pytroll-schedule/issues/68) - Test failure with PyResample 1.23 ([PR 72](https://github.com/pytroll/pytroll-schedule/pull/72) by [@mraspaud](https://github.com/mraspaud))

In this release 2 issues were closed.

### Pull Requests Merged

#### Features added

* [PR 72](https://github.com/pytroll/pytroll-schedule/pull/72) - Start refactoring pytroll schedule ([74](https://github.com/pytroll/pytroll-schedule/issues/74), [68](https://github.com/pytroll/pytroll-schedule/issues/68))
* [PR 71](https://github.com/pytroll/pytroll-schedule/pull/71) - Create dependabot.yml

In this release 2 pull requests were closed.


## Version 0.6.0 (2021/12/09)

### Issues Closed
Expand All @@ -18,7 +50,7 @@ In this release 7 issues were closed.

* [PR 61](https://github.com/pytroll/pytroll-schedule/pull/61) - Allow `mersi-2` as instrument name ([59](https://github.com/pytroll/pytroll-schedule/issues/59))
* [PR 56](https://github.com/pytroll/pytroll-schedule/pull/56) - Remove a bug introduced in PR38 ([52](https://github.com/pytroll/pytroll-schedule/issues/52))
* [PR 51](https://github.com/pytroll/pytroll-schedule/pull/51) - Remove some redundant code and fix a failed unit test.
* [PR 51](https://github.com/pytroll/pytroll-schedule/pull/51) - Remove some redundant code and fix a failed unit test.
* [PR 45](https://github.com/pytroll/pytroll-schedule/pull/45) - Use recent ssl protocol for older python versions
* [PR 38](https://github.com/pytroll/pytroll-schedule/pull/38) - Fix S3 olci scan duration

Expand Down
3 changes: 3 additions & 0 deletions trollsched/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@
'Metop-C': 'avhrr',
'FY-3D': 'avhrr',
'FY-3C': 'avhrr'}

from . import version
__version__ = version.get_versions()['version']
35 changes: 21 additions & 14 deletions trollsched/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,48 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Graph manipulation.
"""
"""Graph manipulation."""
import numpy as np


class Graph(object):
class Graph():
"""A graph class."""

def __init__(self, n_vertices=None, adj_matrix=None):
"""Set up the graph."""
if n_vertices is not None:
self.order = n_vertices
self.vertices = np.arange(self.order)
self.adj_matrix = np.zeros((self.order, self.order), np.bool)
self.weight_matrix = np.zeros((self.order, self.order), np.float)
self.adj_matrix = np.zeros((self.order, self.order), bool)
self.weight_matrix = np.zeros((self.order, self.order), float)
elif adj_matrix is not None:
self.order = adj_matrix.shape[0]
self.vertices = np.arange(self.order)
self.adj_matrix = adj_matrix
self.weight_matrix = np.zeros_like(adj_matrix)

def weight(self, u, v):
"""weight of the *u*-*v* edge.
"""
"""Weight of the *u*-*v* edge."""
return self.weight_matrix[u, v]

def neighbours(self, v):
"""Find neighbours."""
return self.vertices[self.adj_matrix[v, :] != 0]

def add_edge(self, v1, v2, weight=1):
"""Add an edge."""
self.weight_matrix[v1, v2] = weight
self.weight_matrix[v2, v1] = weight
self.adj_matrix[v1, v2] = True
self.adj_matrix[v2, v1] = True

def add_arc(self, v1, v2, weight=1):
"""Add an arc."""
self.adj_matrix[v1, v2] = True
self.weight_matrix[v1, v2] = weight

def bron_kerbosch(self, r, p, x):
"""Get the maximal cliques.
"""
"""Get the maximal cliques."""
if len(p) == 0 and len(x) == 0:
yield r
for v in p:
Expand All @@ -71,7 +73,9 @@ def bron_kerbosch(self, r, p, x):
x = x | set((v, ))

def dag_longest_path(self, v1, v2=None):
"""Give the longest path from *v1* to all other vertices or *v2* if
"""Find the longest path between v1 and v2.
Give the longest path from *v1* to all other vertices or *v2* if
specified. Assumes the vertices are sorted topologically and that the
graph is directed and acyclic (DAG).
"""
Expand All @@ -81,7 +85,9 @@ def dag_longest_path(self, v1, v2=None):
return dist, path

def dag_shortest_path(self, v1, v2=None):
"""Give the sortest path from *v1* to all other vertices or *v2* if
"""Find the shortest path between v1 and v2.
Give the shortest path from *v1* to all other vertices or *v2* if
specified. Assumes the vertices are sorted topologically and that the
graph is directed and acyclic (DAG). *v1* and *v2* are the indices of
the vertices in the vertice list.
Expand Down Expand Up @@ -111,22 +117,23 @@ def dag_shortest_path(self, v1, v2=None):
return dists[v2], path

def save(self, filename):
"""Save a file."""
np.savez_compressed(filename,
adj=self.adj_matrix,
weights=self.weight_matrix)

def load(self, filename):
"""Load a file."""
stuff = np.load(filename)
self.adj_matrix = stuff["adj"]
self.weight_matrix = stuff["weights"]
self.order = self.adj_matrix.shape[0]
self.vertices = np.arange(self.order)

def export(self, filename="./sched.gv", labels=None):
"""dot sched.gv -Tpdf -otruc.pdf
"""
"""dot sched.gv -Tpdf -otruc.pdf."""
with open(filename, "w") as fd_:
fd_.write("digraph schedule { \n size=\"80, 10\";\n center=\"1\";\n")
fd_.write('digraph schedule { \n size="80, 10";\n center="1";\n')
for v1 in range(1, self.order - 1):
for v2 in range(1, self.order - 1):
if self.adj_matrix[v1, v2]:
Expand Down
19 changes: 9 additions & 10 deletions trollsched/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@
# Older versions of pyresample:
from pyresample.utils import parse_area_file

from pyresample.boundary import AreaDefBoundary

from trollsched import utils
from trollsched import MIN_PASS, utils
from trollsched.combine import get_combined_sched
from trollsched.graph import Graph
from trollsched.satpass import SimplePass, get_next_passes
Expand All @@ -53,7 +52,7 @@ class Station:
"""docstring for Station."""

def __init__(self, station_id, name, longitude, latitude, altitude, area, satellites, area_file=None,
min_pass=None, local_horizon=0):
min_pass=MIN_PASS, local_horizon=0):
"""Initialize the station."""
self.id = station_id
self.name = name
Expand Down Expand Up @@ -96,7 +95,7 @@ def single_station(self, sched, start_time, tle_file):

allpasses = self.get_next_passes(opts, sched, start_time, tle_file)

area_boundary = AreaDefBoundary(self.area, frequency=500)
area_boundary = self.area.boundary(8)
self.area.poly = area_boundary.contour_poly

if opts.plot:
Expand Down Expand Up @@ -538,15 +537,15 @@ def send_file(url, file):
del pathname
if url.scheme in ["file", ""]:
pass
elif url.scheme == "ftp":
elif url.scheme in ["ftp", b"ftp"]:
import ftplib
session = ftplib.FTP(url.hostname, url.username, url.password)
with open(file, "rb") as xfile:
session.storbinary("STOR " + str(filename), xfile)
session.quit()
else:
logger.error("Cannot save to %s, but file is there:",
str(url.scheme), str(file))
(str(url.scheme), str(file)))


def combined_stations(scheduler, start_time, graph, allpasses):
Expand Down Expand Up @@ -668,11 +667,11 @@ def collect_labels(newpasses, stats):
logger.info("Finished coordinated schedules.")


def run():
def run(args=None):
"""The schedule command."""
global logger

opts = parse_args()
opts = parse_args(args)

if opts.config:
# read_config() returns:
Expand Down Expand Up @@ -787,7 +786,7 @@ def setup_logging(opts):
logger = logging.getLogger("trollsched")


def parse_args():
def parse_args(args=None):
"""Parse arguments from the command line."""
parser = argparse.ArgumentParser()
# general arguments
Expand Down Expand Up @@ -849,7 +848,7 @@ def parse_args():
help="generate a MEOS schedule file")
group_outp.add_argument("--metno-xml", action="store_true",
help="generate a METNO xml pass data file")
opts = parser.parse_args()
opts = parser.parse_args(args)

if (not opts.config) and (not (opts.lon or opts.lat or opts.alt)):
parser.error("Coordinates must be provided in the absence of "
Expand Down
67 changes: 66 additions & 1 deletion trollsched/tests/test_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
from unittest.mock import patch

import pytest
import yaml

from trollsched.satpass import get_aqua_terra_dumps, get_metopa_passes, get_next_passes
from trollsched.schedule import build_filename, conflicting_passes, fermia, fermib
from trollsched.schedule import build_filename, conflicting_passes, fermia, fermib, run


class TestTools:
Expand Down Expand Up @@ -312,3 +313,67 @@ def test_get_metopa_passes(self, exists):
assert metopa_passes[0].seconds() == pytest.approx(487.512589, 1e-5)
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


euron1 = """euron1:
description: Northern Europe - 1km
projection:
proj: stere
ellps: WGS84
lat_0: 90.0
lon_0: 0.0
lat_ts: 60.0
shape:
height: 3072
width: 3072
area_extent:
lower_left_xy: [-1000000.0, -4500000.0]
upper_right_xy: [2072000.0, -1428000.0]
"""



def test_pyorbitals_platform_name(tmp_path):
"""Test that using pyorbital's platform name allows spurious names in the TLE data."""
spurious_tle = ("NOAA 20 (JPSS-1)\n"
"1 43013U 17073A 24093.57357837 .00000145 00000+0 86604-4 0 9999\n"
"2 43013 98.7039 32.7741 0007542 324.8026 35.2652 14.21254587330172\n")


config_file = tmp_path / "config.yaml"
tle_file = tmp_path / "test.tle"
area_file = tmp_path / "areas.yaml"
sched_file = tmp_path / "mysched.xml"

with open(area_file, "w") as fd:
fd.write(euron1)

with open(tle_file, "w") as fd:
fd.write(spurious_tle)


config = dict(default=dict(station=["nrk"],
forward=12,
start=0,
center_id="SMHI"),
stations=dict(nrk=dict(name="nrk",
longitude=16,
latitude=58,
altitude=0,
satellites=["noaa-20"],
area="euron1",
area_file=os.fspath(area_file))),

pattern=dict(dir_output=os.fspath(tmp_path),
file_xml=os.fspath(sched_file)),
satellites={"noaa-20": dict(schedule_name="noaa20",
international_designator="43013",
night=0.4,
day=0.9)}
)

with open(config_file, "w") as fd:
fd.write(yaml.dump(config))

run(["-c", os.fspath(config_file), "-x", "-t", os.fspath(tle_file)])
assert sched_file in tmp_path.iterdir()
Loading

0 comments on commit 0e1319e

Please sign in to comment.