{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Quickstart with MSG SEVIRI\n", "\n", "For this tutorial, we will use Meteosat Second Generation (MSG) data in uncompressed EUMETSAT HRIT format, read it with satpy, resample it with pyresample and process it a bit. Be sure to have the necessary python packages installed, using eg:\n", "\n", " `pip install satpy`\n", "\n", "Software to uncompress HRIT data is callled Public Wavelet Transform Decompression Library Software and can be obtained from EUMETSAT [on their software page](https://www.eumetsat.int/website/home/Data/DataDelivery/SupportSoftwareandTools/index.html?lang=EN). Compressed HRIT data is easily recognizable as the files end with `C_`, while uncompressed data files end with `__` (two underscores)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading data and generating our first image\n", "\n", "Loading the data is done on-the-fly with satpy when a composite is to be generated. So first we create a scene instance, pointing the `base_dir` directory to the place containing the uncompressed HRIT data files." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from satpy.scene import Scene\n", "from satpy.resample import get_area_def\n", "from satpy import find_files_and_readers\n", "from datetime import datetime\n", "import glob\n", "import warnings\n", "\n", "# Date format in YYYYMMDDhhmm\n", "fnames = glob.glob('/path/to/data/H*202009060000*__')\n", "scn = Scene(reader='seviri_l1b_hrit', filenames=fnames)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We then define a composite to load and show it.\n", "You may see warnings due to deprecated pyproj features and when numpy/dask process NaNs values. NaNs are used to mark invalid pixels and space pixels (like you'll see in a full disk image).\n", "You can silence these with `warnings.filterwarnings('ignore')`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "composite = 'natural_color'\n", "scn.load([composite])\n", "scn.show(composite)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, earth is displayed with North facing down: remember that this is raw data from the hrit files, unprojected, so the pixels are displayed in scanning order.\n", "\n", "To get a list of available composites to choose from:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[DatasetID(name='airmass', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='airmass_corr', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='ash', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='cloudtop', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='convection', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='day_microphysics', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='dust', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='fog', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='green_snow', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='ir_overview', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='natural', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='natural_sun', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='night_fog', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='night_microphysics', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='overview', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='overview_sun', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None),\n", " DatasetID(name='realistic_colors', wavelength=None, resolution=None, polarization=None, calibration=None, modifiers=None)]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scn.available_composite_ids()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading channel data and working with it\n", "\n", "In order to load channel data to work with, the procedure is identical to what we presented above, except the name of a channel or its wavelength (along with the full-featured `DatasetID`) has to be passed. For example:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "dask.array\n", "Coordinates:\n", " * x (x) float64 -5.569e+06 -5.569e+06 -5.569e+06 -5.569e+06 ...\n", " * y (y) float64 5.566e+06 5.566e+06 5.566e+06 5.566e+06 5.566e+06 ...\n", "Attributes:\n", " units: %\n", " wavelength: (0.74, 0.81, 0.88)\n", " standard_name: toa_bidirectional_reflectance\n", " platform_name: Meteosat-10\n", " sensor: seviri\n", " satellite_longitude: 0.0\n", " satellite_latitude: 0.0\n", " satellite_altitude: 35785831.0\n", " start_time: 2017-01-19 09:30:10.553000\n", " end_time: 2017-01-19 09:42:41.403000\n", " area: Area ID: some_area_name\\nDescription: On-the-fly ar...\n", " name: VIS008\n", " resolution: 3000.40316582\n", " calibration: reflectance\n", " polarization: None\n", " modifiers: ()\n", " ancillary_variables: []\n", "\n", "dask.array\n", "Coordinates:\n", " * x (x) float64 -5.569e+06 -5.569e+06 -5.569e+06 -5.569e+06 ...\n", " * y (y) float64 5.566e+06 5.566e+06 5.566e+06 5.566e+06 5.566e+06 ...\n", "Attributes:\n", " units: %\n", " wavelength: (0.56, 0.635, 0.71)\n", " standard_name: toa_bidirectional_reflectance\n", " platform_name: Meteosat-10\n", " sensor: seviri\n", " satellite_longitude: 0.0\n", " satellite_latitude: 0.0\n", " satellite_altitude: 35785831.0\n", " start_time: 2017-01-19 09:30:10.553000\n", " end_time: 2017-01-19 09:42:41.403000\n", " area: Area ID: some_area_name\\nDescription: On-the-fly ar...\n", " name: VIS006\n", " resolution: 3000.40316582\n", " calibration: reflectance\n", " polarization: None\n", " modifiers: ()\n", " ancillary_variables: []\n", "\n", "dask.array\n", "Coordinates:\n", " * x (x) float64 -5.569e+06 -5.569e+06 -5.569e+06 -5.569e+06 ...\n", " * y (y) float64 5.566e+06 5.566e+06 5.566e+06 5.566e+06 5.566e+06 ...\n", " * bands (bands) |S1 'R' 'G' 'B'\n", "Attributes:\n", " units: %\n", " platform_name: Meteosat-10\n", " sensor: seviri\n", " satellite_longitude: 0.0\n", " satellite_latitude: 0.0\n", " satellite_altitude: 35785831.0\n", " start_time: 2017-01-19 09:30:00\n", " end_time: 2017-01-19 09:45:00\n", " area: Area ID: some_area_name\\nDescription: On-the-fly...\n", " polarization: None\n", " ancillary_variables: []\n", " metadata_requirements: []\n", " standard_name: natural\n", " wavelength: None\n", " optional_prerequisites: []\n", " mode: RGB\n", " name: natural\n", " prerequisites: [1.63, 0.85, 0.635]\n", " optional_datasets: []\n", " resolution: None\n", " calibration: None\n", " modifiers: None\n" ] } ], "source": [ "scn.load(['VIS006', 0.8])\n", "print(scn)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Working with the data is quite straightforward as the datasets inside the scene are in effect DataArrays as per the xarray python package." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/a001673/usr/src/dask/dask/local.py:271: RuntimeWarning: invalid value encountered in divide\n", " return func(*args2)\n" ] } ], "source": [ "from satpy.dataset import combine_metadata\n", "ndvi = (scn[0.8] - scn[0.6]) / (scn[0.8] + scn[0.6])\n", "ndvi.attrs = combine_metadata(scn[0.8], scn[0.6])\n", "scn['ndvi'] = ndvi\n", "scn.show('ndvi')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Resampling the data\n", "\n", "Until now, we have used the channels directly as provided by the satellite, that is in satellite projection. Generating composites thus produces views in satellite projection, i.e. as viewed by the satellite.\n", "\n", "Most often however, we will want to project the data onto a specific area so that only the area of interest is depicted in the RGB composites.\n", "\n", "Here is how we do that:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "dask.array\n", "Coordinates:\n", " * y (y) float64 -1.502e+06 -1.504e+06 -1.508e+06 -1.510e+06 ...\n", " * x (x) float64 -3.778e+06 -3.776e+06 -3.772e+06 -3.77e+06 ...\n", "Attributes:\n", " units: %\n", " wavelength: (0.74, 0.81, 0.88)\n", " standard_name: toa_bidirectional_reflectance\n", " platform_name: Meteosat-10\n", " sensor: seviri\n", " satellite_longitude: 0.0\n", " satellite_latitude: 0.0\n", " satellite_altitude: 35785831.0\n", " start_time: 2017-01-19 09:30:10.553000\n", " end_time: 2017-01-19 09:42:41.403000\n", " area: Area ID: eurol\\nDescription: Euro 3.0km area - Euro...\n", " name: VIS008\n", " resolution: 3000.40316582\n", " calibration: reflectance\n", " polarization: None\n", " modifiers: ()\n", " ancillary_variables: []\n", "\n", "dask.array\n", "Coordinates:\n", " * y (y) float64 -1.502e+06 -1.504e+06 -1.508e+06 -1.510e+06 ...\n", " * x (x) float64 -3.778e+06 -3.776e+06 -3.772e+06 -3.77e+06 ...\n", "Attributes:\n", " units: %\n", " wavelength: (0.56, 0.635, 0.71)\n", " standard_name: toa_bidirectional_reflectance\n", " platform_name: Meteosat-10\n", " sensor: seviri\n", " satellite_longitude: 0.0\n", " satellite_latitude: 0.0\n", " satellite_altitude: 35785831.0\n", " start_time: 2017-01-19 09:30:10.553000\n", " end_time: 2017-01-19 09:42:41.403000\n", " area: Area ID: eurol\\nDescription: Euro 3.0km area - Euro...\n", " name: VIS006\n", " resolution: 3000.40316582\n", " calibration: reflectance\n", " polarization: None\n", " modifiers: ()\n", " ancillary_variables: []\n", "\n", "dask.array\n", "Coordinates:\n", " * y (y) float64 -1.502e+06 -1.504e+06 -1.508e+06 -1.510e+06 ...\n", " * x (x) float64 -3.778e+06 -3.776e+06 -3.772e+06 -3.77e+06 ...\n", "Attributes:\n", " satellite_latitude: 0.0\n", " polarization: None\n", " modifiers: ()\n", " satellite_longitude: 0.0\n", " area: Area ID: eurol\\nDescription: Euro 3.0km area - Euro...\n", " sensor: seviri\n", " satellite_altitude: 35785831.0\n", " calibration: reflectance\n", " ancillary_variables: []\n", " platform_name: Meteosat-10\n", " standard_name: toa_bidirectional_reflectance\n", " end_time: 2017-01-19 09:42:41.403000\n", " units: %\n", " resolution: 3000.40316582\n", " start_time: 2017-01-19 09:30:10.553000\n", " name: ndvi\n", "\n", "dask.array\n", "Coordinates:\n", " * bands (bands) |S1 'R' 'G' 'B'\n", " * y (y) float64 -1.502e+06 -1.504e+06 -1.508e+06 -1.510e+06 ...\n", " * x (x) float64 -3.778e+06 -3.776e+06 -3.772e+06 -3.77e+06 ...\n", "Attributes:\n", " units: %\n", " platform_name: Meteosat-10\n", " sensor: seviri\n", " satellite_longitude: 0.0\n", " satellite_latitude: 0.0\n", " satellite_altitude: 35785831.0\n", " start_time: 2017-01-19 09:30:00\n", " end_time: 2017-01-19 09:45:00\n", " area: Area ID: eurol\\nDescription: Euro 3.0km area - E...\n", " polarization: None\n", " ancillary_variables: []\n", " metadata_requirements: []\n", " standard_name: natural\n", " wavelength: None\n", " optional_prerequisites: []\n", " mode: RGB\n", " name: natural\n", " prerequisites: [1.63, 0.85, 0.635]\n", " optional_datasets: []\n", " resolution: None\n", " calibration: None\n", " modifiers: None\n" ] } ], "source": [ "local_scn = scn.resample(\"eurol\")\n", "print(local_scn)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "local_scn.show('ndvi')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "local_scn.show('natural')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" } }, "nbformat": 4, "nbformat_minor": 2 }