[Git][debian-gis-team/pyspectral][upstream] New upstream version 0.13.1+ds

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Wed May 8 07:09:29 BST 2024



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


Commits:
ca16c3c6 by Antonio Valentino at 2024-05-08T05:41:47+00:00
New upstream version 0.13.1+ds
- - - - -


15 changed files:

- .pre-commit-config.yaml
- AUTHORS.md
- CHANGELOG.md
- CHANGELOG_RSR_DATA.rst
- continuous_integration/environment.yaml
- doc/installation.rst
- pyspectral/config.py
- pyspectral/etc/pyspectral.yaml
- pyspectral/utils.py
- + rsr_convert_scripts/ghi_rsr.py
- + rsr_convert_scripts/goci2_rsr.py
- + rsr_convert_scripts/mersi1_rsr.py
- + rsr_convert_scripts/mersirm_rsr.py
- setup.cfg
- setup.py


Changes:

=====================================
.pre-commit-config.yaml
=====================================
@@ -7,10 +7,11 @@ repos:
     - id: flake8
       additional_dependencies: [flake8-docstrings, flake8-debugger, flake8-bugbear]
 -   repo: https://github.com/pycqa/isort
-    rev: 5.12.0
+    rev: 5.13.2
     hooks:
       - id: isort
         language_version: python3
 ci:
   # To trigger manually, comment on a pull request with "pre-commit.ci autofix"
   autofix_prs: false
+  autoupdate_schedule: "monthly"


=====================================
AUTHORS.md
=====================================
@@ -18,3 +18,5 @@ The following people have made contributions to this project:
 - [Ronald Scheirer](https://github.com/)
 - [Xin Zhang (zxdawn)](https://github.com/zxdawn)
 - [Rolf Helge Pfeiffer](https://github.com/HelgeCPH)
+- [Antonio Valentino](https://github.com/avalentino)
+- [Lu Liu (yukaribbba)](https://github.com/yukaribbba)


=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,25 @@
+## Version <v0.13.1> (2024/05/07)
+
+### Issues Closed
+
+* [Issue 219](https://github.com/pytroll/pyspectral/issues/219) - [Question] Using red-band for the representation
+* [Issue 193](https://github.com/pytroll/pyspectral/issues/193) - Question: Is there any details about LUT?
+
+In this release 2 issues were closed.
+
+### Pull Requests Merged
+
+#### Features added
+
+* [PR 225](https://github.com/pytroll/pyspectral/pull/225) - Add fengyun and geo-kompsat-2b sensor support
+* [PR 224](https://github.com/pytroll/pyspectral/pull/224) - Add support and RSR converter for the GOCI2 instrument aboard GK-2B
+* [PR 223](https://github.com/pytroll/pyspectral/pull/223) - Add RSR convert script for MERSI-1 on FY-3A/B/C
+* [PR 222](https://github.com/pytroll/pyspectral/pull/222) - Add a RSR convert script for FY-3G MERSI-RM sensor
+* [PR 192](https://github.com/pytroll/pyspectral/pull/192) - Add a RSR convert script for FY-4B GHI sensor
+
+In this release 5 pull requests were closed.
+
+
 ## Version <v0.13.0> (2023/11/27)
 
 ### Issues Closed


=====================================
CHANGELOG_RSR_DATA.rst
=====================================
@@ -2,6 +2,14 @@ Changelog for the Relative Spectral Response data
 =================================================
 
 
+Version <v1.3.0> (Fri May  3 04:11:43 PM CEST 2024)
+-------------------------------------------
+
+ * Added SRFs (RSRs) for the Mersi-1 sensor onboard FY-3A/B/C
+ * Added SRFs for the Mersi-RM sensor onboard FY-3G
+ * Added SRFs for the GHI (Geostationary High-speed Imager) sensor onboard FY-4B
+ * Added SRFs for GOCI-II (Geostationary Ocean Color Imager: Follow-on) sensor onboard GK-2B (GEO-KOMPSAT-2B)
+
 
 Version <v1.2.4> (Sat Oct 21 12:25:00 PM CEST 2023)
 -------------------------------------------


=====================================
continuous_integration/environment.yaml
=====================================
@@ -21,7 +21,7 @@ dependencies:
   - pytest
   - pytest-cov
   - responses
-  - appdirs
+  - platformdirs
   - python-geotiepoints
   - pip
   - pip:


=====================================
doc/installation.rst
=====================================
@@ -36,7 +36,7 @@ correction in the short wave spectral range.
 Both these datasets downloads automagically from `zenodo.org`_ when needed.
 
 On default these static data will reside in the platform specific standard
-destination for storing user data, via the use of the appdirs_ package. On
+destination for storing user data, via the use of the platformdirs_ package. On
 Linux this will be under *~/.local/share/pyspectral*. See further down.
 
 
@@ -174,5 +174,5 @@ And then adjust the *pyspectral.yaml* so data downloading will not be attempted
 .. _GCC: http://www.star.nesdis.noaa.gov/smcd/GCC/index.php
 .. _instrument response data: http://www.star.nesdis.noaa.gov/smcd/GCC/instrInfo-srf.php
 .. _github: http://github.com/pytroll/pyspectral
-.. _appdirs: https://github.com/ActiveState/appdirs
+.. _platformdirs: https://github.com/platformdirs/platformdirs
 .. _zenodo.org: https://zenodo.org


=====================================
pyspectral/config.py
=====================================
@@ -26,7 +26,7 @@ from os.path import expanduser
 from pathlib import Path
 
 import yaml
-from appdirs import AppDirs
+from platformdirs import AppDirs
 
 try:
     from yaml import UnsafeLoader


=====================================
pyspectral/etc/pyspectral.yaml
=====================================
@@ -16,9 +16,9 @@
 download_from_internet: True
 
 # Everything below this line should not need to be changed!
-# Changes may be done if you want to change the name of the radiance<->Tb LUT filrnames,
+# Changes may be done if you want to change the name of the radiance<->Tb LUT filenames,
 # or if you want to store those files in different directories dependning on the platform/sensor.
-# Also, if you want to read the original agency specific spectral responses you 
+# Also, if you want to read the original agency specific spectral responses you
 # can specify their file names and directory paths here.
 # Adam Dybbroe, 2018-03-20
 
@@ -50,9 +50,11 @@ download_from_internet: True
 #   path: /home/a000680/data/SpectralResponses/modis/aqua
 #   tb2rad_lut_filename: /path/to/radiance/tb/lut/data/tb2rad_lut_aqua_modis_ir3.7.npz
 
-#DSCOVR-epic:
-#  path: C:/Users/Simon/Downloads/EPIC_Filters_Original_Data.xlsx
+# DSCOVR-epic:
+#  path: /path/to/srf/EPIC_Filters_Original_Data.xlsx
 
+# GK-2B-goci2:
+#  path: /path/to/original/gk2b/goci2/data/GOCI-II_SRF_Measured.csv
 
 # NOAA-20-viirs:
 #   # J1_VIIRS_RSR_M1_Detector_Fused_V2.txt
@@ -61,7 +63,7 @@ download_from_internet: True
 
 #   rootdir: /path/to/original/jpss1/viirs/data
 #   tb2rad_lut_filename: /path/to/radiance/tb/lut/data/tb2rad_lut_noaa20_viirs_ir3.7.npz
-  
+
 #   section1:
 #     filename: J1_VIIRS_Detector_RSR_V2/J1_VIIRS_RSR_{bandname}_Detector_Fused_V2.txt
 #     bands: [M1, M2, M3, M4, M5, M6, M7]
@@ -73,11 +75,11 @@ download_from_internet: True
 #   section3:
 #     filename: J1_VIIRS_V1_RSR_used_in_V2/J1_VIIRS_RSR_M8_Det_V1.txt
 #     bands: [M8]
-    
+
 #   section4:
 #     filename: J1_VIIRS_Detector_RSR_V2.1/J1_VIIRS_RSR_M9_Det_V2.1.txt
 #     bands: [M9]
-  
+
 #   section5:
 #     filename: J1_VIIRS_V1_RSR_used_in_V2/J1_VIIRS_RSR_{bandname}_Det_V1.txt
 #     bands: [M10, M11, M12, M14, M15]
@@ -105,7 +107,7 @@ download_from_internet: True
 #   tb2rad_lut_filename:
 #     m12: /path/to/radiance/tb/lut/data/tb2rad_lut_snpp_viirs_m12.npz
 #     i4: /path/to/radiance/tb/lut/data/tb2rad_lut_snpp_viirs_i4.npz
-  
+
 #   section1:
 #     filename: GT_F1_SC_RSR_Release1.0_Best_Mbands/GT_F1_SC_RSR_Release1.0_Best_{bandname}_V2.71_ib_oob.txt
 #     bands: [M1, M2, M3, M4, M5, M6, M7]
@@ -249,6 +251,16 @@ download_from_internet: True
 #     ch14: FY4B_AGRI_SRF_CH14_Pub.txt
 #     ch15: FY4B_AGRI_SRF_CH15_Pub.txt
 
+# FY-4B-ghi:
+    # path: D:/satpy_config/FY4B_GHI_SRF
+    # ch1: FY4B_GHI_SRF_CH01_Pub.txt
+    # ch2: FY4B_GHI_SRF_CH02_Pub.txt
+    # ch3: FY4B_GHI_SRF_CH03_Pub.txt
+    # ch4: FY4B_GHI_SRF_CH04_Pub.txt
+    # ch5: FY4B_GHI_SRF_CH05_Pub.txt
+    # ch6: FY4B_GHI_SRF_CH06_Pub.txt
+    # ch7: FY4B_GHI_SRF_CH07_Pub.txt
+
 #Electro-L-N2-msu-gs:
 #     path: /path/to/rsrs/rtcoef_electro-l_2_msugs_srf/
 #     ch1: rtcoef_electro-l_2_msugs_srf_ch01.txt
@@ -262,6 +274,74 @@ download_from_internet: True
 #     ch9: rtcoef_electro-l_2_msugs_srf_ch09.txt
 #     ch10: rtcoef_electro-l_2_msugs_srf_ch10.txt
 
+# FY-3A-mersi-1:
+   # path: D:/MERSI1
+   # ch1: FY3A_mersi_srf_func_b01.txt
+   # ch2: FY3A_mersi_srf_func_b02.txt
+   # ch3: FY3A_mersi_srf_func_b03.txt
+   # ch4: FY3A_mersi_srf_func_b04.txt
+   # ch5: FY3A_mersi_srf_func_b05.txt
+   # ch6: FY3A_mersi_srf_func_b06.txt
+   # ch7: FY3A_mersi_srf_func_b07.txt
+   # ch8: FY3A_mersi_srf_func_b08.txt
+   # ch9: FY3A_mersi_srf_func_b09.txt
+   # ch10: FY3A_mersi_srf_func_b10.txt
+   # ch11: FY3A_mersi_srf_func_b11.txt
+   # ch12: FY3A_mersi_srf_func_b12.txt
+   # ch13: FY3A_mersi_srf_func_b13.txt
+   # ch14: FY3A_mersi_srf_func_b14.txt
+   # ch15: FY3A_mersi_srf_func_b15.txt
+   # ch16: FY3A_mersi_srf_func_b16.txt
+   # ch17: FY3A_mersi_srf_func_b17.txt
+   # ch18: FY3A_mersi_srf_func_b18.txt
+   # ch19: FY3A_mersi_srf_func_b19.txt
+   # ch20: FY3A_mersi_srf_func_b20.txt
+
+# FY-3B-mersi-1:
+   # path: D:/MERSI1
+   # ch1: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch2: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch3: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch4: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch6: FY3B_mersi_srf_B6-7.txt
+   # ch7: FY3B_mersi_srf_B6-7.txt
+   # ch8: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch9: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch10: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch11: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch12: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch13: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch14: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch15: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch16: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch17: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch18: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch19: FY3B_mersi_srf_B1-4_B8-20.txt
+   # ch20: FY3B_mersi_srf_B1-4_B8-20.txt
+
+# FY-3C-mersi-1:
+   # path: D:/MERSI1
+   # ch1:  FY3C_mersi_srf_b01.txt
+   # ch2: FY3C_mersi_srf_b02.txt
+   # ch3: FY3C_mersi_srf_b03.txt
+   # ch4: FY3C_mersi_srf_b04.txt
+   # ch5: FY3C_mersi_srf_b05.txt
+   # ch6: FY3C_mersi_srf_b06.txt
+   # ch7: FY3C_mersi_srf_b07.txt
+   # ch8: FY3C_mersi_srf_b08.txt
+   # ch9: FY3C_mersi_srf_b09.txt
+   # ch10: FY3C_mersi_srf_b10.txt
+   # ch11: FY3C_mersi_srf_b11.txt
+   # ch12: FY3C_mersi_srf_b12.txt
+   # ch13: FY3C_mersi_srf_b13.txt
+   # ch14: FY3C_mersi_srf_b14.txt
+   # ch15: FY3C_mersi_srf_b15.txt
+   # ch16: FY3C_mersi_srf_b16.txt
+   # ch17: FY3C_mersi_srf_b17.txt
+   # ch18: FY3C_mersi_srf_b18.txt
+   # ch19: FY3C_mersi_srf_b19.txt
+   # ch20: FY3C_mersi_srf_b20.txt
+
 #FY-3B-virr:
 #  path: /Users/davidh/repos/git/pyspectral/virr_srf/FY3B-VIRR
 #  ch1: ch1.prn
@@ -313,6 +393,16 @@ download_from_internet: True
 #   ch24: FY3D_MERSI_SRF_CH24_Pub.txt
 #   ch25: FY3D_MERSI_SRF_CH25_Pub.txt
 
+# FY-3G-mersi-rm:
+  # path: D:/FY-3G_MERSI-RM_SRF
+  # ch1: SRF_FY3G_SRF_CH01.txt
+  # ch2: SRF_FY3G_SRF_CH02.txt
+  # ch3: SRF_FY3G_SRF_CH03.txt
+  # ch4: SRF_FY3G_SRF_CH04.txt
+  # ch5: SRF_FY3G_SRF_CH05.txt
+  # ch6: SRF_FY3G_SRF_CH06.txt
+  # ch7: SRF_FY3G_SRF_CH07.txt
+  # ch8: SRF_FY3G_SRF_CH08.txt
 
 # NOAA-19-avhrr/3:
 #   path: /path/to/original/noaa19/avhrr/data


=====================================
pyspectral/utils.py
=====================================
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2014-2023 Pytroll developers
+# Copyright (c) 2014-2024 Pytroll developers
 #
 #
 # This program is free software: you can redistribute it and/or modify
@@ -54,6 +54,7 @@ INSTRUMENTS = {'Envisat': 'aatsr',
                'Himawari-8': 'ahi',
                'Himawari-9': 'ahi',
                'GEO-KOMPSAT-2A': 'ami',
+               'GEO-KOMPSAT-2B': 'goci-2',
                'NOAA-10': 'avhrr/1',
                'NOAA-6': 'avhrr/1',
                'NOAA-8': 'avhrr/1',
@@ -75,6 +76,7 @@ INSTRUMENTS = {'Envisat': 'aatsr',
                'Meteosat-12': 'fci',
                'MTG-I1': 'fci',
                'FY-3D': 'mersi-2',
+               'FY-3G': 'mersi-rm',
                'Metop-SG-A1': 'metimage',
                'EOS-Aqua': 'modis',
                'EOS-Terra': 'modis',
@@ -92,8 +94,9 @@ INSTRUMENTS = {'Envisat': 'aatsr',
                'NOAA-20': 'viirs',
                'NOAA-21': 'viirs',
                'Suomi-NPP': 'viirs',
-               'FY-3B': 'virr',
-               'FY-3C': 'virr',
+               'FY-3A': ['virr', 'mersi-1'],
+               'FY-3B': ['virr', 'mersi-1'],
+               'FY-3C': ['virr', 'mersi-1'],
                'DSCOVR': 'epic'}
 
 
@@ -101,10 +104,10 @@ INSTRUMENT_TRANSLATION_DASH2SLASH = {'avhrr-1': 'avhrr/1',
                                      'avhrr-2': 'avhrr/2',
                                      'avhrr-3': 'avhrr/3'}
 
-HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/10029746/files/pyspectral_rsr_data.tgz"
+HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/11110033/files/pyspectral_rsr_data.tgz"
 
 RSR_DATA_VERSION_FILENAME = "PYSPECTRAL_RSR_VERSION"
-RSR_DATA_VERSION = "v1.2.4"
+RSR_DATA_VERSION = "v1.3.0"
 
 ATM_CORRECTION_LUT_VERSION = {}
 ATM_CORRECTION_LUT_VERSION['antarctic_aerosol'] = {'version': 'v1.0.1',


=====================================
rsr_convert_scripts/ghi_rsr.py
=====================================
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2018-2023 Pytroll developers
+#
+#
+# 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 the FY-4B GHI relative spectral responses.
+
+Data from https://img.nsmc.org.cn/PORTAL/NSMC/DATASERVICE/SRF/FY4B/FY4B_GHI_SRF.zip
+"""
+import os
+
+import numpy as np
+
+from pyspectral.raw_reader import InstrumentRSR
+from pyspectral.utils import INSTRUMENTS
+from pyspectral.utils import convert2hdf5 as tohdf5
+from pyspectral.utils import get_logger, logging_on
+
+FY4_GHI_BAND_NAMES = ['ch1', 'ch2', 'ch3', 'ch4', 'ch5', 'ch6', 'ch7']
+BANDNAME_SCALE2MICROMETERS = {'FY-4B': {'ch1': 0.001,
+                                        'ch2': 0.001,
+                                        'ch3': 0.001,
+                                        'ch4': 0.001,
+                                        'ch5': 0.001,
+                                        'ch6': 0.001,
+                                        'ch7': 1.0,
+                                        }}
+
+
+class GHIRSR(InstrumentRSR):
+    """Container for the FY-4 GHI RSR data."""
+
+    def __init__(self, bandname, platform_name):
+        """Initialise the FY-4 GHI relative spectral response data."""
+        super(GHIRSR, self).__init__(bandname, platform_name, FY4_GHI_BAND_NAMES)
+
+        self.instrument = INSTRUMENTS.get(platform_name, 'ghi')
+        if type(self.instrument) is list:
+            self.instrument = 'ghi'
+
+        self._get_options_from_config()
+        self._get_bandfilenames()
+
+        LOG.debug("Filenames: %s", str(self.filenames))
+        if self.filenames[bandname] and os.path.exists(self.filenames[bandname]):
+            self.requested_band_filename = self.filenames[bandname]
+            scale = BANDNAME_SCALE2MICROMETERS[platform_name].get(bandname)
+            if scale:
+                self._load(scale=scale)
+            else:
+                LOG.error(
+                    "Failed determine the scale used to convert to wavelength in micrometers - channel = %s", bandname)
+                raise AttributeError('no scale for bandname %s', bandname)
+
+        else:
+            LOG.warning("Couldn't find an existing file for this band: %s",
+                        str(self.bandname))
+
+        self.filename = self.requested_band_filename
+
+    def _load(self, scale=0.001):
+        """Load the GHI RSR data for the band requested.
+
+        Wavelength is given in nanometers.
+        """
+        data = np.genfromtxt(self.requested_band_filename,
+                             unpack=True, delimiter='\t',
+                             names=['wavelength',
+                                    'response'],
+                             skip_header=1)
+
+        wavelength = data[0] * scale
+        response = data[1]
+
+        # Response can be either 0-1 or 0-100 depending on RSR source - this scales to 0-1 range.
+        if np.nanmax(response > 1):
+            response = response / 100.
+
+        # Cut unneeded points
+        pts = np.argwhere(response > 0.001)
+
+        wavelength = np.squeeze(wavelength[pts])
+        response = np.squeeze(response[pts])
+
+        self.rsr = {'wavelength': wavelength, 'response': response}
+
+
+def convert_ghi():
+    """Read original GHI RSR data and convert to common Pyspectral hdf5 format."""
+    # For FY-4B
+    tohdf5(GHIRSR, 'FY-4B', FY4_GHI_BAND_NAMES)
+
+
+if __name__ == "__main__":
+    LOG = get_logger(__name__)
+    logging_on()
+
+    convert_ghi()


=====================================
rsr_convert_scripts/goci2_rsr.py
=====================================
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2024 Pytroll developers
+#
+#
+# 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 the GeoKompsat-2B / GOCI-II spectral response functions.
+
+Data from the Korea Ocean Satellite Centre website:
+https://kosc.kiost.ac.kr/index.nm?menuCd=44&lang=en
+
+The direct link to the SRFs is: https://kosc.kiost.ac.kr/upload/GOCI-II_SRF_Measured.csv
+
+"""
+
+import logging
+import os
+
+import numpy as np
+import pandas as pd
+
+from pyspectral.raw_reader import InstrumentRSR
+from pyspectral.utils import convert2hdf5 as tohdf5
+
+LOG = logging.getLogger(__name__)
+
+GOCI2_BAND_NAMES = {"L380": "B1 (380 nm)",
+                    "L412": "B2 (412 nm)",
+                    "L443": "B3 (443 nm)",
+                    "L490": "B4 (490 nm)",
+                    "L510": "B5 (510 nm)",
+                    "L555": "B6 (555 nm)",
+                    "L620": "B7 (620 nm)",
+                    "L660": "B8 (660 nm)",
+                    "L680": "B9 (680 nm)",
+                    "L709": "B10 (709 nm)",
+                    "L745": "B11 (745 nm)",
+                    "L865": "B12 (865 nm)"}
+
+#: Default time format
+_DEFAULT_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
+
+#: Default log format
+_DEFAULT_LOG_FORMAT = '[%(levelname)s: %(asctime)s : %(name)s] %(message)s'
+
+
+class GOCI2RSR(InstrumentRSR):
+    """Container for the GK-2B GOCI2 relative spectral response data."""
+
+    def __init__(self, bandname, platform_name):
+        """Initialize the GOCI2 RSR class."""
+        super(GOCI2RSR, self).__init__(
+            bandname, platform_name, GOCI2_BAND_NAMES.keys())
+
+        self.instrument = 'goci2'
+        self._get_options_from_config()
+
+        LOG.debug("Filename: %s", str(self.path))
+        if os.path.exists(self.path):
+            self._load()
+        else:
+            LOG.warning("Couldn't find an existing file for this band: %s",
+                        str(self.bandname))
+
+        # To be compatible with VIIRS....
+        self.filename = self.requested_band_filename
+
+        self.unit = 'micrometer'
+        self.wavespace = 'wavelength'
+
+    def _load(self, scale=10000.0):
+        """Load the GOCI2 relative spectral responses."""
+        df1 = pd.read_csv(self.path)
+
+        # Column names don't match band names - so we use a dict to find correct
+        # columns. We also need to find the column with the wavelength data.
+        # This is the column before the actual RSR data for each band.
+        col_pos = df1.columns.get_loc(GOCI2_BAND_NAMES[self.bandname])
+        wvl_data = df1.iloc[:, col_pos - 1]
+        srf_data = df1.iloc[:, col_pos]
+
+        # Not all bands have an identical number of RSR points, so we need to
+        # remove NaNs from the data.
+        wvl_data.dropna(inplace=True)
+        srf_data.dropna(inplace=True)
+
+        # Data is in nanometers, so we need to convert to micrometers.
+        # The SRFs should already be normalised to 1, but we normalise here just to be sure.
+        self.rsr = {'wavelength': np.array(wvl_data) / 1000,
+                    'response': np.array(srf_data) / np.nanmax(srf_data)}
+
+
+if __name__ == "__main__":
+    import sys
+    LOG = logging.getLogger('goci2_rsr')
+    handler = logging.StreamHandler(sys.stderr)
+
+    formatter = logging.Formatter(fmt=_DEFAULT_LOG_FORMAT,
+                                  datefmt=_DEFAULT_TIME_FORMAT)
+    handler.setFormatter(formatter)
+    handler.setLevel(logging.DEBUG)
+    LOG.setLevel(logging.DEBUG)
+    LOG.addHandler(handler)
+
+    for platform_name in ['GK-2B', ]:
+        tohdf5(GOCI2RSR, platform_name, list(GOCI2_BAND_NAMES.keys()))


=====================================
rsr_convert_scripts/mersi1_rsr.py
=====================================
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2018-2024 Pytroll developers
+#
+#
+# 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 the MERSI-1 relative spectral responses.
+
+Data available from NSMC:
+https://img.nsmc.org.cn/PORTAL/NSMC/DATASERVICE/SRF/FY3A/FY3A_MERSI_SRF.rar
+https://img.nsmc.org.cn/PORTAL/NSMC/DATASERVICE/SRF/FY3B/FY3B_MERSI_SRF.rar
+https://img.nsmc.org.cn/PORTAL/NSMC/DATASERVICE/SRF/FY3C/FY3C_MERSI_SRF.rar
+
+"""
+import logging
+import os
+
+import numpy as np
+
+from pyspectral.raw_reader import InstrumentRSR
+from pyspectral.utils import INSTRUMENTS
+from pyspectral.utils import convert2hdf5 as tohdf5
+
+LOG = logging.getLogger(__name__)
+
+MERSI1_FY3AC_BAND_NAMES = ['ch1', 'ch2', 'ch3', 'ch4', 'ch5', 'ch6', 'ch7', 'ch8',
+                           'ch9', 'ch10', 'ch11', 'ch12', 'ch13', 'ch14', 'ch15', 'ch16',
+                           'ch17', 'ch18', 'ch19', 'ch20']
+MERSI1_FY3B_BAND_NAMES = ['ch1', 'ch2', 'ch3', 'ch4', 'ch6', 'ch7', 'ch8',
+                          'ch9', 'ch10', 'ch11', 'ch12', 'ch13', 'ch14', 'ch15', 'ch16',
+                          'ch17', 'ch18', 'ch19', 'ch20']
+
+
+class Mersi1FY3ABRSR(InstrumentRSR):
+    """Container for the FY3A/B/C MERSI-1 RSR data."""
+
+    def __init__(self, bandname, platform_name):
+        """Initialize the MERSI-1 RSR class."""
+        # FY-3B RSR doesn't have ch5(IR) band
+        mersi1_band_names = MERSI1_FY3AC_BAND_NAMES if platform_name != "FY-3B" else MERSI1_FY3B_BAND_NAMES
+        super(Mersi1FY3ABRSR, self).__init__(bandname, platform_name, mersi1_band_names)
+
+        self.instrument = INSTRUMENTS.get(platform_name, 'mersi-1')
+        if type(self.instrument) is list:
+            self.instrument = 'mersi-1'
+
+        self._get_options_from_config()
+        self._get_bandfilenames()
+
+        LOG.debug("Filenames: %s", str(self.filenames))
+        if self.filenames[bandname] and os.path.exists(self.filenames[bandname]):
+            self.requested_band_filename = self.filenames[bandname]
+            self._load()
+
+        else:
+            LOG.warning("Couldn't find an existing file for this band: %s",
+                        str(self.bandname))
+
+        self.filename = self.requested_band_filename
+
+    def _load(self, scale=0.001):
+        """Load the MERSI-1 RSR data for the band requested.
+
+        Wavelength is given in nanometers.
+        """
+        data = np.genfromtxt(self.requested_band_filename,
+                             unpack=True,
+                             skip_header=0)
+        wavelength = data[0] * scale
+
+        if self.platform_name != "FY-3B":
+            response = data[1]
+        else:
+            # FY-3B RSRs are organized in two files
+            fy3b_file1_bands_part1 = ["ch1", "ch2", "ch3", "ch4"]
+            fy3b_file1_bands_part2 = ["ch8", "ch9", "ch10", "ch11", "ch12", "ch13", "ch14", "ch15", "ch16", "ch17",
+                                      "ch18", "ch19", "ch20"]
+            fy3b_file2_bands = ["ch6", "ch7"]
+            if self.bandname in fy3b_file1_bands_part1:
+                response = data[fy3b_file1_bands_part1.index(self.bandname) + 1]
+            elif self.bandname in fy3b_file1_bands_part2:
+                response = data[fy3b_file1_bands_part2.index(self.bandname) + 4]
+            else:
+                response = data[fy3b_file2_bands.index(self.bandname) + 1]
+
+        # Cut unneeded points
+        pts = np.argwhere(response > 0.001)
+        wavelength = np.squeeze(wavelength[pts])
+        response = np.squeeze(response[pts])
+
+        # It is possible that some points of bands 1/2/3 where wavelength > 800 still has response > 0.001
+        # They're out of the wavelength range of the band.
+        # And will trigger a warning in pyspectral when doing atmospheric corrections
+        # So let's cut these points
+        if self.bandname in ["1", "2", "3"]:
+            pts2 = np.argwhere(data['wavelength'] < 800)
+            wavelength = np.squeeze(wavelength[pts2])
+            response = np.squeeze(response[pts2])
+
+        self.rsr = {'wavelength': wavelength, 'response': response}
+
+
+if __name__ == "__main__":
+    for platform_name in ["FY-3A", "FY-3B", "FY-3C"]:
+        band_list = MERSI1_FY3AC_BAND_NAMES if platform_name != "FY-3B" else MERSI1_FY3B_BAND_NAMES
+        tohdf5(Mersi1FY3ABRSR, platform_name, band_list)


=====================================
rsr_convert_scripts/mersirm_rsr.py
=====================================
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2018-2023 Pytroll developers
+#
+#
+# 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 the FY-3G MERSI-RM relative spectral responses.
+
+Data from https://img.nsmc.org.cn/PORTAL/NSMC/DATASERVICE/SRF/FY3G/FY-3G_MERSI-RM_SRF.zip
+"""
+import os
+
+import numpy as np
+
+from pyspectral.raw_reader import InstrumentRSR
+from pyspectral.utils import INSTRUMENTS
+from pyspectral.utils import convert2hdf5 as tohdf5
+from pyspectral.utils import get_logger, logging_on
+
+FY3_MERSIRM_BAND_NAMES = ['ch1', 'ch2', 'ch3', 'ch4', 'ch5', 'ch6', 'ch7', 'ch8']
+
+
+class MersiRMRSR(InstrumentRSR):
+    """Container for the FY-3 MERSI-RM RSR data."""
+
+    def __init__(self, bandname, platform_name):
+        """Initialise the FY-3 MERSI-RM relative spectral response data."""
+        super(MersiRMRSR, self).__init__(bandname, platform_name, FY3_MERSIRM_BAND_NAMES)
+
+        self.instrument = INSTRUMENTS.get(platform_name, 'mersi-rm')
+
+        self._get_options_from_config()
+        self._get_bandfilenames()
+
+        LOG.debug("Filenames: %s", str(self.filenames))
+        if self.filenames[bandname] and os.path.exists(self.filenames[bandname]):
+            self.requested_band_filename = self.filenames[bandname]
+            self._load()
+
+        else:
+            LOG.warning("Couldn't find an existing file for this band: %s",
+                        str(self.bandname))
+
+        self.filename = self.requested_band_filename
+
+    def _load(self, scale=0.001):
+        """Load the MERSI-RM RSR data for the band requested.
+
+        Wavelength is given in nanometers.
+        """
+        data = np.genfromtxt(self.requested_band_filename,
+                             unpack=True,
+                             names=['wavelength',
+                                    'response'],
+                             skip_header=1)
+
+        wavelength = data[0] * scale
+        response = data[1]
+
+        self.rsr = {'wavelength': wavelength, 'response': response}
+
+
+def convert_mersirm():
+    """Read original MERSI-RM RSR data and convert to common Pyspectral hdf5 format."""
+    # For FY-3G
+    tohdf5(MersiRMRSR, 'FY-3G', FY3_MERSIRM_BAND_NAMES)
+
+
+if __name__ == "__main__":
+    LOG = get_logger(__name__)
+    logging_on()
+
+    convert_mersirm()


=====================================
setup.cfg
=====================================
@@ -1,6 +1,6 @@
 [bdist_rpm]
 provides=pyspectral
-requires=numpy h5py python-geotiepoints dask PyYAML python-requests python-appdirs
+requires=numpy h5py python-geotiepoints dask PyYAML python-requests python-platformdirs
 release=1
 
 [bdist_wheel]


=====================================
setup.py
=====================================
@@ -33,7 +33,7 @@ except IOError:
     long_description = ''
 
 requires = ['docutils>=0.3', 'numpy', 'scipy', 'python-geotiepoints>=1.1.1',
-            'h5py>=2.5', 'requests', 'pyyaml', 'appdirs']
+            'h5py>=2.5', 'requests', 'pyyaml', 'platformdirs']
 
 dask_extra = ['dask[array]']
 test_requires = ['pyyaml', 'dask[array]', 'xlrd', 'pytest', 'xarray', 'responses']



View it on GitLab: https://salsa.debian.org/debian-gis-team/pyspectral/-/commit/ca16c3c67f62bf9d95edfb1c40482862e60eed58

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyspectral/-/commit/ca16c3c67f62bf9d95edfb1c40482862e60eed58
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/20240508/2da85a5a/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list