Source code for satpy.readers.camel_l3_nc

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 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 CAMEL Level 3 emissivity files in netCDF4 format.

For more information about the data, see: <https://lpdaac.usgs.gov/products/cam5k30emv002/>.

NOTE: This reader only supports the global 0.05 degree grid data.
"""


import datetime as dt
import logging

import xarray as xr
from pyresample import geometry

from satpy.readers.core.file_handlers import BaseFileHandler

logger = logging.getLogger(__name__)

# Area extent for the CAMEL product (global)
GLOB_AREA_EXT = [-180, -90, 180, 90]


[docs] class CAMELL3NCFileHandler(BaseFileHandler): """File handler for CAMEL data in netCDF format."""
[docs] def __init__(self, filename, filename_info, filetype_info): """Initialize the reader.""" super().__init__(filename, filename_info, filetype_info) self.nc = xr.open_dataset(self.filename, decode_cf=True, mask_and_scale=True, chunks={"xc": "auto", "yc": "auto"}) if "0.05" not in self.nc.attrs["geospatial_lon_resolution"]: raise ValueError("Only 0.05 degree grid data is supported.") if "0.05" not in self.nc.attrs["geospatial_lat_resolution"]: raise ValueError("Only 0.05 degree grid data is supported.") self.nlines = self.nc.sizes["latitude"] self.ncols = self.nc.sizes["longitude"] self.area = None
@property def start_time(self): """Start timestamp of the dataset.""" date_str = self.nc.attrs["time_coverage_start"] return dt.datetime.strptime(date_str, "%Y-%m-%d %H:%M:%SZ") @property def end_time(self): """End timestamp of the dataset.""" date_str = self.nc.attrs["time_coverage_end"] return dt.datetime.strptime(date_str, "%Y-%m-%d %H:%M:%SZ")
[docs] def get_dataset(self, key, info): """Load a dataset.""" var = info["file_key"] logger.debug("Reading in get_dataset %s.", var) variable = self.nc[var] # For the emissivity there are multiple bands, so we need to select the correct one if var == "camel_emis": if info["band_id"] >= variable.shape[2]: raise ValueError("Band id requested is larger than dataset.") variable = variable[:, :, info["band_id"]] # Rename the latitude and longitude dimensions to x and y variable = variable.rename({"latitude": "y", "longitude": "x"}) variable.attrs.update(key.to_dict()) return variable
[docs] def get_area_def(self, dsid): """Get the area definition, a global lat/lon area for this type of dataset.""" proj_param = "EPSG:4326" area = geometry.AreaDefinition("gridded_camel", "A global gridded area", "longlat", proj_param, self.ncols, self.nlines, GLOB_AREA_EXT) self.area = area return area