Skip to content

Commit

Permalink
Merge pull request #1410 from adybbroe/fix-osisaf-reader
Browse files Browse the repository at this point in the history
Fix osisaf SST reader
  • Loading branch information
mraspaud authored Apr 14, 2022
2 parents dd77305 + e3d7dda commit 37e77dd
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 167 deletions.
4 changes: 2 additions & 2 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ the base Satpy installation.
- `slstr_l1b`
- In development
* - OSISAF SST data in GHRSST (netcdf) format
- `ghrsst_l3c_sst`
- `ghrsst_l2`
- In development
* - NUCAPS EDR Retrieval in NetCDF4 format
- `nucaps`
Expand Down Expand Up @@ -245,7 +245,7 @@ the base Satpy installation.
- `glm_l2`
- Beta
* - Sentinel-3 SLSTR SST data in NetCDF4 format
- `slstr_l2`
- `ghrsst_l2`
- Beta
* - IASI level 2 SO2 in BUFR format
- `iasi_l2_so2_bufr`
Expand Down
4 changes: 2 additions & 2 deletions satpy/composites/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2015-2020 Satpy developers
# Copyright (c) 2015-2022 Satpy developers
#
# This file is part of satpy.
#
Expand Down Expand Up @@ -495,7 +495,7 @@ def build_colormap(palette, dtype, info):
Colormaps come in different forms, but they are all supposed to have
color values between 0 and 255. The following cases are considered:
- Palettes comprised of only a list on colors. If *dtype* is uint8,
- Palettes comprised of only a list of colors. If *dtype* is uint8,
the values of the colormap are the enumeration of the colors.
Otherwise, the colormap values will be spread evenly from the min
to the max of the valid_range provided in `info`.
Expand Down
97 changes: 97 additions & 0 deletions satpy/etc/readers/ghrsst_l2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
reader:
description: NC Reader for GHRSST Level 2 data
name: ghrsst_l2
sensors: ['slstr', 'avhrr/3', 'viirs']
default_channels: []
reader: !!python/name:satpy.readers.yaml_reader.FileYAMLReader

file_types:
GHRSST_OSISAF:
file_reader: !!python/name:satpy.readers.ghrsst_l2.GHRSSTL2FileHandler
# S-OSI_-FRA_-NPP_-NARSST_FIELD-202010141300Z.nc
file_patterns: ['S-OSI_-{generating_centre:4s}-{satid:s}-{field_type:s}_FIELD-{valid_time:%Y%m%d%H%M}Z.nc']

SLSTR:
file_reader: !!python/name:satpy.readers.ghrsst_l2.GHRSSTL2FileHandler
file_patterns: ['{dt1:%Y%m%d%H%M%S}-{generating_centre:3s}-{type_id:3s}_GHRSST-SSTskin-SLSTR{something:1s}-{dt2:%Y%m%d%H%M%S}-{version}.nc',
'{mission_id:3s}_SL_{processing_level:1s}_WST____{start_time:%Y%m%dT%H%M%S}_{end_time:%Y%m%dT%H%M%S}_{creation_time:%Y%m%dT%H%M%S}_{duration:4d}_{cycle:3d}_{relative_orbit:3d}_{frame:4s}_{centre:3s}_{mode:1s}_{timeliness:2s}_{collection:3s}.SEN3.tar']

datasets:
# SLSTR SST and Sea Ice products
longitude_slstr:
name: longitude_slstr
resolution: 1000
view: nadir
file_type: SLSTR
standard_name: lon
units: degree

latitude_slstr:
name: latitude_slstr
resolution: 1000
view: nadir
file_type: SLSTR
standard_name: lat
units: degree

sea_surface_temperature_slstr:
name: sea_surface_temperature
sensor: slstr
coordinates: [longitude_slstr, latitude_slstr]
file_type: SLSTR
resolution: 1000
view: nadir
units: kelvin
standard_name: sea_surface_temperature

sea_ice_fraction_slstr:
name: sea_ice_fraction
sensor: slstr
coordinates: [longitude_slstr, latitude_slstr]
file_type: SLSTR
resolution: 1000
view: nadir
units: "%"
standard_name: sea_ice_fraction

# Quality estimation 0-5: no data, cloud, worst, low, acceptable, best
quality_level_slstr:
name: quality_level
sensor: slstr
coordinates: [longitude_slstr, latitude_slstr]
file_type: SLSTR
resolution: 1000
view: nadir
standard_name: quality_level


# OSISAF SST:
longitude_osisaf:
name: longitude_osisaf
resolution: 2000
file_type: GHRSST_OSISAF
standard_name: lon
units: degree

latitude_osisaf:
name: latitude_osisaf
resolution: 2000
file_type: GHRSST_OSISAF
standard_name: lat
units: degree

sea_surface_temperature_osisaf:
name: sea_surface_temperature
coordinates: [longitude_osisaf, latitude_osisaf]
file_type: GHRSST_OSISAF
resolution: 2000
units: kelvin
standard_name: sea_surface_temperature

sea_ice_fraction_osisaf:
name: sea_ice_fraction
coordinates: [longitude_osisaf, latitude_osisaf]
file_type: GHRSST_OSISAF
resolution: 2000
units: "%"
standard_name: sea_ice_fraction
17 changes: 0 additions & 17 deletions satpy/etc/readers/ghrsst_l3c_sst.yaml

This file was deleted.

97 changes: 97 additions & 0 deletions satpy/readers/ghrsst_l2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 - 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 <http://www.gnu.org/licenses/>.
"""Reader for the GHRSST level-2 formatted data."""

import os
import tarfile
from contextlib import suppress
from datetime import datetime
from functools import cached_property

import xarray as xr

from satpy import CHUNK_SIZE
from satpy.readers.file_handlers import BaseFileHandler


class GHRSSTL2FileHandler(BaseFileHandler):
"""File handler for GHRSST L2 netCDF files."""

def __init__(self, filename, filename_info, filetype_info, engine=None):
"""Initialize the file handler for GHRSST L2 netCDF data."""
super().__init__(filename, filename_info, filetype_info)
self._engine = engine
self._tarfile = None

self.filename_info['start_time'] = datetime.strptime(
self.nc.start_time, '%Y%m%dT%H%M%SZ')
self.filename_info['end_time'] = datetime.strptime(
self.nc.stop_time, '%Y%m%dT%H%M%SZ')

@cached_property
def nc(self):
"""Get the xarray Dataset for the filename."""
if os.fspath(self.filename).endswith('tar'):
file_obj = self._open_tarfile()
else:
file_obj = self.filename

nc = xr.open_dataset(file_obj,
decode_cf=True,
mask_and_scale=True,
engine=self._engine,
chunks={'ni': CHUNK_SIZE,
'nj': CHUNK_SIZE})

return nc.rename({'ni': 'x', 'nj': 'y'})

def _open_tarfile(self):
self._tarfile = tarfile.open(name=self.filename, mode='r')
sst_filename = next((name for name in self._tarfile.getnames()
if self._is_sst_file(name)))
file_obj = self._tarfile.extractfile(sst_filename)
return file_obj

@staticmethod
def _is_sst_file(name):
"""Check if file in the tar archive is a valid SST file."""
return name.endswith('nc') and 'GHRSST-SSTskin' in name

def get_dataset(self, key, info):
"""Get any available dataset."""
stdname = info.get('standard_name')
return self.nc[stdname].squeeze()

@property
def start_time(self):
"""Get start time."""
return self.filename_info['start_time']

@property
def end_time(self):
"""Get end time."""
return self.filename_info['end_time']

@property
def sensor(self):
"""Get the sensor name."""
return self.nc.attrs['sensor'].lower()

def __del__(self):
"""Close the tarfile object."""
with suppress(AttributeError):
self._tarfile.close()
77 changes: 0 additions & 77 deletions satpy/readers/slstr_l2.py

This file was deleted.

Loading

0 comments on commit 37e77dd

Please sign in to comment.