def testLevels8_prof(self): vgd0ptr = self._newReadBcmk() MB2PA = 100. p0_stn_mb = 1013. * MB2PA prof = vgd.vgd_levels(vgd0ptr, p0_stn_mb, double_precision=True) self.assertEqual([int(x) for x in prof[0:5]*10000.], [100000, 138426, 176879, 241410, 305984]) self.assertEqual(len(prof.shape),1) self.assertEqual(prof.dtype,np.float64)
def testDiag_withref8_3d(self): ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip() fileName = os.path.join(ATM_MODEL_DFILES,'bcmk_toctoc','2009042700_000') fileId = rmn.fstopenall(fileName, rmn.FST_RO) vgd0ptr = vgd.vgd_read(fileId) levels8 = vgd.vgd_levels(vgd0ptr, fileId, double_precision=True) rmn.fstcloseall(fileId) (ni,nj,nk) = levels8.shape self.assertEqual([int(x) for x in levels8[ni//2,nj//2,0:5]*10000.], [100000, 138425, 176878, 241408, 305980]) self.assertEqual(len(levels8.shape),3) self.assertEqual(levels8.dtype,np.float64)
def get_levels_press(fileId, vGrid, shape, ip1list, datev=-1, ip2=-1, ip3=-1, typvar=' ', etiket=' ', verbose=False): """ """ rfldName = _vgd.vgd_get(vGrid, 'RFLD') rfld = _np.empty(shape, dtype=_np.float32, order='F') rfld[:] = 1000. * _cst.MB2PA if rfldName: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, ip3=ip3, typvar=typvar, etiket=etiket) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, typvar=typvar, etiket=etiket) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, etiket=etiket) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName) if not r2d is None: if verbose: print("Read {nomvar} ip1={ip1} ip2={ip2} ip3={ip3} typv={typvar} etk={etiket}".format(**r2d)) ## g = _rmn.readGrid(fileId, r2d) ## if len(xpts) > 0: ## v1 = _rmn.gdxysval(g['id'], xpts, ypts, r2d['d']) ## rfld[0:len(xy)] = v1[:] ## if len(lats) > 0: ## v1 = _rmn.gdllsval(g['id'], lats, lons, r2d['d']) ## rfld[len(xy):len(xy)+len(ll)] = v1[:] rfld[:,:] = r2d['d'][:,:] * _cst.MB2PA phPa = _vgd.vgd_levels(vGrid, rfld, ip1list) phPa[:,:,:] /= _cst.MB2PA return { 'rfld' : rfld, 'phPa' : phPa }
def test_51(self): """ Vertical Interpolation See also: scipy.interpolate.interp1d """ import os, sys, datetime import numpy as np from scipy.interpolate import interp1d as scipy_interp1d import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd MB2PA = 100. # Restrict to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL, rmn.FSTOPI_MSG_CATAST) # Open Input file hour = 48 fdate = datetime.date.today().strftime('%Y%m%d') + '00_0' + str(hour) CMCGRIDF = os.getenv('CMCGRIDF').strip() fileNameOut = os.path.join(CMCGRIDF, 'prog', 'regeta', fdate) try: fileIdIn = rmn.fstopenall(fileNameOut, rmn.FST_RO) except: sys.stderr.write("Problem opening the input file: %s\n" % fileNameOut) sys.exit(1) try: # Get the vgrid def present in the file # and the full list of ip1 # and the surface reference field name for the coor vIn = vgd.vgd_read(fileIdIn) ip1listIn0 = vgd.vgd_get(vIn, 'VIPT') rfldNameIn = vgd.vgd_get(vIn, 'RFLD') vkind = vgd.vgd_get(vIn, 'KIND') vver = vgd.vgd_get(vIn, 'VERS') VGD_KIND_VER_INV = dict( (v, k) for k, v in vgd.VGD_KIND_VER.items()) vtype = VGD_KIND_VER_INV[(vkind, vver)] print( "CB51: Found vgrid type=%s (kind=%d, vers=%d) with %d levels, RFLD=%s" % (vtype, vkind, vver, len(ip1listIn0), rfldNameIn)) # Trim the list of thermo ip1 to actual levels in files for TT # since the vgrid in the file is a super set of all levels # and get their "key" ip1Keys = [] rshape = None for ip1 in ip1listIn0: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileIdIn, nomvar='TT', ip2=hour, ip1=rmn.ip1_all(lval, lkind)) if key is not None: print("CB51: Found TT at ip1=%d, ip2=%d" % (ip1, hour)) ip1Keys.append((ip1, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(ip1Keys)) # Read every level for TT at ip2=hour, re-use 2d array while reading # and store the data in a 3d array # with lower level at nk, top at 0 as in the model r2d = {'d': None} r3d = None k = 0 gIn = None for ip1, key in ip1Keys: try: r2d = rmn.fstluk(key, dataArray=r2d['d']) print("CB51: Read TT at ip1=%d, ip2=%d" % (ip1, hour)) if r3d is None: r3d = r2d.copy() r3d['d'] = np.empty(rshape, dtype=r2d['d'].dtype, order='FORTRAN') r3d['d'][:, :, k] = r2d['d'][:, :] k += 1 if gIn is None: gIn = rmn.readGrid(fileIdIn, r2d) print("CB51: Read the horizontal grid descriptors") except: pass # Add the vgrid and the actual ip1 list in the r3d dict, update shape and nk r3d['vgd'] = vIn r3d['ip1list'] = [x[0] for x in ip1Keys] r3d['shape'] = rshape r3d['nk'] = rshape[2] # Read the Input reference fields rfldIn = None if rfldNameIn: rfldIn = rmn.fstlir(fileIdIn, nomvar=rfldNameIn, ip2=hour) if rfldNameIn.strip() == 'P0': rfldIn['d'][:] *= MB2PA print( "CB51: Read input RFLD=%s at ip2=%d [min=%7.0f, max=%7.0f]" % (rfldNameIn, hour, rfldIn['d'].min(), rfldIn['d'].max())) except: raise # pass finally: # Close file even if an error occured above rmn.fstcloseall(fileIdIn) # Define the destination vertical grid/levels try: lvlsOut = (500., 850., 1000.) vOut = vgd.vgd_new_pres(lvlsOut) ip1listOut = vgd.vgd_get(vOut, 'VIPT') rfldNameOut = vgd.vgd_get(vIn, 'RFLD') rfldOut = None # in this case, Pressure levels, there are no RFLD print("CB51: Defined a Pres vgrid with lvls=%s" % str(lvlsOut)) except: sys.stderr.write("Problem creating a new vgrid\n") sys.exit(1) # Get input and output 3d pressure cubes try: ## if rfldIn is None: ## rfldIn = pIn = vgd.vgd_levels(vIn, ip1list=r3d['ip1list'], rfld=rfldIn['d']) print( "CB51: Computed input pressure cube, k0:[min=%7.0f, max=%7.0f], nk:[min=%7.0f, max=%7.0f]" % (pIn[:, :, 0].min(), pIn[:, :, 0].max(), pIn[:, :, -1].min(), pIn[:, :, -1].max())) if rfldOut is None: rfldOut = rfldIn # provide a dummy rfld for array shape pOut = vgd.vgd_levels(vOut, ip1list=ip1listOut, rfld=rfldOut['d']) print( "CB51: Computed output pressure cube, k0:[min=%7.0f, max=%7.0f], nk:[min=%7.0f, max=%7.0f]" % (pOut[:, :, 0].min(), pOut[:, :, 0].max(), pOut[:, :, -1].min(), pOut[:, :, -1].max())) except: raise sys.stderr.write("Problem computing pressure cubes\n") sys.exit(1) # Use scipy.interpolate.interp1d to vertically interpolate try: ## f = scipy_interp1d(fromLvls, toLvls, kind='cubic', ## assume_sorted=True, bounds_error=False, ## fill_value='extrapolate', copy=False) ## # Unfortunately, looks like interp1d take colomn data ## f = scipy_interp1d(pIn, r3d['d'], kind='cubic', ## bounds_error=False, ## fill_value='extrapolate', copy=False) ## r3dout = f(pOut) ## # Unfortunately, assume_sorted, 'extrapolate' not support in my version ## extrap_value = 'extrapolate' # -99999. ## # Way too slow, needs a C implementation extrap_value = -999. ## for j in range(rshape[1]): ## for i in range(rshape[0]): ## f = scipy_interp1d(pIn[i,j,:], r3d['d'][i,j,:], ## kind='cubic', ## bounds_error=False, ## fill_value=extrap_value, copy=False) ## r1d = f(pOut[i,j,:]) ## #print i,j,r1d except: raise sys.stderr.write("Problem Interpolating data\n") sys.exit(1)
def get_levels_press(fileId, vGrid, shape, ip1list, datev=-1, ip2=-1, ip3=-1, typvar=' ', etiket=' ', verbose=False): """ Read the reference surface field and computer the pressure cube press = get_levels_press(fileId, vGrid, shape, ip1list) press = get_levels_press(fileId, vGrid, shape, ip1list, datev, ip2, ip3, typvar, etiket) Args: fileId : unit number associated to the file obtained with fnom+fstouv vGrid : vertical grid descriptor shape : shape of the field ip1list : vertical levels ip lists datev : valid date ip2 : forecast hour ip3 : user defined identifier typvar : type of field etiket : label verbose : Print some info when true Returns: { 'rfld' : rfld, # 2d field reference value 'phPa' : phPa # 3d pressure values } Raises: TypeError on wrong input arg types ValueError on invalid input arg value FSTDError on any other error Examples: >>> import os, os.path >>> import rpnpy.librmn.all as rmn >>> import rpnpy.utils.fstd3d as fstd3d >>> ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip() >>> filename = os.path.join(ATM_MODEL_DFILES,'bcmk') >>> >>> # Open existing file in Rear Only mode >>> fileId = rmn.fstopenall(filename, rmn.FST_RO) >>> >>> # Get the pressure cube >>> ipkeys = fstd3d.get_levels_keys(fileId, 'TT', thermoMom='VIPT') >>> ip1list = [ip1 for ip1,key in ipkeys['ip1keys']] >>> shape = rmn.fstinf(fileId, nomvar='TT')['shape'][0:2] >>> press = fstd3d.get_levels_press(fileId, ipkeys['vgrid'], shape, ip1list) >>> print('# {} {} {}'.format(shape, press['rfld'].shape, press['phPa'].shape)) # (200, 100) (200, 100) (200, 100, 80) >>> rmn.fstcloseall(fileId) See Also: get_levels_keys fst_read_3d rpnpy.librmn.fstd98.fstlir rpnpy.librmn.fstd98.fstprm rpnpy.librmn.fstd98.fstluk rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.vgd.base.vgd_levels """ rfldName = _vgd.vgd_get(vGrid, 'RFLD') rfld = _np.empty(shape, dtype=_np.float32, order='F') rfld[:] = 1000. * _cst.MB2PA if rfldName: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, ip3=ip3, typvar=typvar, etiket=etiket) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, typvar=typvar, etiket=etiket) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, etiket=etiket) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev) if r2d is None: r2d = _rmn.fstlir(fileId, nomvar=rfldName) if not r2d is None: if verbose: print( "Read {nomvar} ip1={ip1} ip2={ip2} ip3={ip3} typv={typvar} etk={etiket}" .format(**r2d)) ## g = _rmn.readGrid(fileId, r2d) ## if len(xpts) > 0: ## v1 = _rmn.gdxysval(g['id'], xpts, ypts, r2d['d']) ## rfld[0:len(xy)] = v1[:] ## if len(lats) > 0: ## v1 = _rmn.gdllsval(g['id'], lats, lons, r2d['d']) ## rfld[len(xy):len(xy)+len(ll)] = v1[:] rfld[:, :] = r2d['d'][:, :] * _cst.MB2PA phPa = _vgd.vgd_levels(vGrid, rfld, ip1list) phPa[:, :, :] /= _cst.MB2PA return {'rfld': rfld, 'phPa': phPa}
def test_51(self): """ Vertical Interpolation See also: scipy.interpolate.interp1d """ import os, sys, datetime import numpy as np from scipy.interpolate import interp1d as scipy_interp1d import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd MB2PA = 100. # Restric to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL,rmn.FSTOPI_MSG_CATAST) # Open Input file hour = 48 fdate = datetime.date.today().strftime('%Y%m%d') + '00_0' + str(hour) CMCGRIDF = os.getenv('CMCGRIDF').strip() fileNameOut = os.path.join(CMCGRIDF, 'prog', 'regeta', fdate) try: fileIdIn = rmn.fstopenall(fileNameOut, rmn.FST_RO) except: sys.stderr.write("Problem opening the input file: %s\n" % fileNameOut) sys.exit(1) try: # Get the vgrid def present in the file # and the full list of ip1 # and the surface reference field name for the coor vIn = vgd.vgd_read(fileIdIn) ip1listIn0 = vgd.vgd_get(vIn, 'VIPT') rfldNameIn = vgd.vgd_get(vIn, 'RFLD') vkind = vgd.vgd_get(vIn, 'KIND') vver = vgd.vgd_get(vIn, 'VERS') VGD_KIND_VER_INV = dict((v, k) for k, v in vgd.VGD_KIND_VER.iteritems()) vtype = VGD_KIND_VER_INV[(vkind,vver)] print("CB51: Found vgrid type=%s (kind=%d, vers=%d) with %d levels, RFLD=%s" % (vtype, vkind, vver, len(ip1listIn0), rfldNameIn)) # Trim the list of thermo ip1 to actual levels in files for TT # since the vgrid in the file is a super set of all levels # and get their "key" ip1Keys = [] rshape = None for ip1 in ip1listIn0: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileIdIn, nomvar='TT', ip2=hour, ip1=rmn.ip1_all(lval, lkind)) if key is not None: print("CB51: Found TT at ip1=%d, ip2=%d" % (ip1, hour)) ip1Keys.append((ip1, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(ip1Keys)) # Read every level for TT at ip2=hour, re-use 2d array while reading # and store the data in a 3d array # with lower level at nk, top at 0 as in the model r2d = {'d' : None} r3d = None k = 0 gIn = None for ip1, key in ip1Keys: try: r2d = rmn.fstluk(key, dataArray=r2d['d']) print("CB51: Read TT at ip1=%d, ip2=%d" % (ip1, hour)) if r3d is None: r3d = r2d.copy() r3d['d'] = np.empty(rshape, dtype=r2d['d'].dtype, order='FORTRAN') r3d['d'][:,:,k] = r2d['d'][:,:] k += 1 if gIn is None: gIn = rmn.readGrid(fileIdIn, r2d) print("CB51: Read the horizontal grid descriptors") except: pass # Add the vgrid and the actual ip1 list in the r3d dict, update shape and nk r3d['vgd'] = vIn r3d['ip1list'] = [x[0] for x in ip1Keys] r3d['shape'] = rshape r3d['nk'] = rshape[2] # Read the Input reference fields rfldIn = None if rfldNameIn: rfldIn = rmn.fstlir(fileIdIn, nomvar=rfldNameIn, ip2=hour) if rfldNameIn.strip() == 'P0': rfldIn['d'][:] *= MB2PA print("CB51: Read input RFLD=%s at ip2=%d [min=%7.0f, max=%7.0f]" % (rfldNameIn, hour, rfldIn['d'].min(), rfldIn['d'].max())) except: raise # pass finally: # Close file even if an error occured above rmn.fstcloseall(fileIdIn) # Define the destination vertical grid/levels try: lvlsOut = (500.,850.,1000.) vOut = vgd.vgd_new_pres(lvlsOut) ip1listOut = vgd.vgd_get(vOut, 'VIPT') rfldNameOut = vgd.vgd_get(vIn, 'RFLD') rfldOut = None # in this case, Pressure levels, there are no RFLD print("CB51: Defined a Pres vgrid with lvls=%s" % str(lvlsOut)) except: sys.stderr.write("Problem creating a new vgrid\n") sys.exit(1) # Get input and output 3d pressure cubes try: ## if rfldIn is None: ## rfldIn = pIn = vgd.vgd_levels(vIn, ip1list=r3d['ip1list'], rfld=rfldIn['d']) print("CB51: Computed input pressure cube, k0:[min=%7.0f, max=%7.0f], nk:[min=%7.0f, max=%7.0f]" % (pIn[:,:,0].min(), pIn[:,:,0].max(), pIn[:,:,-1].min(), pIn[:,:,-1].max())) if rfldOut is None: rfldOut = rfldIn # provide a dummy rfld for array shape pOut = vgd.vgd_levels(vOut, ip1list=ip1listOut, rfld=rfldOut['d']) print("CB51: Computed output pressure cube, k0:[min=%7.0f, max=%7.0f], nk:[min=%7.0f, max=%7.0f]" % (pOut[:,:,0].min(), pOut[:,:,0].max(), pOut[:,:,-1].min(), pOut[:,:,-1].max())) except: raise sys.stderr.write("Problem computing pressure cubes\n") sys.exit(1) # Use scipy.interpolate.interp1d to vertically interpolate try: ## f = scipy_interp1d(fromLvls, toLvls, kind='cubic', ## assume_sorted=True, bounds_error=False, ## fill_value='extrapolate', copy=False) ## # Unfortunately, looks like interp1d take colomn data ## f = scipy_interp1d(pIn, r3d['d'], kind='cubic', ## bounds_error=False, ## fill_value='extrapolate', copy=False) ## r3dout = f(pOut) ## # Unfortunately, assume_sorted, 'extrapolate' not support in my version ## extrap_value = 'extrapolate' # -99999. ## # Way too slow, needs a C implementation extrap_value = -999. ## for j in xrange(rshape[1]): ## for i in xrange(rshape[0]): ## f = scipy_interp1d(pIn[i,j,:], r3d['d'][i,j,:], ## kind='cubic', ## bounds_error=False, ## fill_value=extrap_value, copy=False) ## r1d = f(pOut[i,j,:]) ## #print i,j,r1d except: raise sys.stderr.write("Problem Interpolating data\n") sys.exit(1)