Geospatial Averaging#

Example Datasets: Zhu, F. & Zhu, J. Long simulations of the Miocene Climatic Optimum, DOI: 10.5065/3QFN-GN70 (2025). https://rda.ucar.edu/datasets/d010026/.

[1]:
%load_ext autoreload
%autoreload 2

import os
import numpy as np
os.chdir('/glade/u/home/fengzhu/Github/x4c/docsrc/notebooks')
import x4c
print(x4c.__version__)
2025.6.22

Loading a netCDF file as an xarray.Dataset#

The x4c.load_dataset() function is an enhanced version of xarray.load_dataset() for CESM output. The users may specify the component (comp) and grid (grid) information while loading the file.

[ ]:
dirpath = '/glade/campaign/cesm/community/palwg/MCO_LongSims/b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005'
fname = 'b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005.cam.h0.TS.895101-900012.nc'
ds = x4c.load_dataset(
    os.path.join(dirpath, 'atm/proc/tseries/month_1', fname),
    comp='atm',
    grid='ne16np4',
)
ds
<xarray.Dataset> Size: 34MB
Dimensions:       (lev: 30, ilev: 31, ncol: 13826, time: 600, nbnd: 2)
Coordinates:
  * lev           (lev) float64 240B 3.643 7.595 14.36 ... 957.5 976.3 992.6
  * ilev          (ilev) float64 248B 2.255 5.032 10.16 ... 967.5 985.1 1e+03
  * time          (time) object 5kB 8951-02-01 00:00:00 ... 9001-01-01 00:00:00
Dimensions without coordinates: ncol, nbnd
Data variables: (12/31)
    hyam          (lev) float64 240B 0.003643 0.007595 0.01436 ... 0.001989 0.0
    hybm          (lev) float64 240B 0.0 0.0 0.0 0.0 ... 0.9512 0.9743 0.9926
    P0            float64 8B 1e+05
    hyai          (ilev) float64 248B 0.002255 0.005032 0.01016 ... 0.0 0.0
    hybi          (ilev) float64 248B 0.0 0.0 0.0 0.0 ... 0.9636 0.9851 1.0
    lat           (ncol) float64 111kB -35.26 -35.98 -37.07 ... 37.91 36.74
    ...            ...
    n2ovmr        (time) float64 5kB 2.757e-07 2.757e-07 ... 2.757e-07 2.757e-07
    f11vmr        (time) float64 5kB 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    f12vmr        (time) float64 5kB 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    sol_tsi       (time) float64 5kB -1.0 -1.0 -1.0 -1.0 ... -1.0 -1.0 -1.0 -1.0
    nsteph        (time) int32 2kB 156805488 156806832 ... 157678512 157680000
    TS            (time, ncol) float32 33MB 303.9 303.3 302.5 ... 292.6 293.3
Attributes: (12/18)
    np:               4
    ne:               16
    Conventions:      CF-1.0
    source:           CAM
    case:             b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO...
    title:            UNSET
    ...               ...
    path:             /glade/campaign/cesm/community/palwg/MCO_LongSims/b.e13...
    comp:             atm
    grid:             ne16np4
    gw:               <xarray.DataArray 'area' (ncol: 13826)> Size: 111kB\nar...
    lat:              <xarray.DataArray 'lat' (ncol: 13826)> Size: 111kB\narr...
    lon:              <xarray.DataArray 'lon' (ncol: 13826)> Size: 111kB\narr...
[10]:
print(ds.attrs['comp'])
print(ds.attrs['grid'])
print(ds.attrs['path'])
atm
ne16np4
/glade/campaign/cesm/community/palwg/MCO_LongSims/b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005/atm/proc/tseries/month_1/b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005.cam.h0.TS.895101-900012.nc

The loaded dataset has add-on attributes such as comp and grid that are useful for later analysis and visualization. The add-on attribute path is good for file tracking.

Note that the time axis is offset by one month in the raw iCESM1 output, and x4c.load_dataset() provides the option adjust_month=True to fix this issue. This won’t be an issue for CESM2 & 3 outputs.

[6]:
dirpath = '/glade/campaign/cesm/community/palwg/MCO_LongSims/b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005'
fname = 'b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005.cam.h0.TS.895101-900012.nc'
ds = x4c.load_dataset(
    os.path.join(dirpath, 'atm/proc/tseries/month_1', fname),
    comp='atm',
    grid='ne16np4',
    adjust_month=True,
)
ds
[6]:
<xarray.Dataset> Size: 34MB
Dimensions:       (lev: 30, ilev: 31, ncol: 13826, time: 600, nbnd: 2)
Coordinates:
  * lev           (lev) float64 240B 3.643 7.595 14.36 ... 957.5 976.3 992.6
  * ilev          (ilev) float64 248B 2.255 5.032 10.16 ... 967.5 985.1 1e+03
  * time          (time) object 5kB 8951-01-31 00:00:00 ... 9000-12-31 00:00:00
Dimensions without coordinates: ncol, nbnd
Data variables: (12/31)
    hyam          (lev) float64 240B 0.003643 0.007595 0.01436 ... 0.001989 0.0
    hybm          (lev) float64 240B 0.0 0.0 0.0 0.0 ... 0.9512 0.9743 0.9926
    P0            float64 8B 1e+05
    hyai          (ilev) float64 248B 0.002255 0.005032 0.01016 ... 0.0 0.0
    hybi          (ilev) float64 248B 0.0 0.0 0.0 0.0 ... 0.9636 0.9851 1.0
    lat           (ncol) float64 111kB -35.26 -35.98 -37.07 ... 37.91 36.74
    ...            ...
    n2ovmr        (time) float64 5kB 2.757e-07 2.757e-07 ... 2.757e-07 2.757e-07
    f11vmr        (time) float64 5kB 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    f12vmr        (time) float64 5kB 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    sol_tsi       (time) float64 5kB -1.0 -1.0 -1.0 -1.0 ... -1.0 -1.0 -1.0 -1.0
    nsteph        (time) int32 2kB 156805488 156806832 ... 157678512 157680000
    TS            (time, ncol) float32 33MB 303.9 303.3 302.5 ... 292.6 293.3
Attributes: (12/18)
    np:               4
    ne:               16
    Conventions:      CF-1.0
    source:           CAM
    case:             b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO...
    title:            UNSET
    ...               ...
    path:             /glade/campaign/cesm/community/palwg/MCO_LongSims/b.e13...
    comp:             atm
    grid:             ne16np4
    gw:               <xarray.DataArray 'area' (ncol: 13826)> Size: 111kB\nar...
    lat:              <xarray.DataArray 'lat' (ncol: 13826)> Size: 111kB\narr...
    lon:              <xarray.DataArray 'lon' (ncol: 13826)> Size: 111kB\narr...

Geospatial Averaging#

x4c provides geo_mean() for geosptial averaging based on the given latlon_range, leveraging the add-on attribute gw as the weights, which is automatically created while loading the CESM output based on the component and grid information provided by the user.

[19]:
da.x.geo_mean(latlon_range=(-90, 90, 0, 360))
[19]:
<xarray.DataArray 'TS' (time: 600)> Size: 5kB
array([296.16860627, 296.46203748, 297.09469609, 297.59485891,
       297.95926162, 298.6234351 , 299.10125627, 299.08852801,
       298.49119802, 297.55110397, 296.68452308, 296.2498364 ,
       296.54773538, 297.01978869, 297.58764512, 297.99747084,
       298.2507888 , 298.8391296 , 299.23983388, 299.09213968,
       298.43686204, 297.38524448, 296.39325564, 295.58343039,
       295.77977   , 296.52031847, 296.94285375, 297.3576286 ,
       297.81592553, 298.43670997, 298.89024496, 298.77082064,
       298.0444007 , 297.21271238, 296.22355048, 295.72279369,
       295.90895338, 296.60404577, 297.05070794, 297.45165451,
       297.87765839, 298.51489297, 299.09142302, 299.04457161,
       298.36347876, 297.3651331 , 296.55483819, 296.26627823,
       296.47617127, 297.01447052, 297.41547468, 297.77382965,
       298.11188602, 298.72725935, 299.0948921 , 298.99442647,
       298.25064386, 297.37620884, 296.57421889, 295.82445333,
       296.15800348, 296.62280769, 297.14061182, 297.50651454,
       297.99136245, 298.5246584 , 299.04984751, 298.92695308,
       298.31819784, 297.31717609, 296.380258  , 295.91365125,
       296.31723092, 296.64843889, 297.23886846, 297.65831906,
       298.03429836, 298.66560378, 299.0849317 , 298.92305472,
...
       298.14456561, 298.64809189, 299.13048411, 298.96367537,
       298.24651323, 297.22074071, 296.36394192, 295.98814871,
       296.16552529, 296.54215428, 297.17914139, 297.60043659,
       298.05276826, 298.58220107, 299.15931945, 299.02595599,
       298.3678354 , 297.44156937, 296.45728231, 296.0439142 ,
       296.38586211, 296.85866471, 297.2277705 , 297.58272218,
       298.0377194 , 298.67653814, 299.12262889, 299.12360658,
       298.44157249, 297.46767142, 296.45388267, 295.92249286,
       296.14196164, 296.65947139, 297.1241124 , 297.5161505 ,
       297.95922087, 298.43168323, 298.81014285, 298.8183174 ,
       298.17081749, 297.22277869, 296.30321846, 295.87178128,
       295.90683976, 296.35722317, 296.91078382, 297.27972666,
       297.75290153, 298.50044764, 298.98749006, 298.89064277,
       298.33347541, 297.22780811, 296.36685504, 296.1631142 ,
       296.30286457, 297.07099721, 297.52550234, 297.75175365,
       298.058346  , 298.64544721, 298.99794477, 298.87081614,
       298.27798672, 297.25826701, 296.17837978, 295.73374184,
       296.01612641, 296.41009797, 296.90784369, 297.36341704,
       297.90602219, 298.42144086, 298.79841648, 298.71377871,
       298.08224109, 297.14845483, 296.11775075, 295.70135667])
Coordinates:
  * time     (time) object 5kB 8951-01-31 00:00:00 ... 9000-12-31 00:00:00
Attributes:
    units:         K
    long_name:     Surface temperature (radiative)
    cell_methods:  time: mean
    path:          /glade/campaign/cesm/community/palwg/MCO_LongSims/b.e13.B1...
    gw:            <xarray.DataArray 'area' (ncol: 13826)> Size: 111kB\narray...
    lat:           <xarray.DataArray 'lat' (ncol: 13826)> Size: 111kB\narray(...
    lon:           <xarray.DataArray 'lon' (ncol: 13826)> Size: 111kB\narray(...
    comp:          atm
    grid:          ne16np4