Skip to content

Convert NetCDF Climate Data

This tutorial shows how to convert climate data into a DGGS.

Download and load the unidata example file from the Community Climate System Model (CCSM), one time step of precipitation flux, air temperature, and eastward wind:

julia
using YAXArrays
using DimensionalData
using NetCDF
using Downloads

url = "https://www.unidata.ucar.edu/software/netcdf/examples/sresa1b_ncar_ccsm3-example.nc"
path = Downloads.download(url, tempname() * ".nc")
geo_ds = open_dataset(path)
YAXArray Dataset
Shared Axes: 
  (lon Sampled{Float32} 0.0f0:1.40625f0:358.59375f0 ForwardOrdered Regular Points,
lat Sampled{Float32} -88.927734f0:1.4004368f0:88.927734f0 ForwardOrdered Regular Points)

Variables: 
area, msk_rgn

Variables with additional axes:
  Additional Axes: 
  (plev Sampled{Float64} [100000.0, …, 1000.0] ReverseOrdered Irregular Points,
time Sampled{CFTime.DateTimeNoLeap} [CFTime.DateTimeNoLeap(2000-05-16T12:00:00)] ForwardOrdered Irregular Points)
  Variables: 
  ua

  Additional Axes: 
  (time Sampled{CFTime.DateTimeNoLeap} [CFTime.DateTimeNoLeap(2000-05-16T12:00:00)] ForwardOrdered Irregular Points)
  Variables: 
  pr, tas

Properties: Dict{String, Any}("cmd_ln" => "bds -x 256 -y 128 -m 23 -o /data/zender/data/dst_T85.nc", "references" => "Collins, W.D., et al., 2005:\n The Community Climate System Model, Version 3\n Journal of Climate\n \n Main website: http://www.ccsm.ucar.edu", "CVS_Id" => "\$Id\$", "model_name_english" => "NCAR CCSM", "creation_date" => "", "acknowledgment" => " Any use of CCSM data should acknowledge the contribution\n of the CCSM project and CCSM sponsor agencies with the \n following citation:\n 'This research uses data provided by the Community Climate\n System Model project (www.ccsm.ucar.edu), supported by the\n Directorate for Geosciences of the National Science Foundation\n and the Office of Biological and Environmental Research of\n the U.S. Department of Energy.'\nIn addition, the words 'Community Climate System Model' and\n 'CCSM' should be included as metadata for webpages referencing\n work using CCSM data or as keywords provided to journal or book\npublishers of your manuscripts.\nUsers of CCSM data accept the responsibility of emailing\n citations of publications of research using CCSM data to\n ccsm@ucar.edu.\nAny redistribution of CCSM data must include this data\n acknowledgement statement.", "realization" => 1, "contact" => "ccsm@ucar.edu", "Conventions" => "CF-1.0", "history" => "Tue Oct 25 15:08:51 2005: ncks -O -x -v va -m sresa1b_ncar_ccsm3_0_run1_200001.nc sresa1b_ncar_ccsm3_0_run1_200001.nc\nTue Oct 25 15:07:21 2005: ncks -d time,0 sresa1b_ncar_ccsm3_0_run1_200001_201912.nc sresa1b_ncar_ccsm3_0_run1_200001.nc\nTue Oct 25 13:29:43 2005: ncks -d time,0,239 sresa1b_ncar_ccsm3_0_run1_200001_209912.nc /var/www/html/tmp/sresa1b_ncar_ccsm3_0_run1_200001_201912.nc\nThu Oct 20 10:47:50 2005: ncks -A -v va /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/sresa1b_ncar_ccsm3_0_run1_va_200001_209912.nc /data/brownmc/sresa1b/atm/mo/tas/ncar_ccsm3_0/run1/sresa1b_ncar_ccsm3_0_run1_200001_209912.nc\nWed Oct 19 14:55:04 2005: ncks -F -d time,01,1200 /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/sresa1b_ncar_ccsm3_0_run1_va_200001_209912.nc /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/sresa1b_ncar_ccsm3_0_run1_va_200001_209912.nc\nWed Oct 19 14:53:28 2005: ncrcat /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/foo_05_1200.nc /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/foo_1192_1196.nc /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/sresa1b_ncar_ccsm3_0_run1_va_200001_209912.nc\nWed Oct 19 14:50:38 2005: ncks -F -d time,05,1200 /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/va_A1.SRESA1B_1.CCSM.atmm.2000-01_cat_2099-12.nc /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/foo_05_1200.nc\nWed Oct 19 14:49:45 2005: ncrcat /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/va_A1.SRESA1B_1.CCSM.atmm.2000-01_cat_2079-12.nc /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/va_A1.SRESA1B_1.CCSM.atmm.2080-01_cat_2099-12.nc /data/brownmc/sresa1b/atm/mo/va/ncar_ccsm3_0/run1/va_A1.SRESA1B_1.CCSM.atmm.2000-01_cat_2099-12.nc\nCreated from CCSM3 case b30.040a\n by wgstrand@ucar.edu\n on Wed Nov 17 14:12:57 EST 2004\n \n For all data, added IPCC requested metadata"…)

Plot temperature at the first time point:

julia
using GLMakie
plot(geo_ds.tas[time=1])

Note, that the longitude dimension must be shifted to fit within [-180,180]:

julia
function shift_lon(arr)
    old_lon = arr.lon.val
    n = length(old_lon) ÷ 2
    new_lon = vcat(old_lon[n+1:end] .- 360, old_lon[1:n])
    data_reordered = circshift(collect(arr.data), (n, 0, 0))
    arr2 = YAXArray((new_lon |> X, arr.lat.val |> Y, arr.time), data_reordered, arr.properties)
    return arr2
end

arr_tas = shift_lon(geo_ds.tas)
arr_pr = shift_lon(geo_ds.pr)
geo_ds2 = Dataset(tas = arr_tas, pr = arr_pr)
YAXArray Dataset
Shared Axes: 
  (Y Sampled{Float32} -88.927734f0:1.4004368f0:88.927734f0 ForwardOrdered Regular Points,
time Sampled{CFTime.DateTimeNoLeap} [CFTime.DateTimeNoLeap(2000-05-16T12:00:00)] ForwardOrdered Irregular Points)

Variables with additional axes:
  Additional Axes: 
  (X Sampled{Float32} [-180.0f0, …, 178.59375f0] ForwardOrdered Irregular Points)
  Variables: 
  pr

  Additional Axes: 
  (X Sampled{Float32} [-180.0f0, …, 178.59375f0] ForwardOrdered Irregular Points)
  Variables: 
  tas

Convert to DGGS:

julia
using DGGS
p = to_dggs_pyramid(geo_ds2, 5, "EPSG:4326")
DGGSPyramid
├─── branches ┤
  :dggs_s1 dims: dggs_i, dggs_j, dggs_n, time size: 4×2×5×1 layers: :pr, :tas
  :dggs_s2 dims: dggs_i, dggs_j, dggs_n, time size: 8×4×5×1 layers: :pr, :tas
  :dggs_s3 dims: dggs_i, dggs_j, dggs_n, time size: 16×8×5×1 layers: :pr, :tas
  :dggs_s4 dims: dggs_i, dggs_j, dggs_n, time size: 32×16×5×1 layers: :pr, :tas
  :dggs_s5 dims: dggs_i, dggs_j, dggs_n, time size: 64×32×5×1 layers: :pr, :tas
├─────── DGGS ┤ 
  DGGSRS:     ISEA4D.Penta
  Geo BBox:   Extent(X = (-180.0f0, 178.59375f0), Y = (-88.927734f0, 88.927734f0))
└─────────────┘

Plot DGGS data at a given spatial resolution, layer and time:

julia
plot(p[5].tas[time=1])