Last active
November 24, 2022 16:45
-
-
Save dvgodoy/8fa5b358d0409258d7e8097d6fd3006f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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