From c45588fb9ac749f31dc831bc3533493bf85846bc Mon Sep 17 00:00:00 2001 From: Mattia Almansi Date: Thu, 1 Feb 2024 19:18:45 +0100 Subject: [PATCH] bias maps --- .../cmip6_sea_ice_thickness_bias_maps.ipynb | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 notebooks/wp4/cmip6_sea_ice_thickness_bias_maps.ipynb diff --git a/notebooks/wp4/cmip6_sea_ice_thickness_bias_maps.ipynb b/notebooks/wp4/cmip6_sea_ice_thickness_bias_maps.ipynb new file mode 100644 index 0000000..38c4c52 --- /dev/null +++ b/notebooks/wp4/cmip6_sea_ice_thickness_bias_maps.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "767f05ef", + "metadata": {}, + "source": [ + "## CMIP6 sea ice thickness bias" + ] + }, + { + "cell_type": "markdown", + "id": "4dfe1c7f", + "metadata": {}, + "source": [ + "## Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51de2ed2-daed-4360-9ec1-b14eacad4608", + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "\n", + "import cartopy.crs as ccrs\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import xarray as xr\n", + "from c3s_eqc_automatic_quality_control import diagnostics, download, plot\n", + "\n", + "plt.style.use(\"seaborn-v0_8-notebook\")\n", + "warnings.filterwarnings(\"ignore\", module=\"cf_xarray\")" + ] + }, + { + "cell_type": "markdown", + "id": "8bc4ee9d", + "metadata": {}, + "source": [ + "## Set parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c2fc4017-d3b8-4daf-8f20-effa7e7bc2b2", + "metadata": {}, + "outputs": [], + "source": [ + "year_start = 2002\n", + "year_stop = 2014\n", + "assert year_start >= 2002 and year_stop <= 2014\n", + "\n", + "# Choose CMIP6 historical models\n", + "models = [\n", + " \"access_cm2\",\n", + " \"access_esm1_5\",\n", + " \"canesm5\",\n", + " \"cmcc_cm2_sr5\",\n", + " \"cmcc_esm2\",\n", + " \"cnrm_cm6_1\",\n", + " \"cnrm_cm6_1_hr\",\n", + " \"cnrm_esm2_1\",\n", + " \"e3sm_1_0\",\n", + " \"e3sm_1_1\",\n", + " \"e3sm_1_1_eca\",\n", + " \"ec_earth3_aerchem\",\n", + " \"ec_earth3_cc\",\n", + " \"ec_earth3_veg_lr\",\n", + " \"hadgem3_gc31_ll\",\n", + " \"ipsl_cm5a2_inca\",\n", + " \"ipsl_cm6a_lr\",\n", + " \"miroc6\",\n", + " \"miroc_es2l\",\n", + " \"mpi_esm1_2_hr\",\n", + " \"mpi_esm1_2_lr\",\n", + " \"nesm3\",\n", + " \"norcpm1\",\n", + " # \"taiesm1\", # very large values\n", + " \"ukesm1_0_ll\",\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "15f1a9a1", + "metadata": {}, + "source": [ + "## Define request" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4fab90a8-b9ad-4e86-a4dc-be51e749b6b7", + "metadata": {}, + "outputs": [], + "source": [ + "months = [f\"{month:02d}\" for month in [1, 2, 3, 4, 10, 11, 12]]\n", + "year_ranges = {\n", + " \"envisat\": range(max(2002, year_start), min(2010, year_stop) + 1),\n", + " \"cryosat_2\": range(max(2010, year_start), min(2020, year_stop) + 1),\n", + "}\n", + "collection_id_satellite = \"satellite-sea-ice-thickness\"\n", + "request_satellite = {\n", + " \"version\": \"2_0\",\n", + " \"cdr_type\": \"cdr\",\n", + " \"variable\": \"all\",\n", + " \"month\": months,\n", + "}\n", + "\n", + "collection_id_cmip6 = \"projections-cmip6\"\n", + "request_cmip6 = {\n", + " \"format\": \"zip\",\n", + " \"temporal_resolution\": \"monthly\",\n", + " \"experiment\": \"historical\",\n", + " \"variable\": \"sea_ice_thickness\",\n", + " \"month\": months,\n", + "}\n", + "\n", + "chunks = {\"year\": 1}" + ] + }, + { + "cell_type": "markdown", + "id": "2b1b4a55", + "metadata": {}, + "source": [ + "## Define function to cache" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d1c76126-b244-48d1-86b7-21310a695647", + "metadata": {}, + "outputs": [], + "source": [ + "def regridded_time_weighted_mean(ds, times, **kwargs):\n", + " ds_sat = download.download_and_transform(\n", + " \"satellite-sea-ice-thickness\",\n", + " {\n", + " \"satellite\": \"envisat\",\n", + " \"version\": \"2_0\",\n", + " \"cdr_type\": \"cdr\",\n", + " \"variable\": \"all\",\n", + " \"year\": \"2002\",\n", + " \"month\": [f\"{month:02d}\" for month in [1, 2, 3, 4, 10, 11, 12]],\n", + " },\n", + " chunks={\"year\": 1},\n", + " )\n", + " ds[\"time\"] = pd.to_datetime(ds[\"time\"].dt.strftime(\"%Y-%m\"))\n", + " ds[\"time\"].attrs[\"standard_name\"] = \"time\"\n", + " ds = ds.sel(time=times)\n", + " ds = diagnostics.time_weighted_mean(ds)\n", + " return diagnostics.regrid(ds, ds_sat[[\"latitude\", \"longitude\"]], **kwargs)" + ] + }, + { + "cell_type": "markdown", + "id": "1591e857", + "metadata": {}, + "source": [ + "## Download and transform" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe14c6bc-da5d-4cdf-864f-26acc1ceb4dd", + "metadata": {}, + "outputs": [], + "source": [ + "datasets_satellites = []\n", + "datasets_cmip6 = []\n", + "for satellite, year_range in year_ranges.items():\n", + " print(f\"{satellite=}\")\n", + " years = list(map(str, year_range))\n", + " ds = download.download_and_transform(\n", + " collection_id_satellite,\n", + " request_satellite | {\"satellite\": satellite, \"year\": years},\n", + " chunks=chunks,\n", + " )\n", + " times = ds[\"time\"].dt.strftime(\"%Y-%m\").values.tolist()\n", + " ds = diagnostics.time_weighted_mean(ds)\n", + " datasets_satellites.append(\n", + " ds.expand_dims(satellite=[satellite], product=[\"satellite\"])\n", + " )\n", + "\n", + " model_datasets = []\n", + " for model in models:\n", + " print(f\"{satellite=} {model=}\")\n", + " ds = download.download_and_transform(\n", + " collection_id_cmip6,\n", + " request_cmip6 | {\"model\": model, \"year\": years},\n", + " chunks=chunks,\n", + " transform_chunks=False,\n", + " transform_func=regridded_time_weighted_mean,\n", + " transform_func_kwargs={\n", + " \"times\": times,\n", + " \"method\": \"nearest_s2d\",\n", + " \"periodic\": True,\n", + " \"ignore_degenerate\": True,\n", + " },\n", + " )\n", + " model_datasets.append(\n", + " ds.expand_dims(model=[model], satellite=[satellite], product=[\"cmip6\"])\n", + " )\n", + " datasets_cmip6.append(\n", + " xr.concat(model_datasets, \"model\").mean(\"model\", keep_attrs=True)\n", + " )\n", + "ds_satellites = xr.concat(datasets_satellites, \"satellite\")\n", + "ds_cmip6 = xr.concat(datasets_cmip6, \"satellite\")" + ] + }, + { + "cell_type": "markdown", + "id": "cec1f783", + "metadata": {}, + "source": [ + "## Plot maps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d97f2e93-a02e-4bad-b5ce-061f0e20f994", + "metadata": {}, + "outputs": [], + "source": [ + "projection = ccrs.Stereographic(central_latitude=90)\n", + "\n", + "biases = []\n", + "for satellite, ds_satellite in ds_satellites.groupby(\"satellite\"):\n", + " da_satellite = ds_satellite[\"sea_ice_thickness\"]\n", + " da_cmip6 = ds_cmip6.sel(satellite=[satellite])[\"sithick\"]\n", + " da = xr.concat([da_satellite, da_cmip6], \"product\")\n", + " facet = plot.projected_map(\n", + " da, col=\"product\", vmin=0, robust=True, projection=projection\n", + " )\n", + " facet.fig.suptitle(satellite, y=1.05)\n", + "\n", + " with xr.set_options(keep_attrs=True):\n", + " bias = da_cmip6.squeeze(\"product\") - da_satellite.squeeze(\"product\")\n", + " bias.attrs[\"long_name\"] = \"Bias of \" + bias.attrs[\"long_name\"]\n", + " biases.append(bias)\n", + "\n", + "bias = xr.concat(biases, \"satellite\")\n", + "plot.projected_map(bias, col=\"satellite\", projection=projection, robust=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}