Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions satpy/etc/readers/fci_l2_bufr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,34 @@ datasets:
- latitude

# ---- ASR products ------------
vza:
name: vza
long_name: Satellite Viewing Zenith Angle
standard_name: viewing_zenith_angle
resolution: 32000
file_type: fci_l2_bufr_asr
key: '#1#satelliteZenithAngle'
cell_method: area:mean
units: K
fill_value: -1.0e+100
coordinates:
- longitude
- latitude

sza:
name: sza
long_name: Solar Zenith Angle
standard_name: solar_zenith_angle
resolution: 32000
file_type: fci_l2_bufr_asr
key: '#1#solarZenithAngle'
cell_method: area:mean
units: K
fill_value: -1.0e+100
coordinates:
- longitude
- latitude

bt_mean_all_ir38:
name: bt_mean_all_ir38
long_name: TOA Brightness Temperature segment mean at 3.8um (all pixels)
Expand Down Expand Up @@ -1253,3 +1281,55 @@ datasets:
coordinates:
- longitude
- latitude

pixel_percentage_cloudy:
name: pixel_percentage_cloudy
long_name: Cloud Fraction in Segment
standard_name: pixels_used_fraction
resolution: 32000
file_type: fci_l2_bufr_asr
key: '#1#cloudAmountInSegment'
fill_value: -1.0e+100
units: '%'
coordinates:
- longitude
- latitude

pixel_percentage_cloudy_low:
name: pixel_percentage_cloudy_low
long_name: Low Cloud Fraction in Segment
standard_name: pixels_used_fraction
resolution: 32000
file_type: fci_l2_bufr_asr
key: '#2#cloudAmountInSegment'
fill_value: -1.0e+100
units: '%'
coordinates:
- longitude
- latitude

pixel_percentage_cloudy_mid:
name: pixel_percentage_cloudy_mid
long_name: Middle Cloud Fraction in Segment
standard_name: pixels_used_fraction
resolution: 32000
file_type: fci_l2_bufr_asr
key: '#3#cloudAmountInSegment'
fill_value: -1.0e+100
units: '%'
coordinates:
- longitude
- latitude

pixel_percentage_cloudy_high:
name: pixel_percentage_cloudy_high
long_name: High Cloud Fraction in Segment
standard_name: pixels_used_fraction
resolution: 32000
file_type: fci_l2_bufr_asr
key: '#4#cloudAmountInSegment'
fill_value: -1.0e+100
units: '%'
coordinates:
- longitude
- latitude
69 changes: 69 additions & 0 deletions satpy/etc/readers/fci_l2_nc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,14 @@ datasets:
file_type: nc_fci_crm
nc_key: mean_solar_zenith

mean_vza:
name: mean_vza
long_name: Satellite Viewing Zenith Angle (temporal average)
standard_name: viewing_zenith_angle
resolution: 1000
file_type: nc_fci_crm
nc_key: mean_satellite_zenith

mean_rel_azi:
name: mean_rel_azi
long_name: Relative Solar Satellite Azimuth Angle (temporal average)
Expand Down Expand Up @@ -1377,6 +1385,28 @@ datasets:
import_enum_information: True

# ASR - All-Sky Radiances
vza:
name: vza
long_name: Satellite Viewing Zenith Angle
standard_name: viewing_zenith_angle
resolution: 32000
file_type: nc_fci_asr
nc_key: satellite_zenith_angle
coordinates:
- longitude
- latitude

sza:
name: sza
long_name: Solar Zenith Angle
standard_name: solar_zenith_angle
resolution: 32000
file_type: nc_fci_asr
nc_key: solar_zenith_angle
coordinates:
- longitude
- latitude

bt_max:
name: bt_max
long_name: TOA Brightess Temperature Segment max
Expand Down Expand Up @@ -3147,3 +3177,42 @@ datasets:
coordinates:
- longitude
- latitude

pixel_percentage_cloudy_low:
name: pixel_percentage_cloudy_low
long_name: Percentage of FoR pixels used (cloudy pixels)
standard_name: pixels_used_fraction
resolution: 32000
file_type: nc_fci_asr
nc_key: pixel_percentage
category_id: 3
units: '%'
coordinates:
- longitude
- latitude

pixel_percentage_cloudy_mid:
name: pixel_percentage_cloudy_mid
long_name: Percentage of FoR pixels used (cloudy pixels)
standard_name: pixels_used_fraction
resolution: 32000
file_type: nc_fci_asr
nc_key: pixel_percentage
category_id: 4
units: '%'
coordinates:
- longitude
- latitude

pixel_percentage_cloudy_high:
name: pixel_percentage_cloudy_high
long_name: Percentage of FoR pixels used (cloudy pixels)
standard_name: pixels_used_fraction
resolution: 32000
file_type: nc_fci_asr
nc_key: pixel_percentage
category_id: 5
units: '%'
coordinates:
- longitude
- latitude
4 changes: 2 additions & 2 deletions satpy/readers/eum_l2_bufr.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from satpy.readers.core.eum import get_service_mode, recarray2dict
from satpy.readers.core.file_handlers import BaseFileHandler
from satpy.readers.core.seviri import mpef_product_header
from satpy.utils import get_legacy_chunk_size
from satpy.utils import get_chunk_size_limit

try:
import eccodes as ec
Expand All @@ -47,7 +47,7 @@

logger = logging.getLogger("EumetsatL2Bufr")

CHUNK_SIZE = get_legacy_chunk_size()
CHUNK_SIZE = get_chunk_size_limit()

SSP_DEFAULT = 0.0
BUFR_FILL_VALUE = -1.e+100
Expand Down
4 changes: 2 additions & 2 deletions satpy/readers/eum_l2_grib.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
from satpy.readers.core.seviri import REPEAT_CYCLE_DURATION as SEVIRI_REPEAT_CYCLE_DURATION
from satpy.readers.core.seviri import REPEAT_CYCLE_DURATION_RSS as SEVIRI_REPEAT_CYCLE_DURATION_RSS
from satpy.readers.core.seviri import calculate_area_extent as seviri_calculate_area_extent
from satpy.utils import get_legacy_chunk_size
from satpy.utils import get_chunk_size_limit

CHUNK_SIZE = get_legacy_chunk_size()
CHUNK_SIZE = get_chunk_size_limit()

try:
import eccodes as ec
Expand Down
42 changes: 27 additions & 15 deletions satpy/readers/fci_l2_nc.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
from satpy.readers.core.eum import get_service_mode
from satpy.readers.core.fci import platform_name_translate
from satpy.readers.core.file_handlers import BaseFileHandler
from satpy.utils import get_legacy_chunk_size
from satpy.utils import get_chunk_size_limit

logger = logging.getLogger(__name__)

CHUNK_SIZE = get_legacy_chunk_size()
CHUNK_SIZE = get_chunk_size_limit()

SSP_DEFAULT = 0.0

Expand All @@ -55,15 +55,22 @@ def sensor_name(self):

@property
def ssp_lon(self):
"""Return longitude at subsatellite point."""
"""Return central longitude of GEOS projection grid.

This is needed to compute the area definition for the gridded products (pixel-based and segmented).
For the AMV product it is not needed and therefore no warning is issued if missing.
"""
try:
return float(self.nc["mtg_geos_projection"].attrs["longitude_of_projection_origin"])
except (KeyError, AttributeError):
logger.warning(f"ssp_lon could not be obtained from file content, using default value "
f"of {SSP_DEFAULT} degrees east instead")
if self.product_type != "amv":
logger.warning(
f"ssp_lon could not be obtained from file content, "
f"using default value of {SSP_DEFAULT} degrees east instead"
)
return SSP_DEFAULT

def _get_global_attributes(self, product_type="pixel"):
def _get_global_attributes(self):
"""Create a dictionary of global attributes to be added to all datasets.

Returns:
Expand All @@ -86,18 +93,19 @@ def _get_global_attributes(self, product_type="pixel"):
"platform_name": platform_name_translate.get(self.spacecraft_name, self.spacecraft_name)
}

if product_type=="amv":
if self.product_type == "amv":
attributes["channel"] = self.filename_info["channel"]
attributes["time_parameters"] = {}
attributes["time_parameters"]["wind_time"] = self.wind_time

return attributes

def _set_attributes(self, variable, dataset_info, product_type="pixel"):
def _set_attributes(self, variable, dataset_info):
"""Set dataset attributes."""
if product_type in ["pixel", "segmented"]:
if product_type == "pixel":
if self.product_type in ["pixel", "segmented"]:
if self.product_type == "pixel":
xdim, ydim = "number_of_columns", "number_of_rows"
elif product_type == "segmented":
elif self.product_type == "segmented":
xdim, ydim = "number_of_FoR_cols", "number_of_FoR_rows"

if dataset_info["nc_key"] not in ["product_quality",
Expand All @@ -112,7 +120,7 @@ def _set_attributes(self, variable, dataset_info, product_type="pixel"):
del variable.attrs["unit"]

variable.attrs.update(dataset_info)
variable.attrs.update(self._get_global_attributes(product_type=product_type))
variable.attrs.update(self._get_global_attributes())

import_enum_information = dataset_info.get("import_enum_information", False)
if import_enum_information:
Expand Down Expand Up @@ -180,8 +188,9 @@ class FciL2NCFileHandler(FciL2CommonFunctions, BaseFileHandler):
def __init__(self, filename, filename_info, filetype_info, with_area_definition=True):
"""Open the NetCDF file with xarray and prepare for dataset reading."""
super().__init__(filename, filename_info, filetype_info)
self.product_type = "pixel"

# Use xarray's default netcdf4 engine to open the fileq
# Use xarray's default netcdf4 engine to open the file
self.nc = xr.open_dataset(
self.filename,
decode_cf=True,
Expand Down Expand Up @@ -343,6 +352,8 @@ class FciL2NCSegmentFileHandler(FciL2CommonFunctions, BaseFileHandler):
def __init__(self, filename, filename_info, filetype_info, with_area_definition=False):
"""Open the NetCDF file with xarray and prepare for dataset reading."""
super().__init__(filename, filename_info, filetype_info)
self.product_type = "segmented"

# Use xarray's default netcdf4 engine to open the file
self.nc = xr.open_dataset(
self.filename,
Expand Down Expand Up @@ -396,7 +407,7 @@ def get_dataset(self, dataset_id, dataset_info):
if "fill_value" in dataset_info:
variable = self._mask_data(variable, dataset_info["fill_value"])

variable = self._set_attributes(variable, dataset_info, product_type="segmented")
variable = self._set_attributes(variable, dataset_info)

return variable

Expand Down Expand Up @@ -457,6 +468,7 @@ class FciL2NCAMVFileHandler(FciL2CommonFunctions, BaseFileHandler):
def __init__(self, filename, filename_info, filetype_info):
"""Open the NetCDF file with xarray and prepare for dataset reading."""
super().__init__(filename, filename_info, filetype_info)
self.product_type = "amv"

@cached_property
def nc(self):
Expand Down Expand Up @@ -499,6 +511,6 @@ def get_dataset(self, dataset_id, dataset_info):
return None

# Manage the attributes of the dataset
variable = self._set_attributes(variable, dataset_info, product_type="amv")
variable = self._set_attributes(variable, dataset_info)

return variable
8 changes: 4 additions & 4 deletions satpy/tests/reader_tests/test_eum_l2_grib.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ def common_checks(ec_, reader, mock_file, dataset_id):
def test_seviri_data_reading(da_, xr_, setup_reader):
"""Test the reading of data from the product."""
from satpy.readers.eum_l2_grib import EUML2GribFileHandler
from satpy.utils import get_legacy_chunk_size
from satpy.utils import get_chunk_size_limit
ec_ = setup_reader
chunk_size = get_legacy_chunk_size()
chunk_size = get_chunk_size_limit()

with mock.patch("builtins.open", mock.mock_open()) as mock_file:
with mock.patch("satpy.readers.eum_l2_grib.ec", ec_):
Expand Down Expand Up @@ -214,9 +214,9 @@ def test_seviri_data_reading(da_, xr_, setup_reader):
def test_fci_data_reading(da_, xr_, setup_reader):
"""Test the reading of fci data from the product."""
from satpy.readers.eum_l2_grib import EUML2GribFileHandler
from satpy.utils import get_legacy_chunk_size
from satpy.utils import get_chunk_size_limit
ec_ = setup_reader
chunk_size = get_legacy_chunk_size()
chunk_size = get_chunk_size_limit()

with mock.patch("builtins.open", mock.mock_open()) as mock_file:
with mock.patch("satpy.readers.eum_l2_grib.ec", ec_):
Expand Down
6 changes: 3 additions & 3 deletions satpy/tests/reader_tests/test_fci_l2_nc.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ def test_all_basic(self, amv_filehandler, amv_file):
assert amv_filehandler.sensor_name == "test_data_source"
assert amv_filehandler.ssp_lon == 0.0

global_attributes = amv_filehandler._get_global_attributes(product_type="amv")
global_attributes = amv_filehandler._get_global_attributes()
expected_global_attributes = {
"filename": amv_file,
"spacecraft_name": "TEST_PLATFORM",
Expand All @@ -637,8 +637,8 @@ def test_all_basic(self, amv_filehandler, amv_file):

# Drop wind_time dataset and check that wind_time attribute becomes None
amv_filehandler.nc = amv_filehandler.nc.drop_vars("wind_time")
expected_global_attributes["time_parameters"] = {"wind_time":None}
global_attributes = amv_filehandler._get_global_attributes(product_type="amv")
expected_global_attributes["time_parameters"] = {"wind_time": None}
global_attributes = amv_filehandler._get_global_attributes()
assert global_attributes == expected_global_attributes

def test_dataset(self, amv_filehandler):
Expand Down
Loading