[Git][debian-gis-team/pygac][upstream] New upstream version 1.7.4

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Fri Jul 19 08:14:22 BST 2024



Antonio Valentino pushed to branch upstream at Debian GIS Project / pygac


Commits:
dc834512 by Antonio Valentino at 2024-07-19T06:07:49+00:00
New upstream version 1.7.4
- - - - -


19 changed files:

- − .bumpversion.cfg
- .github/workflows/deploy-sdist.yaml
- .gitignore
- − .landscape.yaml
- .pre-commit-config.yaml
- − .stickler.yml
- CHANGELOG.md
- MANIFEST.in
- − bin/pygac-run
- pygac/calibration.py
- − pygac/gac_calibration.py_old
- − pygac/gac_io.py_old
- − pygac/investigate_bts1.m
- bin/pygac-convert-patmosx-coefficients → pygac/patmosx_coeff_reader.py
- pygac/reader.py
- pygac/tests/test_klm.py
- pyproject.toml
- − setup.cfg
- − setup.py


Changes:

=====================================
.bumpversion.cfg deleted
=====================================
@@ -1,6 +0,0 @@
-[bumpversion]
-current_version = 1.4.0
-commit = True
-tag = True
-
-[bumpversion:file:pygac/version.py]


=====================================
.github/workflows/deploy-sdist.yaml
=====================================
@@ -11,15 +11,17 @@ jobs:
 
     steps:
       - name: Checkout source
-        uses: actions/checkout at v2
+        uses: actions/checkout at v4
 
       - name: Create sdist
         shell: bash -l {0}
-        run: python setup.py sdist
+        run: |
+          python -m pip install -q build
+          python -m build -s
 
       - name: Publish package to PyPI
         if: github.event.action == 'published'
-        uses: pypa/gh-action-pypi-publish at v1.4.1
+        uses: pypa/gh-action-pypi-publish at v1.9.0
         with:
           user: __token__
           password: ${{ secrets.pypi_password }}


=====================================
.gitignore
=====================================
@@ -6,5 +6,11 @@ doc/build
 dist
 pygac.egg-info
 etc/*.cfg
-gapfilled_tles/
+gapfilled_tles/*
 pygac/version.py
+
+tmp
+.vscode
+.venv
+*.lock
+.python-version


=====================================
.landscape.yaml deleted
=====================================
@@ -1,11 +0,0 @@
-doc-warnings: yes
-test-warnings: yes
-strictness: high
-max-line-length: 120
-autodetect: yes
-ignore-paths:
-    - doc
-    - etc
-ignore-patterns:
-    - ^example/doc_.*\.py$
-    - (^|/)doc(/|$)


=====================================
.pre-commit-config.yaml
=====================================
@@ -1,8 +1,15 @@
 exclude: '^$'
 fail_fast: false
+
 repos:
--   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v2.2.3
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    # Ruff version.
+    rev: 'v0.3.2'
     hooks:
-    - id: flake8
-      additional_dependencies: [flake8-docstrings, flake8-debugger, flake8-bugbear]
+      - id: ruff
+        args: [--fix]
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.5.0
+    hooks:
+      - id: trailing-whitespace
+      - id: end-of-file-fixer


=====================================
.stickler.yml deleted
=====================================
@@ -1,7 +0,0 @@
-linters:
-  flake8:
-    fixer: true
-    python: 3
-    config: setup.cfg
-fixers:
-  enable: true


=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,21 @@
+## Version 1.7.4 (2024/07/17)
+
+### Issues Closed
+
+* [Issue 128](https://github.com/pytroll/pygac/issues/128) - Reading of files broken for numpy 2.0.0
+* [Issue 114](https://github.com/pytroll/pygac/issues/114) - Feature request: Overlap Area Crop just like pygac-fdr
+
+In this release 2 issues were closed.
+
+### Pull Requests Merged
+
+#### Features added
+
+* [PR 126](https://github.com/pytroll/pygac/pull/126) - Switch to `pyproject.toml`entirely
+
+In this release 1 pull request was closed.
+
+
 ## Version 1.7.3 (2024/03/19)
 
 


=====================================
MANIFEST.in
=====================================
@@ -1,6 +1,5 @@
-include etc/*
-include gapfilled_tles/*
-include bin/pygac-*
+include etc/pygac.cfg.template
+include gapfilled_tles/TLE_*.txt
 include LICENSE.txt
 include README.md
 include pygac/version.py


=====================================
bin/pygac-run deleted
=====================================
@@ -1,172 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2012, 2014 Abhay Devasthale and Martin Raspaud
-
-# Author(s):
-
-#   Abhay Devasthale <abhay.devasthale at smhi.se>
-#   Martin Raspaud <martin.raspaud at smhi.se>
-#   Carlos Horn <carlos.horn at external.eumetsat.int>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-"""Read a gac file.
-
-"""
-
-import argparse
-import logging
-import os
-import sys
-import tarfile
-from datetime import datetime
-from functools import wraps
-
-import pygac
-
-if sys.version_info.major < 3:
-    class FileNotFoundError(OSError):
-        pass
-
-logger = logging.getLogger("pygac")
-
-verbosity2loglevel = {
-    1: logging.INFO,
-    2: logging.DEBUG
-}
-
-class MyFormatter(logging.Formatter):
-    converter = datetime.fromtimestamp
-
-    def formatTime(self, record, datefmt=None):
-        ct = self.converter(record.created)
-        if datefmt:
-            s = ct.strftime(datefmt)
-        else:
-            t = ct.strftime("%Y-%m-%d %H:%M:%S")
-            s = "%s.%03d" % (t, record.msecs)
-        return s
-
-
-def str2scanline(string):
-    """Convert string to scanline.
-
-    Make sure, the scanline is not negative.
-
-    Args:
-        string (str): String to be converted
-
-    Returns:
-        int: Scanline
-    """
-    integer = int(string)
-    if integer < 0:
-        raise argparse.ArgumentTypeError('Scanlines must be >= 0')
-    return integer
-
-
-def validate_args(args):
-    if args.end_line > 0 and args.start_line > args.end_line:
-        raise ValueError('Start Scanline > End Scanline')
-    if args.config and not os.path.isfile(args.config):
-        raise FileNotFoundError(
-            'The provided config file "%s" does not exist!'
-            % args.config)
-    if args.verbose > 0:
-        # redirect the log messages to the standart output
-        ch = logging.StreamHandler()
-        formatter = MyFormatter(
-            '[ %(levelname)s %(name)s %(asctime)s] %(message)s')
-        ch.setFormatter(formatter)
-        logger.addHandler(ch)
-        # set the log-level depending on user verbosity
-        verbosity = min(len(verbosity2loglevel), args.verbose)
-        logger.setLevel(verbosity2loglevel[verbosity])
-
-
-def tarfile_walker(path):
-    """Yield all files from a tar archive.
-
-        Args:
-            path (str): Path to archive
-        Yields:
-            filename: name of the extracted file
-            fileobj: corresponding file object
-    """
-    with tarfile.open(path) as archive:
-        for tarinfo in archive:
-            if tarinfo.isfile():
-                filename = tarinfo.name
-                fileobj = archive.extractfile(filename)
-                yield filename, fileobj
-
-def logged_trial(processor, debug=False):
-    """Decorator to logs exceptions during processing."""
-    @wraps(processor)
-    def wrapper(filename, *args, **kwargs):
-        try:
-            processor(filename, *args, **kwargs)
-        except Exception:
-            logger.exception('Could not process "%s"' % str(filename))
-            if debug:
-                raise
-    return wrapper
-
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(
-        description='Read, calibrate and navigate NOAA AVHRR GAC data')
-    parser.add_argument('path', type=str, help='Path to GAC file(s) to be processed'
-                        ' (Can be a file, directory or tar-archive)')
-    parser.add_argument('start_line', type=str2scanline,
-                        help='First scanline to be processed (0-based)')
-    parser.add_argument('end_line', type=str2scanline,
-                        help='Last scanline to be processed (0-based, '
-                             'set to 0 for the last available scanline)')
-    parser.add_argument('-c', '--config', type=str,
-                        help='pygac config file to be used')
-    parser.add_argument('-v', '--verbose', action='count', default=0,
-                        help='Explain what is being done, frequent occurrence'
-                             ' increases details')
-    parser.add_argument('--debug', action='store_true',
-                        help="If given, stop on the first exception, otherwise"
-                        " log exception and continue with next file")
-    parser.add_argument('--version', action='version',
-                        version='pygac %s' % pygac.__version__)
-    args = parser.parse_args()
-    validate_args(args)
-    if args.config:
-        pygac.read_config_file(args.config)
-    processor = logged_trial(pygac.process_file, debug=args.debug)
-    path = args.path
-    start_line = args.start_line
-    end_line = args.end_line
-    if os.path.isfile(path): 
-        if tarfile.is_tarfile(path):
-            logger.info('Open archive "%s"' % str(path))
-            for filename, fileobj in tarfile_walker(path):
-                processor(filename, start_line, end_line, fileobj=fileobj)
-        else:
-            filename = path
-            # Raise exceptions in case of a single file.
-            pygac.process_file(filename, start_line, end_line)
-    elif os.path.isdir(path):
-        logger.info('Open directory "%s"' % str(path))
-        for basename in os.listdir(path):
-            filename = os.path.join(path, basename)
-            processor(filename, start_line, end_line)
-    else:
-        raise FileNotFoundError(
-            'The provided path "%s" is neither a file nor a directory!' % args.path)


=====================================
pygac/calibration.py
=====================================
@@ -24,17 +24,18 @@
 """Calibration coefficients and generic calibration functions
 """
 from __future__ import division
-from enum import Enum
-import sys
-import logging
-import numpy as np
-import json
+
+import datetime as dt
 import hashlib
+import json
+import logging
+import sys
 import warnings
-import datetime as dt
 from collections import namedtuple
-from pkg_resources import resource_filename
+from enum import Enum
+from importlib.resources import files
 
+import numpy as np
 
 LOG = logging.getLogger(__name__)
 
@@ -172,7 +173,7 @@ class Calibrator(object):
             LOG.info('Read calibration coefficients from "%s"', coeffs_file)
         else:
             LOG.debug("Read PyGAC internal calibration coefficients.")
-            coeffs_file = resource_filename('pygac', 'data/calibration.json')
+            coeffs_file = files("pygac") / "data/calibration.json"
         with open(coeffs_file, mode='rb') as json_file:
             content = json_file.read()
             coeffs = json.loads(content)


=====================================
pygac/gac_calibration.py_old deleted
=====================================
@@ -1,428 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014 Martin Raspaud, Abhay Devasthale
-
-# Author(s):
-
-#   Martin Raspaud <martin.raspaud at smhi.se>
-#   Abhay Devasthale <abhay.devasthale at smhi.se>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-"""Calibration coefficients and generic calibration functions
-"""
-import numpy as np
-
-coeffs = {
-    'metop02': {'ah': [0.1665, 0.1905, 0.217],
-                'al': [0.0555, 0.0635, 0.031],
-                'bh': [1.797, 2.149, 4.11],
-                'bl': [1.797, 2.149, 4.11],
-                'c_dark': [40.43, 39.75, 41.8],
-                'c_s': [501.0, 500.0, 502.0],
-                'ch': [-0.352, -0.225, 0.0],
-                'cl': [-0.352, -0.225, 0.0],
-                'l_date': 2006.77,
-                'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                               [276.6194, 0.050919, 1.471E-06, 0.0, 0.0],
-                               [276.6511, 0.050892, 1.489E-06, 0.0, 0.0],
-                               [276.6597, 0.050845, 1.521E-06, 0.0, 0.0],
-                               [276.3685, 0.050992, 1.482E-06, 0.0, 0.0]]),
-                'n_s': np.array([0.0, -4.98, -3.40]),
-                'c_wn': np.array([2687.0392, 927.27630, 837.80762]),
-                'a': np.array([2.0653147, 0.56503332, 0.38472766]),
-                'b': np.array([1.0 / 1.0034418,
-                               1.0 / 1.0015090,
-                               1.0 / 1.0011264]),
-                'b0': np.array([0.0, 5.44, 3.84]),
-                'b1': np.array([1 - 0.0, 1 - 0.10152, 1 - 0.06249]),
-                'b2': np.array([0.0, 0.00046964, 0.00025239]),
-                },
-    'noaa07': {'ah': np.array([0.111206, 0.107664, 0.0]),
-               'al': np.array([0.111206, 0.107664, 0.0]),
-               'bh': np.array([8.8581, 20.7843, 0.0]),
-               'bl': np.array([8.8581, 20.7843, 0.0]),
-               'c_dark': np.array([36.0, 37.0, 39.0]),
-               'ch': np.array([-1.11938, -4.32167, 0.0]),
-               'cl': np.array([-1.11938, -4.32167, 0.0]),
-               'l_date': 1981.4764,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [277.099, 5.048E-2, 2.823E-6, 0, 0],
-                              [276.734, 5.069E-2, 2.493E-6, 0, 0],
-                              [276.876, 5.148E-2, 1.040E-6, 0, 0],
-                              [276.160, 5.128E-2, 1.414E-6, 0, 0]]),
-               'n_s': np.array([0.0, -5.16, -4.28]),
-               'c_wn': np.array([2684.5233, 928.23757, 841.52137]),
-               'a': np.array([1.94882690, 0.52807997, 0.40557027]),
-               'b': np.array([1.0 / 1.0029260,
-                              1.0 / 1.0014039,
-                              1.0 / 1.0011789]),
-               'b1': np.array([1.0, 0.89783, 0.93683]),
-               'b2': np.array([0.0, 0.0004819, 0.0002425]),
-               'b0': np.array([0.0, 5.25, 3.93]),
-               },
-    'noaa09': {'ah': np.array([0.109312, 0.11601, 0.0]),
-               'al': np.array([0.109312, 0.11601, 0.0]),
-               'bh': np.array([5.66526, 3.93889, 0.0]),
-               'bl': np.array([5.66526, 3.93889, 0.0]),
-               'c_dark': np.array([38.0, 40.0, 38.0]),
-               'ch': np.array([0.27152, -0.258047, 0.0]),
-               'cl': np.array([0.27152, -0.258047, 0.0]),
-               'l_date': 1984.948,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [277.018000, 0.051280, 0.0, 0, 0],
-                              [276.750000, 0.051280, 0.0, 0, 0],
-                              [276.862000, 0.051280, 0.0, 0, 0],
-                              [276.546000, 0.051280, 0.0, 0, 0]]),
-
-               'n_s': np.array([0.0, -5.530, -3.06]),
-               'c_wn': np.array([2690.0451, 930.50230, 845.75000]),
-               'a': np.array([1.8832662, 0.5115335, 0.3882150]),
-               'b': np.array([1.0 / 1.0028978,
-                              1.0 / 1.0013570,
-                              1.0 / 1.0011210]),
-               'b1': np.array([1.0, 0.88643, 0.95311]),
-               'b2': np.array([0.0, 0.0006033, 0.0002198]),
-               'b0': np.array([0.0, 5.24, 2.42]),
-               },
-    'noaa10': {'ah': np.array([0.114803, 0.132682, 0.0]),
-               'al': np.array([0.114803, 0.132682, 0.0]),
-               'bh': np.array([3.43456, 0.00926103, 0.0]),
-               'bl': np.array([3.43456, 0.00926103, 0.0]),
-               'c_dark': np.array([39.44, 39.40, 37.51]),
-               'ch': np.array([-0.384635, 0.137333, 0.0]),
-               'cl': np.array([-0.384635, 0.137333, 0.0]),
-               'l_date': 1986.712,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.659, 0.051275, 1.363e-06, 0, 0],
-                              [276.659, 0.051275, 1.363e-06, 0, 0],
-                              [276.659, 0.051275, 1.363e-06, 0, 0],
-                              [276.659, 0.051275, 1.363e-06, 0, 0]]),
-               'n_s': np.array([0.0, 0.0, 0.0]),
-               'c_wn': np.array([2672.6392, 910.51930, 910.51930]),
-               'a': np.array([1.80168640, 0.45707890, 0.45707890]),
-               'b': np.array([1.0 / 1.0026383,
-                              1.0 / 1.0012338,
-                              1.0 / 1.0012338]),
-               'b1': np.array([1.0, 1.0, 1.0]),
-               'b2': np.array([0.0, 0.0, 0.0]),
-               'b0': np.array([0.0, 0.0, 0.0]),
-               },
-    'noaa11': {'ah': np.array([0.114786, 0.115219, 0.0]),
-               'al': np.array([0.114786, 0.115219, 0.0]),
-               'bh': np.array([-1.82974, -1.39495, 0.0]),
-               'bl': np.array([-1.82974, -1.39494, 0.0]),
-               'c_dark': np.array([40.0, 40.0, 40.0]),
-               'ch': np.array([0.412551, 0.236978, 0.0]),
-               'cl': np.array([0.412551, 0.236978, 0.0]),
-               'l_date': 1988.7064,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0]]),
-               'n_s': np.array([0.0, -8.055, -3.51]),
-               'c_wn': np.array([2680.05, 927.462, 840.746]),
-               'a': np.array([1.738973, 0.321199, 0.048652]),
-               'b': np.array([1.0 / 1.003354,
-                              1.0 / 1.001213,
-                              1.0 / 1.000664]),
-               'b1': np.array([1.0, 0.84120, 0.94598]),
-               'b2': np.array([0.0, 0.0008739, 0.0002504]),
-               'b0': np.array([0.0, 7.21, 2.92]),
-               },
-    'noaa12': {'ah': np.array([0.118059, 0.135684, 0.0]),
-               'al': np.array([0.118059, 0.135684, 0.0]),
-               'bh': np.array([4.88848, 4.67098, 0.0]),
-               'bl': np.array([4.88848, 4.67098, 0.0]),
-               'c_dark': np.array([41.0, 40.0, 40.0]),
-               'ch': np.array([-0.347769, -0.399447, 0.0]),
-               'cl': np.array([-0.347769, -0.399447, 0.0]),
-               'l_date': 1991.3669,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0]]),
-               'n_s': np.array([0.0, -5.510, -2.51]),
-               'c_wn': np.array([2651.7708, 922.36261, 838.02678]),
-               'a': np.array([1.90527390, 0.63404209, 0.41086587]),
-               'b': np.array([1.0 / 1.0030100,
-                              1.0 / 1.0017076,
-                              1.0 / 1.0012010]),
-               'b1': np.array([1.0, 0.88929, 0.96299]),
-               'b2': np.array([0.0, 0.0005968, 0.0001775]),
-               'b0': np.array([0.0, 5.11, 1.91]),
-               },
-    'noaa14': {'ah': np.array([0.121408, 0.144515, 0.0]),
-               'al': np.array([0.121408, 0.144515, 0.0]),
-               'bh': np.array([4.07313, 0.885331, 0.0]),
-               'bl': np.array([4.07313, 0.885331, 0.0]),
-               'c_dark': np.array([41.0, 41.0, 39.0]),
-               'ch': np.array([-0.375215, 0.233727, 0.0]),
-               'cl': np.array([-0.375215, 0.233727, 0.0]),
-               'l_date': 1994.9699,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0],
-                              [276.597, 0.051275, 1.363e-06, 0, 0]]),
-               'n_s': np.array([0.0069, -4.05, -2.29]),
-               'c_wn': np.array([2654.25, 928.349, 833.040]),
-               'a': np.array([1.885330, 0.308384, 0.022171]),
-               'b': np.array([1.0 / 1.003839, 1.0 / 1.001443, 1.0 / 1.000538]),
-               'b1': np.array([1.00359, 0.92378, 0.96194]),
-               'b2': np.array([0.0, 0.000382, 0.0001742]),
-               'b0': np.array([-0.0031, 3.72, 2.00])},
-    'noaa15': {'ah': np.array([0.1815, 0.2025, 0.1846]),
-               'al': np.array([0.0605, 0.0675, 0.0275]),
-               'bh': np.array([0.447, 0.035, 0.0]),
-               'bl': np.array([0.447, 0.035, 0.0]),
-               'c_dark': np.array([39.0, 40.0, 39.0]),
-               'c_s': np.array([500.0, 500.0, 500.0]),
-               'ch': np.array([-0.060, 0.007, 0.0]),
-               'cl': np.array([-0.060, 0.007, 0.0]),
-               'l_date': 1998.3641,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.60157, 0.051045, 1.36328E-06, 0.0, 0.0],
-                              [276.62531, 0.050909, 1.47266E-06, 0.0, 0.0],
-                              [276.67413, 0.050907, 1.47656E-06, 0.0, 0.0],
-                              [276.59258, 0.050966, 1.47656E-06, 0.0, 0.0]]),
-               'n_s': np.array([0.0, -4.50, -3.61]),
-               'c_wn': np.array([2695.9743, 925.4075, 839.8979]),
-               'a': np.array([1.624481, 0.338243, 0.304856]),
-               'b': np.array([1.0 / 1.001989,
-                              1.0 / 1.001283,
-                              1.0 / 1.000977]),
-               'b0': np.array([0.0, 4.76, 3.83]),
-               'b1': np.array([1 - 0.0, 1 - 0.0932, 1 - 0.0659]),
-               'b2': np.array([0.0, 0.0004524, 0.0002811]),
-               },
-    'noaa16': {'ah': np.array([0.168, 0.174, 0.2013]),
-               'al': np.array([0.056, 0.058, 0.0288]),
-               'bh': np.array([0.306, 0.586, -0.810]),
-               'bl': np.array([0.306, 0.586, -0.81]),
-               'c_dark': np.array([39.3, 38.9, 38.4]),
-               'c_s': np.array([498.96, 500.17, 499.43]),
-               'ch': np.array([0.0250, 0.036, 0.0]),
-               'cl': np.array([0.0250, 0.036, 0.0]),
-               'l_date': 2000.7228,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.355, 5.562E-02, -1.590E-05,
-                                  2.486E-08, -1.199E-11],
-                              [276.142, 5.605E-02, -1.707E-05,
-                                  2.595E-08, -1.224E-11],
-                              [275.996, 5.486E-02, -1.223E-05,
-                                  1.862E-08, -0.853E-11],
-                              [276.132, 5.494E-02, -1.344E-05,
-                                  2.112E-08, -1.001E-11]]),
-               'n_s': np.array([0.0, -2.467, -2.009]),
-               'c_wn': np.array([2681.2540, 922.34790, 834.61814]),
-               'a': np.array([1.6774586, 0.55636216, 0.41430789]),
-               'b': np.array([1.0 / 1.0017316,
-                              1.0 / 1.0014921,
-                              1.0 / 1.0012166]),
-               'b0': np.array([0.0, 2.96, 2.25]),
-               'b1': np.array([1 - 0.0, 1 - 0.05411, 1 - 0.03665]),
-               'b2': np.array([0.0, 0.00024532, 0.00014854]),
-               },
-    'noaa17': {'ah': np.array([0.1725, 0.1950, 0.2153]),
-               'al': np.array([0.0575, 0.0650, 0.0308]),
-               'bh': np.array([1.707, 3.117, 4.06]),
-               'bl': np.array([1.707, 3.117, 4.06]),
-               'c_dark': np.array([39.99, 39.09, 42.09]),
-               'c_s': np.array([501.12, 500.73, 501.37]),
-               'ch': np.array([-0.151, -0.265, -0.37]),
-               'cl': np.array([-0.151, -0.265, -0.37]),
-               'l_date': 2002.47912,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.628, 0.05098, 1.371E-06, 0.0, 0.0],
-                              [276.538, 0.05098, 1.371E-06, 0.0, 0.0],
-                              [276.761, 0.05097, 1.369E-06, 0.0, 0.0],
-                              [276.660, 0.05100, 1.348E-06, 0.0, 0.0]]),
-               'n_s': np.array([0.0, -8.55, -3.97]),
-               'c_wn': np.array([2669.1414, 928.29959, 840.20289]),
-               'a': np.array([1.70002941, 0.56634758, 0.37264803]),
-               'b': np.array([1.0 / 1.0026724,
-                              1.0 / 1.0015205,
-                              1.0 / 1.0010841]),
-               'b0': np.array([0.0, 8.22, 4.31]),
-               'b1': np.array([1 - 0.0, 1 - 0.15795, 1 - 0.07318]),
-               'b2': np.array([0.0, 0.00075579, 0.00030976]),
-               },
-    'noaa18': {'ah': np.array([0.1665, 0.1785, 0.1849]),
-               'al': np.array([0.0555, 0.0595, 0.0262]),
-               'bh': np.array([3.068, 4.541, 0.0]),
-               'bl': np.array([3.068, 4.541, 0.0]),
-               'c_dark': np.array([39.44, 39.40, 37.51]),
-               'c_s': np.array([500.54, 500.40, 500.56]),
-               'ch': np.array([-0.443, -0.611, 0.0]),
-               'cl': np.array([-0.443, -0.611, 0.0]),
-               'l_date': 2005.18891,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.601, 0.05090, 1.657E-06, 0.0, 0.0],
-                              [276.683, 0.05101, 1.482E-06, 0.0, 0.0],
-                              [276.565, 0.05117, 1.313E-06, 0.0, 0.0],
-                              [276.615, 0.05103, 1.484E-06, 0.0, 0.0]]),
-               'n_s': np.array([0.0, -5.53, -2.22]),
-               'c_wn': np.array([2660.6468, 928.73452, 834.08306]),
-               'a': np.array([1.7222650, 0.54696239, 0.39938376]),
-               'b': np.array([1.0 / 1.0028633,
-                              1.0 / 1.0014581,
-                              1.0 / 1.0011724]),
-               'b0': np.array([0.0, 5.82, 2.67]),
-               'b1': np.array([1 - 0.0, 1 - 0.11069, 1 - 0.04360]),
-               'b2': np.array([0.0, 0.00052337, 0.00017715]),
-               },
-    'noaa19': {'ah': np.array([0.1680, 0.1755, 0.1880]),
-               'al': np.array([0.0560, 0.0585, 0.0272]),
-               'bh': np.array([-5.985, 2.263, 0.0]),
-               'bl': np.array([-5.985, 2.263, 0.0]),
-               'c_dark': np.array([38.8, 39.00, 39.4]),
-               'c_s': np.array([496.43, 500.37, 496.11]),
-               'ch': np.array([-8.687, 0.748, 0.0]),
-               'cl': np.array([-8.687, 0.748, 0.0]),
-               'l_date': 2009.096,
-               'd': np.array([[0, 0, 0, 0, 0],  # reset prt
-                              [276.6067, 0.051111, 1.405783e-06, 0, 0],
-                              [276.6119, 0.051090, 1.496037e-06, 0, 0],
-                              [276.6311, 0.051033, 1.496990e-06, 0, 0],
-                              [276.6268, 0.051058, 1.493110e-06, 0, 0]]),
-               'n_s': np.array([0.0, -5.49, -3.39]),
-               'c_wn': np.array([2670.2425, 927.92374, 831.28619]),
-               'a': np.array([1.6863857, 0.39419031, 0.26364620]),
-               'b': np.array([1.0 / 1.0025955,
-                              1.0 / 1.0013299,
-                              1.0 / 1.0009546]),
-               'b0': np.array([0.0, 5.70, 3.58]),
-               'b1': np.array([1 - 0.0, 1 - 0.11187, 1 - 0.05991]),
-               'b2': np.array([0.0, 0.00054668, 0.00024985])}}
-
-
-class Calibrator(object):
-
-    def __init__(self, spacecraft):
-        self.ah = None
-        self.al = None
-        self.bh = None
-        self.bl = None
-        self.ch = None
-        self.cl = None
-        self.c_s = None
-        self.c_dark = None
-        self.l_date = None
-        self.d = None
-        self.n_s = None
-        self.c_wn = None
-        self.a = None
-        self.b = None
-        self.b0 = None
-        self.b1 = None
-        self.b2 = None
-        self.__dict__.update(coeffs[spacecraft])
-
-
-def calibrate_solar(counts, chan, year, jday, spacecraft, corr=1):
-    """Do the solar calibration and return reflectance (between 0 and 100).
-    """
-    cal = Calibrator(spacecraft)
-
-    t = (year + jday / 365.0) - cal.l_date
-    stl = (cal.al[chan] * (100.0 + cal.bl[chan] * t +
-                           cal.cl[chan] * t * t)) / 100.0
-    sth = (cal.ah[chan] * (100.0 + cal.bh[chan] * t +
-                           cal.ch[chan] * t * t)) / 100.0
-    if cal.c_s is not None:
-        return np.where(counts <= cal.c_s[chan],
-                        (counts - cal.c_dark[chan]) * stl,
-                        (cal.c_s[chan] - cal.c_dark[chan]) * stl
-                        + (counts - cal.c_s[chan]) * sth)
-    else:
-        return (counts - cal.c_dark[chan]) * stl * corr
-
-
-def calibrate_thermal(counts, prt, ict, space, line_numbers, channel, spacecraft):
-    """Do the thermal calibration and return brightness temperatures (K).
-    """
-    cal = Calibrator(spacecraft)
-
-    chan = channel - 3
-
-    lines, columns = counts.shape[:2]
-
-    offset = 0
-
-    for i, prt_val in enumerate(prt):
-        if prt_val < 50:
-            offset = i
-            break
-
-    iprt = (line_numbers - line_numbers[0] + 5 - offset) % 5
-
-    tprt = (cal.d[iprt, 0] + prt *
-            (cal.d[iprt, 1] + prt *
-             (cal.d[iprt, 2] + prt *
-              (cal.d[iprt, 3] + prt *
-               (cal.d[iprt, 4])))))
-
-    zeros = iprt == 0
-    nonzeros = np.logical_not(zeros)
-
-    tprt[zeros] = np.interp((zeros).nonzero()[0],
-                            (nonzeros).nonzero()[0],
-                            tprt[nonzeros])
-
-    # convolving and smoothing PRT, ICT and SPACE values
-    if lines > 51:
-        wlength = 51
-    else:
-        wlength = 3
-
-    weighting_function = np.ones(wlength, dtype=float) / wlength
-    tprt_convolved = np.convolve(tprt, weighting_function, 'same')
-    ict_convolved = np.convolve(ict, weighting_function, 'same')
-    space_convolved = np.convolve(space, weighting_function, 'same')
-
-    # take care of the beginning and end
-    tprt_convolved[0:(wlength - 1) / 2] = tprt_convolved[(wlength - 1) / 2]
-    ict_convolved[0:(wlength - 1) / 2] = ict_convolved[(wlength - 1) / 2]
-    space_convolved[0:(wlength - 1) / 2] = space_convolved[(wlength - 1) / 2]
-    tprt_convolved[-(wlength - 1) / 2:] = tprt_convolved[-((wlength + 1) / 2)]
-    ict_convolved[-(wlength - 1) / 2:] = ict_convolved[-((wlength + 1) / 2)]
-    space_convolved[-(wlength - 1) / 2:] = \
-        space_convolved[-((wlength + 1) / 2)]
-
-    new_tprt = np.transpose(np.tile(tprt_convolved, (columns, 1)))
-    new_ict = np.transpose(np.tile(ict_convolved, (columns, 1)))
-    new_space = np.transpose(np.tile(space_convolved, (columns, 1)))
-
-    # calibrating thermal channel
-
-    tBB = new_tprt
-    tsBB = cal.a[chan] + cal.b[chan] * tBB
-    nBB_num = (1.1910427 * 0.000010) * cal.c_wn[chan] ** 3
-    nBB = nBB_num / (np.exp((1.4387752 * cal.c_wn[chan]) / tsBB) - 1.0)
-
-    Nlin = (cal.n_s[chan] +
-            (((nBB - cal.n_s[chan])
-              * (new_space - counts))
-             / (new_space - new_ict)))
-    Ncor = cal.b0[chan] + Nlin * (cal.b1[chan] + cal.b2[chan] * Nlin)
-    Ne = Ncor
-    tsE = ((1.4387752 * cal.c_wn[chan])
-           / np.log(1.0 + nBB_num / Ne))
-    bt = (tsE - cal.a[chan]) / cal.b[chan]
-
-    return bt


=====================================
pygac/gac_io.py_old deleted
=====================================
@@ -1,509 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2012, 2014 Abhay Devasthale
-
-# Author(s):
-
-#   Abhay Devasthale <abhay.devasthale at smhi.se>
-#   Adam Dybbroe <adam.dybbroe at smhi.se>
-#   Sara Hornquist <sara.hornquist at smhi.se>
-#   Martin Raspaud <martin.raspaud at smhi.se>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-import h5py
-import numpy as np
-import time
-import calendar
-
-import logging
-LOG = logging.getLogger(__name__)
-
-import ConfigParser
-import os
-
-try:
-    CONFIG_FILE = os.environ['PYGAC_CONFIG_FILE']
-except KeyError:
-    LOG.exception('Environment variable PYGAC_CONFIG_FILE not set!')
-    raise
-
-if not os.path.exists(CONFIG_FILE) or not os.path.isfile(CONFIG_FILE):
-    raise IOError(str(CONFIG_FILE) + " pointed to by the environment " +
-                  "variable PYGAC_CONFIG_FILE is not a file or does not exist!")
-
-conf = ConfigParser.ConfigParser()
-try:
-    conf.read(CONFIG_FILE)
-except ConfigParser.NoSectionError:
-    LOG.exception('Failed reading configuration file: ' + str(CONFIG_FILE))
-    raise
-
-options = {}
-for option, value in conf.items('output', raw=True):
-    options[option] = value
-
-OUTDIR = options['output_dir']
-OUTPUT_FILE_PREFIX = options['output_file_prefix']
-
-SUNSATANGLES_DIR = os.environ.get('SM_SUNSATANGLES_DIR', OUTDIR)
-AVHRR_DIR = os.environ.get('SM_AVHRR_DIR', OUTDIR)
-QUAL_DIR = os.environ.get('SM_AVHRR_DIR', OUTDIR)
-MISSING_DATA = -32001
-
-
-def save_gac(satellite_name,
-             start, end,
-             lats, lons,
-             ref1, ref2, ref3,
-             bt3, bt4, bt5,
-             sun_zen, sat_zen, sun_azi, sat_azi, rel_azi,
-             mask, qual_flags, switch=None):
-
-    bt3 -= 273.15
-    bt4 -= 273.15
-    bt5 -= 273.15
-
-    sat_azi -= 180.0
-    rel_azi = abs(rel_azi)
-    rel_azi = 180.0 - rel_azi
-
-    for array in [ref1, ref2, ref3, bt3, bt4, bt5,
-                  sun_zen, sat_zen, sun_azi, sat_azi, rel_azi]:
-        array *= 100
-    for array in [lats, lons, ref1, ref2, ref3, bt3, bt4, bt5,
-                  sun_zen, sat_zen, sun_azi, sat_azi, rel_azi]:
-        array[mask] = MISSING_DATA
-    for ref in [ref1, ref2, ref3]:
-        ref[ref < 0] = MISSING_DATA
-
-    if switch is not None:
-        ref3[switch == 0] = MISSING_DATA
-        bt3[switch == 1] = MISSING_DATA
-
-    startdate = start.strftime("%Y%m%d")
-    starttime = start.strftime("%H%M%S%f")[:-5]
-    enddate = end.strftime("%Y%m%d")
-    endtime = end.strftime("%H%M%S%f")[:-5]
-
-    avhrrGAC_io(satellite_name, startdate, enddate, starttime, endtime,
-                lats, lons, ref1, ref2, ref3, bt3, bt4, bt5,
-                sun_zen, sat_zen, sun_azi, sat_azi, rel_azi, qual_flags)
-
-
-def avhrrGAC_io(satellite_name, startdate, enddate, starttime, endtime,
-                arrLat_full, arrLon_full, ref1, ref2, ref3, bt3, bt4, bt5,
-                arrSZA, arrSTZ, arrSAA, arrSTA, arrRAA, qual_flags):
-    import os
-
-    # Calculate start and end time in sec1970
-    t_obj = time.strptime(startdate + starttime[0:6], "%Y%m%d%H%M%S")
-    starttime_sec1970 = calendar.timegm(t_obj)
-    t_obj = time.strptime(enddate + endtime[0:6], "%Y%m%d%H%M%S")
-    endtime_sec1970 = calendar.timegm(t_obj)
-
-    LOG.info('Output file prefix = ' + str(OUTPUT_FILE_PREFIX))
-    LOG.info('AVHRR data will be written to ' + str(AVHRR_DIR))
-    ofn = os.path.join(AVHRR_DIR, (OUTPUT_FILE_PREFIX + '_avhrr_' +
-                                   satellite_name + '_99999_' +
-                                   startdate + 'T' + starttime + 'Z_' +
-                                   enddate + 'T' + endtime + 'Z.h5'))
-    LOG.info('Filename: ' + str(os.path.basename(ofn)))
-
-    fout = h5py.File(ofn, "w")
-
-    dset1 = fout.create_dataset("/image1/data", dtype='int16', data=ref1)
-    dset2 = fout.create_dataset("/image2/data", dtype='int16', data=ref2)
-    dset3 = fout.create_dataset("/image3/data", dtype='int16', data=bt3)
-    dset4 = fout.create_dataset("/image4/data", dtype='int16', data=bt4)
-    dset5 = fout.create_dataset("/image5/data", dtype='int16', data=bt5)
-    dset6 = fout.create_dataset("/image6/data", dtype='int16', data=ref3)
-    dset7 = fout.create_dataset("/where/lat/data", dtype='int32',
-                                data=arrLat_full)
-    dset8 = fout.create_dataset("/where/lon/data", dtype='int32',
-                                data=arrLon_full)
-
-    channellist = []
-    channellist.append("channel1")
-    channellist.append("channel2")
-    channellist.append("channel3b")
-    channellist.append("channel4")
-    channellist.append("channel5")
-    channellist.append("channel3a")
-    dset10 = fout.create_dataset("/how/channel_list",
-                                 data=channellist)
-
-    # Attributes directly on highest level groups
-    g1 = fout.require_group("/image1")
-    g2 = fout.require_group("/image2")
-    g3 = fout.require_group("/image3")
-    g4 = fout.require_group("/image4")
-    g5 = fout.require_group("/image5")
-    g6 = fout.require_group("/image6")
-    g7 = fout.require_group("/where")
-
-    g1.attrs["channel"] = "1"
-    g1.attrs["description"] = "AVHRR ch1"
-    g2.attrs["channel"] = "2"
-    g2.attrs["description"] = "AVHRR ch2"
-    g3.attrs["channel"] = "3b"
-    g3.attrs["description"] = "AVHRR ch3b"
-    g4.attrs["channel"] = "4"
-    g4.attrs["description"] = "AVHRR ch4"
-    g5.attrs["channel"] = "5"
-    g5.attrs["description"] = "AVHRR ch5"
-    g6.attrs["channel"] = "3a"
-    g6.attrs["description"] = "AVHRR ch3a"
-    g7.attrs["num_of_pixels"] = np.int32(arrSZA.shape[1])
-    g7.attrs["num_of_lines"] = np.int32(arrSZA.shape[0])
-    g7.attrs["xscale"] = np.float32(0.0)  # PPS says 1100.0, is that really
-    g7.attrs["yscale"] = np.float32(0.0)  # true for GAC? /SHq
-
-    # Attributes in the 'what' groups
-    g1 = fout.create_group("/image1/what")
-    g2 = fout.create_group("/image2/what")
-    g3 = fout.create_group("/image3/what")
-    g4 = fout.create_group("/image4/what")
-    g5 = fout.create_group("/image5/what")
-    g6 = fout.create_group("/image6/what")
-    g7 = fout.create_group("/where/lat/what")
-    g8 = fout.create_group("/where/lon/what")
-    g9 = fout.create_group("/what")
-
-    g1.attrs["product"] = "SATCH"
-    g1.attrs["quantity"] = "REFL"
-    g1.attrs["dataset_name"] = 'Channel 1 reflectance'
-    g1.attrs["units"] = '%'
-    g1.attrs["gain"] = np.float32(0.01)
-    g1.attrs["offset"] = np.float32(0.0)
-    g1.attrs["missingdata"] = np.int32(-32001)
-    g1.attrs["nodata"] = np.int32(-32001)
-    g1.attrs["starttime"] = starttime[0:6]
-    g1.attrs["endtime"] = endtime[0:6]
-    g1.attrs["startdate"] = startdate
-    g1.attrs["enddate"] = enddate
-
-    g2.attrs["product"] = "SATCH"
-    g2.attrs["quantity"] = "REFL"
-    g2.attrs["dataset_name"] = 'Channel 2 reflectance'
-    g2.attrs["units"] = '%'
-    g2.attrs["gain"] = np.float32(0.01)
-    g2.attrs["offset"] = np.float32(0.0)
-    g2.attrs["missingdata"] = np.int32(-32001)
-    g2.attrs["nodata"] = np.int32(-32001)
-    g2.attrs["starttime"] = starttime[0:6]
-    g2.attrs["endtime"] = endtime[0:6]
-    g2.attrs["startdate"] = startdate
-    g2.attrs["enddate"] = enddate
-
-    g6.attrs["product"] = "SATCH"
-    g6.attrs["quantity"] = "REFL"
-    g6.attrs["dataset_name"] = 'Channel 3a reflectance'
-    g6.attrs["units"] = '%'
-    g6.attrs["gain"] = np.float32(0.01)
-    g6.attrs["offset"] = np.float32(0.0)
-    g6.attrs["missingdata"] = np.int32(-32001)
-    g6.attrs["nodata"] = np.int32(-32001)
-    g6.attrs["starttime"] = starttime[0:6]
-    g6.attrs["endtime"] = endtime[0:6]
-    g6.attrs["startdate"] = startdate
-    g6.attrs["enddate"] = enddate
-
-    g3.attrs["product"] = "SATCH"
-    g3.attrs["quantity"] = "TB"
-    g3.attrs["dataset_name"] = 'Channel 3b brightness temperature'
-    g3.attrs["units"] = 'K'
-    g3.attrs["gain"] = np.float32(0.01)
-    g3.attrs["offset"] = np.float32(273.15)
-    g3.attrs["missingdata"] = np.int32(-32001)
-    g3.attrs["nodata"] = np.int32(-32001)
-    g3.attrs["starttime"] = starttime[0:6]
-    g3.attrs["endtime"] = endtime[0:6]
-    g3.attrs["startdate"] = startdate
-    g3.attrs["enddate"] = enddate
-
-    g4.attrs["product"] = "SATCH"
-    g4.attrs["quantity"] = "TB"
-    g4.attrs["dataset_name"] = 'Channel 4 brightness temperature'
-    g4.attrs["units"] = 'K'
-    g4.attrs["gain"] = np.float32(0.01)
-    g4.attrs["offset"] = np.float32(273.15)
-    g4.attrs["missingdata"] = np.int32(-32001)
-    g4.attrs["nodata"] = np.int32(-32001)
-    g4.attrs["starttime"] = starttime[0:6]
-    g4.attrs["endtime"] = endtime[0:6]
-    g4.attrs["startdate"] = startdate
-    g4.attrs["enddate"] = enddate
-
-    g5.attrs["product"] = "SATCH"
-    g5.attrs["quantity"] = "TB"
-    g5.attrs["dataset_name"] = 'Channel 5 brightness temperature'
-    g5.attrs["units"] = 'K'
-    g5.attrs["gain"] = np.float32(0.01)
-    g5.attrs["offset"] = np.float32(273.15)
-    g5.attrs["missingdata"] = np.int32(-32001)
-    g5.attrs["nodata"] = np.int32(-32001)
-    g5.attrs["starttime"] = starttime[0:6]
-    g5.attrs["endtime"] = endtime[0:6]
-    g5.attrs["startdate"] = startdate
-    g5.attrs["enddate"] = enddate
-
-    g7.attrs["dataset_name"] = 'Latitude'
-    g7.attrs["units"] = 'Deg'
-    g7.attrs["gain"] = np.float32(0.010)
-    g7.attrs["offset"] = np.float32(0.0)
-    g7.attrs["missingdata"] = np.int32(-32001)
-    g7.attrs["nodata"] = np.int32(-32001)
-    g7.attrs["starttime"] = starttime[0:6]
-    g7.attrs["endtime"] = endtime[0:6]
-    g7.attrs["startdate"] = startdate
-    g7.attrs["enddate"] = enddate
-
-    g8.attrs["dataset_name"] = 'Longitude'
-    g8.attrs["units"] = 'Deg'
-    g8.attrs["gain"] = np.float32(0.010)
-    g8.attrs["offset"] = np.float32(0.0)
-    g8.attrs["missingdata"] = np.int32(-32001)
-    g8.attrs["nodata"] = np.int32(-32001)
-    g8.attrs["starttime"] = starttime[0:6]
-    g8.attrs["endtime"] = endtime[0:6]
-    g8.attrs["startdate"] = startdate
-    g8.attrs["enddate"] = enddate
-
-    g9.attrs["object"] = "SATP"
-    g9.attrs["sets"] = np.int32(len(channellist))
-    g9.attrs["version"] = "H5rad ?.?"
-    g9.attrs["date"] = startdate
-    g9.attrs["time"] = starttime[0:6]
-
-    # Attributes in the 'how' groups
-    g1 = fout.create_group("/image1/how")
-    g2 = fout.create_group("/image2/how")
-    g3 = fout.create_group("/image3/how")
-    g4 = fout.create_group("/image4/how")
-    g5 = fout.create_group("/image5/how")
-    g6 = fout.create_group("/image6/how")
-    g10 = fout.require_group("/how")
-
-    # SHq: Is the sun_earth_distance correction applied?
-    g1.attrs["sun_earth_distance_correction_applied"] = "TRUE"
-    g1.attrs["sun_earth_distance_correction_factor"] = np.int32(1.0)
-    g2.attrs["sun_earth_distance_correction_applied"] = "TRUE"
-    g2.attrs["sun_earth_distance_correction_factor"] = np.int32(1.0)
-    # No attributes on 'how' for image3,4,5
-    g6.attrs["sun_earth_distance_correction_applied"] = "TRUE"
-    g6.attrs["sun_earth_distance_correction_factor"] = np.int32(1.0)
-
-    # We do not know much about how; mostly use no-data
-    g10.attrs["yaw_error"] = 0.0
-    g10.attrs["roll_error"] = 0.0
-    g10.attrs["pich_error"] = 0.0
-    g10.attrs["startepochs"] = starttime_sec1970
-    g10.attrs["endepochs"] = endtime_sec1970
-    g10.attrs["platform"] = satellite_name
-    g10.attrs["instrument"] = "avhrr"
-    g10.attrs["orbit_number"] = np.int32(99999)
-    g10.attrs["software"] = "pyGAC"
-    g10.attrs["version"] = "1.0"
-
-    fout.close()
-
-    LOG.info('Sun and Satellite viewing angles will be ' +
-             'written to ' + str(SUNSATANGLES_DIR))
-    ofn = os.path.join(SUNSATANGLES_DIR,
-                       (OUTPUT_FILE_PREFIX + '_sunsatangles_' +
-                        satellite_name + '_99999_' + startdate +
-                        'T' + starttime + 'Z_' +
-                        enddate + 'T' + endtime + 'Z.h5'))
-    LOG.info('Filename: ' + str(os.path.basename(ofn)))
-    fout = h5py.File(ofn, "w")
-
-    dset1 = fout.create_dataset("/image1/data", dtype='int16', data=arrSZA)
-    dset2 = fout.create_dataset("/image2/data", dtype='int16', data=arrSTZ)
-    dset3 = fout.create_dataset("/image3/data", dtype='int16', data=arrRAA)
-    dset4 = fout.create_dataset("/image4/data", dtype='int16', data=arrSAA)
-    dset5 = fout.create_dataset("/image5/data", dtype='int16', data=arrSTA)
-    dset6 = fout.create_dataset("/where/lat/data", dtype='int32',
-                                data=arrLat_full)
-    dset7 = fout.create_dataset("/where/lon/data", dtype='int32',
-                                data=arrLon_full)
-
-    # Attributes directly on highest level groups
-    g1 = fout.require_group("/image1")
-    g2 = fout.require_group("/image2")
-    g3 = fout.require_group("/image3")
-    g4 = fout.require_group("/image4")
-    g5 = fout.require_group("/image5")
-    g6 = fout.require_group("/where")
-
-    g1.attrs["description"] = 'Solar zenith angle'
-    g2.attrs["description"] = 'Satellite zenith angle'
-    g3.attrs["description"] = 'Relative satellite-sun azimuth angle'
-    g4.attrs["description"] = 'Solar azimuth angle'
-    g5.attrs["description"] = 'Satellite azimuth angle'
-    g6.attrs["num_of_pixels"] = np.int32(arrSZA.shape[1])
-    g6.attrs["num_of_lines"] = np.int32(arrSZA.shape[0])
-    g6.attrs["xscale"] = np.float32(0.0)  # PPS says 1100.0, is that really
-    g6.attrs["yscale"] = np.float32(0.0)  # true for GAC? /SHq
-
-    # Attributes in the 'what' groups + 'how'
-    g1 = fout.create_group("/image1/what")
-    g2 = fout.create_group("/image2/what")
-    g3 = fout.create_group("/image3/what")
-    g4 = fout.create_group("/image4/what")
-    g5 = fout.create_group("/image5/what")
-    g6 = fout.create_group("/where/lat/what")
-    g7 = fout.create_group("/where/lon/what")
-    g8 = fout.create_group("/what")
-    g9 = fout.create_group("/how")
-
-    g1.attrs["product"] = "SUNZ"
-    g1.attrs["quantity"] = "DEG"
-    g1.attrs["dataset_name"] = 'Solar zenith angle'
-    g1.attrs["units"] = 'Deg'
-    g1.attrs["gain"] = np.float32(0.01)
-    g1.attrs["offset"] = np.float32(0.0)
-    g1.attrs["missingdata"] = np.int32(-32001)
-    g1.attrs["nodata"] = np.int32(-32001)
-    g1.attrs["starttime"] = starttime[0:6]
-    g1.attrs["endtime"] = endtime[0:6]
-    g1.attrs["startdate"] = startdate
-    g1.attrs["enddate"] = enddate
-
-    g2.attrs["product"] = "SATZ"
-    g2.attrs["quantity"] = "DEG"
-    g2.attrs["dataset_name"] = 'Satellite zenith angle'
-    g2.attrs["units"] = 'Deg'
-    g2.attrs["gain"] = np.float32(0.01)
-    g2.attrs["offset"] = np.float32(0.0)
-    g2.attrs["missingdata"] = np.int32(-32001)
-    g2.attrs["nodata"] = np.int32(-32001)
-    g2.attrs["starttime"] = starttime[0:6]
-    g2.attrs["endtime"] = endtime[0:6]
-    g2.attrs["startdate"] = startdate
-    g2.attrs["enddate"] = enddate
-
-    g3.attrs["product"] = "SSAZD"
-    g3.attrs["quantity"] = "DEG"
-    g3.attrs["dataset_name"] = 'Relative satellite-sun azimuth angle'
-    g3.attrs["units"] = 'Deg'
-    g3.attrs["gain"] = np.float32(0.01)
-    g3.attrs["offset"] = np.float32(0.0)
-    g3.attrs["missingdata"] = np.int32(-32001)
-    g3.attrs["nodata"] = np.int32(-32001)
-    g3.attrs["starttime"] = starttime[0:6]
-    g3.attrs["endtime"] = endtime[0:6]
-    g3.attrs["startdate"] = startdate
-    g3.attrs["enddate"] = enddate
-
-    g4.attrs["product"] = "SUNA"
-    g4.attrs["quantity"] = "DEG"
-    g4.attrs["dataset_name"] = 'Solar azimuth angle'
-    g4.attrs["units"] = 'Deg'
-    g4.attrs["gain"] = np.float32(0.01)
-    g4.attrs["offset"] = np.float32(180.0)
-    g4.attrs["missingdata"] = np.int32(-32001)
-    g4.attrs["nodata"] = np.int32(-32001)
-    g4.attrs["starttime"] = starttime[0:6]
-    g4.attrs["endtime"] = endtime[0:6]
-    g4.attrs["startdate"] = startdate
-    g4.attrs["enddate"] = enddate
-
-    g5.attrs["product"] = "SATA"
-    g5.attrs["quantity"] = "DEG"
-    g5.attrs["dataset_name"] = 'Satellite azimuth angle'
-    g5.attrs["units"] = 'Deg'
-    g5.attrs["gain"] = np.float32(0.01)
-    g5.attrs["offset"] = np.float32(180.0)
-    g5.attrs["missingdata"] = np.int32(-32001)
-    g5.attrs["nodata"] = np.int32(-32001)
-    g5.attrs["starttime"] = starttime[0:6]
-    g5.attrs["endtime"] = endtime[0:6]
-    g5.attrs["startdate"] = startdate
-    g5.attrs["enddate"] = enddate
-
-    g6.attrs["dataset_name"] = 'Latitude'
-    g6.attrs["units"] = 'Deg'
-    g6.attrs["gain"] = np.float32(0.010)
-    g6.attrs["offset"] = np.float32(0.0)
-    g6.attrs["missingdata"] = np.int32(-32001)
-    g6.attrs["nodata"] = np.int32(-32001)
-    g6.attrs["starttime"] = starttime[0:6]
-    g6.attrs["endtime"] = endtime[0:6]
-    g6.attrs["startdate"] = startdate
-    g6.attrs["enddate"] = enddate
-
-    g7.attrs["dataset_name"] = 'Longitude'
-    g7.attrs["units"] = 'Deg'
-    g7.attrs["gain"] = np.float32(0.010)
-    g7.attrs["offset"] = np.float32(0.0)
-    g7.attrs["missingdata"] = np.int32(-32001)
-    g7.attrs["nodata"] = np.int32(-32001)
-    g7.attrs["starttime"] = starttime[0:6]
-    g7.attrs["endtime"] = endtime[0:6]
-    g7.attrs["startdate"] = startdate
-    g7.attrs["enddate"] = enddate
-
-    g8.attrs["object"] = "SATP"
-    g8.attrs["sets"] = np.int32(5)
-    g8.attrs["version"] = "H5rad ?.?"
-    g8.attrs["date"] = startdate
-    g8.attrs["time"] = starttime[0:6]
-
-    # We do not know much about how; mostly use no-data
-    g9.attrs["yaw_error"] = 0.0
-    g9.attrs["roll_error"] = 0.0
-    g9.attrs["pich_error"] = 0.0
-    g9.attrs["startepochs"] = starttime_sec1970
-    g9.attrs["endepochs"] = endtime_sec1970
-    g9.attrs["platform"] = satellite_name
-    g9.attrs["instrument"] = "avhrr"
-    g9.attrs["orbit_number"] = np.int32(99999)
-    g9.attrs["software"] = "pyGAC"
-    g9.attrs["version"] = "1.0"
-
-    fout.close()
-
-
-    LOG.info('Quality flags will be ' +
-             'written to ' + str(QUAL_DIR))
-    ofn = os.path.join(QUAL_DIR,
-                       (OUTPUT_FILE_PREFIX + '_qualflags_' +
-                        satellite_name + '_99999_' + startdate +
-                        'T' + starttime + 'Z_' +
-                        enddate + 'T' + endtime + 'Z.h5'))
-    LOG.info('Filename: ' + str(os.path.basename(ofn)))
-    fout = h5py.File(ofn, "w")
-
-    dset1 = fout.create_dataset("/qual_flags/data", dtype='int8', data=qual_flags)
-
-    g1 = fout.require_group("/qual_flags")
-
-    g1.attrs["product"] = "QFLAG"
-    g1.attrs["quantity"] = "INT"
-    g1.attrs["dataset_name"] = 'Scanline quality flags'
-    g1.attrs["units"] = 'None'
-    g1.attrs["gain"] = np.int32(1)
-    g1.attrs["offset"] = np.int32(0)
-    g1.attrs["missingdata"] = np.int32(-32001)
-    g1.attrs["nodata"] = np.int32(-32001)
-    g1.attrs["starttime"] = starttime[0:6]
-    g1.attrs["endtime"] = endtime[0:6]
-    g1.attrs["startdate"] = startdate
-    g1.attrs["enddate"] = enddate
-
-    fout.close()
-


=====================================
pygac/investigate_bts1.m deleted
=====================================
@@ -1,50 +0,0 @@
-clear all;
-close all;
-
-fn='temp1.h5';
-
-prt=hdf5read(fn,'prt');
-iprt=hdf5read(fn,'iprt');
-lines=hdf5read(fn,'lines');
-counts=hdf5read(fn,'counts');
-space=hdf5read(fn,'space');
-nlin=hdf5read(fn,'nlin');
-ncor=hdf5read(fn,'ncor');
-tse=hdf5read(fn,'tse');
-
-hold on;
-
-i=find(iprt==1);
-plot(lines(i),prt(i),'r-');
-
-i=find(iprt==2);
-plot(lines(i),prt(i),'g-');
-
-i=find(iprt==3);
-plot(lines(i),prt(i),'b-');
-
-i=find(iprt==4);
-plot(lines(i),prt(i),'k-');
-
-
-plot(lines(1:length(lines)-1),diff(lines)+230,'c-');
-
-
-i=find(iprt==0);
-plot(lines(i),prt(i)+250,'m-');
-
-
-figure;
-
-subplot(4,1,1);
-imagesc(counts-space); colorbar;
-
-subplot(4,1,2);
-imagesc(nlin); colorbar;
-
-subplot(4,1,3);
-imagesc(ncor); colorbar;
-
-subplot(4,1,4);
-imagesc(tse); colorbar;
-


=====================================
bin/pygac-convert-patmosx-coefficients → pygac/patmosx_coeff_reader.py
=====================================
@@ -23,14 +23,16 @@ The official tarballs are available on the PATMOS-x webpage "https://cimss.ssec.
 """
 
 import argparse
-import pathlib
 import datetime as dt
-import tarfile
-import re
 import json
 import logging
+import pathlib
+import re
+import tarfile
+
 from scipy.optimize import bisect
 
+
 class PatmosxReader:
     """Read PATMOS-x coefficient files tarballs."""
     # regular expression with named capturing groups to read an entire patmosx file
@@ -38,9 +40,9 @@ class PatmosxReader:
         r'\s*(?P<sat_name>\w+)[^\n]*\n'
         r'\s*(?P<solar_3b>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<ew_3b>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch3b_Ns>[eE0-9\.-]+),?\s*(?P<ch3b_b0>[eE0-9\.-]+),?\s*(?P<ch3b_b1>[eE0-9\.-]+),?\s*(?P<ch3b_b2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch4_Ns>[eE0-9\.-]+),?\s*(?P<ch4_b0>[eE0-9\.-]+),?\s*(?P<ch4_b1>[eE0-9\.-]+),?\s*(?P<ch4_b2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch5_Ns>[eE0-9\.-]+),?\s*(?P<ch5_b0>[eE0-9\.-]+),?\s*(?P<ch5_b1>[eE0-9\.-]+),?\s*(?P<ch5_b2>[eE0-9\.-]+)[^\n]*\n'
+        r'\s*(?P<ch3b_Ns>[eE0-9\.-]+),?\s*(?P<ch3b_b0>[eE0-9\.-]+),?\s*(?P<ch3b_b1>[eE0-9\.-]+),?\s*(?P<ch3b_b2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch4_Ns>[eE0-9\.-]+),?\s*(?P<ch4_b0>[eE0-9\.-]+),?\s*(?P<ch4_b1>[eE0-9\.-]+),?\s*(?P<ch4_b2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch5_Ns>[eE0-9\.-]+),?\s*(?P<ch5_b0>[eE0-9\.-]+),?\s*(?P<ch5_b1>[eE0-9\.-]+),?\s*(?P<ch5_b2>[eE0-9\.-]+)[^\n]*\n'  # noqa
         r'\s*(?P<nu_3b>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<a1_3b>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<a2_3b>[eE0-9\.-]+)[^\n]*\n'
@@ -54,23 +56,23 @@ class PatmosxReader:
         r'\s*(?P<ch2_dark_count>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<ch3a_dark_count>[eE0-9\.-]+)[^\n]*\n'
         r'(?:[a-z]+[^\n]*\n)?'
-        r'\s*(?P<ch1_low_gain_S0>[eE0-9\.-]+)\s*(?P<ch1_low_gain_S1>[eE0-9\.-]+)\s*(?P<ch1_low_gain_S2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch1_high_gain_S0>[eE0-9\.-]+)\s*(?P<ch1_high_gain_S1>[eE0-9\.-]+)\s*(?P<ch1_high_gain_S2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch2_low_gain_S0>[eE0-9\.-]+)\s*(?P<ch2_low_gain_S1>[eE0-9\.-]+)\s*(?P<ch2_low_gain_S2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch2_high_gain_S0>[eE0-9\.-]+)\s*(?P<ch2_high_gain_S1>[eE0-9\.-]+)\s*(?P<ch2_high_gain_S2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch3a_low_gain_S0>[eE0-9\.-]+)\s*(?P<ch3a_low_gain_S1>[eE0-9\.-]+)\s*(?P<ch3a_low_gain_S2>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<ch3a_high_gain_S0>[eE0-9\.-]+)\s*(?P<ch3a_high_gain_S1>[eE0-9\.-]+)\s*(?P<ch3a_high_gain_S2>[eE0-9\.-]+)[^\n]*\n'
+        r'\s*(?P<ch1_low_gain_S0>[eE0-9\.-]+)\s*(?P<ch1_low_gain_S1>[eE0-9\.-]+)\s*(?P<ch1_low_gain_S2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch1_high_gain_S0>[eE0-9\.-]+)\s*(?P<ch1_high_gain_S1>[eE0-9\.-]+)\s*(?P<ch1_high_gain_S2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch2_low_gain_S0>[eE0-9\.-]+)\s*(?P<ch2_low_gain_S1>[eE0-9\.-]+)\s*(?P<ch2_low_gain_S2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch2_high_gain_S0>[eE0-9\.-]+)\s*(?P<ch2_high_gain_S1>[eE0-9\.-]+)\s*(?P<ch2_high_gain_S2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch3a_low_gain_S0>[eE0-9\.-]+)\s*(?P<ch3a_low_gain_S1>[eE0-9\.-]+)\s*(?P<ch3a_low_gain_S2>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<ch3a_high_gain_S0>[eE0-9\.-]+)\s*(?P<ch3a_high_gain_S1>[eE0-9\.-]+)\s*(?P<ch3a_high_gain_S2>[eE0-9\.-]+)[^\n]*\n'  # noqa
         r'\s*(?P<date_of_launch>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<ch1_gain_switches_count>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<ch2_gain_switches_count>[eE0-9\.-]+)[^\n]*\n'
         r'\s*(?P<ch3a_gain_switches_count>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<PRT1_0>[eE0-9\.-]+)\,*\s*(?P<PRT1_1>[eE0-9\.-]+)\,*\s*(?P<PRT1_2>[eE0-9\.-]+)\,*\s*(?P<PRT1_3>[eE0-9\.-]+)\,*\s*(?P<PRT1_4>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<PRT2_0>[eE0-9\.-]+)\,*\s*(?P<PRT2_1>[eE0-9\.-]+)\,*\s*(?P<PRT2_2>[eE0-9\.-]+)\,*\s*(?P<PRT2_3>[eE0-9\.-]+)\,*\s*(?P<PRT2_4>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<PRT3_0>[eE0-9\.-]+)\,*\s*(?P<PRT3_1>[eE0-9\.-]+)\,*\s*(?P<PRT3_2>[eE0-9\.-]+)\,*\s*(?P<PRT3_3>[eE0-9\.-]+)\,*\s*(?P<PRT3_4>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<PRT4_0>[eE0-9\.-]+)\,*\s*(?P<PRT4_1>[eE0-9\.-]+)\,*\s*(?P<PRT4_2>[eE0-9\.-]+)\,*\s*(?P<PRT4_3>[eE0-9\.-]+)\,*\s*(?P<PRT4_4>[eE0-9\.-]+)[^\n]*\n'
-        r'\s*(?P<PRT_weight_1>[eE0-9\.-]+)\s*(?P<PRT_weight_2>[eE0-9\.-]+)\s*(?P<PRT_weight_3>[eE0-9\.-]+)\s*(?P<PRT_weight_4>[eE0-9\.-]+)[^\n]*\n'
-        r'(?:\s*(?P<sst_mask_day_0>[eE0-9\.-]+),\s*(?P<sst_mask_day_1>[eE0-9\.-]+),\s*(?P<sst_mask_day_2>[eE0-9\.-]+),\s*(?P<sst_mask_day_3>[eE0-9\.-]+)[^\n]*\n)?'
-        r'(?:\s*(?P<sst_mask_night_0>[eE0-9\.-]+),\s*(?P<sst_mask_night_1>[eE0-9\.-]+),\s*(?P<sst_mask_night_2>[eE0-9\.-]+),\s*(?P<sst_mask_night_3>[eE0-9\.-]+)[^\n]*\n)?'
+        r'\s*(?P<PRT1_0>[eE0-9\.-]+)\,*\s*(?P<PRT1_1>[eE0-9\.-]+)\,*\s*(?P<PRT1_2>[eE0-9\.-]+)\,*\s*(?P<PRT1_3>[eE0-9\.-]+)\,*\s*(?P<PRT1_4>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<PRT2_0>[eE0-9\.-]+)\,*\s*(?P<PRT2_1>[eE0-9\.-]+)\,*\s*(?P<PRT2_2>[eE0-9\.-]+)\,*\s*(?P<PRT2_3>[eE0-9\.-]+)\,*\s*(?P<PRT2_4>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<PRT3_0>[eE0-9\.-]+)\,*\s*(?P<PRT3_1>[eE0-9\.-]+)\,*\s*(?P<PRT3_2>[eE0-9\.-]+)\,*\s*(?P<PRT3_3>[eE0-9\.-]+)\,*\s*(?P<PRT3_4>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<PRT4_0>[eE0-9\.-]+)\,*\s*(?P<PRT4_1>[eE0-9\.-]+)\,*\s*(?P<PRT4_2>[eE0-9\.-]+)\,*\s*(?P<PRT4_3>[eE0-9\.-]+)\,*\s*(?P<PRT4_4>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'\s*(?P<PRT_weight_1>[eE0-9\.-]+)\s*(?P<PRT_weight_2>[eE0-9\.-]+)\s*(?P<PRT_weight_3>[eE0-9\.-]+)\s*(?P<PRT_weight_4>[eE0-9\.-]+)[^\n]*\n'  # noqa
+        r'(?:\s*(?P<sst_mask_day_0>[eE0-9\.-]+),\s*(?P<sst_mask_day_1>[eE0-9\.-]+),\s*(?P<sst_mask_day_2>[eE0-9\.-]+),\s*(?P<sst_mask_day_3>[eE0-9\.-]+)[^\n]*\n)?'  # noqa
+        r'(?:\s*(?P<sst_mask_night_0>[eE0-9\.-]+),\s*(?P<sst_mask_night_1>[eE0-9\.-]+),\s*(?P<sst_mask_night_2>[eE0-9\.-]+),\s*(?P<sst_mask_night_3>[eE0-9\.-]+)[^\n]*\n)?'  # noqa
         r'(?:\![^v][^\n]*\n)*'
         r'(?:\!(?P<version>v\w+))?'
     )
@@ -122,7 +124,7 @@ class Translator:
                 "s2": "quadratic single-gain calibration slope parameter [% years^{-2}]",
                 "date_of_launch": "timestamp of launch date [UTC]"
             },
-            "method": 'Heidinger, A.K., W.C. Straka III, C.C. Molling, J.T. Sullivan, and X. Wu, 2010: Deriving an inter-sensor consistent calibration for the AVHRR solar reflectance data record. International Journal of Remote Sensing, 31:6493-6517'
+            "method": 'Heidinger, A.K., W.C. Straka III, C.C. Molling, J.T. Sullivan, and X. Wu, 2010: Deriving an inter-sensor consistent calibration for the AVHRR solar reflectance data record. International Journal of Remote Sensing, 31:6493-6517'  # noqa
         },
         "thermal": {
             "channels": ['3b', '4', '5'],
@@ -132,7 +134,7 @@ class Translator:
                 "b1": "linear non-linear radiance correction coefficient []",
                 "b2": "quadratic non-linear radiance correction coefficient [(mW^{-1} m^2 sr^{-1} cm)]",
                 "space_radiance": "radiance of space [mW m^{-2} sr cm^{-1}]",
-                "to_eff_blackbody_intercept": "thermal channel temperature to effective blackbody temperature intercept [K]",
+                "to_eff_blackbody_intercept": "thermal channel temperature to effective blackbody temperature intercept [K]",  # noqa
                 "to_eff_blackbody_slope": "thermal channel temperature to effective blackbody temperature slope []",
                 "d0": "constant thermometer counts to temperature conversion coefficient [K]",
                 "d1": "linear thermometer counts to temperature conversion coefficient [K]",
@@ -140,7 +142,7 @@ class Translator:
                 "d3": "cubic thermometer counts to temperature conversion coefficient [K]",
                 "d4": "quartic thermometer counts to temperature conversion coefficient [K]"
             },
-            "method": "Goodrum, G., Kidwell, K.B. and W. Winston, 2000: NOAA KLM User's Guide. U.S. Department of Commerce, National Oceanic and Atmospheric Administration, National Environmental Satellite, Data and Information Service; Walton, C. C., J. T. Sullivan, C. R. N. Rao, and M. P. Weinreb, 1998: Corrections for detector nonlinearities and calibration inconsistencies of the infrared channels of the Advanced Very High Resolution Radiometer. J. Geophys. Res., 103, 3323-3337; Trishchenko, A.P., 2002: Removing Unwanted Fluctuations in the AVHRR Thermal Calibration Data Using Robust Techniques. Journal of Atmospheric and Oceanic Technology, 19:1939-1954"
+            "method": "Goodrum, G., Kidwell, K.B. and W. Winston, 2000: NOAA KLM User's Guide. U.S. Department of Commerce, National Oceanic and Atmospheric Administration, National Environmental Satellite, Data and Information Service; Walton, C. C., J. T. Sullivan, C. R. N. Rao, and M. P. Weinreb, 1998: Corrections for detector nonlinearities and calibration inconsistencies of the infrared channels of the Advanced Very High Resolution Radiometer. J. Geophys. Res., 103, 3323-3337; Trishchenko, A.P., 2002: Removing Unwanted Fluctuations in the AVHRR Thermal Calibration Data Using Robust Techniques. Journal of Atmospheric and Oceanic Technology, 19:1939-1954"  # noqa
         }
     }
 
@@ -251,7 +253,8 @@ class Translator:
             json.dump(self.coeffs, json_file, indent=4, sort_keys=True)
 
 
-if __name__ == "__main__":
+def main():
+    """The main function."""
     parser = argparse.ArgumentParser(description=__doc__)
     parser.add_argument('tarball', type=str, help='path to PATMOS-x coefficients tarball')
     parser.add_argument('-o', '--output', type=str, metavar="JSON",
@@ -272,3 +275,6 @@ if __name__ == "__main__":
     logging.info('Write PyGAC calibration json file "%s".', output)
     pygac_coeffs.save(output)
     logging.info('Done!')
+
+if __name__ == "__main__":
+    main()


=====================================
pygac/reader.py
=====================================
@@ -24,26 +24,24 @@
 
 Can't be used as is, has to be subclassed to add specific read functions.
 """
-from abc import ABCMeta, abstractmethod
 import datetime
 import logging
-
-import numpy as np
 import os
 import re
-import six
 import types
 import warnings
-import pyorbital
+from abc import ABCMeta, abstractmethod
 
-from pygac.utils import (centered_modulus,
-                         calculate_sun_earth_distance_correction,
-                         get_absolute_azimuth_angle_diff)
-from pyorbital.orbital import Orbital
+import numpy as np
+import pyorbital
+import six
+from packaging.version import Version
 from pyorbital import astronomy
-from pygac.calibration import Calibrator, calibrate_solar, calibrate_thermal
+from pyorbital.orbital import Orbital
+
 from pygac import gac_io
-from packaging.version import Version
+from pygac.calibration import Calibrator, calibrate_solar, calibrate_thermal
+from pygac.utils import calculate_sun_earth_distance_correction, centered_modulus, get_absolute_azimuth_angle_diff
 
 LOG = logging.getLogger(__name__)
 
@@ -865,7 +863,7 @@ class Reader(six.with_metaclass(ABCMeta)):
 
         jday = np.where(np.logical_or(jday < 1, jday > 366),
                         np.median(jday), jday)
-        if_wrong_jday = np.ediff1d(jday, to_begin=0)
+        if_wrong_jday = np.ediff1d(jday, to_begin=jday.dtype.type(0))
         jday = np.where(if_wrong_jday < 0, max(jday), jday)
 
         if_wrong_msec = np.where(msec < 1)
@@ -877,7 +875,7 @@ class Reader(six.with_metaclass(ABCMeta)):
                 msec0 = np.median(msec - msec_lineno)
                 msec = msec0 + msec_lineno
 
-        if_wrong_msec = np.ediff1d(msec, to_begin=0)
+        if_wrong_msec = np.ediff1d(msec, to_begin=msec.dtype.type(0))
         msec = np.where(np.logical_and(np.logical_or(if_wrong_msec < -1000, if_wrong_msec > 1000), if_wrong_jday != 1),
                         msec[0] + msec_lineno, msec)
 


=====================================
pygac/tests/test_klm.py
=====================================
@@ -112,7 +112,7 @@ class TestKLM:
             QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION,
             QFlag.TIME_ERROR | QFlag.DATA_GAP,
             QFlag.FATAL_FLAG
-        ], dtype=np.uint32)
+        ], dtype=np.int64)
         reader.scans = {self.reader._quality_indicators_key: quality_indicators}
         # test mask, i.e. QFlag.FATAL_FLAG | QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION
         expected_mask = np.array([False, True, True, False, True], dtype=bool)


=====================================
pyproject.toml
=====================================
@@ -1,6 +1,66 @@
+[project]
+name = "pygac"
+dynamic = ["version"]
+description = "NOAA AVHRR GAC/LAC/FRAC reader and calibration"
+authors = [
+    { name = "The Pytroll Team", email = "pytroll at googlegroups.com" }
+]
+dependencies = [
+    "bottleneck>=1.0.0",
+    "docutils>=0.3",
+    "h5py>=2.0.1",
+    "numpy>=1.8.0",
+    "pyorbital>=0.3.2",
+    "python-geotiepoints>=1.1.8",
+    "scipy>=0.8.0",
+    "packaging"
+]
+readme = "README.md"
+requires-python = ">=3.8"
+license = { text = "GPLv3" }
+classifiers = [
+    "Programming Language :: Python :: 3",
+    "Operating System :: OS Independent",
+    "Development Status :: 4 - Beta",
+    "Intended Audience :: Science/Research",
+    "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
+    "Operating System :: OS Independent",
+    "Topic :: Scientific/Engineering"
+]
+
+[project.urls]
+Homepage = "https://github.com/pytroll/pygac"
+"Bug Tracker" = "https://github.com/pytroll/pygac/issues"
+Documentation = "https://pygac.readthedocs.io/en/stable/"
+"Source Code" = "https://github.com/pytroll/pygac"
+Organization = "https://pytroll.github.io/"
+Slack = "https://pytroll.slack.com/"
+"Release Notes" = "https://github.com/pytroll/pygac/blob/main/CHANGELOG.md"
+
+[project.optional-dependencies]
+dev = ['pytest', 'pre-commit', 'ruff']
+
+[project.scripts]
+pygac-convert-patmosx-coefficients = "pygac.patmosx_coeff_reader:main"
+
 [build-system]
-requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.2", 'setuptools_scm_git_archive']
-build-backend = "setuptools.build_meta"
+requires = ["hatchling", "hatch-vcs"]
+build-backend = "hatchling.build"
+
+[tool.hatch.metadata]
+allow-direct-references = true
+
+[tool.hatch.build.targets.wheel]
+packages = ["pygac"]
+
+[tool.hatch.version]
+source = "vcs"
+
+[tool.hatch.build.hooks.vcs]
+version-file = "pygac/version.py"
+
+[tool.ruff]
+line-length = 120
 
-[tool.setuptools_scm]
-write_to = "pygac/version.py"
+[tool.ruff.lint]
+select = ["E", "W", "F", "I"]


=====================================
setup.cfg deleted
=====================================
@@ -1,7 +0,0 @@
-[options]
-setup_requires =
-    setuptools_scm
-    setuptools_scm_git_archive
-
-[flake8]
-max-line-length = 120


=====================================
setup.py deleted
=====================================
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014 Abhay Devasthale, Adam.Dybbroe, Martin Raspaud
-
-# Author(s):
-
-#   Adam.Dybbroe <a000680 at c14526.ad.smhi.se>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""The setup module."""
-
-from setuptools import setup
-import os
-
-if __name__ == '__main__':
-    with open("README.md", "r") as fd:
-        long_description = fd.read()
-
-    requirements = ['docutils>=0.3',
-                    'numpy>=1.8.0',
-                    'pyorbital>=v0.3.2',
-                    'h5py>=2.0.1',
-                    'scipy>=0.8.0',
-                    'python-geotiepoints>=1.1.8',
-                    'bottleneck>=1.0.0']
-    extras_require = {
-        'dev': ['pytest', 'pre-commit', 'flake8']
-    }
-
-    setup(name='pygac',
-          description='NOAA AVHRR GAC/LAC reader and calibration',
-          author='The Pytroll Team',
-          author_email='pytroll at googlegroups.com',
-          classifiers=["Development Status :: 4 - Beta",
-                       "Intended Audience :: Science/Research",
-                       "License :: OSI Approved :: GNU General Public License v3 " +
-                       "or later (GPLv3+)",
-                       "Operating System :: OS Independent",
-                       "Programming Language :: Python",
-                       "Topic :: Scientific/Engineering"],
-          url="https://github.com/pytroll/pygac",
-          long_description=long_description,
-          long_description_content_type='text/markdown',
-          license='GPLv3',
-
-          packages=['pygac'],
-          package_data={'pygac': ['data/calibration.json']},
-
-          # Project should use reStructuredText, so ensure that the docutils get
-          # installed or upgraded on the target machine
-          install_requires=requirements,
-          extras_require=extras_require,
-          scripts=[os.path.join('bin', item) for item in os.listdir('bin')],
-          data_files=[('etc', ['etc/pygac.cfg.template']),
-                      ('gapfilled_tles', ['gapfilled_tles/TLE_noaa16.txt'])],
-          python_requires='>=3.8',
-          zip_safe=False
-          )



View it on GitLab: https://salsa.debian.org/debian-gis-team/pygac/-/commit/dc834512d1d633773539c65ff802f61b707d8da8

-- 
This project does not include diff previews in email notifications.
View it on GitLab: https://salsa.debian.org/debian-gis-team/pygac/-/commit/dc834512d1d633773539c65ff802f61b707d8da8
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/20240719/452bca53/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list