diff --git a/doc/source/index.rst b/doc/source/index.rst index d7f02207a6..f7971e586e 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -243,8 +243,12 @@ the base Satpy installation. * - OMPS EDR data in HDF5 format - `omps_edr` - Beta + * - VII Level 2 in NetCDF4 format + - `vii_l2_nc` + - Beta * - VII Level 1b in NetCDF4 format - `vii_l1b_nc` + - Beta * - MTG FCI Level 2 in NetCDF4 format - `fci_l2_nc` - Beta diff --git a/satpy/etc/readers/vii_l2_nc.yaml b/satpy/etc/readers/vii_l2_nc.yaml new file mode 100644 index 0000000000..e1b146eeb9 --- /dev/null +++ b/satpy/etc/readers/vii_l2_nc.yaml @@ -0,0 +1,436 @@ +reader: + name: vii_l2_nc + short_name: VII L2 NetCDF4 + long_name: EPS-SG VII L2 (NetCDF4) + description: > + Reader for EUMETSAT EPSG-SG Visual Infrared Imager Level 2 files in NetCDF4 format. + sensors: [vii] + reader: !!python/name:satpy.readers.yaml_reader.FileYAMLReader + +file_types: + # EUMETSAT EPSG-SG Visual Infrared Imager Level 2 Cloud Mask files in NetCDF4 format + nc_vii_l2_cld: + file_reader: !!python/name:satpy.readers.vii_l2_nc.ViiL2NCFileHandler + file_patterns: ['W_xx-eumetsat-darmstadt,SAT,{spacecraft_name:s}-VII-02-CLD_C_EUM_{creation_time:%Y%m%d%H%M%S}_{mission_type:s}_{environment:s}_{sensing_start_time:%Y%m%d%H%M%S}_{sensing_end_time:%Y%m%d%H%M%S}_{disposition_mode:s}_{processing_mode:s}____.nc'] + cached_longitude: data/measurement_data/longitude + cached_latitude: data/measurement_data/latitude + orthorect: False + + # EUMETSAT EPSG-SG Visual Infrared Imager Level 2 Cloud Top Pressure (using the Oxygen-A Band) files in NetCDF4 format + nc_vii_l2_ctp: + file_reader: !!python/name:satpy.readers.vii_l2_nc.ViiL2NCFileHandler + file_patterns: ['W_xx-eumetsat-darmstadt,SAT,{spacecraft_name:s}-VII-02-CTP_C_EUM_{creation_time:%Y%m%d%H%M%S}_{mission_type:s}_{environment:s}_{sensing_start_time:%Y%m%d%H%M%S}_{sensing_end_time:%Y%m%d%H%M%S}_{disposition_mode:s}_{processing_mode:s}____.nc'] + cached_longitude: data/measurement_data/longitude + cached_latitude: data/measurement_data/latitude + + # EUMETSAT EPSG-SG Visual Infrared Imager Level 2 Cloud Mask and First Guess Cloud Properties files in NetCDF4 format + nc_vii_l2_icm: + file_reader: !!python/name:satpy.readers.vii_l2_nc.ViiL2NCFileHandler + file_patterns: ['W_xx-eumetsat-darmstadt,SAT,{spacecraft_name:s}-VII-02-ICM_C_EUM_{creation_time:%Y%m%d%H%M%S}_{mission_type:s}_{environment:s}_{sensing_start_time:%Y%m%d%H%M%S}_{sensing_end_time:%Y%m%d%H%M%S}_{disposition_mode:s}_{processing_mode:s}____.nc'] + cached_longitude: data/measurement_data/longitude + cached_latitude: data/measurement_data/latitude + + # EUMETSAT EPSG-SG Visual Infrared Imager Level 2 Optimal Cloud Analysis files in NetCDF4 format + nc_vii_l2_oca: + file_reader: !!python/name:satpy.readers.vii_l2_nc.ViiL2NCFileHandler + file_patterns: ['W_xx-eumetsat-darmstadt,SAT,{spacecraft_name:s}-VII-02-OCA_C_EUM_{creation_time:%Y%m%d%H%M%S}_{mission_type:s}_{environment:s}_{sensing_start_time:%Y%m%d%H%M%S}_{sensing_end_time:%Y%m%d%H%M%S}_{disposition_mode:s}_{processing_mode:s}____.nc'] + cached_longitude: data/measurement_data/longitude + cached_latitude: data/measurement_data/latitude + + # EUMETSAT EPSG-SG Visual Infrared Imager Level 2 Total Precipitable Water (from VII visible/near-infrared) files in NetCDF4 format + nc_vii_l2_wvv: + file_reader: !!python/name:satpy.readers.vii_l2_nc.ViiL2NCFileHandler + file_patterns: ['W_xx-eumetsat-darmstadt,SAT,{spacecraft_name:s}-VII-02-WVV_C_EUM_{creation_time:%Y%m%d%H%M%S}_{mission_type:s}_{environment:s}_{sensing_start_time:%Y%m%d%H%M%S}_{sensing_end_time:%Y%m%d%H%M%S}_{disposition_mode:s}_{processing_mode:s}____.nc'] + cached_longitude: data/measurement_data/longitude + cached_latitude: data/measurement_data/latitude + interpolate: False + orthorect: False + + # EUMETSAT EPSG-SG Visual Infrared Imager Level 2 Total Precipitable Water (from VII thermal infra-red) files in NetCDF4 format + nc_vii_l2_wvi: + file_reader: !!python/name:satpy.readers.vii_l2_nc.ViiL2NCFileHandler + file_patterns: ['W_xx-eumetsat-darmstadt,SAT,{spacecraft_name:s}-VII-02-WVI_C_EUM_{creation_time:%Y%m%d%H%M%S}_{mission_type:s}_{environment:s}_{sensing_start_time:%Y%m%d%H%M%S}_{sensing_end_time:%Y%m%d%H%M%S}_{disposition_mode:s}_{processing_mode:s}____.nc'] + cached_longitude: data/measurement_data/longitude + cached_latitude: data/measurement_data/latitude + interpolate: False + orthorect: False + +datasets: + +# --- Coordinates --- + # TODO Coordinates on tie points are kept for test purposes + lon_tie_points: + name: lon_tie_points + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/longitude + standard_name: longitude + + lat_tie_points: + name: lat_tie_points + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/latitude + standard_name: latitude + + lon_pixels_no_orthorect: + name: lon_pixels_no_orthorect + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: cached_longitude + standard_name: longitude + + lat_pixels_no_orthorect: + name: lat_pixels_no_orthorect + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: cached_latitude + standard_name: latitude + + lon_pixels: + name: lon_pixels + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: cached_longitude + orthorect_data: data/measurement_data/delta_lon + standard_name: longitude + + lat_pixels: + name: lat_pixels + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: cached_latitude + orthorect_data: data/measurement_data/delta_lat + standard_name: latitude + + lon_pixels2: + name: lon_pixels2 + file_type: nc_vii_l2_oca + file_key: cached_longitude + orthorect_data: data/measurement_data/delta_lon_cloud2 + standard_name: longitude + + lat_pixels2: + name: lat_pixels2 + file_type: nc_vii_l2_oca + file_key: cached_latitude + orthorect_data: data/measurement_data/delta_lat_cloud2 + standard_name: latitude + +# --- Measurement data --- + cs_confidence: + name: cs_confidence + file_type: [nc_vii_l2_cld, nc_vii_l2_icm] + file_key: data/measurement_data/cs_confidence + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_area_fraction + + flag_cm: + name: flag_cm + file_type: [nc_vii_l2_cld, nc_vii_l2_icm] + file_key: data/measurement_data/flag_cm + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_mask_classification + + surface_type: + name: surface_type + file_type: [nc_vii_l2_cld, nc_vii_l2_icm] + file_key: data/measurement_data/surface_type + coordinates: [lon_pixels, lat_pixels] + standard_name: surface_type + + ctp_o2: + name: ctp_o2 + file_type: nc_vii_l2_ctp + file_key: data/measurement_data/ctp_o2 + coordinates: [lon_pixels, lat_pixels] + standard_name: air_pressure_at_cloud_top + + log10_ctp_o2_err: + name: log10_ctp_o2_err + file_type: nc_vii_l2_ctp + file_key: data/measurement_data/log10_ctp_o2_err + coordinates: [lon_pixels, lat_pixels] + standard_name: air_pressure_at_cloud_top + + log10_cot_o2: + name: log10_cot_o2 + file_type: nc_vii_l2_ctp + file_key: data/measurement_data/log10_cot_o2 + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_optical_depth + + log10_cot_o2_err: + name: log10_cot_o2_err + file_type: nc_vii_l2_ctp + file_key: data/measurement_data/log10_cot_o2_err + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_optical_depth + + vii_ch_sel1: + name: vii_ch_sel1 + file_type: nc_vii_l2_icm + file_key: data/measurement_data/vii_ch_sel1 + coordinates: [lon_pixels, lat_pixels] + standard_name: toa_outgoing_radiance_per_unit_wavelength + + vii_ch_sel2: + name: vii_ch_sel2 + file_type: nc_vii_l2_icm + file_key: data/measurement_data/vii_ch_sel2 + coordinates: [lon_pixels, lat_pixels] + standard_name: toa_outgoing_radiance_per_unit_wavelength + + vii_ch_sel3: + name: vii_ch_sel3 + file_type: nc_vii_l2_icm + file_key: data/measurement_data/vii_ch_sel3 + coordinates: [lon_pixels, lat_pixels] + standard_name: toa_outgoing_radiance_per_unit_wavelength + + flag_cph: + name: flag_cph + file_type: nc_vii_l2_icm + file_key: data/measurement_data/flag_cph + coordinates: [lon_pixels, lat_pixels] + standard_name: thermodynamic_phase_of_cloud_water_particles_at_cloud_top + + log10_cot_fg: + name: log10_cot_fg + file_type: nc_vii_l2_icm + file_key: data/measurement_data/log10_cot_fg + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_optical_depth + + log10_err_cot_fg: + name: log10_err_cot_fg + file_type: nc_vii_l2_icm + file_key: data/measurement_data/log10_err_cot_fg + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_optical_depth + + cth_fg: + name: cth_fg + file_type: nc_vii_l2_icm + file_key: data/measurement_data/cth_fg + coordinates: [lon_pixels, lat_pixels] + standard_name: height_at_cloud_top + + err_cth_fg: + name: err_cth_fg + file_type: nc_vii_l2_icm + file_key: data/measurement_data/err_cth_fg + coordinates: [lon_pixels, lat_pixels] + standard_name: height_at_cloud_top + + moca_model_final: + name: moca_model_final + file_type: nc_vii_l2_oca + file_key: data/measurement_data/moca_model_final + coordinates: [lon_pixels, lat_pixels] + standard_name: scene_classification + + log10_cot: + name: log10_cot + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_cot + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_optical_depth + + log10_err_cot: + name: log10_err_cot + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_err_cot + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_optical_depth + + cre: + name: cre + file_type: nc_vii_l2_oca + file_key: data/measurement_data/cre + coordinates: [lon_pixels, lat_pixels] + standard_name: effective_radius_of_cloud_condensed_water_particles_at_cloud_top + + log10_err_cre: + name: log10_err_cre + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_err_cre + coordinates: [lon_pixels, lat_pixels] + standard_name: effective_radius_of_cloud_condensed_water_particles_at_cloud_top + + ctp: + name: ctp + file_type: nc_vii_l2_oca + file_key: data/measurement_data/ctp + coordinates: [lon_pixels, lat_pixels] + standard_name: air_pressure_at_cloud_top + + log10_err_ctp: + name: log10_err_ctp + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_err_ctp + coordinates: [lon_pixels, lat_pixels] + standard_name: air_pressure_at_cloud_top + + ctt: + name: ctt + file_type: nc_vii_l2_oca + file_key: data/measurement_data/ctt + coordinates: [lon_pixels, lat_pixels] + standard_name: air_temperature_at_cloud_top + + log10_cot2: + name: log10_cot2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_cot2 + coordinates: [lon_pixels2, lat_pixels2] + standard_name: cloud_optical_depth + + log10_err_cot2: + name: log10_err_cot2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_err_cot2 + coordinates: [lon_pixels2, lat_pixels2] + standard_name: cloud_optical_depth + + ctp2: + name: ctp2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/ctp2 + coordinates: [lon_pixels2, lat_pixels2] + standard_name: air_pressure_at_cloud_top + + log10_err_ctp2: + name: log10_err_ctp2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/log10_err_ctp2 + coordinates: [lon_pixels2, lat_pixels2] + standard_name: air_pressure_at_cloud_top + + ctt2: + name: ctt2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/ctt2 + coordinates: [lon_pixels2, lat_pixels2] + standard_name: air_temperature_at_cloud_top + + tpw: + name: tpw + file_type: [nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/measurement_data/tpw + coordinates: [lon_pixels, lat_pixels] + standard_name: mass_of_water_in_air + + tpw_err: + name: tpw_err + file_type: [nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/measurement_data/tpw_err + coordinates: [lon_pixels, lat_pixels] + standard_name: mass_of_water_in_air + +# --- Geometric data --- + # TODO Geometric data on tie points are kept for test purposes + solar_zenith_tie_points: + name: solar_zenith_tie_points + standard_name: solar_zenith_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/solar_zenith + coordinates: [lon_tie_points, lat_tie_points] + + solar_azimuth_tie_points: + name: solar_azimuth_tie_points + standard_name: solar_azimuth_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/solar_azimuth + coordinates: [lon_tie_points, lat_tie_points] + + observation_zenith_tie_points: + name: observation_zenith_tie_points + standard_name: sensor_zenith_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/observation_zenith + coordinates: [lon_tie_points, lat_tie_points] + + observation_azimuth_tie_points: + name: observation_azimuth_tie_points + standard_name: sensor_azimuth_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/observation_azimuth + coordinates: [lon_tie_points, lat_tie_points] + + solar_zenith: + name: solar_zenith + standard_name: solar_zenith_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/measurement_data/solar_zenith + interpolate: True + coordinates: [lon_pixels_no_orthorect, lat_pixels_no_orthorect] + + solar_azimuth: + name: solar_azimuth + standard_name: solar_azimuth_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/measurement_data/solar_azimuth + interpolate: True + coordinates: [lon_pixels_no_orthorect, lat_pixels_no_orthorect] + + observation_zenith: + name: observation_zenith + standard_name: sensor_zenith_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/measurement_data/observation_zenith + interpolate: True + coordinates: [lon_pixels_no_orthorect, lat_pixels_no_orthorect] + + observation_azimuth: + name: observation_azimuth + standard_name: sensor_azimuth_angle + file_type: [nc_vii_l2_cld, nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/measurement_data/observation_azimuth + interpolate: True + coordinates: [lon_pixels_no_orthorect, lat_pixels_no_orthorect] + +# --- Orthorectification data --- + delta_lat: + name: delta_lat + file_type: [nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/delta_lat + coordinates: [lon_pixels, lat_pixels] + standard_name: parallax_delta_latitude + + delta_lon: + name: delta_lon + file_type: [nc_vii_l2_ctp, nc_vii_l2_icm, nc_vii_l2_oca] + file_key: data/measurement_data/delta_lon + coordinates: [lon_pixels, lat_pixels] + standard_name: parallax_delta_longitude + + delta_lat_cloud2: + name: delta_lat_cloud2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/delta_lat_cloud2 + coordinates: [lon_pixels, lat_pixels] + standard_name: parallax_delta_latitude + + delta_lon_cloud2: + name: delta_lon_cloud2 + file_type: nc_vii_l2_oca + file_key: data/measurement_data/delta_lon_cloud2 + coordinates: [lon_pixels, lat_pixels] + standard_name: parallax_delta_longitude + +# --- Quality Information data --- + log10_j: + name: log10_j + file_type: [nc_vii_l2_ctp, nc_vii_l2_oca, nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/quality_information/log10_j + coordinates: [lon_pixels, lat_pixels] + standard_name: cost_function + + flag_ml: + name: flag_ml + file_type: nc_vii_l2_ctp + file_key: data/quality_information/flag_ml + coordinates: [lon_pixels, lat_pixels] + standard_name: cloud_multilayer_classification + + qi_forecast: + name: qi_forecast + file_type: [nc_vii_l2_wvi, nc_vii_l2_wvv] + file_key: data/quality_information/qi_forecast + coordinates: [lon_pixels, lat_pixels] + standard_name: mass_of_water_in_air diff --git a/satpy/readers/vii_l2_nc.py b/satpy/readers/vii_l2_nc.py new file mode 100644 index 0000000000..3ce3926674 --- /dev/null +++ b/satpy/readers/vii_l2_nc.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2020 Satpy developers +# +# 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 . + +"""EUMETSAT EPS-SG Visible/Infrared Imager (VII) Level 2 products reader.""" + +import logging + +from satpy.readers.vii_base_nc import ViiNCBaseFileHandler + +logger = logging.getLogger(__name__) + + +class ViiL2NCFileHandler(ViiNCBaseFileHandler): + """Reader class for VII L2 products in netCDF format.""" + + def _perform_orthorectification(self, variable, orthorect_data_name): + """Perform the orthorectification. + + Args: + variable: xarray DataArray containing the dataset to correct for orthorectification. + orthorect_data_name: name of the orthorectification correction data in the product. + + Returns: + DataArray: array containing the corrected values and all the original metadata. + + """ + try: + orthorect_data = self[orthorect_data_name] + variable += orthorect_data + except KeyError: + logger.warning('Required dataset %s for orthorectification not available, skipping', orthorect_data_name) + return variable diff --git a/satpy/tests/reader_tests/test_vii_l2_nc.py b/satpy/tests/reader_tests/test_vii_l2_nc.py new file mode 100644 index 0000000000..1336da2e7e --- /dev/null +++ b/satpy/tests/reader_tests/test_vii_l2_nc.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2020 Satpy developers +# +# 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 . + +"""The vii_2_nc reader tests package.""" + +import os +import numpy as np +import xarray as xr +import dask.array as da +import datetime +from netCDF4 import Dataset +import uuid + +from satpy.readers.vii_l2_nc import ViiL2NCFileHandler + +import unittest + + +TEST_FILE = 'test_file_vii_l2_nc.nc' + + +class TestViiL2NCFileHandler(unittest.TestCase): + """Test the ViiL2NCFileHandler reader.""" + + def setUp(self): + """Set up the test.""" + # Easiest way to test the reader is to create a test netCDF file on the fly + # uses a UUID to avoid permission conflicts during execution of tests in parallel + self.test_file_name = TEST_FILE + str(uuid.uuid1()) + + with Dataset(self.test_file_name, 'w') as nc: + # Create data group + g1 = nc.createGroup('data') + + # Add dimensions to data group + g1.createDimension('num_pixels', 10) + g1.createDimension('num_lines', 100) + + # Create measurement_data group + g1_2 = g1.createGroup('measurement_data') + + # Add variables to data/measurement_data group + delta_lat = g1_2.createVariable('delta_lat', np.float32, dimensions=('num_pixels', 'num_lines')) + delta_lat[:] = 0.1 + + self.reader = ViiL2NCFileHandler( + filename=self.test_file_name, + filename_info={ + 'creation_time': datetime.datetime(year=2017, month=9, day=22, + hour=22, minute=40, second=10), + 'sensing_start_time': datetime.datetime(year=2017, month=9, day=20, + hour=12, minute=30, second=30), + 'sensing_end_time': datetime.datetime(year=2017, month=9, day=20, + hour=18, minute=30, second=50) + }, + filetype_info={} + ) + + def tearDown(self): + """Remove the previously created test file.""" + # Catch Windows PermissionError for removing the created test file. + try: + os.remove(self.test_file_name) + except OSError: + pass + + def test_functions(self): + """Test the functions.""" + # Checks that the _perform_orthorectification function is correctly executed + variable = xr.DataArray( + dims=('num_pixels', 'num_lines'), + name='test_name', + attrs={ + 'key_1': 'value_1', + 'key_2': 'value_2' + }, + data=da.from_array(np.ones((10, 100))) + ) + orthorect_variable = self.reader._perform_orthorectification(variable, 'data/measurement_data/delta_lat') + + expected_values = 1.1 * np.ones((10, 100)) + self.assertTrue(np.allclose(orthorect_variable.values, expected_values)) + self.assertEqual(orthorect_variable.attrs['key_1'], 'value_1')