def spi_netcdf_grid(rfile, wfile, vname, nspi):
    from netcdf_tools import ncextractall
    from netcdf_tools import ncwrite_climgrid
    from netCDF4 import num2date
    from netCDF4 import date2num
    import numpy as np

    # Import and extract the netcdf file, returns a dictionary
    datdict = ncextractall(rfile)

    # Read each variable
    data = datdict[vname]
    lon = datdict["lon"]
    lat = datdict["lat"]
    time = datdict["time"]

    # convert missing numbers to NaN
    miss = datdict[vname + "_missing_value"]
    data = np.where(data == miss, np.nan, data)

    # convert time units to actual date
    time_u = datdict["time_units"]
    if "time_calendar" in datdict.keys():
        cal = datdict["time_calendar"]
        time = num2date(time, units=time_u, calendar=cal)
    else:
        time = num2date(time, units=time_u)

    trimmed = grid_tools.trim_time_jandec(data, time)
    data = trimmed[0]
    time = trimmed[1]

    # Create an empty array to store the SPI data
    spigrid = np.zeros(data.shape)

    # Compute the SPI at all locations
    for i in range(0, len(lat)):
        for j in range(0, len(lon)):
            tmpdata = data[:, i, j]
            tmpdata = tmpdata.flatten()
            tmpspi = spi(tmpdata, nspi)
            tmpspi = tmpspi.flatten()
            spigrid[:, i, j] = tmpspi

    # convert missing numbers back to a float
    spigrid = np.where(spigrid == np.nan, miss, spigrid)

    # convert time back to original units
    if "time_calendar" in datdict.keys():
        cal = datdict["time_calendar"]
        time = date2num(time, units=time_u, calendar=cal)
    else:
        time = date2num(time, units=time_u)

    spidescrip = "The Standardised Precipitation Index (SPI) computed as per McKee et al. (1993)"
    spilong_name = str(nspi) + "-month Standardised Precipitation Index"
    spiname = "SPI" + str(nspi)

    write = ncwrite_climgrid(
        wfile, spigrid, spiname, spidescrip, spilong_name, miss, "standardised units", time, lon, lat, time_u
    )

    return spigrid, lon, lat, time
Example #2
0
def nc_ipophase():
	from netCDF4 import date2num
	from netCDF4 import num2date
	import numpy as np
	from netcdf_tools import ncwrite_climgrid
	from netcdf_tools import ncextractall

	#Input file (this file goes from January 1870 to April 2016 as is)
	file = '/Users/ailieg/Data/HadISST_sst.nc'
	
	nc = ncextractall(file)
	sst = nc['sst']
	lon = nc['longitude']
	nlon = lon.size
	lat = nc['latitude']
	nlat = lat.size
	time = nc['time']
	miss = nc['sst_missing_value']
	units = nc['sst_units']
	
	#convert time units to actual date
	time_u = nc['time_units']
	if 'time_calendar' in nc.keys(): 
	     cal = nc['time_calendar']
	     time = num2date(time,units = time_u, calendar=cal)
	else: time = num2date(time,units = time_u)
	
	#extract years and months from the datetime array
	ntime = time.size
	year = np.zeros(ntime)
	month = np.zeros(ntime)
	i = 0
	while (i < ntime):
		year[i] = time[i].year
		month[i] = time[i].month
		i=i+1
		
	#Extract data from 1950 to 2015 only
	sst = sst[(year > 1976) & (year < 2000), :,:]
	time = time[(year > 1976) & (year < 2000)]
	ntime = time.size
	
	#Reshape the array to determine climatology over the whole period
	nyear = ntime/12
	sst = sst.reshape([nyear,12,nlat,nlon])
	time = time.reshape([nyear, 12])
	mid = int(nyear/2)
	time = time[mid,:]
	
	sst = np.mean(sst, axis=0)
	
	#Write the output file
	descrip = 'Monthly climatology of HadISST SSTs from IPO positive years computed as 1977-1999'
	long_name = 'sst'
	missing = miss
	climunits = units
	time = date2num(time,units = time_u, calendar=cal)
	print(sst.shape,time.size,lon.size,lat.size)
	filename = '/Users/ailieg/Data/IPO_ACCESS/HadISST_IPOpos_1977_1999.nc'
	
	print("Writing netCDF file...")
	ncw = ncwrite_climgrid(filename, sst, 'sst', descrip, long_name, missing, climunits, time, lon, lat, time_u, cal)
	print("NetCDF file written")
	
	return sst, lat, lon