The python code below shows how to interpolate a data from CESM hybrid sigma level to pressure level.

"""
Created on Wed Nov 16 2022

@author: Yuntao Bao
contact: bao.291@osu.edu
"""

import numpy as np
import netCDF4 as nc4
import xarray as xr
   
def interp_hybsigma2lev(lev_from, lev_to, datain):
    nlev = len(lev_to)  
    print('Start linear interpolation:')
    new_data = np.zeros((nt,nlev,ny,nx), dtype='float32')
    for t in range(nt):
        print('OK', t)
        for j in range(ny):
            for i in range(nx):
                new_data[t,:,j,i] = np.interp(lev_to , lev_from[t,:,j,i], datain[t,:,j,i])    
    return new_data

if __name__ == "__main__":
    # modify here to change the variable
    var = 'Q' 

    # must included a CESM output file with 'hyam' and 'hybm' inside
    info = nc4.Dataset('.../f.e13.Fi1850C5.f02_f02.cam.h0.000101-002512.nc','r') 
    hyam = info['hyam'][:].data
    hybm = info['hybm'][:].data
    P0 = 1000

    # input data file with a variable to be interpolated
    fin = 'f.e13.Fi1850C5.f02_f02.cam.h0.'+var+'.nc'
    # input data file with a variable 'surface pressure'
    fps = ps_dir + 'f.e13.Fi1850C5.f02_f02.cam.h0.PS.nc'

    dsdat = nc4.Dataset(fin)
    dsps = nc4.Dataset(fps)
    data = dsdat[var][:].data
    ps = dsps['PS'][:].data/100   # hPa

    lev = dsdat['lev_p'][:].data
    lon = dsdat['lon'][:].data
    lat = dsdat['lat'][:].data
    time = dsdat['time'][:].data
    [nx, ny, nz, nt] = len(lon), len(lat), len(lev), len(time)
    print(lev)

    press = P0*hyam[None,:,None,None] + hybm[None,:,None,None]*ps[:,None,:,:]
    lev_from = press
    # You can also define your own pressure level array!
    lev_to = np.array([100., 125., 150., 175., 200., 225.,\
                    250., 300., 350., 400., 450., 500., 550., \
                    600., 650., 700., 750., 775., 800., 825., \
                    850., 875., 900., 925., 950., 975., 1000.], dtype='float32') 
    print(lev_from) 
    print(lev_to)

    # call function to interpolate
    data_new = interp_hybsigma2lev(lev_from, lev_to, data)
    print('End linear interpolation')

If you want to contiune interpolate data in pressure level to pure sigma level, see: Model data interpolation from pressure level to sigma level

Last updated: 02/12/2023