Weights¶
In this notebook we demonstrate all of netCDF-SCM’s known weightings. These weights are used when taking area overages for different SCM boxes e.g. the ocean/land boxes or the El Nino box.
Note: here we use the “last resort” land surface fraction values. However, if land surface fraction data is available then that is used to do land/ocean weighting rather than the “last resort” values.
This notebook is set out as follows:
we show the default weights
we show how the different available options for combining area and surface fraction information
we show all our inbuilt weights
we show how the user can define their own custom weights.
Imports¶
[1]:
# NBVAL_IGNORE_OUTPUT
from os.path import join
import iris
import iris.quickplot as qplt
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import regionmask
from netcdf_scm.iris_cube_wrappers import CMIP6OutputCube
from netcdf_scm.weights import (
AreaSurfaceFractionWeightCalculator,
AreaWeightCalculator,
get_weights_for_area,
WEIGHTS_FUNCTIONS_WITHOUT_AREA_WEIGHTING,
)
[2]:
plt.style.use("bmh")
%matplotlib inline
Data path¶
Here we use our test data.
[3]:
DATA_PATH_TEST = join("..", "..", "..", "tests", "test-data")
DATA_PATH_TEST_CMIP6_ROOT = join(DATA_PATH_TEST, "cmip6output")
Load the cube¶
[4]:
example = CMIP6OutputCube()
example.load_data_in_directory(
join(
DATA_PATH_TEST_CMIP6_ROOT,
# "CMIP6/ScenarioMIP/BCC/BCC-CSM2-MR/ssp126/r1i1p1f1/Amon/example/gn/v20190314",
"CMIP6/CMIP/NCAR/CESM2/historical/r10i1p1f1/Amon/tas/gn/v20190313",
)
)
Interpolate the cube to get higher resolution data.
[5]:
sample_points = [
("longitude", np.arange(0, 360, 2)),
("latitude", np.arange(-90, 90 + 1, 2)),
]
example.cube = example.cube.interpolate(sample_points, iris.analysis.Linear())
Weights¶
Default weights¶
By default, only land/ocean and hemispheric weights are considered.
[6]:
# NBVAL_IGNORE_OUTPUT
default_weights = example.get_scm_timeseries_weights()
/Users/znicholls/miniconda3/envs/netcdf-scm/lib/python3.9/site-packages/iris/analysis/cartography.py:394: UserWarning: Using DEFAULT_SPHERICAL_EARTH_RADIUS.
warnings.warn("Using DEFAULT_SPHERICAL_EARTH_RADIUS.")
[7]:
# NBVAL_IGNORE_OUTPUT
def plot_weights(weights_to_plot, constraint=None, axes=None, **kwargs):
for i, (label, weights) in enumerate(weights_to_plot.items()):
if axes is None:
ax = plt.figure().add_subplot(111)
else:
ax = axes[i]
weight_cube = example.cube.collapsed("time", iris.analysis.MEAN)
weight_cube.data = weights
weight_cube.units = ""
if constraint is not None:
weight_cube = weight_cube.extract(constraint)
plt.sca(ax)
qplt.pcolormesh(
weight_cube, **kwargs,
)
plt.gca().set_title(label)
plt.gca().coastlines()
plot_weights(default_weights)
Area and surface fraction combination options¶
By defaults, the weights are calculated as the combination of area and surface fractions using netcdf_scm.weights.AreaSurfaceFractionWeightCalculator
.
[8]:
# NBVAL_IGNORE_OUTPUT
print(AreaSurfaceFractionWeightCalculator.__doc__)
Calculates weights which are both area and surface fraction weighted
.. math::
w(lat, lon) = a(lat, lon) \\times s(lat, lon)
where :math:`w(lat, lon)` is the weight of the cell at given latitude and
longitude, :math:`a` is area of the cell and :math:`s` is the surface
fraction of the cell (e.g. fraction of ocean area for ocean based regions).
For land/ocean weights, this causes regions on coastlines to have weights less than their area weight, because they are not fully land or ocean.
The user can instead use netcdf_scm.weights.AreaWeightCalculator
, which focusses on area weights but removes any areas that have a surface fraction of zero.
[9]:
# NBVAL_IGNORE_OUTPUT
print(AreaWeightCalculator.__doc__)
Calculates weights which are area weighted but surface fraction aware.
This means that any cells which have a surface fraction of zero will
receive zero weight, otherwise cells are purely area weighted.
.. math::
w(lat, lon) = \\begin{cases}
a(lat, lon), & s(lat, lon) > 0 \\\\
0, & s(lat, lon) = 0
\\end{cases}
where :math:`w(lat, lon)` is the weight of the cell at given latitude and
longitude, :math:`a` is area of the cell and :math:`s` is the surface
fraction of the cell (e.g. fraction of ocean area for ocean based regions).
[10]:
# NBVAL_IGNORE_OUTPUT
area_weights = example.get_scm_timeseries_weights(cell_weights="area-only")
/Users/znicholls/miniconda3/envs/netcdf-scm/lib/python3.9/site-packages/iris/analysis/cartography.py:394: UserWarning: Using DEFAULT_SPHERICAL_EARTH_RADIUS.
warnings.warn("Using DEFAULT_SPHERICAL_EARTH_RADIUS.")
[11]:
# NBVAL_IGNORE_OUTPUT
fig, axes = plt.subplots(figsize=(16, 9), nrows=2, ncols=2)
for i, (w, title) in enumerate(
((default_weights, "Default"), (area_weights, "No land fraction"))
):
plt_weights = {k: w[k] for k in ["World|Ocean", "World|Land"]}
zoom_constraint = iris.Constraint(
latitude=lambda cell: -45 < cell < -25
) & iris.Constraint(longitude=lambda cell: 120 < cell < 160)
plot_weights(
plt_weights, constraint=zoom_constraint, axes=[axes[0][i], axes[1][i]],
)
cf = plt.gcf()
for i, (w, title) in enumerate(
((default_weights, "Default"), (area_weights, "Area only"))
):
title_ax = cf.axes[i * 4]
title_ax.set_title("{}\n{}".format(title, title_ax.get_title()))
All inbuilt masks¶
The default masks do not contain all inbuilt masks. We also provide masks for the IPCC AR6 regions, as defined in Iturbide et al. (2020), as well as country-level (at the 50m scale) masks defined by Natural Earth. For both these masks, we use the regionmask implementation.
The regionmask names can be inspected as shown below. Not that the abbreviations for the countries are not unique.
[12]:
regionmask_countries = (
pd.DataFrame(
{
"name": regionmask.defined_regions.natural_earth.countries_50.names,
"abbreviation": regionmask.defined_regions.natural_earth.countries_50.abbrevs,
}
)
.sort_values(by="name")
.reset_index(drop=True)
)
regionmask_countries
[12]:
name | abbreviation | |
---|---|---|
0 | Afghanistan | AF |
1 | Albania | AL |
2 | Algeria | DZ |
3 | American Samoa | AS |
4 | Andorra | AND |
... | ... | ... |
236 | Yemen | YE |
237 | Zambia | ZM |
238 | Zimbabwe | ZW |
239 | eSwatini | SW |
240 | Åland | AI |
241 rows × 2 columns
Below we show a selection of plots for the regions we include.
[13]:
selection_inbuilt_weights = example.get_scm_timeseries_weights(
regions=[
"World",
"World|Northern Hemisphere",
"World|Southern Hemisphere",
"World|Land",
"World|Ocean",
"World|Northern Hemisphere|Land",
"World|Southern Hemisphere|Land",
"World|Northern Hemisphere|Ocean",
"World|Southern Hemisphere|Ocean",
"World|North Atlantic Ocean",
"World|El Nino N3.4",
"World|AR6|GIC",
"World|AR6|NWN",
"World|AR6|NEN",
"World|AR6|WNA",
"World|AR6|SSA",
"World|AR6|NEU",
]
+ [
"World|Natural Earth 50m|{}".format(c)
for c in [
"Australia",
"Austria",
"China",
"New Zealand",
"United States of America",
# this fails as the region is tiny and
# our data is not high-resolution enough to capture it
"Vatican",
"Vietnam",
]
]
)
/Users/znicholls/Documents/AGCEC/netCDF-SCM/netcdf-scm/src/netcdf_scm/weights/__init__.py:869: UserWarning: Failed to create 'World|Natural Earth 50m|Vatican' weights: All weights are zero for region: `World|Natural Earth 50m|Vatican`
warnings.warn(warn_str)
[14]:
# NBVAL_IGNORE_OUTPUT
plot_weights(selection_inbuilt_weights)
<ipython-input-7-e10806626a7c>:5: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
ax = plt.figure().add_subplot(111)
[15]:
# full list of available regions
sorted(list(WEIGHTS_FUNCTIONS_WITHOUT_AREA_WEIGHTING.keys()))
[15]:
['World',
'World|AR6|ARO',
'World|AR6|ARP',
'World|AR6|ARS',
'World|AR6|BOB',
'World|AR6|CAF',
'World|AR6|CAR',
'World|AR6|CAU',
'World|AR6|CNA',
'World|AR6|EAN',
'World|AR6|EAO',
'World|AR6|EAS',
'World|AR6|EAU',
'World|AR6|ECA',
'World|AR6|EEU',
'World|AR6|EIO',
'World|AR6|ENA',
'World|AR6|EPO',
'World|AR6|ESAF',
'World|AR6|ESB',
'World|AR6|GIC',
'World|AR6|MDG',
'World|AR6|MED',
'World|AR6|NAO',
'World|AR6|NAU',
'World|AR6|NCA',
'World|AR6|NEAF',
'World|AR6|NEN',
'World|AR6|NES',
'World|AR6|NEU',
'World|AR6|NPO',
'World|AR6|NSA',
'World|AR6|NWN',
'World|AR6|NWS',
'World|AR6|NZ',
'World|AR6|RAR',
'World|AR6|RFE',
'World|AR6|SAH',
'World|AR6|SAM',
'World|AR6|SAO',
'World|AR6|SAS',
'World|AR6|SAU',
'World|AR6|SCA',
'World|AR6|SEA',
'World|AR6|SEAF',
'World|AR6|SES',
'World|AR6|SIO',
'World|AR6|SOO',
'World|AR6|SPO',
'World|AR6|SSA',
'World|AR6|SWS',
'World|AR6|TIB',
'World|AR6|WAF',
'World|AR6|WAN',
'World|AR6|WCA',
'World|AR6|WCE',
'World|AR6|WNA',
'World|AR6|WSAF',
'World|AR6|WSB',
'World|El Nino N3.4',
'World|Land',
'World|Natural Earth 50m|Afghanistan',
'World|Natural Earth 50m|Albania',
'World|Natural Earth 50m|Algeria',
'World|Natural Earth 50m|American Samoa',
'World|Natural Earth 50m|Andorra',
'World|Natural Earth 50m|Angola',
'World|Natural Earth 50m|Anguilla',
'World|Natural Earth 50m|Antarctica',
'World|Natural Earth 50m|Antigua and Barb.',
'World|Natural Earth 50m|Argentina',
'World|Natural Earth 50m|Armenia',
'World|Natural Earth 50m|Aruba',
'World|Natural Earth 50m|Ashmore and Cartier Is.',
'World|Natural Earth 50m|Australia',
'World|Natural Earth 50m|Austria',
'World|Natural Earth 50m|Azerbaijan',
'World|Natural Earth 50m|Bahamas',
'World|Natural Earth 50m|Bahrain',
'World|Natural Earth 50m|Bangladesh',
'World|Natural Earth 50m|Barbados',
'World|Natural Earth 50m|Belarus',
'World|Natural Earth 50m|Belgium',
'World|Natural Earth 50m|Belize',
'World|Natural Earth 50m|Benin',
'World|Natural Earth 50m|Bermuda',
'World|Natural Earth 50m|Bhutan',
'World|Natural Earth 50m|Bolivia',
'World|Natural Earth 50m|Bosnia and Herz.',
'World|Natural Earth 50m|Botswana',
'World|Natural Earth 50m|Br. Indian Ocean Ter.',
'World|Natural Earth 50m|Brazil',
'World|Natural Earth 50m|British Virgin Is.',
'World|Natural Earth 50m|Brunei',
'World|Natural Earth 50m|Bulgaria',
'World|Natural Earth 50m|Burkina Faso',
'World|Natural Earth 50m|Burundi',
'World|Natural Earth 50m|Cabo Verde',
'World|Natural Earth 50m|Cambodia',
'World|Natural Earth 50m|Cameroon',
'World|Natural Earth 50m|Canada',
'World|Natural Earth 50m|Cayman Is.',
'World|Natural Earth 50m|Central African Rep.',
'World|Natural Earth 50m|Chad',
'World|Natural Earth 50m|Chile',
'World|Natural Earth 50m|China',
'World|Natural Earth 50m|Colombia',
'World|Natural Earth 50m|Comoros',
'World|Natural Earth 50m|Congo',
'World|Natural Earth 50m|Cook Is.',
'World|Natural Earth 50m|Costa Rica',
'World|Natural Earth 50m|Croatia',
'World|Natural Earth 50m|Cuba',
'World|Natural Earth 50m|Curaçao',
'World|Natural Earth 50m|Cyprus',
'World|Natural Earth 50m|Czechia',
"World|Natural Earth 50m|Côte d'Ivoire",
'World|Natural Earth 50m|Dem. Rep. Congo',
'World|Natural Earth 50m|Denmark',
'World|Natural Earth 50m|Djibouti',
'World|Natural Earth 50m|Dominica',
'World|Natural Earth 50m|Dominican Rep.',
'World|Natural Earth 50m|Ecuador',
'World|Natural Earth 50m|Egypt',
'World|Natural Earth 50m|El Salvador',
'World|Natural Earth 50m|Eq. Guinea',
'World|Natural Earth 50m|Eritrea',
'World|Natural Earth 50m|Estonia',
'World|Natural Earth 50m|Ethiopia',
'World|Natural Earth 50m|Faeroe Is.',
'World|Natural Earth 50m|Falkland Is.',
'World|Natural Earth 50m|Fiji',
'World|Natural Earth 50m|Finland',
'World|Natural Earth 50m|Fr. Polynesia',
'World|Natural Earth 50m|Fr. S. Antarctic Lands',
'World|Natural Earth 50m|France',
'World|Natural Earth 50m|Gabon',
'World|Natural Earth 50m|Gambia',
'World|Natural Earth 50m|Georgia',
'World|Natural Earth 50m|Germany',
'World|Natural Earth 50m|Ghana',
'World|Natural Earth 50m|Greece',
'World|Natural Earth 50m|Greenland',
'World|Natural Earth 50m|Grenada',
'World|Natural Earth 50m|Guam',
'World|Natural Earth 50m|Guatemala',
'World|Natural Earth 50m|Guernsey',
'World|Natural Earth 50m|Guinea',
'World|Natural Earth 50m|Guinea-Bissau',
'World|Natural Earth 50m|Guyana',
'World|Natural Earth 50m|Haiti',
'World|Natural Earth 50m|Heard I. and McDonald Is.',
'World|Natural Earth 50m|Honduras',
'World|Natural Earth 50m|Hong Kong',
'World|Natural Earth 50m|Hungary',
'World|Natural Earth 50m|Iceland',
'World|Natural Earth 50m|India',
'World|Natural Earth 50m|Indian Ocean Ter.',
'World|Natural Earth 50m|Indonesia',
'World|Natural Earth 50m|Iran',
'World|Natural Earth 50m|Iraq',
'World|Natural Earth 50m|Ireland',
'World|Natural Earth 50m|Isle of Man',
'World|Natural Earth 50m|Israel',
'World|Natural Earth 50m|Italy',
'World|Natural Earth 50m|Jamaica',
'World|Natural Earth 50m|Japan',
'World|Natural Earth 50m|Jersey',
'World|Natural Earth 50m|Jordan',
'World|Natural Earth 50m|Kazakhstan',
'World|Natural Earth 50m|Kenya',
'World|Natural Earth 50m|Kiribati',
'World|Natural Earth 50m|Kosovo',
'World|Natural Earth 50m|Kuwait',
'World|Natural Earth 50m|Kyrgyzstan',
'World|Natural Earth 50m|Laos',
'World|Natural Earth 50m|Latvia',
'World|Natural Earth 50m|Lebanon',
'World|Natural Earth 50m|Lesotho',
'World|Natural Earth 50m|Liberia',
'World|Natural Earth 50m|Libya',
'World|Natural Earth 50m|Liechtenstein',
'World|Natural Earth 50m|Lithuania',
'World|Natural Earth 50m|Luxembourg',
'World|Natural Earth 50m|Macao',
'World|Natural Earth 50m|Macedonia',
'World|Natural Earth 50m|Madagascar',
'World|Natural Earth 50m|Malawi',
'World|Natural Earth 50m|Malaysia',
'World|Natural Earth 50m|Maldives',
'World|Natural Earth 50m|Mali',
'World|Natural Earth 50m|Malta',
'World|Natural Earth 50m|Marshall Is.',
'World|Natural Earth 50m|Mauritania',
'World|Natural Earth 50m|Mauritius',
'World|Natural Earth 50m|Mexico',
'World|Natural Earth 50m|Micronesia',
'World|Natural Earth 50m|Moldova',
'World|Natural Earth 50m|Monaco',
'World|Natural Earth 50m|Mongolia',
'World|Natural Earth 50m|Montenegro',
'World|Natural Earth 50m|Montserrat',
'World|Natural Earth 50m|Morocco',
'World|Natural Earth 50m|Mozambique',
'World|Natural Earth 50m|Myanmar',
'World|Natural Earth 50m|N. Cyprus',
'World|Natural Earth 50m|N. Mariana Is.',
'World|Natural Earth 50m|Namibia',
'World|Natural Earth 50m|Nauru',
'World|Natural Earth 50m|Nepal',
'World|Natural Earth 50m|Netherlands',
'World|Natural Earth 50m|New Caledonia',
'World|Natural Earth 50m|New Zealand',
'World|Natural Earth 50m|Nicaragua',
'World|Natural Earth 50m|Niger',
'World|Natural Earth 50m|Nigeria',
'World|Natural Earth 50m|Niue',
'World|Natural Earth 50m|Norfolk Island',
'World|Natural Earth 50m|North Korea',
'World|Natural Earth 50m|Norway',
'World|Natural Earth 50m|Oman',
'World|Natural Earth 50m|Pakistan',
'World|Natural Earth 50m|Palau',
'World|Natural Earth 50m|Palestine',
'World|Natural Earth 50m|Panama',
'World|Natural Earth 50m|Papua New Guinea',
'World|Natural Earth 50m|Paraguay',
'World|Natural Earth 50m|Peru',
'World|Natural Earth 50m|Philippines',
'World|Natural Earth 50m|Pitcairn Is.',
'World|Natural Earth 50m|Poland',
'World|Natural Earth 50m|Portugal',
'World|Natural Earth 50m|Puerto Rico',
'World|Natural Earth 50m|Qatar',
'World|Natural Earth 50m|Romania',
'World|Natural Earth 50m|Russia',
'World|Natural Earth 50m|Rwanda',
'World|Natural Earth 50m|S. Geo. and the Is.',
'World|Natural Earth 50m|S. Sudan',
'World|Natural Earth 50m|Saint Helena',
'World|Natural Earth 50m|Saint Lucia',
'World|Natural Earth 50m|Samoa',
'World|Natural Earth 50m|San Marino',
'World|Natural Earth 50m|Saudi Arabia',
'World|Natural Earth 50m|Senegal',
'World|Natural Earth 50m|Serbia',
'World|Natural Earth 50m|Seychelles',
'World|Natural Earth 50m|Siachen Glacier',
'World|Natural Earth 50m|Sierra Leone',
'World|Natural Earth 50m|Singapore',
'World|Natural Earth 50m|Sint Maarten',
'World|Natural Earth 50m|Slovakia',
'World|Natural Earth 50m|Slovenia',
'World|Natural Earth 50m|Solomon Is.',
'World|Natural Earth 50m|Somalia',
'World|Natural Earth 50m|Somaliland',
'World|Natural Earth 50m|South Africa',
'World|Natural Earth 50m|South Korea',
'World|Natural Earth 50m|Spain',
'World|Natural Earth 50m|Sri Lanka',
'World|Natural Earth 50m|St-Barthélemy',
'World|Natural Earth 50m|St-Martin',
'World|Natural Earth 50m|St. Kitts and Nevis',
'World|Natural Earth 50m|St. Pierre and Miquelon',
'World|Natural Earth 50m|St. Vin. and Gren.',
'World|Natural Earth 50m|Sudan',
'World|Natural Earth 50m|Suriname',
'World|Natural Earth 50m|Sweden',
'World|Natural Earth 50m|Switzerland',
'World|Natural Earth 50m|Syria',
'World|Natural Earth 50m|São Tomé and Principe',
'World|Natural Earth 50m|Taiwan',
'World|Natural Earth 50m|Tajikistan',
'World|Natural Earth 50m|Tanzania',
'World|Natural Earth 50m|Thailand',
'World|Natural Earth 50m|Timor-Leste',
'World|Natural Earth 50m|Togo',
'World|Natural Earth 50m|Tonga',
'World|Natural Earth 50m|Trinidad and Tobago',
'World|Natural Earth 50m|Tunisia',
'World|Natural Earth 50m|Turkey',
'World|Natural Earth 50m|Turkmenistan',
'World|Natural Earth 50m|Turks and Caicos Is.',
'World|Natural Earth 50m|U.S. Virgin Is.',
'World|Natural Earth 50m|Uganda',
'World|Natural Earth 50m|Ukraine',
'World|Natural Earth 50m|United Arab Emirates',
'World|Natural Earth 50m|United Kingdom',
'World|Natural Earth 50m|United States of America',
'World|Natural Earth 50m|Uruguay',
'World|Natural Earth 50m|Uzbekistan',
'World|Natural Earth 50m|Vanuatu',
'World|Natural Earth 50m|Vatican',
'World|Natural Earth 50m|Venezuela',
'World|Natural Earth 50m|Vietnam',
'World|Natural Earth 50m|W. Sahara',
'World|Natural Earth 50m|Wallis and Futuna Is.',
'World|Natural Earth 50m|Yemen',
'World|Natural Earth 50m|Zambia',
'World|Natural Earth 50m|Zimbabwe',
'World|Natural Earth 50m|eSwatini',
'World|Natural Earth 50m|Åland',
'World|North Atlantic Ocean',
'World|Northern Hemisphere',
'World|Northern Hemisphere|Land',
'World|Northern Hemisphere|Ocean',
'World|Ocean',
'World|Southern Hemisphere',
'World|Southern Hemisphere|Land',
'World|Southern Hemisphere|Ocean']
User-defined masks¶
As a user, you can also define weights. Simply add them to netcdf_scm.WEIGHTS_FUNCTIONS_WITHOUT_AREA_WEIGHTING.WEIGHTS_FUNCTIONS_WITHOUT_AREA_WEIGHTING
and then use them in your get_scm_cubes
call.
[16]:
WEIGHTS_FUNCTIONS_WITHOUT_AREA_WEIGHTING["custom mask"] = get_weights_for_area(
-60, 100, -10, 330
)
WEIGHTS_FUNCTIONS_WITHOUT_AREA_WEIGHTING[
"Northern Atlantic area bounds"
] = get_weights_for_area(0, -80, 65, 0)
[17]:
custom_weights = example.get_scm_timeseries_weights(
regions=[
"World|El Nino N3.4",
"custom mask",
"World|Land",
"Northern Atlantic area bounds",
]
)
[18]:
plot_weights(custom_weights)