Annualize CESM output with flexible months

Contents

Annualize CESM output with flexible months#

[1]:
%load_ext autoreload
%autoreload 2

import os
os.chdir('/glade/u/home/fengzhu/Github/x4c/docsrc/notebooks')
import x4c
print(x4c.__version__)
2024.4.13

ATM#

Note that with adjust_month=False, the default output from CESM is offset by one month.

[3]:
dirpath = '/glade/campaign/univ/ubrn0018/fengzhu/CESM_output/timeseries/b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005/atm/proc/tseries/month_1'
fname = 'b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO2.005.cam.h0.TS.695101-700012.nc'
ds = x4c.load_dataset(os.path.join(dirpath, fname), comp='atm', grid='ne16', adjust_month=False)
ds
[3]:
<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 6951-02-01 00:00:00 ... 7001-01-01 00:00:00
Dimensions without coordinates: ncol, nbnd
Data variables: (12/32)
    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
    ...            ...
    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 121765488 121766832 ... 122638512 122640000
    TS            (time, ncol) float32 33MB 303.3 302.6 301.7 ... 293.7 294.3
    gw            (ncol) float64 111kB 0.0001546 0.000515 ... 0.00129 0.001289
Attributes: (12/14)
    np:               4
    ne:               16
    Conventions:      CF-1.0
    source:           /glade/campaign/univ/ubrn0018/fengzhu/CESM_output/times...
    case:             b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO...
    title:            UNSET
    ...               ...
    Version:          $Name$
    revision_Id:      $Id$
    initial_file:     /glade/work/fengzhu/Projects/Miocene-on-Derecho/04.atm-...
    topography_file:  /glade/work/fengzhu/Projects/Miocene-on-Derecho/04.atm-...
    comp:             atm
    grid:             ne16

Therefore, we should always set adjust_month=True when dealing with CESM output.

[5]:
ds = x4c.load_dataset(os.path.join(dirpath, fname), comp='atm', grid='ne16', adjust_month=True)
ds
[5]:
<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 6951-01-31 00:00:00 ... 7000-12-31 00:00:00
Dimensions without coordinates: ncol, nbnd
Data variables: (12/32)
    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
    ...            ...
    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 121765488 121766832 ... 122638512 122640000
    TS            (time, ncol) float32 33MB 303.3 302.6 301.7 ... 293.7 294.3
    gw            (ncol) float64 111kB 0.0001546 0.000515 ... 0.00129 0.001289
Attributes: (12/14)
    np:               4
    ne:               16
    Conventions:      CF-1.0
    source:           /glade/campaign/univ/ubrn0018/fengzhu/CESM_output/times...
    case:             b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO...
    title:            UNSET
    ...               ...
    Version:          $Name$
    revision_Id:      $Id$
    initial_file:     /glade/work/fengzhu/Projects/Miocene-on-Derecho/04.atm-...
    topography_file:  /glade/work/fengzhu/Projects/Miocene-on-Derecho/04.atm-...
    comp:             atm
    grid:             ne16

By default, the annualize() method will take a calendar year annualization. It works on both xarray.Dataset and xarray.DataArray.

[7]:
ds_ann = ds.x.annualize()
ds_ann
[7]:
<xarray.Dataset> Size: 25MB
Dimensions:  (lev: 30, time: 50, ilev: 31, ncol: 13826)
Coordinates:
  * lev      (lev) float64 240B 3.643 7.595 14.36 24.61 ... 957.5 976.3 992.6
  * ilev     (ilev) float64 248B 2.255 5.032 10.16 18.56 ... 967.5 985.1 1e+03
  * time     (time) object 400B 6951-12-31 00:00:00 ... 7000-12-31 00:00:00
Dimensions without coordinates: ncol
Data variables: (12/29)
    hyam     (time, lev) float64 12kB 0.003643 0.007595 0.01436 ... 0.001989 0.0
    hybm     (time, lev) float64 12kB 0.0 0.0 0.0 0.0 ... 0.9512 0.9743 0.9926
    P0       (time) float64 400B 1e+05 1e+05 1e+05 1e+05 ... 1e+05 1e+05 1e+05
    hyai     (time, ilev) float64 12kB 0.002255 0.005032 0.01016 ... 0.0 0.0
    hybi     (time, ilev) float64 12kB 0.0 0.0 0.0 0.0 ... 0.9636 0.9851 1.0
    lat      (time, ncol) float64 6MB -35.26 -35.98 -37.07 ... 37.91 37.91 36.74
    ...       ...
    f11vmr   (time) float64 400B 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    f12vmr   (time) float64 400B 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    sol_tsi  (time) float64 400B -1.0 -1.0 -1.0 -1.0 ... -1.0 -1.0 -1.0 -1.0
    nsteph   (time) float64 400B 1.218e+08 1.218e+08 ... 1.226e+08 1.226e+08
    TS       (time, ncol) float32 3MB 300.4 299.7 298.9 ... 298.8 297.6 298.3
    gw       (time, ncol) float64 6MB 0.0001546 0.000515 ... 0.00129 0.001289
Attributes: (12/14)
    np:               4
    ne:               16
    Conventions:      CF-1.0
    source:           /glade/campaign/univ/ubrn0018/fengzhu/CESM_output/times...
    case:             b.e13.B1850C5.ne16_g16.icesm131_d18O_fixer.Miocene.3xCO...
    title:            UNSET
    ...               ...
    Version:          $Name$
    revision_Id:      $Id$
    initial_file:     /glade/work/fengzhu/Projects/Miocene-on-Derecho/04.atm-...
    topography_file:  /glade/work/fengzhu/Projects/Miocene-on-Derecho/04.atm-...
    comp:             atm
    grid:             ne16
[8]:
da_ann = ds['TS'].x.annualize()
da_ann
[8]:
<xarray.DataArray 'TS' (time: 50, ncol: 13826)> Size: 3MB
array([[300.4056 , 299.74374, 298.8827 , ..., 297.77768, 296.3739 ,
        297.2957 ],
       [300.51978, 299.91406, 299.13815, ..., 297.63562, 296.27377,
        297.19717],
       [300.5768 , 299.933  , 299.0933 , ..., 297.89706, 296.53174,
        297.4404 ],
       ...,
       [300.45587, 299.7728 , 298.87228, ..., 298.27094, 296.86743,
        297.82123],
       [300.5035 , 299.86862, 299.03717, ..., 298.3373 , 296.99435,
        297.9501 ],
       [300.90073, 300.207  , 299.28955, ..., 298.82007, 297.5945 ,
        298.29617]], dtype=float32)
Coordinates:
  * time     (time) object 400B 6951-12-31 00:00:00 ... 7000-12-31 00:00:00
Dimensions without coordinates: ncol
Attributes:
    units:         K
    long_name:     Surface temperature (radiative)
    cell_methods:  time: mean

Now let’s take the summer annualization (JJA) with months=[6, 7, 8].

[9]:
da_ann = ds['TS'].x.annualize(months=[6, 7, 8])
da_ann
[9]:
<xarray.DataArray 'TS' (time: 50, ncol: 13826)> Size: 3MB
array([[297.55188, 296.90125, 296.1971 , ..., 302.71777, 302.07346,
        303.05008],
       [297.93976, 297.3142 , 296.6012 , ..., 301.59506, 301.23608,
        302.09348],
       [297.83105, 297.22702, 296.50568, ..., 302.66476, 301.6821 ,
        302.7534 ],
       ...,
       [297.81192, 297.14175, 296.36304, ..., 302.9569 , 302.0776 ,
        303.00082],
       [297.62015, 296.9952 , 296.3026 , ..., 302.48465, 301.4866 ,
        302.63806],
       [297.92096, 297.23682, 296.54926, ..., 303.61307, 303.0111 ,
        303.62378]], dtype=float32)
Coordinates:
  * time     (time) object 400B 6951-08-31 00:00:00 ... 7000-08-31 00:00:00
Dimensions without coordinates: ncol
Attributes:
    units:         K
    long_name:     Surface temperature (radiative)
    cell_methods:  time: mean

Now let’s take the winter annualization (DJF) with months=[-12, 1, 2]. Note that for such cases with months acrossing two years, the output will have an extra year.

[10]:
da_ann = ds['TS'].x.annualize(months=[-12, 1, 2])
da_ann
[10]:
<xarray.DataArray 'TS' (time: 51, ncol: 13826)> Size: 3MB
array([[304.11615, 303.55984, 302.69208, ..., 292.9821 , 290.6372 ,
        291.5415 ],
       [302.8373 , 302.32922, 301.65878, ..., 293.52878, 291.0331 ,
        292.12653],
       [303.2499 , 302.66833, 301.8291 , ..., 293.30777, 290.8607 ,
        291.7891 ],
       ...,
       [303.36325, 302.76614, 301.80032, ..., 294.45523, 292.2219 ,
        293.23636],
       [303.76077, 303.16336, 302.2713 , ..., 294.30753, 292.04373,
        292.99838],
       [302.0511 , 301.19028, 299.91696, ..., 296.0614 , 293.69016,
        294.33484]], dtype=float32)
Coordinates:
  * time     (time) object 408B 6951-02-28 00:00:00 ... 7001-02-28 00:00:00
Dimensions without coordinates: ncol
Attributes:
    units:         K
    long_name:     Surface temperature (radiative)
    cell_methods:  time: mean
[ ]: