Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Converts Scripps CO2 Mauna Loa data into a CF-compliant netCDF4 file for use in ILAMB
import numpy as np
from netCDF4 import Dataset
import pylab as plt
import os
import time
from urllib.request import urlretrieve
remote_source = "http://scrippsco2.ucsd.edu/assets/data/atmospheric/stations/in_situ_co2/monthly/monthly_in_situ_co2_mlo.csv"
gist_source = "https://gist.github.com/nocollier/d73585731756fa472731065389af45dc"
local_source = os.path.basename(remote_source)
if not os.path.isfile(local_source):
urlretrieve(remote_source, local_source)
stamp = time.strftime('%Y-%m-%d', time.localtime(os.path.getmtime(local_source)))
# parse CSV file, we use the 9th column for the CO2 data
rec = np.genfromtxt("monthly_in_situ_co2_mlo.csv", delimiter=",", skip_header=57)
year = rec[:, 0]
month = rec[:, 1].astype(int)
co2 = np.ma.masked_values(rec[:, 8], -99.99).reshape((-1, 1)).astype(np.float32)
# create time and its bounds in days since 1850-1-1
bnd_months = np.asarray([0., 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365])
tb = ((year-1850)*365)[:, np.newaxis] + np.asarray([bnd_months[month-1], bnd_months[month]]).T
t = tb.mean(axis=1)
# location information pulled from webpage
lat = np.asarray([19.5]).astype(np.float32)
lon = np.asarray([-155.6]).astype(np.float32)
elevation = np.asarray([3397.]).astype(np.float32)
with Dataset("co2.nc", mode="w") as dset:
# dimensions
dset.createDimension("time", size=t.size)
dset.createDimension("data", size=1)
dset.createDimension("nb", size=2)
# time
T = dset.createVariable("time", t.dtype, ("time"))
T[...] = t
T.units = "days since 1850-01-01 00:00:00"
T.calendar = "noleap"
T.bounds = "time_bounds"
# time bounds
TB = dset.createVariable("time_bounds", t.dtype, ("time", "nb"))
TB[...] = tb
# latitude
X = dset.createVariable("lat", lat.dtype, ("data"))
X[...] = lat
X.standard_name = "latitude"
X.long_name = "site latitude"
X.units = "degrees_north"
# longitude
Y = dset.createVariable("lon", lon.dtype, ("data"))
Y[...] = lon
Y.standard_name = "longitude"
Y.long_name = "site longitude"
Y.units = "degrees_east"
# elevation
Z = dset.createVariable("elevation", elevation.dtype, ("data"))
Z[...] = elevation
Z.units = "m"
Z.positive = "up"
# data
D = dset.createVariable("co2", co2.dtype, ("time", "data"), fill_value = -99.99)
D[...] = co2
D.units = "ppm"
D.standard_name = "atmosphere_moles_of_carbon_dioxide"
D.long_name = "CO2 concentration"
D.actual_range = np.asarray([co2.min(),co2.max()])
dset.title = "Primary Mauna Loa CO2 Record (1958 - present)"
dset.institution = "Scripps Institution of Oceanography"
dset.source = "in situ air measurements"
dset.history = """
%s: downloaded source from %s
%s: converted to netCDF with %s""" % (stamp, remote_source, stamp, gist_source)
dset.references = """
@TechReport{Keeling2001,
author = {C.~D. Keeling and S.~C. Piper and R.~B. Bacastow and M. Wahlen and T.~P. Whorf and M. Heimann and H.~A. Meijer},
title = {Exchanges of atmospheric {CO2} and {13CO2} with the terrestrial biosphere and oceans from 1978 to 2000. {I}. Global aspects},
institution = {SIO Reference Series},
year = {2001},
number = {01-06},
address = {Scripps Institution of Oceanography, San Diego}
}
@InBook{Keeling2005,
author = {C.~D. Keeling and S.~C. Piper and R.~B. Bacastow and M. Wahlen and T.~P. Whorf and M. Heimann and H.~A. Meijer},
editor = {J.~R. Ehleringer and T.~E. Cerling and M.~D. Dearing},
title = {A History of Atmospheric {CO2} and its effects on Plants, Animals, and Ecosystems},
chapter = {Atmospheric {CO2} and {13CO2} exchange with the terrestrial biosphere and oceans from 1978 to 2000: observations and carbon cycle implications},
publisher = {Springer Verlag},
year = {2005},
address = {New York},
pages = {83-113}
}"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment