Source code for satpy.readers.msu_gsa_l1b

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2022 Satpy developers
# This file is part of satpy.
# satpy 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.
# satpy 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
# satpy.  If not, see <>.

"""Reader for the Arctica-M1 MSU-GS/A data.

The files for this reader are HDF5 and contain channel data at 1km resolution
for the VIS channels and 4km resolution for the IR channels. Geolocation data
is available at both resolutions, as is sun and satellite geometry.

This reader was tested on sample data provided by EUMETSAT.


import datetime as dt

import numpy as np

from satpy.readers.hdf5_utils import HDF5FileHandler

[docs] class MSUGSAFileHandler(HDF5FileHandler): """MSU-GS/A L1B file reader.""" @property def start_time(self): """Time for timeslot scan start.""" dtstr = self["/attr/timestamp_without_timezone"] return dt.datetime.strptime(dtstr, "%Y-%m-%dT%H:%M:%S") @property def satellite_altitude(self): """Satellite altitude at time of scan. There is no documentation but this appears to be height above surface in meters. """ return float(self["/attr/satellite_observation_point_height"]) @property def satellite_latitude(self): """Satellite latitude at time of scan.""" return float(self["/attr/satellite_observation_point_latitude"]) @property def satellite_longitude(self): """Satellite longitude at time of scan.""" return float(self["/attr/satellite_observation_point_longitude"]) @property def sensor_name(self): """Sensor name is hardcoded.""" sensor = "msu_gsa" return sensor @property def platform_name(self): """Platform name is also hardcoded.""" platform = "Arctica-M-N1" return platform
[docs] @staticmethod def _apply_scale_offset(in_data): """Apply the scale and offset to data.""" scl = in_data.attrs["scale"] off = in_data.attrs["offset"] return in_data * scl + off
[docs] def get_dataset(self, dataset_id, ds_info): """Load data variable and metadata and calibrate if needed.""" file_key = ds_info.get("file_key", dataset_id["name"]) data = self[file_key] attrs = data.attrs.copy() # avoid contaminating other band loading attrs.update(ds_info) # The fill value also needs to be applied fill_val = attrs.pop("fill_value") data = data.where(data != fill_val, np.nan) # Data has a scale and offset that we must apply data = self._apply_scale_offset(data) # Data is given as radiance values, we must convert if we want reflectance if dataset_id.get("calibration") == "reflectance": solconst = float(attrs.pop("F_solar_constant")) data = np.pi * data / solconst # Satpy expects reflectance values in 0-100 range data = data * 100. data.attrs = attrs data.attrs.update({ "platform_name": self.platform_name, "sensor": self.sensor_name, "sat_altitude": self.satellite_altitude, "sat_latitude": self.satellite_latitude, "sat_longitude": self.satellite_longitude, }) return data