<jupyter_start><jupyter_text>421 - Sentinel-3 OLCI - Radiances - Level 1 - Exercise >> 40 - EXERCISES PREREQUISITES The following **20 - DATA DISCOVERY** module is a prerequisite:- [241 - Sentinel-5P TROPOMI - Carbon Monoxide - Level 2 - Load and browse](../20_data_discovery/241_Sentinel-5P_TROPOMI_CO_L2_load_browse.ipynb)        It is recommended to go through the module before you do this exercise workbook.   4.1.1 Copernicus Sentinel-5P TROPOMI - Carbon Monoxide - Level 2 This notebook is an `exercise workbook`, where you can practise the data handling with Sentinel-5P TROPOMI Level 2 data.   How it works This exercise workbook consists of two types of exercises:  Coding assignmentsCoding assignments ask you to fill an empty code cell with code. You recognize `coding assignments` as the yellow-coloured boxes.Coding assignment  QuestionsQuestions ask you to reflect on a result and output. `Questions` are provided as green-coloured boxes.Question  Outline * [1. Load a Sentinel-5P data file](load)* [2. Select a data variable](select_variable)* [3. Load the latitude and longitude information and store some attributes](lat_lon)* [4. Visualize the DataArray](visualize)* [5. Create a geographical subset](subset)* [6. Convert the CO values from mol per m2 to molecules per cm2](convert)   Load required libraries<jupyter_code>import os
import xarray as xr

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.feature as cfeature

from matplotlib.axes import Axes
from cartopy.mpl.geoaxes import GeoAxes
GeoAxes._pcolormesh_patched = Axes.pcolormesh

import warnings
warnings.simplefilter(action = "ignore", category = UserWarning)<jupyter_output><empty_output><jupyter_text>Load helper functions<jupyter_code>%run ../functions.ipynb<jupyter_output><empty_output><jupyter_text>Exercise example - Siberian fires monitored by Sentinel-5P This exercise aims to get familiar with Sentinel-5P Carbon Monoxide data. The exercise examines the Siberian fires that occured in July and August 2019.  1. Load a Sentinel-5P data file Let us load a Sentinel-5P file of carbon monoxide from `29th December 2019`. Sentinel-5P files are organised in two groups: `PRODUCT` and `METADATA`. The `PRODUCT` group stores the main data fields of the product, including `latitude`, `longitude` and the variable itself. The `METADATA` group provides additional metadata items.Multiple `netCDF` files can be loaded with the xarray function `xr.open_mfdataset()`.We define the following keyword arguments:* `concat_dim`: the dimenension the files shall be concatenated, e.g. **scanline*** `combine`: the way how the files shall be combined, choose between **nested** or **by_coords*** `group`: specify the name of the group that holds the data. For Sentinel-5P data it is **PRODUCT** Execute the cell below and understand the structure of the loaded `xarray.Dataset`.<jupyter_code>file = xr.open_mfdataset('../eodata/sentinel5p/co/2019/12/29/*',concat_dim='scanline', combine='nested',group='PRODUCT')
file<jupyter_output><empty_output><jupyter_text>Question:   Can you identify the dimensions of the dataset and description? What data variables are available in the data file? **Response**:The loaded data file has five dimensions:* `corner`: pixel corner index* `ground_pixel`: the number of spectra in a measurement / across-track dimension index* `layer`: this dimension indicates the vertical grid of profile variables* `scanline`: the number of measurements in the granule / along-track dimension index* `time`: time reference for the dataThe following data variables are offered:* `delta_time`: the offset of individual measurements within the granule, given in milliseconds* `time_utc`: valid time stamp of the data* `ga_value`: quality descriptor, varying between 0 (nodata) and 1 (full quality data).* `carbonmonoxide_total_column`: Vertically integrated CO column density* `carbonmonoxide_total_column_precision`: Standard error of the vertically integrate CO column    2. Select a data variable As a next step, you want to load the data variable `carbonmonoxide_total_column` from the `xarray.Dataset` `file` above and call it `s5p_co`. Coding assignment:   Enter below the code which selects the data variable carbonmonoxide_total_column from the xarray.Dataset file and call it s5p_co<jupyter_code># Enter your solution here
s




s5p_co = file['carbonmonoxide_total_column']
s5p_co<jupyter_output><empty_output><jupyter_text>Question:    Can you identify the unit of the selected data variable and do you know where it is stored? **Response**:Information about the unit of a data variable is stored as `units` attribute. The unit of **carbonmonoxide_total_column** is `mol m-2`.  You see that the `xarray.DataArray` has three dimensions, with the dimension time only having one entry. Let us select the single time step, in order to have the two-dimensional data array. Coding assignment:   Enter below the code which selects the one time step from the xarray DataArray s5p_co and call it s5p_co_time<jupyter_code># Enter your solution here





s5p_co_time = s5p_co[0,:,:]
s5p_co_time<jupyter_output><empty_output><jupyter_text>3. Load the latitude and longitude information and store some attributes In preparation of plotting, let us store the `latitude` and `longitude` information and some attributes that might be useful later on. Coding assignment:   Enter below the code which selects the longitude and latitude values of the s5p_co_time DataArray and call it latitude and longitude respectively.<jupyter_code># Enter your solution here





latitude = s5p_co_time.latitude
print(latitude)
longitude = s5p_co_time.longitude
print(longitude)<jupyter_output><xarray.DataArray 'latitude' (scanline: 8344, ground_pixel: 215)>
dask.array<getitem, shape=(8344, 215), dtype=float32, chunksize=(4172, 215), chunktype=numpy.ndarray>
Coordinates:
  * scanline      (scanline) float64 0.0 1.0 2.0 ... 4.17e+03 4.171e+03
  * ground_pixel  (ground_pixel) float64 0.0 1.0 2.0 3.0 ... 212.0 213.0 214.0
    time          datetime64[ns] 2019-12-29
    latitude      (scanline, ground_pixel) float32 dask.array<chunksize=(4172, 215), meta=np.ndarray>
    longitude     (scanline, ground_pixel) float32 dask.array<chunksize=(4172, 215), meta=np.ndarray>
Attributes:
    long_name:      pixel center latitude
    units:          degrees_north
    standard_name:  latitude
    valid_min:      -90.0
    valid_max:      90.0
    bounds:         /PRODUCT/SUPPORT_DATA/GEOLOCATIONS/latitude_bounds
<xarray.DataArray 'longitude' (scanline: 8344, ground_pixel: 215)>
dask.array<getitem, shape=(8344, 215), dtype=float32, chunksize=(4172, 215), chunktype=numpy.ndarray>
Coordinates:[...]<jupyter_text>Coding assignment:Enter below the code which selects the following attributes: - units,- long_name, and - multiplication_factor.Call them units, long_name and multiplication_factor respectively.<jupyter_code># Enter your solution here






units = s5p_co_time.units
print(units)
long_name = s5p_co_time.long_name
print(long_name)

multiplication_factor=s5p_co_time.multiplication_factor_to_convert_to_molecules_percm2
print(multiplication_factor)<jupyter_output>mol m-2
Vertically integrated CO column
6.022141e+19<jupyter_text>5. Create a geographical subset for Australia Let us zoom into the region of fire occurence and create a geographical subset for Australia. Coding assignment:Create a geographical subset for Siberia. Make use of the function generate_geographical_subset and call the new DataArray s5p_co_subset.The bounding box information can be the following:- **latmin=-50**- **latmax=-19**- **lonmin=130**- **lonmax=170**HINT: With `?generate_geographical_subset`, you can see what keyword arguments the function requires.<jupyter_code>?generate_geographical_subset
# Enter your solution here






latmin=-50.
latmax=-19.
lonmin=130.
lonmax=170.

s5p_co_subset = generate_geographical_subset(xarray=s5p_co_time,
                                             latmin=latmin,
                                             latmax=latmax,
                                             lonmin=lonmin,
                                             lonmax=lonmax)

s5p_co_subset<jupyter_output><empty_output><jupyter_text>Question:How many entries for `scanline` does the DataArray **s5p_co_subset** have compared to the DataArray **s5p_co_time**? **Response**The scanline entries have reduced from formerly `8344` to now `1462` values.  And now, you can visualize the geographical subset. Make use of the function [visualize_pcolormesh](../functions.ipynbvisualize_pcolormesh). Coding assignment:Make use of the function [visualize_pcolormesh](../functions.ipynbvisualize_pcolormesh) in order to visualize the subsetted DataArray s5p_co_subset.     The following kwargs have to be defined:* `data_array`* `longitude`* `latitude`* `projection`* `color_sale`* `unit`* `longname`* `vmin`,* `vmax`,* `lonmin`, `lonmax`, `latmin`, `latmax`* `set_global`<jupyter_code># Enter your solution here






visualize_pcolormesh(data_array=s5p_co_subset,
                     longitude=s5p_co_subset.longitude,
                     latitude=s5p_co_subset.latitude,
                     projection=ccrs.PlateCarree(),
                     color_scale='viridis',
                     unit=units,
                     long_name=long_name,
                     vmin=0, 
                     vmax=0.2,
                     lonmin=lonmin,
                     lonmax=lonmax,
                     latmin=latmin,
                     latmax=latmax,
                     set_global=False)<jupyter_output><empty_output><jupyter_text>6. Convert the CO values from `mol per m-2` to `molecules per cm-2` Sentinel-5P data are disseminated in `SI units` and the `SI unit` for the total column of carbon monoxide is `mol per m``2`. A more common unit is `molecules per cm``2` though. Let us convert the values from `mol per m``2` to `molecules per cm``2` with the help of the defined `multiplication factor` you have defined before. Coding assignment:Convert the data values of the subsetted DataArray to `molecules per cm``2` by multiplying the DataArray with the multiplication_factor.You might want to store the multiplication facor attribute as separate variable.NOTE:The multiplication factor is provided in the attributes of the DataArray **s5p_co_subset**.<jupyter_code># Enter your solution here







multiplication_factor = s5p_co_subset.multiplication_factor_to_convert_to_molecules_percm2
print(multiplication_factor)

s5p_co_subset_converted = s5p_co_subset*multiplication_factor
print(s5p_co_subset_converted)<jupyter_output>6.022141e+19
<xarray.DataArray 'carbonmonoxide_total_column' (scanline: 1462, ground_pixel: 215)>
dask.array<mul, shape=(1462, 215), dtype=float32, chunksize=(768, 215), chunktype=numpy.ndarray>
Coordinates:
  * scanline      (scanline) float64 1.523e+03 1.524e+03 ... 2.192e+03 2.193e+03
  * ground_pixel  (ground_pixel) float64 0.0 1.0 2.0 3.0 ... 212.0 213.0 214.0
    time          datetime64[ns] 2019-12-29
    latitude      (scanline, ground_pixel) float32 dask.array<chunksize=(694, 215), meta=np.ndarray>
    longitude     (scanline, ground_pixel) float32 dask.array<chunksize=(694, 215), meta=np.ndarray><jupyter_text>In a final step, we want to visualize the DataArray again, but this time with the data values converted to `molecules per cm``2`. Coding assignment:Visualize the DataArray `s5p_co_subset_converted` with the function [visualize_pcolormesh](../functions.ipynbvisualize_pcolormesh).HINT:You might need to make adjustments to the following keyword arguments:* **unit*** the **DataArray** itself,* **latitude** and **longitude*** **vmin** and **vmax**<jupyter_code># Enter your solution here







visualize_pcolormesh(data_array=s5p_co_subset_converted * 1e-18,
                     longitude=s5p_co_subset_converted.longitude,
                     latitude=s5p_co_subset_converted.latitude,
                     projection=ccrs.PlateCarree(),
                     color_scale='viridis',
                     unit='*1e-18 molecules per cm2',
                     long_name=long_name,
                     vmin=0, 
                     vmax=10,
                     lonmin=lonmin,
                     lonmax=lonmax,
                     latmin=latmin,
                     latmax=latmax,
                     set_global=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08165718406923632, 'fraction_numerical': 0.03149290808558378, 'mean_word_length': 4.069049553208774, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '117867', 'license': 'MIT', 'n_tokens_mistral': 4026, 'n_tokens_neox': 3607, 'n_words': 1226, 'path': '40_exercises/411_Sentinel-5P_TROPOMI_CO_L2_exercise.ipynb', 'repo_name': 'trivedi-c/atm_Practical3', 'size': '12479'}