Skip to content

Commit

Permalink
Merge pull request #223 from yukaribbba/add_fy3abc_mersi1_rsr
Browse files Browse the repository at this point in the history
Add RSR convert script for MERSI-1 on FY-3A/B/C
  • Loading branch information
adybbroe committed May 3, 2024
2 parents 33a25ac + d3b18d6 commit 4de1bed
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 2 deletions.
68 changes: 68 additions & 0 deletions pyspectral/etc/pyspectral.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,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
Expand Down
5 changes: 3 additions & 2 deletions pyspectral/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@
'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'}


Expand Down
119 changes: 119 additions & 0 deletions rsr_convert_scripts/mersi1_rsr.py
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 4de1bed

Please sign in to comment.