[Git][debian-gis-team/pyspectral][master] 4 commits: New upstream version 0.8.9+ds

Antonio Valentino gitlab at salsa.debian.org
Mon Jul 8 06:56:57 BST 2019



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


Commits:
4dc76bc9 by Antonio Valentino at 2019-07-08T05:39:22Z
New upstream version 0.8.9+ds
- - - - -
91f02b8c by Antonio Valentino at 2019-07-08T05:39:24Z
Update upstream source from tag 'upstream/0.8.9+ds'

Update to upstream version '0.8.9+ds'
with Debian dir a1488d511ecd8a5ae6f72fbddbe5dc7f251ebb82
- - - - -
3d165f42 by Antonio Valentino at 2019-07-08T05:46:43Z
New upstream release

- - - - -
e7d0ab7a by Antonio Valentino at 2019-07-08T05:52:44Z
Set distribution to unstable

- - - - -


13 changed files:

- CHANGELOG.md
- bin/download_atm_correction_luts.py
- bin/download_rsr.py
- debian/changelog
- doc/37_reflectance.rst
- doc/usage.rst
- pyspectral/config.py
- pyspectral/rayleigh.py
- pyspectral/rsr_reader.py
- pyspectral/utils.py
- pyspectral/version.py
- rsr_convert_scripts/metimage_rsr.py
- rsr_convert_scripts/olci_rsr.py


Changes:

=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,43 @@
+## Version <RELEASE_VERSION> (2019/06/07)
+
+### Issues Closed
+
+* [Issue 75](https://github.com/pytroll/pyspectral/issues/75) - 'download_luts' and 'download_rsr' functions always download files ([PR 76](https://github.com/pytroll/pyspectral/pull/76))
+
+In this release 1 issue was closed.
+
+### Pull Requests Merged
+
+#### Features added
+
+* [PR 76](https://github.com/pytroll/pyspectral/pull/76) - Feature download LUT files only if outdated ([75](https://github.com/pytroll/pyspectral/issues/75))
+
+In this release 1 pull request was closed.
+
+## Version <RELEASE_VERSION> (2019/04/29)
+
+### Issues Closed
+
+* [Issue 70](https://github.com/pytroll/pyspectral/issues/70) - Update yaml usage to work with pyyaml 5.1+ ([PR 71](https://github.com/pytroll/pyspectral/pull/71))
+* [Issue 66](https://github.com/pytroll/pyspectral/issues/66) - Throws a warning about non-existing directory - storing/reading cached radiance-tb look-up-tables ([PR 67](https://github.com/pytroll/pyspectral/pull/67))
+* [Issue 61](https://github.com/pytroll/pyspectral/issues/61) - can this program be used for user-defined sensor or rsr? ([PR 62](https://github.com/pytroll/pyspectral/pull/62))
+* [Issue 58](https://github.com/pytroll/pyspectral/issues/58) - Use dask instead of numpy masked arrays ([PR 59](https://github.com/pytroll/pyspectral/pull/59))
+
+In this release 4 issues were closed.
+
+### Pull Requests Merged
+
+#### Features added
+
+* [PR 71](https://github.com/pytroll/pyspectral/pull/71) - Fix yaml 5.1+ support with unsafe loading ([70](https://github.com/pytroll/pyspectral/issues/70), [70](https://github.com/pytroll/pyspectral/issues/70))
+* [PR 69](https://github.com/pytroll/pyspectral/pull/69) - Feature rayleigh catch exception
+* [PR 68](https://github.com/pytroll/pyspectral/pull/68) - Feaure metimage multiple detectors
+* [PR 65](https://github.com/pytroll/pyspectral/pull/65) - Feature add metimage
+
+
+In this release 4 pull requests were closed.
+
+
 ## Version <RELEASE_VERSION> (2019/04/09)
 
 ### Issues Closed
@@ -12,8 +52,10 @@ In this release 3 issues were closed.
 
 #### Bugs fixed
 
+* [PR 67](https://github.com/pytroll/pyspectral/pull/67) - Bugfix tb2rad lut caching ([66](https://github.com/pytroll/pyspectral/issues/66))
 * [PR 64](https://github.com/pytroll/pyspectral/pull/64) - Fix interp function in rayleigh correction to be serializable
 
+
 #### Features added
 
 * [PR 59](https://github.com/pytroll/pyspectral/pull/59) - Daskify NIR reflectance calculations ([58](https://github.com/pytroll/pyspectral/issues/58))


=====================================
bin/download_atm_correction_luts.py
=====================================
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2018 Adam.Dybbroe
+# Copyright (c) 2018, 2019 Adam.Dybbroe
 
 # Author(s):
 
@@ -27,9 +27,11 @@ spectral range
 
 import logging
 import argparse
-from pyspectral.utils import download_luts, AEROSOL_TYPES
+from pyspectral.utils import AEROSOL_TYPES
 from pyspectral.utils import logging_on, logging_off
+from pyspectral.rayleigh import check_and_download
 
+LOG = logging.getLogger(__name__)
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(
@@ -53,5 +55,4 @@ if __name__ == "__main__":
     else:
         logging_off()
 
-    # Download:
-    download_luts(aerosol_type=aerosol_types, dry_run=dry_run)
+    check_and_download(aerosol_type=aerosol_types, dry_run=dry_run)


=====================================
bin/download_rsr.py
=====================================
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2018 Adam.Dybbroe
+# Copyright (c) 2018, 2019 Adam.Dybbroe
 
 # Author(s):
 
@@ -25,8 +25,11 @@
 
 import logging
 import argparse
-from pyspectral.utils import download_rsr
 from pyspectral.utils import logging_on, logging_off
+from pyspectral.rsr_reader import check_and_download
+
+LOG = logging.getLogger(__name__)
+
 
 if __name__ == "__main__":
 
@@ -51,6 +54,6 @@ if __name__ == "__main__":
         logging_off()
 
     if dest_dir:
-        download_rsr(dest_dir=dest_dir, dry_run=dry_run)
+        check_and_download(dest_dir=dest_dir, dry_run=dry_run)
     else:
-        download_rsr(dry_run=dry_run)
+        check_and_download(dry_run=dry_run)


=====================================
debian/changelog
=====================================
@@ -1,9 +1,13 @@
-pyspectral (0.8.7+ds-2) UNRELEASED; urgency=medium
+pyspectral (0.8.9+ds-1) unstable; urgency=medium
 
-  * Team upload.
+  [ Bas Couwenberg ]
   * Update gbp.conf to use --source-only-changes by default.
 
- -- Bas Couwenberg <sebastic at debian.org>  Sun, 07 Jul 2019 09:43:20 +0200
+  [ Antonio Valentino ]
+  * New upstream release.
+  * Set distribution to unstable.
+
+ -- Antonio Valentino <antonio.valentino at tiscali.it>  Mon, 08 Jul 2019 05:47:10 +0000
 
 pyspectral (0.8.7+ds-1) experimental; urgency=medium
 


=====================================
doc/37_reflectance.rst
=====================================
@@ -255,5 +255,5 @@ Using the example of the VIIRS M12 band from above this gives the following spec
   >>> ['{tb:6.3f}'.format(tb=np.round(t, 4)) for t in tb]
   ['266.996', '267.262', '267.991', '271.033', '271.927']
   >>> rad = refl_m12.emissive_part_3x(tb=False)
-  >>> ['{rad:6.3f}'.format(rad=np.round(r, 4)) for r in rad]
-  ['80285.149', '81458.022', '84749.639', '99761.401', '104582.030']
+  >>> ['{rad:6.3f}'.format(rad=np.round(r, 3)) for r in rad]
+  ['80285.149', '81458.022', '84749.639', '99761.400', '104582.030']


=====================================
doc/usage.rst
=====================================
@@ -18,7 +18,7 @@ Now, you can work with the data as you wish, make some simple plot for instance:
   >>> [str(b) for b in olci.band_names]
   ['Oa01', 'Oa02', 'Oa03', 'Oa04', 'Oa05', 'Oa06', 'Oa07', 'Oa08', 'Oa09', 'Oa10', 'Oa11', 'Oa12', 'Oa13', 'Oa14', 'Oa15', 'Oa16', 'Oa17', 'Oa18', 'Oa19', 'Oa20', 'Oa21']
   >>> print("Central wavelength = {wvl:7.6f}".format(wvl=olci.rsr['Oa01']['det-1']['central_wavelength']))
-  Central wavelength = 0.400123
+  Central wavelength = 0.400303
   >>> import matplotlib.pyplot as plt
   >>> dummy = plt.figure(figsize=(10, 5))
   >>> import numpy as np


=====================================
pyspectral/config.py
=====================================
@@ -31,6 +31,11 @@ import yaml
 from collections import Mapping
 import pkg_resources
 
+try:
+    from yaml import UnsafeLoader
+except ImportError:
+    from yaml import Loader as UnsafeLoader
+
 
 LOG = logging.getLogger(__name__)
 
@@ -72,7 +77,7 @@ def get_config():
 
     config = {}
     with open(configfile, 'r') as fp_:
-        config = recursive_dict_update(config, yaml.load(fp_))
+        config = recursive_dict_update(config, yaml.load(fp_, Loader=UnsafeLoader))
 
     app_dirs = AppDirs('pyspectral', 'pytroll')
     user_datadir = app_dirs.user_data_dir


=====================================
pyspectral/rayleigh.py
=====================================
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2016-2018 Pytroll
+# Copyright (c) 2016-2019 Pytroll
 
 # Author(s):
 
@@ -71,42 +71,81 @@ class BandFrequencyOutOfRange(ValueError):
     pass
 
 
-class Rayleigh(object):
-    """Container for the atmospheric correction of satellite imager bands.
-
-    This class removes background contributions of Rayleigh scattering of
-    molecules and Mie scattering and absorption by aerosols.
-
-    """
+class RayleighConfigBaseClass(object):
+    """A base class for the Atmospheric correction, handling the configuration and LUT download"""
 
-    def __init__(self, platform_name, sensor, **kwargs):
+    def __init__(self, aerosol_type, atm_type='us-standard'):
         """Initialize class and determine LUT to use."""
-        self.platform_name = platform_name
-        self.sensor = sensor
-        self.coeff_filename = None
         options = get_config()
         self.do_download = False
         self._lutfiles_version_uptodate = False
 
-        atm_type = kwargs.get('atmosphere', 'us-standard')
+        if 'download_from_internet' in options and options['download_from_internet']:
+            self.do_download = True
+
         if atm_type not in ATMOSPHERES:
             raise AttributeError('Atmosphere type not supported! ' +
                                  'Need to be one of {}'.format(str(ATMOSPHERES)))
 
-        aerosol_type = kwargs.get('aerosol_type', 'marine_clean_aerosol')
         self._aerosol_type = aerosol_type
-
         if aerosol_type not in AEROSOL_TYPES:
             raise AttributeError('Aerosol type not supported! ' +
                                  'Need to be one of {0}'.format(str(AEROSOL_TYPES)))
 
-        rayleigh_dir = RAYLEIGH_LUT_DIRS[aerosol_type]
-
         if atm_type not in ATMOSPHERES.keys():
             LOG.error("Atmosphere type %s not supported", atm_type)
 
         LOG.info("Atmosphere chosen: %s", atm_type)
 
+        if (self._aerosol_type in ATM_CORRECTION_LUT_VERSION and
+                self._get_lutfiles_version() == ATM_CORRECTION_LUT_VERSION[self._aerosol_type]['version']):
+            self.lutfiles_version_uptodate = True
+
+    def _get_lutfiles_version(self):
+        """Check the version of the atm correction luts from the version file in the
+           specific aerosol correction directory
+
+        """
+        basedir = RAYLEIGH_LUT_DIRS[self._aerosol_type]
+        lutfiles_version_path = os.path.join(basedir,
+                                             ATM_CORRECTION_LUT_VERSION[self._aerosol_type]['filename'])
+
+        if not os.path.exists(lutfiles_version_path):
+            return "v0.0.0"
+
+        with open(lutfiles_version_path, 'r') as fpt:
+            # Get the version from the file
+            return fpt.readline().strip()
+
+    @property
+    def lutfiles_version_uptodate(self):
+        return self._lutfiles_version_uptodate
+
+    @lutfiles_version_uptodate.setter
+    def lutfiles_version_uptodate(self, value):
+        self._lutfiles_version_uptodate = value
+
+
+class Rayleigh(RayleighConfigBaseClass):
+    """Container for the atmospheric correction of satellite imager bands.
+
+    This class removes background contributions of Rayleigh scattering of
+    molecules and Mie scattering and absorption by aerosols.
+
+    """
+
+    def __init__(self, platform_name, sensor, **kwargs):
+        """Initialize class and determine LUT to use."""
+
+        atm_type = kwargs.get('atmosphere', 'us-standard')
+        aerosol_type = kwargs.get('aerosol_type', 'marine_clean_aerosol')
+
+        super(Rayleigh, self).__init__(aerosol_type, atm_type)
+
+        self.platform_name = platform_name
+        self.sensor = sensor
+        self.coeff_filename = None
+
         # Try fix instrument naming
         instr = INSTRUMENTS.get(platform_name, sensor)
         if instr != sensor:
@@ -116,12 +155,7 @@ class Rayleigh(object):
 
         self.sensor = sensor.replace('/', '')
 
-        if 'download_from_internet' in options and options['download_from_internet']:
-            self.do_download = True
-
-        if (self._aerosol_type in ATM_CORRECTION_LUT_VERSION and
-                self._get_lutfiles_version() == ATM_CORRECTION_LUT_VERSION[self._aerosol_type]['version']):
-            self._lutfiles_version_uptodate = True
+        rayleigh_dir = RAYLEIGH_LUT_DIRS[aerosol_type]
 
         ext = atm_type.replace(' ', '_')
         lutname = "rayleigh_lut_{0}.h5".format(ext)
@@ -144,22 +178,6 @@ class Rayleigh(object):
         self._satz_sec_coord = None
         self._sunz_sec_coord = None
 
-    def _get_lutfiles_version(self):
-        """Check the version of the atm correction luts from the version file in the
-           specific aerosol correction directory
-
-        """
-        basedir = RAYLEIGH_LUT_DIRS[self._aerosol_type]
-        lutfiles_version_path = os.path.join(basedir,
-                                             ATM_CORRECTION_LUT_VERSION[self._aerosol_type]['filename'])
-
-        if not os.path.exists(lutfiles_version_path):
-            return "v0.0.0"
-
-        with open(lutfiles_version_path, 'r') as fpt:
-            # Get the version from the file
-            return fpt.readline().strip()
-
     def get_effective_wavelength(self, bandname):
         """Get the effective wavelength with Rayleigh scattering in mind"""
         try:
@@ -171,7 +189,10 @@ class Rayleigh(object):
                 LOG.warning(
                     "Effective wavelength is set to the requested band wavelength = %f", bandname)
                 return bandname
-            return None
+
+            msg = ("Can't get effective wavelength for band %s on platform %s and sensor %s" %
+                   (str(bandname), self.platform_name, self.sensor))
+            raise KeyError(msg)
 
         if isinstance(bandname, str):
             bandname = BANDNAMES.get(self.sensor, BANDNAMES['generic']).get(bandname, bandname)
@@ -220,15 +241,9 @@ class Rayleigh(object):
             wvl = bandname * 1000.0
         else:
             wvl = self.get_effective_wavelength(bandname)
-            if wvl is None:
-                LOG.error("Can't get effective wavelength for band %s on platform %s and sensor %s",
-                          str(bandname), self.platform_name, self.sensor)
-                return None
-            else:
-                wvl = wvl * 1000.0
+            wvl = wvl * 1000.0
 
-        rayl, wvl_coord, azid_coord, satz_sec_coord, sunz_sec_coord = \
-            self.get_reflectance_lut()
+        rayl, wvl_coord, azid_coord, satz_sec_coord, sunz_sec_coord = self.get_reflectance_lut()
 
         # force dask arrays
         compute = False
@@ -255,8 +270,7 @@ class Rayleigh(object):
             LOG.info(
                 "Set the rayleigh/aerosol reflectance contribution to zero!")
             if HAVE_DASK:
-                chunks = sun_zenith.chunks if redband is None \
-                    else redband.chunks
+                chunks = sun_zenith.chunks if redband is None else redband.chunks
                 res = zeros(shape, chunks=chunks)
                 return res.compute() if compute else res
             else:
@@ -335,3 +349,22 @@ def get_reflectance_lut(filename):
         h5f.close()
 
     return tab, wvl, azidiff, satellite_zenith_secant, sun_zenith_secant
+
+
+def check_and_download(**kwargs):
+    """Do a check for the version of the atmospheric correction LUTs and attempt
+       downloading only if needed
+
+    """
+
+    aerosol_types = kwargs.get('aerosol_types', AEROSOL_TYPES)
+    dry_run = kwargs.get('dry_run', False)
+
+    for aerosol_type in aerosol_types:
+        atmcorr = RayleighConfigBaseClass(aerosol_type)
+        if atmcorr.lutfiles_version_uptodate:
+            LOG.info("Atm correction LUTs, for aerosol distribution %s, already the latest!",
+                     aerosol_type)
+        else:
+            # Download
+            download_luts(aerosol_type=aerosol_type, dry_run=dry_run)


=====================================
pyspectral/rsr_reader.py
=====================================
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2014-2018 Adam.Dybbroe
+# Copyright (c) 2014-2019 Adam.Dybbroe
 
 # Author(s):
 
@@ -38,25 +38,11 @@ from pyspectral.utils import (INSTRUMENTS, download_rsr)
 from pyspectral.utils import (RSR_DATA_VERSION_FILENAME, RSR_DATA_VERSION)
 
 
-class RelativeSpectralResponse(object):
-    """Container for the relative spectral response functions for various
-    satellite imagers
-    """
+class RSRDataBaseClass(object):
 
-    def __init__(self, platform_name=None, instrument=None, **kwargs):
+    def __init__(self):
         """Create the instance either from platform name and instrument or from
         filename and load the data"""
-        self.platform_name = platform_name
-        self.instrument = instrument
-        self.filename = None
-        if not self.instrument or not self.platform_name:
-            if 'filename' in kwargs:
-                self.filename = kwargs['filename']
-            else:
-                raise AttributeError(
-                    "platform name and sensor or filename must be specified")
-        else:
-            self._check_instrument()
 
         self.rsr = {}
         self.description = "Unknown"
@@ -76,6 +62,48 @@ class RelativeSpectralResponse(object):
         if self._get_rsr_data_version() == RSR_DATA_VERSION:
             self._rsr_data_version_uptodate = True
 
+    def _get_rsr_data_version(self):
+        """Check the version of the RSR data from the version file in the RSR
+           directory
+
+        """
+
+        rsr_data_version_path = os.path.join(self.rsr_dir, RSR_DATA_VERSION_FILENAME)
+        if not os.path.exists(rsr_data_version_path):
+            return "v0.0.0"
+
+        with open(rsr_data_version_path, 'r') as fpt:
+            # Get the version from the file
+            return fpt.readline().strip()
+
+    @property
+    def rsr_data_version_uptodate(self):
+        return self._rsr_data_version_uptodate
+
+
+class RelativeSpectralResponse(RSRDataBaseClass):
+    """Container for the relative spectral response functions for various
+    satellite imagers
+    """
+
+    def __init__(self, platform_name=None, instrument=None, **kwargs):
+        """Create the instance either from platform name and instrument or from
+        filename and load the data"""
+
+        super(RelativeSpectralResponse, self).__init__()
+
+        self.platform_name = platform_name
+        self.instrument = instrument
+        self.filename = None
+        if not self.instrument or not self.platform_name:
+            if 'filename' in kwargs:
+                self.filename = kwargs['filename']
+            else:
+                raise AttributeError(
+                    "platform name and sensor or filename must be specified")
+        else:
+            self._check_instrument()
+
         if not self.filename:
             self._get_filename()
 
@@ -95,20 +123,6 @@ class RelativeSpectralResponse(object):
         LOG.debug('Filename: %s', str(self.filename))
         self.load()
 
-    def _get_rsr_data_version(self):
-        """Check the version of the RSR data from the version file in the RSR
-           directory
-
-        """
-
-        rsr_data_version_path = os.path.join(self.rsr_dir, RSR_DATA_VERSION_FILENAME)
-        if not os.path.exists(rsr_data_version_path):
-            return "v0.0.0"
-
-        with open(rsr_data_version_path, 'r') as fpt:
-            # Get the version from the file
-            return fpt.readline().strip()
-
     def _check_instrument(self):
         """Check and try fix instrument name if needed"""
         instr = INSTRUMENTS.get(self.platform_name, self.instrument.lower())
@@ -252,6 +266,22 @@ class RelativeSpectralResponse(object):
             raise NotImplementedError(errmsg)
 
 
+def check_and_download(**kwargs):
+    """Do a check for the version and attempt downloading only if needed"""
+
+    dry_run = kwargs.get('dry_run', False)
+    dest_dir = kwargs.get('dest_dir', None)
+
+    rsr = RSRDataBaseClass()
+    if rsr.rsr_data_version_uptodate:
+        LOG.info("RSR data already the latest!")
+    else:
+        if dest_dir:
+            download_rsr(dest_dir=dest_dir, dry_run=dry_run)
+        else:
+            download_rsr(dry_run=dry_run)
+
+
 def main():
     """Main"""
     modis = RelativeSpectralResponse('EOS-Terra', 'modis')


=====================================
pyspectral/utils.py
=====================================
@@ -123,9 +123,9 @@ INSTRUMENTS = {'NOAA-19': 'avhrr/3',
                'Feng-Yun 3D': 'mersi-2'
                }
 
-HTTP_PYSPECTRAL_RSR = "https://zenodo.org/record/2617441/files/pyspectral_rsr_data.tgz"
+HTTP_PYSPECTRAL_RSR = "https://zenodo.org/record/2653487/files/pyspectral_rsr_data.tgz"
 RSR_DATA_VERSION_FILENAME = "PYSPECTRAL_RSR_VERSION"
-RSR_DATA_VERSION = "v1.0.5"
+RSR_DATA_VERSION = "v1.0.6"
 
 ATM_CORRECTION_LUT_VERSION = {}
 ATM_CORRECTION_LUT_VERSION['antarctic_aerosol'] = {'version': 'v1.0.1',


=====================================
pyspectral/version.py
=====================================
@@ -46,9 +46,9 @@ def get_keywords():
     # setup.py/versioneer.py will grep for the variable names, so they must
     # each be defined on a line of their own. _version.py will just call
     # get_keywords().
-    git_refnames = " (tag: v0.8.7)"
-    git_full = "4cd92661e6a5bfde3526a832e1b8eab9b741592d"
-    git_date = "2019-04-09 17:10:33 +0200"
+    git_refnames = " (tag: v0.8.9)"
+    git_full = "b3a1f58f49e2ab7c81c331e379065f24eb21f1ba"
+    git_date = "2019-06-07 09:27:42 +0200"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 


=====================================
rsr_convert_scripts/metimage_rsr.py
=====================================
@@ -28,7 +28,7 @@ derived from specifications I assume.
 
 import os
 import numpy as np
-from pyspectral.utils import convert2hdf5 as tohdf5
+from pyspectral.utils import get_central_wave
 from pyspectral.raw_reader import InstrumentRSR
 import logging
 
@@ -80,13 +80,84 @@ class MetImageRSR(InstrumentRSR):
         wavelength = 1. / data['wavenumber'] * 10000.
         response = data['response']
 
-        self.rsr = {'wavelength': wavelength, 'response': response}
+        # The real MetImage has 24 detectors. However, for now we store the
+        # single rsr as 'detector-1', indicating that there will be multiple
+        # detectors in the future:
+        detectors = {}
+        detectors['det-1'] = {'wavelength': wavelength, 'response': response}
+        self.rsr = detectors
+
+
+def generate_metimage_file(platform_name):
+    """Retrieve original RSR data and convert to internal hdf5 format.
+    """
+    import h5py
+
+    bandnames = METIMAGE_BAND_NAMES
+    instr = MetImageRSR(bandnames[0], platform_name)
+    instr_name = instr.instrument.replace('/', '')
+    filename = os.path.join(instr.output_dir,
+                            "rsr_{0}_{1}.h5".format(instr_name,
+                                                    platform_name))
+
+    with h5py.File(filename, "w") as h5f:
+        h5f.attrs['description'] = ('Relative Spectral Responses for ' +
+                                    instr.instrument.upper())
+        h5f.attrs['platform_name'] = platform_name
+        h5f.attrs['band_names'] = bandnames
+
+        for chname in bandnames:
+            metimage = MetImageRSR(chname, platform_name)
+            grp = h5f.create_group(chname)
+            grp.attrs['number_of_detectors'] = len(metimage.rsr.keys())
+            # Loop over each detector to check if the sampling wavelengths are
+            # identical:
+            det_names = list(metimage.rsr.keys())
+            wvl = metimage.rsr[det_names[0]]['wavelength']
+            wvl, idx = np.unique(wvl, return_index=True)
+            wvl_is_constant = True
+            for det in det_names[1:]:
+                det_wvl = np.unique(metimage.rsr[det]['wavelength'])
+                if not np.alltrue(wvl == det_wvl):
+                    LOG.warning(
+                        "Wavelngth arrays are not the same among detectors!")
+                    wvl_is_constant = False
+
+            if wvl_is_constant:
+                arr = wvl
+                dset = grp.create_dataset('wavelength', arr.shape, dtype='f')
+                dset.attrs['unit'] = 'm'
+                dset.attrs['scale'] = 1e-06
+                dset[...] = arr
+
+            # Loop over each detector:
+            for det in metimage.rsr:
+                det_grp = grp.create_group(det)
+                wvl = metimage.rsr[det]['wavelength'][
+                    ~np.isnan(metimage.rsr[det]['wavelength'])]
+                rsp = metimage.rsr[det]['response'][
+                    ~np.isnan(metimage.rsr[det]['wavelength'])]
+                wvl, idx = np.unique(wvl, return_index=True)
+                rsp = np.take(rsp, idx)
+                LOG.debug("wvl.shape: %s", str(wvl.shape))
+                det_grp.attrs[
+                    'central_wavelength'] = get_central_wave(wvl, rsp)
+                if not wvl_is_constant:
+                    arr = wvl
+                    dset = det_grp.create_dataset(
+                        'wavelength', arr.shape, dtype='f')
+                    dset.attrs['unit'] = 'm'
+                    dset.attrs['scale'] = 1e-06
+                    dset[...] = arr
+
+                dset = det_grp.create_dataset('response', rsp.shape, dtype='f')
+                dset[...] = rsp
 
 
 def main():
     """Main"""
     for platform_name in ["Metop-SG-A1", ]:
-        tohdf5(MetImageRSR, platform_name, METIMAGE_BAND_NAMES)
+        generate_metimage_file(platform_name)
 
 
 if __name__ == "__main__":


=====================================
rsr_convert_scripts/olci_rsr.py
=====================================
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2016, 2017, 2018 Adam.Dybbroe
+# Copyright (c) 2016 - 2019 Adam.Dybbroe
 
 # Author(s):
 
@@ -23,7 +23,10 @@
 """
 Reading the Sentinel-3 OLCI relative spectral responses
 
-https://sentinel.esa.int/documents/247904/322304/OLCI+SRF+%28NetCDF%29/15cfd7a6-b7bc-4051-87f8-c35d765ae43a
+https://sentinel.esa.int/documents/247904/322304/OLCI+SRF+%28NetCDF%29/
+
+https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-olci/olci-instrument/spectral-response-function-data
+
 """
 
 from netCDF4 import Dataset
@@ -34,7 +37,8 @@ import logging
 
 LOG = logging.getLogger(__name__)
 
-RSRFILE = '/home/a000680/data/SpectralResponses/olci/OLCISRFNetCDF.nc4'
+RSRFILE = {'Sentinel-3A': '/home/a000680/data/SpectralResponses/olci/S3A_OL_SRF_20160713_mean_rsr.nc4',
+           'Sentinel-3B': '/home/a000680/data/SpectralResponses/olciB/S3B_OL_SRF_0_20180109_mean_rsr.nc4'}
 
 
 OLCI_BAND_NAMES = ['Oa01', 'Oa02', 'Oa03', 'Oa04',
@@ -73,18 +77,24 @@ class OlciRSR(InstrumentRSR):
         ncf = Dataset(self.path, 'r')
 
         bandnum = OLCI_BAND_NAMES.index(self.bandname)
-        cam = 0
-        view = 0
+        # cam = 0
+        # view = 0
+        # resp = ncf.variables[
+        #     'spectral_response_function'][bandnum, cam, view, :]
+        # wvl = ncf.variables[
+        #     'spectral_response_function_wavelength'][bandnum, cam, view, :] * scale
         resp = ncf.variables[
-            'spectral_response_function'][bandnum, cam, view, :]
+            'mean_spectral_response_function'][bandnum, :]
         wvl = ncf.variables[
-            'spectral_response_function_wavelength'][bandnum, cam, view, :] * scale
+            'mean_spectral_response_function_wavelength'][bandnum, :] * scale
+
         self.rsr = {'wavelength': wvl, 'response': resp}
 
 
 def main():
     """Main"""
-    for platform_name in ['Sentinel-3A', ]:
+    # for platform_name in ['Sentinel-3A', 'Sentinel-3B']:
+    for platform_name in ['Sentinel-3B', ]:
         tohdf5(OlciRSR, platform_name, OLCI_BAND_NAMES)
 
 
@@ -119,5 +129,6 @@ def testplot():
     fig.savefig('olci_band1.png')
     # pylab.show()
 
+
 if __name__ == "__main__":
     main()



View it on GitLab: https://salsa.debian.org/debian-gis-team/pyspectral/compare/e74ea87d4d89efc6c877b6a78140b1d193e182bf...e7d0ab7a44541869249917e4b47be4062827d79f

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyspectral/compare/e74ea87d4d89efc6c877b6a78140b1d193e182bf...e7d0ab7a44541869249917e4b47be4062827d79f
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/20190708/498f2512/attachment-0001.html>


More information about the Pkg-grass-devel mailing list