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')