diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 056fafa..f50189f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.6, 3.9] + python-version: [3.7, 3.9] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 diff --git a/README.md b/README.md index 0f413c5..6e9a6f3 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Batch converts NAV and OBS GPS RINEX (including Hatanaka compressed OBS) data in [xarray.Dataset](http://xarray.pydata.org/en/stable/api.html#dataset) for easy use in analysis and plotting. This gives remarkable speed vs. legacy iterative methods, and allows for HPC / out-of-core operations on massive amounts of GNSS data. -GeoRinex works in Python ≥ 3.6 and has over 125 unit tests driven by Pytest. +GeoRinex has over 125 unit tests driven by Pytest. Pure compiled language RINEX processors such as within Fortran NAPEOS give perhaps 2x faster performance than this Python program--that's pretty good for a scripted language like Python! However, the initial goal of this Python program was to be for one-time offline conversion of ASCII (and compressed ASCII) RINEX to HDF5/NetCDF4, diff --git a/setup.cfg b/setup.cfg index 5c8fb28..0cf0bc4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -55,6 +55,7 @@ lint = flake8-builtins flake8-blind-except mypy + types-python-dateutil plot = matplotlib seaborn diff --git a/src/georinex/base.py b/src/georinex/base.py index cf48ead..16735e5 100644 --- a/src/georinex/base.py +++ b/src/georinex/base.py @@ -59,13 +59,7 @@ def load( if tlim[1] < tlim[0]: raise ValueError("stop time must be after start time") - try: - info = rinexinfo(rinexfn) - except RuntimeError: - logging.error( - f"could not read {rinexfn} header. It may not be a known type of RINEX file." - ) - return None + info = rinexinfo(rinexfn) if info["rinextype"] == "nav": return rinexnav(rinexfn, outfn, use=use, tlim=tlim, overwrite=overwrite) diff --git a/src/georinex/geo.py b/src/georinex/geo.py index 48a0df6..a166cfa 100644 --- a/src/georinex/geo.py +++ b/src/georinex/geo.py @@ -19,7 +19,9 @@ def get_locations(files: list[Path]) -> pandas.DataFrame: if isinstance(files[0], io.StringIO): locs = pandas.DataFrame(index=["0"], columns=["lat", "lon", "interval"]) elif isinstance(files[0], Path): - locs = pandas.DataFrame(index=[file.name for file in files], columns=["lat", "lon", "interval"]) + locs = pandas.DataFrame( + index=[file.name for file in files], columns=["lat", "lon", "interval"] + ) else: raise TypeError("Expecting pathlib.Path") diff --git a/src/georinex/keplerian.py b/src/georinex/keplerian.py index 6ecc368..90007fc 100644 --- a/src/georinex/keplerian.py +++ b/src/georinex/keplerian.py @@ -9,7 +9,9 @@ import numpy as np -def keplerian2ecef(sv: xarray.DataArray) -> tuple[np.ndarray, np.ndarray, np.ndarray]: +def keplerian2ecef( + sv: xarray.Dataset, +) -> tuple[xarray.DataArray, xarray.DataArray, xarray.DataArray]: """ based on: https://ascelibrary.org/doi/pdf/10.1061/9780784411506.ap03 diff --git a/src/georinex/obs2.py b/src/georinex/obs2.py index a14521d..49c0d8f 100644 --- a/src/georinex/obs2.py +++ b/src/georinex/obs2.py @@ -403,7 +403,7 @@ def obsheader2( hdr["Nobs"] = len(hdr["fields"]) if isinstance(meas, (tuple, list, np.ndarray)): - ind = np.zeros(len(hdr["fields"]), dtype=bool) + ind: T.Any = np.zeros(len(hdr["fields"]), dtype=bool) for m in meas: for i, field in enumerate(hdr["fields"]): if field.startswith(m): diff --git a/src/georinex/obs3.py b/src/georinex/obs3.py index 2d4d468..a46637d 100644 --- a/src/georinex/obs3.py +++ b/src/georinex/obs3.py @@ -348,7 +348,7 @@ def obsheader3(f: T.TextIO, use: list[str] = None, meas: list[str] = None) -> di # perhaps this could be done more efficiently, but it's probably low impact on overall program. # simple set and frozenset operations do NOT preserve order, which would completely mess up reading! - sysind = {} + sysind: dict[str, T.Any] = {} if isinstance(meas, (tuple, list, np.ndarray)): for sk in fields: # iterate over each system # ind = np.isin(fields[sk], meas) # boolean vector diff --git a/src/georinex/tests/test_scripts.py b/src/georinex/tests/test_scripts.py index a6af6c3..e46ebb5 100755 --- a/src/georinex/tests/test_scripts.py +++ b/src/georinex/tests/test_scripts.py @@ -13,6 +13,7 @@ def test_convenience(): def test_time(): + pytest.importorskip("unlzw3") subprocess.check_call(["georinex_time", str(R)]) diff --git a/src/georinex/utils.py b/src/georinex/utils.py index 70790e6..ee63a35 100644 --- a/src/georinex/utils.py +++ b/src/georinex/utils.py @@ -117,7 +117,7 @@ def rinexheader(fn: T.TextIO | Path) -> dict[str, T.Any]: return hdr -def _tlim(tlim: tuple[str, str] | tuple[datetime, datetime] = None) -> tuple[datetime, datetime]: +def _tlim(tlim: tuple[datetime, datetime] = None) -> tuple[datetime, datetime]: if tlim is None: pass elif len(tlim) == 2 and isinstance(tlim[0], datetime):