Skip to content

Instantly share code, notes, and snippets.

@dvgodoy
Last active November 24, 2022 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvgodoy/8fa5b358d0409258d7e8097d6fd3006f to your computer and use it in GitHub Desktop.
Save dvgodoy/8fa5b358d0409258d7e8097d6fd3006f to your computer and use it in GitHub Desktop.
import numpy as np
import netCDF4 as nc
import requests
import os
def download(url=None, cached_etag=None):
try:
if url is None:
base = b'https://www.ncei.noaa.gov/data/noaa-global-surface-temperature/v5/access/gridded/'
resp = requests.get(base)
start = resp.content.find(b'href="NOAAGlobalTemp')
end = resp.content.find(b'>', start)
fname = resp.content[start+6:end-1]
url = base+fname
if not os.path.exists(fname):
resp = requests.head(url, allow_redirects=True)
if resp.status_code == 200:
headers = resp.headers
etag = headers['ETag']
if (cached_etag is None) or etag != cached_etag:
local_filename = url.split(b'/')[-1]
r = requests.get(url, stream=True, allow_redirects=True)
if r.status_code == 200:
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return fname.decode('utf-8')
except Exception as e:
pass
def noaa_temperatures(fname, yearly=True, start=1971,
span=30, stat='mean', grid_size=5):
# Reads NetCDF file
ds = nc.Dataset(fname)
# Anomaly data (z)
anom = ds['anom'][:].data
# Value used to replace missing values
nanval = ds['anom'].missing_value
# Original shape is (n_years, 1, 36, 72)
gridded = anom.squeeze()
gridded[gridded == nanval] = np.nan
stat = 'mean'
funcs = {'mean': np.mean, 'max': np.max, 'min': np.min}
# Gets the number of full years in the file
n_years = gridded.shape[0]//12
end = start + span - 1
if (start != 1971) or (end != 2000):
polygons = surface_polygons(grid_size)
surface_perc = surface_area(polygons, perc=True)
# Computes weighted average using surface area of grid boxes
adjustment = np.mean(surface_stat(gridded[(start-1880)*12:(end-1880+1)*12],
surface_perc))
# Adjusts baseline
gridded = gridded - adjustment
# Computes the average over each year
griddedy = np.array([funcs[stat](gridded[i*12:(i+1)*12], axis=0)
for i in range(n_years)])
# NetCDF has latitudes from -87.5 to 87.5 (it uses the centers of the
# grid boxes) but we need to flip it upside down to use in Plotly
griddedy = griddedy[:, ::-1]
# NetCDF has longitudes from 0 to 360, but we need to rearrange it from
# -180 to 180 to use in Plotly, so we concatenate the last 36 columns
# (180 to 360 = -180 to 0) to the first 36 columns (0 to 180)
griddedy = np.concatenate([griddedy[:, :, 36:], griddedy[:, :, :36]], axis=2)
return griddedy if yearly else gridded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment