def getFuzzyNiNj(lonVal, latVal, gridData): xypos = rmn.gdxyfll(gridData, latVal, lonVal) ni = int(round(xypos['x'])) - 1 #-1 to use 0 as list index nj = int(round(xypos['y'])) - 1 print('Closest lonlat values: ({}, {})'.format(lonData[ni][nj], latData[ni][nj])) return ni, nj
def data_from_key(key, file_id, lonarr, latarr): meta = rmn.fstprm(key) meta['iunit'] = file_id data = rmn.fstluk(key)['d'] grid = rmn.ezqkdef(meta) xypos = rmn.gdxyfll(grid, latarr, lonarr) val = rmn.gdxysval(grid, xypos['x'], xypos['y'], data) return meta, grid, xypos, val
def getNiNj(lonVal, latVal, gridID): xypos = rmn.gdxyfll(gridID, latVal, lonVal) ni = int(round(xypos['x'])) - 1 #-1 to use 0 as list index nj = int(round(xypos['y'])) - 1 gridData = rmn.gdll(gridID) if ni >= len(gridData['lon']) or nj >= len(gridData['lon'][0]): print( 'lon lat values of station outside of grid domain. Please check your values.' ) return None else: return ni, nj
def getNiNjRange(LL, UR, gridData): """ Get the range of ni, nj values based on the defaultLL and defaultUR provided. Function will process lonlat values, otherewise will check to see if the ninj range provided is reasonable. """ if LLURareLonLat == True: try: xyposLL = rmn.gdxyfll(gridData, LL[1], LL[0]) LLni = int(round(xyposLL['x'])) - 1 #-1 to use 0 as list index LLnj = int(round(xyposLL['y'])) - 1 xyposUR = rmn.gdxyfll(gridData, UR[1], UR[0]) URni = int(round(xyposUR['x'])) - 1 URnj = int(round(xyposUR['y'])) - 1 print ('Closest lonlat values: LL({}, {}), UR({}, {}).'.format(gridData['lon'][LLni][LLnj], gridData['lat'][LLni][LLnj], gridData['lon'][URni][URnj], gridData['lat'][URni][URnj])) except: LLni = 0 LLnj = 0 URni = len(gridData['lon']) URnj = len(gridData['lon'][0]) print('LonLat values are out of range, will plot using entire grid.') else: if LL[1] < len(gridData['lon']) and UR[1] < len(gridData['lon'][0]): LLni = LL[0] LLnj = LL[1] URni = UR[0] URnj = UR[1] print('NiNj values: LL({}, {}), UR({}, {}).'.format(LLni, LLnj, URni, URnj)) else: LLni = 0 LLnj = 0 URni = len(gridData['lon']) URnj = len(gridData['lon'][0]) print('NiNj values are out of range, will plot using entire grid.') niRange = sorted([LLni, URni]) njRange = sorted([LLnj, URnj]) return niRange, njRange
def ezgetlalo(nij, grtyp, refparam, xyAxis, hasAxis, ij0, doCorners): """Get Lat-Lon of grid points centers and corners (lat, lon, clat, clon) = Fstdc.ezgetlalo((niS, njS), grtypS, (grrefS, ig1S, ig2S, ig3S, ig4S), (xsS, ysS), hasSrcAxis, (i0S, j0S), doCorners) @param ...TODO... @return tuple of (numpy.ndarray) with center lat/lon (lat, lon) and optionally corners lat/lon (clat, clon) @exception TypeError @exception Fstdc.error """ try: gid = _getGridHandle(nij[0], nij[1], grtyp, refparam[0], refparam[1], refparam[2], refparam[3], refparam[4], ij0[0], ij0[1], xyAxis[0], xyAxis[1]) except: raise error("ezgetlalo: Invalid Grid Desc") try: gridLaLo = _rmn.gdll(gid); except: raise error("ezgetlalo: Problem computing lat, lon in ezscint") if not doCorners: return (gridLaLo['lat'], gridLaLo['lon']) xyc = _rmn.gdxyfll(gid, gridLaLo['lat'], gridLaLo['lon']) xc1 = xyc['x'] yc1 = xyc['y'] nij2 = (4, gridLaLo['lat'].shape[0], gridLaLo['lat'].shape[1]) xc4 = _np.empty(nij2, dtype=_np.float32, order='FORTRAN') yc4 = _np.empty(nij2, dtype=_np.float32, order='FORTRAN') ## x = _np.arange(float(nij2[1])) ## y = _np.arange(float(nij2[2])) ## fx = interpolate.interp2d(x, y, xc1, kind='linear', copy=False) ## fy = interpolate.interp2d(x, y, yc1, kind='linear', copy=False) dij_corners = ( (-0.5, -0.5), #SW (-0.5, 0.5), #NW ( 0.5, 0.5), #NE ( 0.5, -0.5) #SE ) for icorner in range(4): di = dij_corners[icorner][0] dj = dij_corners[icorner][1] ## xnew = x.copy('FORTRAN') + dij_corners[icorner][0] ## ynew = y.copy('FORTRAN') + dij_corners[icorner][1] ## xc4[icorner, :, :] = fx(xnew, ynew) ## yc4[icorner, :, :] = fy(xnew, ynew) xc4[icorner, :, :] = xc1[:, :] + dij_corners[icorner][0] yc4[icorner, :, :] = yc1[:, :] + dij_corners[icorner][1] llc = _rmn.gdllfxy(gid, xc4, yc4) return (gridLaLo['lat'], gridLaLo['lon'], llc['lat'], llc['lon'])
def ezgetlalo(nij, grtyp, refparam, xyAxis, hasAxis, ij0, doCorners): """Get Lat-Lon of grid points centers and corners (lat, lon, clat, clon) = Fstdc.ezgetlalo((niS, njS), grtypS, (grrefS, ig1S, ig2S, ig3S, ig4S), (xsS, ysS), hasSrcAxis, (i0S, j0S), doCorners) @param ...TODO... @return tuple of (numpy.ndarray) with center lat/lon (lat, lon) and optionally corners lat/lon (clat, clon) @exception TypeError @exception Fstdc.error """ try: gid = _getGridHandle(nij[0], nij[1], grtyp, refparam[0], refparam[1], refparam[2], refparam[3], refparam[4], ij0[0], ij0[1], xyAxis[0], xyAxis[1]) except: raise error("ezgetlalo: Invalid Grid Desc") try: gridLaLo = _rmn.gdll(gid); except: raise error("ezgetlalo: Problem computing lat, lon in ezscint") if not doCorners: return (gridLaLo['lat'], gridLaLo['lon']) xyc = _rmn.gdxyfll(gid, gridLaLo['lat'], gridLaLo['lon']) xc1 = xyc['x'] yc1 = xyc['y'] nij2 = (4, gridLaLo['lat'].shape[0], gridLaLo['lat'].shape[1]) xc4 = _np.empty(nij2, dtype=_np.float32, order='FORTRAN') yc4 = _np.empty(nij2, dtype=_np.float32, order='FORTRAN') ## x = _np.arange(float(nij2[1])) ## y = _np.arange(float(nij2[2])) ## fx = interpolate.interp2d(x, y, xc1, kind='linear', copy=False) ## fy = interpolate.interp2d(x, y, yc1, kind='linear', copy=False) dij_corners = ( (-0.5, -0.5), #SW (-0.5, 0.5), #NW ( 0.5, 0.5), #NE ( 0.5, -0.5) #SE ) for icorner in xrange(4): di = dij_corners[icorner][0] dj = dij_corners[icorner][1] ## xnew = x.copy('FORTRAN') + dij_corners[icorner][0] ## ynew = y.copy('FORTRAN') + dij_corners[icorner][1] ## xc4[icorner, :, :] = fx(xnew, ynew) ## yc4[icorner, :, :] = fy(xnew, ynew) xc4[icorner, :, :] = xc1[:, :] + dij_corners[icorner][0] yc4[icorner, :, :] = yc1[:, :] + dij_corners[icorner][1] llc = _rmn.gdllfxy(gid, xc4, yc4) return (gridLaLo['lat'], gridLaLo['lon'], llc['lat'], llc['lon'])
def test_ezgkdef_fmem_gdxyfll(self): gp = self.getGridParams_ZE() gid1 = rmn.ezgdef_fmem(gp['ni'],gp['nj'],gp['grtyp'],gp['grref'], gp['ig1ref'],gp['ig2ref'],gp['ig3ref'],gp['ig4ref'], gp['ax'],gp['ay']) self.assertTrue(gid1>=0) lat = np.array([gp['ay'][0,0],gp['ay'][0,1]],dtype=np.float32,order='FORTRAN') lon = np.array([gp['ax'][0,0],gp['ax'][1,0]],dtype=np.float32,order='FORTRAN') xypts = rmn.gdxyfll(gid1, lat, lon) self.assertEqual(xypts['x'].shape,lat.shape) self.assertEqual(xypts['y'].shape,lat.shape) self.assertTrue(abs(xypts['x'][0]-1.)<self.epsilon) self.assertTrue(abs(xypts['y'][0]-1.)<self.epsilon) self.assertTrue(abs(xypts['x'][1]-2.)<self.epsilon) self.assertTrue(abs(xypts['y'][1]-2.)<self.epsilon) rmn.gdrls(gid1)
def _gen_xyll(self): from collections import OrderedDict import numpy as np from rpnpy.librmn.all import gdll, gdxyfll from fstd2nc.mixins import _var_type, _axis_type ll = gdll(self._grd['id']) self._lonarray = ll['lon'].transpose( ) # Switch from Fortran to C order. self._lonatts = OrderedDict() self._lonatts['long_name'] = 'longitude' self._lonatts['standard_name'] = 'longitude' self._lonatts['units'] = 'degrees_east' self._latarray = ll['lat'].transpose( ) # Switch from Fortran to C order. self._latatts = OrderedDict() self._latatts['long_name'] = 'latitude' self._latatts['standard_name'] = 'latitude' self._latatts['units'] = 'degrees_north' xy = gdxyfll(self._grd['id'], ll['lat'], ll['lon']) # Scale grid coordinates back to actual coordinates in projection plane self._ax = (np.rint(xy['x'][:, 0]) - 1) * self._res # metres self._ay = (np.rint(xy['y'][0, :]) - 1) * self._res # Determine the false easting and northing from # the coordinates of the pole and of grid point (1,1) _pole_pi = self._grd['pi'] _pole_pj = self._grd['pj'] self._false_easting = self._ax[int(round(_pole_pi)) - 1] - self._ax[0] self._false_northing = self._ay[int(round(_pole_pj)) - 1] - self._ay[0] self._xaxisatts[ 'long_name'] = 'x-coordinate of polar-stereographic projection' self._xaxisatts['standard_name'] = 'projection_x_coordinate' self._xaxisatts['units'] = 'm' self._xaxisatts['axis'] = 'X' self._yaxisatts[ 'long_name'] = 'y-coordinate of polar-stereographic projection' self._yaxisatts['standard_name'] = 'projection_y_coordinate' self._yaxisatts['units'] = 'm' self._yaxisatts['axis'] = 'Y' self.xaxis = _axis_type('xc', self._xaxisatts, self._ax) self.yaxis = _axis_type('yc', self._yaxisatts, self._ay) self.gridaxes = [self.yaxis, self.xaxis] self.lon = _var_type('lon', self._lonatts, self.gridaxes, self._lonarray) self.lat = _var_type('lat', self._latatts, self.gridaxes, self._latarray) return (self._false_easting, self._false_northing, self.xaxis, self.yaxis, \ self.gridaxes, self.lon, self.lat)
def getNiNj(lonVal, latVal, gridID): """ Get the ni,nj position in a grid for a given lon/lat value. Function returns None if lon/lat value is out of bounds. """ xypos = rmn.gdxyfll(gridID, latVal, lonVal) ni = int(math.floor(xypos['x'])) - 1 #-1 to use 0 as list index nj = int(math.floor(xypos['y'])) - 1 gridData = rmn.gdll(gridID) if ni >= len(gridData['lon']) or nj >= len(gridData['lon'][0]): print( 'lon lat values of station outside of grid domain. Please check your values.' ) return None else: return ni, nj
def gdxyfll(latin, lonin, nij, grtyp, refparam, xyAxis, hasAxis, ij0): """Get (x, y) pairs cooresponding to (lat, lon) grid coordinates (x, y) = Fstdc.gdxyfll(latin, lonin, (ni, nj), grtyp, (grref, ig1, ig2, ig3, ig4), (xs, ys), hasAxis, (i0, j0)) @param latin, lonin: input coordinates (as float32 numpy array) @param (ni, nj) .. (i0, j0): Grid definition parameters @return (x, y): Computed x and y coordinates (as floating point) """ try: gid = _getGridHandle(nij[0], nij[1], grtyp, refparam[0], refparam[1], refparam[2], refparam[3], refparam[4], ij0[0], ij0[1], xyAxis[0], xyAxis[1]) except: raise error("gdxyfll: Invalid Grid Desc") try: xyc = _rmn.gdxyfll(gid, latin, lonin) except: raise error("gdxyfll: Problem computing x, y coor") return (xyc['x'], xyc['y'])
def defineZPSGrid(txtRec, verbose=False): """ Define a North polar sterographic grid, ezscint encoded See: https://wiki.cmc.ec.gc.ca/wiki/Python-RPN/2.1/rpnpy/librmn/grids#defGrid_PS """ if txtRec['Projection'] != 'PolarStereographic': raise ValueError('Unknown projection: {}'.format(txtRec['Projection'])) if int(float(txtRec['TrueLatitude'])) != 60: raise ValueError('Cannot encode TrueLatitude of: {}'.format(txtRec['TrueLatitude'])) if verbose: sys.stdout.write('Defining a North PS grid: {}\n'.format(filename)) ni, nj = txtRec['Data'].shape ## First define a base projection as a grid centered on the N-pole pi, pj = float(ni)/2., float(nj)/2. gp = { 'grtyp' : 'N', 'north' : True, 'ni' : ni, 'nj' : nj, 'pi' : pi, 'pj' : pj, 'd60' : float(txtRec['Scale']) * 1000., 'dgrw' : float(txtRec['ReferenceLongitude']), } g = rmn.encodeGrid(gp) ## Second correct the base grid position lon0 = float(txtRec['LonCentre']) lat0 = float(txtRec['LatCentre']) xy = rmn.gdxyfll(g['id'], lat0, lon0) gp['pi'] = float(ni) - xy['x'][0] gp['pj'] = float(nj) - xy['y'][0] g = rmn.encodeGrid(gp) return g
(lon,lat) = np.loadtxt(options.lolafile, dtype=np.float32, unpack=True) ## lat = np.asfortranarray(lat, dtype=np.float32) ## lon = np.asfortranarray(lon, dtype=np.float32) except: raise IOError('Problem reading the lola file: %s' % (options.lolafile)) # Interpolate input data to lat lon and print rmn.ezsetopt(rmn.EZ_OPT_INTERP_DEGREE,inttypelist[inttype]) #rmn.ezsetopt(rmn.EZ_OPT_EXTRAP_DEGREE,rmn.EZ_EXTRAP_MAX) (ni,nj) = data.shape outfile = open(options.outfile, 'w') for n in xrange(lat.size): (lat2,lon2) = (np.asarray([lat[n]]),np.asarray([lon[n]])) lldata2 = rmn.gdllsval(grid, lat2, lon2, data) xypos2 = rmn.gdxyfll(grid, lat2, lon2) extrap = '' if (xypos2['x'][0] < 1. or xypos2['x'][0] > ni or xypos2['y'][0] < 1. or xypos2['y'][0] > nj): extrap='extrap' outfile.write("%9.5f, %9.5f, %9.5f, %s\n" % (lon[n], lat[n], lldata2[0], extrap)) del lldata2, lat2, lon2, xypos2 outfile.close() # Close the RPN STD file try: rmn.fstcloseall(funit) except: pass
# Convert latlon to xy # Use results to add to lat and lon list of coordinates for given concentration import os import rpnpy.librmn.all as rmn import numpy as np defaultLat = 0 defaultLon = 0 getGrid(directory) xypost = rmn.gdxyfll(grid, lat=defaultLat, lon=defaultLon) gridx = np.int
def getFuzzyNiNj(lonVal, latVal, gridData): print('Now fuzzing: [{},{}]'.format(lonVal, latVal)) xypos = rmn.gdxyfll(gridData, latVal, lonVal) ni = int(round(xypos['x'])) - 1 #-1 to use 0 as list index nj = int(round(xypos['y'])) - 1 return ni, nj
fileMeta['iunit'] = fileID #add to dictionary as key,val pair gridData = rmn.ezqkdef(fileMeta) gridDecode = rmn.decodeGrid(gridData) #use this for information, not really needed if just getting all lat lon values, but can get bottom left corner if needed for something else llGridData = rmn.gdll(gridData) # is a dictionary of two arrays for lat and lon latData = llGridData['lat'] lonData = llGridData['lon'] return latData, lonData // lat0, lon 0 = lon lat of lower left corner of grid using N and E(from prime meridian, can go over and up to 360 instead of using west) >>> for locx in range(dataRec['ni']): ... for locy in range(dataRec['nj']): ... xypos=rmn.gdxyfll(gridData,lat=latDic[locx][locy],lon=lonDic[locx][locy]) ... xlist+=[np.int(xypos['x'][0])] ... ylist+=[np.int(xypos['y'][0])] ... >>> >>> len(xlist) 495624 >>> len(ylist) 495624 >>> >>> fileMeta = rmn.fstprm(dataKey) >>> fileMeta['iunit'] Traceback (most recent call last):
def getFuzzyNiNj(lonVal, latVal, gridData): xypos = rmn.gdxyfll(gridData, latVal, lonVal) ni = int(round(xypos['x'])) - 1 #-1 to use 0 as list index nj = int(round(xypos['y'])) - 1 return ni, nj
unpack=True) ## lat = np.asfortranarray(lat, dtype=np.float32) ## lon = np.asfortranarray(lon, dtype=np.float32) except: raise IOError('Problem reading the lola file: %s' % (options.lolafile)) # Interpolate input data to lat lon and print rmn.ezsetopt(rmn.EZ_OPT_INTERP_DEGREE, inttypelist[inttype]) #rmn.ezsetopt(rmn.EZ_OPT_EXTRAP_DEGREE,rmn.EZ_EXTRAP_MAX) (ni, nj) = data.shape outfile = open(options.outfile, 'w') for n in range(lat.size): (lat2, lon2) = (np.asarray([lat[n]]), np.asarray([lon[n]])) lldata2 = rmn.gdllsval(grid, lat2, lon2, data) xypos2 = rmn.gdxyfll(grid, lat2, lon2) extrap = '' if (xypos2['x'][0] < 1. or xypos2['x'][0] > ni or xypos2['y'][0] < 1. or xypos2['y'][0] > nj): extrap = 'extrap' outfile.write("%9.5f, %9.5f, %9.5f, %s\n" % (lon[n], lat[n], lldata2[0], extrap)) del lldata2, lat2, lon2, xypos2 outfile.close() # Close the RPN STD file try: rmn.fstcloseall(funit) except: pass