def test_ConvertIp_toIP(self): """convertIp to ip1 should give known result with known input""" for lvlnew,lvlold,ipnew,ipold,kind in self.ip1knownValues: ipnew2 = rmn.convertIp(rmn.CONVIP_P2IP_NEW,lvlnew,kind) self.assertEqual(ipnew2,ipnew) ipold2 = rmn.convertIp(rmn.CONVIP_P2IP_OLD,lvlold,kind) self.assertEqual(ipold2,ipold)
def test_14bqd(self): import os, sys, datetime import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd rmn.fstopt(rmn.FSTOP_MSGLVL,rmn.FSTOPI_MSG_CATAST) fdate = datetime.date.today().strftime('%Y%m%d') + '00_048' CMCGRIDF = os.getenv('CMCGRIDF').strip() fileId = rmn.fstopenall(CMCGRIDF+'/prog/regpres/'+fdate, rmn.FST_RO) v = vgd.vgd_read(fileId) (tlvlkeys, rshape) = ([], None) for ip1 in vgd.vgd_get(v, 'VIPT'): (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileId, nomvar='TT', ip2=48, ip1=rmn.ip1_all(lval, lkind)) if key is not None: tlvlkeys.append((ip1, key['key'])) if rshape is None and key is not None: rshape = key['shape'] (r2d, r3d, k, rshape) = ({'d' : None}, None, 0, (rshape[0], rshape[1], len(tlvlkeys))) for ip1, key in tlvlkeys: r2d = rmn.fstluk(key, dataArray=r2d['d']) if r3d is None: r3d = r2d.copy() r3d['d'] = np.empty(rshape, dtype=r2d['d'].dtype, order='FORTRAN') r3d['d'][:,:,k] = r2d['d'][:,:] rmn.fstcloseall(fileId) r3d.update({'vgd':v, 'ip1list':[x[0] for x in tlvlkeys], 'shape':rshape, 'nk':rshape[2]}) (i1, j1) = (rshape[0]//2, rshape[1]//2) print("CB14bqd: The TT profile at point (%d, %d) is:" % (i1, j1)) for k in xrange(rshape[2]): (ldiagval, ldiagkind) = rmn.convertIp(rmn.CONVIP_DECODE, r3d['ip1list'][k]) print("CB14bqd: TT(%d, %d, %7.2f %s) = %6.1f C [mean=%6.1f, std=%6.1f, min=%6.1f, max=%6.1f]" % (i1, j1, ldiagval, rmn.kindToString(ldiagkind), r3d['d'][i1,j1,k], r3d['d'][:,:,k].mean(), r3d['d'][:,:,k].std(), r3d['d'][:,:,k].min(), r3d['d'][:,:,k].max()))
def test_ConvertIp_toIP(self): """convertIp to ip1 should give known result with known input""" for lvlnew, lvlold, ipnew, ipold, kind in self.ip1knownValues: ipnew2 = rmn.convertIp(rmn.CONVIP_P2IP_NEW, lvlnew, kind) self.assertEqual(ipnew2, ipnew) ipold2 = rmn.convertIp(rmn.CONVIP_P2IP_OLD, lvlold, kind) self.assertEqual(ipold2, ipold)
def test_ConvertIp_fromIP(self): """ConvertIp from ip1 should give known result with known input""" for lvlnew, lvlold, ipnew, ipold, kind in self.ip1knownValues: (lvl2, kind2) = rmn.convertIp(rmn.CONVIP_IP2P, ipnew) self.assertEqual(kind2, kind) self.assertAlmostEqual(lvlnew, lvl2, 6) (lvl2, kind2) = rmn.convertIp(rmn.CONVIP_IP2P, ipold) self.assertEqual(kind2, kind) self.assertAlmostEqual(lvlold, lvl2, 6)
def test_ConvertIp_Sanity(self): """ConvertIp fromIP then toIP should give back the provided IP""" for lvlnew, lvlold, ipnew, ipold, kind in self.ip1knownValues: (lvl2, kind2) = rmn.convertIp(rmn.CONVIP_IP2P, ipnew) ipnew2 = rmn.convertIp(rmn.CONVIP_P2IP_NEW, lvl2, kind2) self.assertEqual(ipnew2, ipnew) (lvl2, kind2) = rmn.convertIp(rmn.CONVIP_IP2P, ipold) ipold2 = rmn.convertIp(rmn.CONVIP_P2IP_OLD, lvl2, kind2) self.assertEqual(ipold2, ipold)
def test_ConvertIp_Sanity(self): """ConvertIp fromIP then toIP should give back the provided IP""" for lvlnew,lvlold,ipnew,ipold,kind in self.ip1knownValues: (lvl2,kind2) = rmn.convertIp(rmn.CONVIP_IP2P,ipnew) ipnew2 = rmn.convertIp(rmn.CONVIP_P2IP_NEW,lvl2,kind2) self.assertEqual(ipnew2,ipnew) (lvl2,kind2) = rmn.convertIp(rmn.CONVIP_IP2P,ipold) ipold2= rmn.convertIp(rmn.CONVIP_P2IP_OLD,lvl2,kind2) self.assertEqual(ipold2,ipold)
def test_ConvertIp_fromIP(self): """ConvertIp from ip1 should give known result with known input""" for lvlnew,lvlold,ipnew,ipold,kind in self.ip1knownValues: (lvl2,kind2) = rmn.convertIp(rmn.CONVIP_IP2P,ipnew) self.assertEqual(kind2,kind) self.assertAlmostEqual(lvlnew,lvl2,6) (lvl2,kind2) = rmn.convertIp(rmn.CONVIP_IP2P,ipold) self.assertEqual(kind2,kind) self.assertAlmostEqual(lvlold,lvl2,6)
def test_10(self): """ Encoding values Encoding values are usefull in 2 situations: * providing the metadata when writing a record, it is best to encode in the new format then * specify search criterions to read a record, it is best to search for the old and new formats, the ip1_all and ip2_all functions can be used for that sake as long as no value range are needed. See also: rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.convertIPtoPK rpnpy.librmn.fstd98.EncodeIp rpnpy.librmn.fstd98.ip1_all rpnpy.librmn.fstd98.ip2_all rpnpy.librmn.fstd98.ip3_all rpnpy.librmn.proto.FLOAT_IP rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstinf rpnpy.librmn.fstd98.fstinl rpnpy.librmn.fstd98.fstprm rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.FSTDError rpnpy.librmn.RMNError rpnpy.librmn.const """ import os import rpnpy.librmn.all as rmn ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES') fileName = os.path.join(ATM_MODEL_DFILES.strip(), 'bcmk/2009042700_012') ip1new = rmn.convertIp(rmn.CONVIP_ENCODE, 850., rmn.KIND_PRESSURE) ip1old = rmn.convertIp(rmn.CONVIP_ENCODE_OLD, 10., rmn.KIND_ABOVE_SEA) ip1newall = rmn.ip1_all(1., rmn.KIND_HYBRID) # Use ip1newall as a search criterion to find a record try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) ktt = rmn.fstinf(fileId, nomvar='TT', ip1=ip1newall) except: raise rmn.FSTDError( "Problem finding of TT with ip1=%d record from file: %s" % (ip1newall, fileName)) if not ktt: print("Not Found: TT with ip1=%d record from file: %s" % (ip1newall, fileName))
def test_14bqd(self): import os, sys, datetime import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd rmn.fstopt(rmn.FSTOP_MSGLVL, rmn.FSTOPI_MSG_CATAST) fdate = datetime.date.today().strftime('%Y%m%d') + '00_048' CMCGRIDF = os.getenv('CMCGRIDF').strip() fileId = rmn.fstopenall(CMCGRIDF + '/prog/regpres/' + fdate, rmn.FST_RO) v = vgd.vgd_read(fileId) (tlvlkeys, rshape) = ([], None) for ip1 in vgd.vgd_get(v, 'VIPT'): (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileId, nomvar='TT', ip2=48, ip1=rmn.ip1_all(lval, lkind)) if key is not None: tlvlkeys.append((ip1, key['key'])) if rshape is None and key is not None: rshape = key['shape'] (r2d, r3d, k, rshape) = ({ 'd': None }, None, 0, (rshape[0], rshape[1], len(tlvlkeys))) for ip1, key in tlvlkeys: r2d = rmn.fstluk(key, dataArray=r2d['d']) if r3d is None: r3d = r2d.copy() r3d['d'] = np.empty(rshape, dtype=r2d['d'].dtype, order='FORTRAN') r3d['d'][:, :, k] = r2d['d'][:, :] rmn.fstcloseall(fileId) r3d.update({ 'vgd': v, 'ip1list': [x[0] for x in tlvlkeys], 'shape': rshape, 'nk': rshape[2] }) (i1, j1) = (rshape[0] // 2, rshape[1] // 2) print("CB14bqd: The TT profile at point (%d, %d) is:" % (i1, j1)) for k in range(rshape[2]): (ldiagval, ldiagkind) = rmn.convertIp(rmn.CONVIP_DECODE, r3d['ip1list'][k]) print( "CB14bqd: TT(%d, %d, %7.2f %s) = %6.1f C [mean=%6.1f, std=%6.1f, min=%6.1f, max=%6.1f]" % (i1, j1, ldiagval, rmn.kindToString(ldiagkind), r3d['d'][i1, j1, k], r3d['d'][:, :, k].mean(), r3d['d'][:, :, k].std(), r3d['d'][:, :, k].min(), r3d['d'][:, :, k].max()))
def level_to_ip1(level_list, kind): """Encode level value to ip1 (Interface to convip) myip1List = Fstdc.level_to_ip1(level_list, kind) @param level_list list of level values (list of float) @param kind type of level (int) @return [(ip1new, ip1old), ...] (list of tuple of int) @exception TypeError @exception Fstdc.error """ try: return [(_rmn.convertIp(CONVIP_STYLE_NEW, lvl, kind), _rmn.convertIp(CONVIP_STYLE_OLD, lvl, kind)) for lvl in level_list] except: raise error("")
def test_14(self): """ Queries: Get Vertical Grid Info This example shows how to get the vertical grid definition and print some info. See also: rpnpy.librmn.fstd98.fstopt rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.kindToString rpnpy.vgd.base.vgd_read rpnpy.vgd.base.vgd_get rpnpy.librmn.const rpnpy.vgd.const """ import os, sys, datetime import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd # Restrict to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL, rmn.FSTOPI_MSG_CATAST) # Open file fdate = datetime.date.today().strftime('%Y%m%d') + '00_048' CMCGRIDF = os.getenv('CMCGRIDF').strip() fileName = os.path.join(CMCGRIDF, 'prog', 'regeta', fdate) try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) except: sys.stderr.write("Problem opening the file: %s\n" % fileName) sys.exit(1) try: # Get the vgrid definition present in the file v = vgd.vgd_read(fileId) # Get Some info about the vgrid vkind = vgd.vgd_get(v, 'KIND') vver = vgd.vgd_get(v, 'VERS') tlvl = vgd.vgd_get(v, 'VIPT') try: ip1diagt = vgd.vgd_get(v, 'DIPT') except: ip1diagt = 0 (ldiagval, ldiagkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1diagt) VGD_KIND_VER_INV = dict( (v, k) for k, v in vgd.VGD_KIND_VER.items()) vtype = VGD_KIND_VER_INV[(vkind, vver)] print( "CB14: Found vgrid type=%s (kind=%d, vers=%d) with %d levels and diag level=%7.2f%s (ip1=%d)" % (vtype, vkind, vver, len(tlvl), ldiagval, rmn.kindToString(ldiagkind), ip1diagt)) except: raise finally: # Close file even if an error occured above rmn.fstcloseall(fileId)
def test_10(self): """ Encoding values Encoding values are usefull in 2 situations: * providing the metadata when writing a record, it is best to encode in the new format then * specify search criterions to read a record, it is best to search for the old and new formats, the ip1_all and ip2_all functions can be used for that sake as long as no value range are needed. See also: rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.convertIPtoPK rpnpy.librmn.fstd98.EncodeIp rpnpy.librmn.fstd98.ip1_all rpnpy.librmn.fstd98.ip2_all rpnpy.librmn.fstd98.ip3_all rpnpy.librmn.proto.FLOAT_IP rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstinf rpnpy.librmn.fstd98.fstinl rpnpy.librmn.fstd98.fstprm rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.FSTDError rpnpy.librmn.RMNError rpnpy.librmn.const """ import os import rpnpy.librmn.all as rmn ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES') fileName = os.path.join(ATM_MODEL_DFILES.strip(), 'bcmk/2009042700_012') ip1new = rmn.convertIp(rmn.CONVIP_ENCODE, 850., rmn.KIND_PRESSURE) ip1old = rmn.convertIp(rmn.CONVIP_ENCODE_OLD, 10., rmn.KIND_ABOVE_SEA) ip1newall = rmn.ip1_all(1., rmn.KIND_HYBRID) # Use ip1newall as a search criterion to find a record try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) ktt = rmn.fstinf(fileId, nomvar='TT', ip1=ip1newall) except: raise rmn.FSTDError("Problem finding of TT with ip1=%d record from file: %s" % (ip1newall, fileName)) if not ktt: print("Not Found: TT with ip1=%d record from file: %s" % (ip1newall, fileName))
def test_14(self): """ Queries: Get Vertical Grid Info This example shows how to get the vertical grid definition and print some info. See also: rpnpy.librmn.fstd98.fstopt rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.kindToString rpnpy.vgd.base.vgd_read rpnpy.vgd.base.vgd_get rpnpy.librmn.const rpnpy.vgd.const """ import os, sys, datetime import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd # Restrict to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL,rmn.FSTOPI_MSG_CATAST) # Open file fdate = datetime.date.today().strftime('%Y%m%d') + '00_048' CMCGRIDF = os.getenv('CMCGRIDF').strip() fileName = os.path.join(CMCGRIDF, 'prog', 'regpres', fdate) try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) except: sys.stderr.write("Problem opening the file: %s\n" % fileName) sys.exit(1) try: # Get the vgrid definition present in the file v = vgd.vgd_read(fileId) # Get Some info about the vgrid vkind = vgd.vgd_get(v, 'KIND') vver = vgd.vgd_get(v, 'VERS') ip1diagt = vgd.vgd_get(v, 'DIPT') tlvl = vgd.vgd_get(v, 'VIPT') VGD_KIND_VER_INV = dict((v, k) for k, v in vgd.VGD_KIND_VER.iteritems()) vtype = VGD_KIND_VER_INV[(vkind,vver)] (ldiagval, ldiagkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1diagt) print("CB14: Found vgrid type=%s (kind=%d, vers=%d) with %d levels and diag level=%7.2f%s (ip1=%d)" % (vtype, vkind, vver, len(tlvl), ldiagval, rmn.kindToString(ldiagkind), ip1diagt)) except: raise finally: # Close file even if an error occured above rmn.fstcloseall(fileId)
def ConvertP2Ip(pvalue, pkind, istyle): """Encoding of P (real value, kind) into IP123 RPN-STD files tags ip123 = Fstdc.ConvertP2Ip(pvalue, pkind, istyle) @param pvalue, value to encode, units depends on the kind (float) @param pkind, kind of pvalue (int) @param istyle, CONVIP_STYLE_NEW/OLD/DEFAULT (int) @return IP encoded value (int) @exception TypeError @exception Fstdc.error """ return _rmn.convertIp(istyle, pvalue, pkind)
def ConvertIp2P(ip123, imode): """Decoding of IP123 RPN-STD files tags into P (real values, kind) (pvalue, pkind) = Fstdc.ConvertIp2P(ip123, imode) @param ip123, IP encoded value (int) @param imode, CONVIP_IP2P_DEFAULT or CONVIP_IP2P_31BITS (int) @return pvalue, real decoded value, units depends on the kind (float) @return pkind, kind of pvalue (int) @exception TypeError @exception Fstdc.error """ return _rmn.convertIp(imode, ip123)
def ip1_to_level(ip1_list): """Decode ip1 to level type, value (Interface to convip) myLevelList = Fstdc.ip1_to_level(ip1_list) @param tuple/list of ip1 values to decode @return list of tuple (level, kind) @exception TypeError @exception Fstdc.error """ try: return [_rmn.convertIp(CONVIP_IP2P_DEFAULT, ip1) for ip1 in ip1_list] except: raise error("")
def test_9(self): """ Decoding values When reading an FSTD record metadata, the ip1, ip2, ip3 contains the encoded time and levels values. In the old format, ip1 is used for the level value and ip2 is a none encoded time value in hours. In the new format, all ip1, ip2, ip3 can be used to specify time and level as well as ranges. See also: rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.convertIPtoPK rpnpy.librmn.fstd98.DecodeIp rpnpy.librmn.fstd98.kindToString rpnpy.librmn.proto.FLOAT_IP rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstinf rpnpy.librmn.fstd98.fstinl rpnpy.librmn.fstd98.fstprm rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.FSTDError rpnpy.librmn.RMNError rpnpy.librmn.const """ import os import rpnpy.librmn.all as rmn ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES') fileName = os.path.join(ATM_MODEL_DFILES.strip(), 'bcmk/2009042700_012') # Get list of records try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) keyList = rmn.fstinl(fileId, nomvar='TT') except: raise rmn.FSTDError( "Problem getting list of TT records from file: %s" % fileName) # Get metadata and Decode level value try: for k in keyList: recMeta = rmn.fstprm(k) (level, ikind) = rmn.convertIp(rmn.CONVIP_DECODE, recMeta['ip1']) kindstring = rmn.kindToString(ikind) print("Found %s at level %f %s" % (recMeta['nomvar'], level, kindstring)) except: raise rmn.FSTDError( "Problem getting metadata for TT from file: %s " % fileName) rmn.fstcloseall(fileId)
def get_levels_keys(fileId, nomvar, datev=-1, ip2=-1, ip3=-1, typvar=' ', etiket=' ', vGrid=None, thermoMom='VIPT', verbose=False): """ """ #TODO: try to get the sorted ip1 list w/o vgrid, because vgrid doesn;t support 2 different vertical coor in the same file (or list of linked files) # Get the vgrid definition present in the file if vGrid is None: if verbose: print("Getting vertical grid description") _vgd.vgd_put_opt('ALLOW_SIGMA', _vgd.VGD_ALLOW_SIGMA) vGrid = _vgd.vgd_read(fileId) vip = _vgd.vgd_get(vGrid, thermoMom) if verbose: vkind = _vgd.vgd_get(vGrid, 'KIND') vver = _vgd.vgd_get(vGrid, 'VERS') vtype = _vgd.VGD_KIND_VER_INV[(vkind,vver)] print("Found %d %s levels of type %s" % (len(vip), thermoMom, vtype)) # Trim the list of ip1 to actual levels in files for nomvar # since the vgrid in the file is a super set of all levels # and get their "key" vipkeys = [] for ip1 in vip: (lval, lkind) = _rmn.convertIp(_rmn.CONVIP_DECODE, ip1) key = _rmn.fstinf(fileId, nomvar=nomvar, datev=datev, ip2=ip2, ip3=ip3, ip1=_rmn.ip1_all(lval, lkind), typvar=typvar, etiket=etiket) if key is not None: vipkeys.append((ip1, key['key'])) if datev == -1 or ip2 == -1 or ip3 == -1 or typvar.strip() == '' or etiket.strip() == '': meta = _rmn.fstprm(key) datev = meta['datev'] ip2 = meta['ip2'] ip3 = meta['ip3'] typvar = meta['typvar'] etiket = meta['etiket'] return { 'nomvar' : nomvar, 'datev' : datev, 'ip2' : ip2, 'ip3' : ip3, 'typvar' : typvar, 'etiket' : etiket, 'v' : vGrid, 'ip1keys': vipkeys }
def test_9(self): """ Decoding values When reading an FSTD record metadata, the ip1, ip2, ip3 contains the encoded time and levels values. In the old format, ip1 is used for the level value and ip2 is a none encoded time value in hours. In the new format, all ip1, ip2, ip3 can be used to specify time and level as well as ranges. See also: rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.convertIPtoPK rpnpy.librmn.fstd98.DecodeIp rpnpy.librmn.fstd98.kindToString rpnpy.librmn.proto.FLOAT_IP rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstinf rpnpy.librmn.fstd98.fstinl rpnpy.librmn.fstd98.fstprm rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.FSTDError rpnpy.librmn.RMNError rpnpy.librmn.const """ import os import rpnpy.librmn.all as rmn ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES') fileName = os.path.join(ATM_MODEL_DFILES.strip(), 'bcmk/2009042700_012') # Get list of records try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) keyList = rmn.fstinl(fileId, nomvar='TT') except: raise rmn.FSTDError("Problem getting list of TT records from file: %s" % fileName) # Get metadata and Decode level value try: for k in keyList: recMeta = rmn.fstprm(k) (level, ikind) = rmn.convertIp(rmn.CONVIP_DECODE, recMeta['ip1']) kindstring = rmn.kindToString(ikind) print("Found %s at level %f %s" % (recMeta['nomvar'], level, kindstring)) except: raise rmn.FSTDError("Problem getting metadata for TT from file: %s " % fileName) rmn.fstcloseall(fileId)
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)
try: #Get vertical grid definition from file v = vgd.vgd_read(file) #Get the list of ip1 on thermo levels in this file #tlvl = vgd.vgd_get(v, 'VIPT') tlvl = level # 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" tlvlkeys = [] rshape = None #for ip1 in tlvl: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, level) key = rmn.fstinf(file, nomvar=var, ip2=fhour, ip1=rmn.ip1_all(lval, lkind)) if key is not None: tlvlkeys.append((level, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(tlvlkeys)) r2d = {'d': None} r3d = None k = 0 try: r2d = rmn.fstluk(key, dataArray=r2d['d']) if r3d is None: r3d = r2d.copy() r3d['d'] = np.empty(rshape, dtype=r2d['d'].dtype, order='FORTRAN')
def test_14b(self): """ Queries: Get Vertical Grid info, Read 3D Field This example shows how to * get the vertical grid definition. * use it to read a 3D field (records on all levels) * then print a profile for this var See also: rpnpy.librmn.fstd98.fstopt rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.fstlinf rpnpy.librmn.fstd98.fstlluk rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.kindToString rpnpy.vgd.base.vgd_read rpnpy.vgd.base.vgd_get rpnpy.librmn.const rpnpy.vgd.const """ import os, sys, datetime import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd # Restrict to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL, rmn.FSTOPI_MSG_CATAST) # Open file fdate = datetime.date.today().strftime('%Y%m%d') + '00_048' CMCGRIDF = os.getenv('CMCGRIDF').strip() fileName = os.path.join(CMCGRIDF, 'prog', 'regeta', fdate) try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) except: sys.stderr.write("Problem opening the file: %s\n" % fileName) sys.exit(1) try: # Get the vgrid definition present in the file v = vgd.vgd_read(fileId) # Get the list of ip1 on thermo levels in this file tlvl = vgd.vgd_get(v, 'VIPT') # 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" tlvlkeys = [] rshape = None for ip1 in tlvl: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileId, nomvar='TT', ip2=48, ip1=rmn.ip1_all(lval, lkind)) if key is not None: tlvlkeys.append((ip1, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(tlvlkeys)) # Read every level for TT at ip2=48, 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 # Note that for efficiency reasons, if only a profile was needed, # only that profile would be saved instead of the whole 3d field r2d = {'d': None} r3d = None k = 0 for ip1, key in tlvlkeys: try: r2d = rmn.fstluk(key, dataArray=r2d['d']) 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 except: pass except: pass finally: # Close file even if an error occured above rmn.fstcloseall(fileId) # Add the vgrid and the actual ip1 list in the r3d dict, update shape and nk r3d['vgd'] = v r3d['ip1list'] = [x[0] for x in tlvlkeys] r3d['shape'] = rshape r3d['nk'] = rshape[2] # Print a profile of TT and stats by level (i1, j1) = (rshape[0] // 2, rshape[1] // 2) print("CB14b: The TT profile at point (%d, %d) is:" % (i1, j1)) for k in range(rshape[2]): ip1 = r3d['ip1list'][k] (ldiagval, ldiagkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) print( "CB14b: TT(%d, %d, %7.2f %s) = %6.1f C [mean=%6.1f, std=%6.1f, min=%6.1f, max=%6.1f]" % (i1, j1, ldiagval, rmn.kindToString(ldiagkind), r3d['d'][i1, j1, k], r3d['d'][:, :, k].mean(), r3d['d'][:, :, k].std(), r3d['d'][:, :, k].min(), r3d['d'][:, :, k].max()))
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)
def test_14b(self): """ Queries: Get Vertical Grid info, Read 3D Field This example shows how to * get the vertical grid definition. * use it to read a 3D field (records on all levels) * then print a profile for this var See also: rpnpy.librmn.fstd98.fstopt rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.fstlinf rpnpy.librmn.fstd98.fstlluk rpnpy.librmn.fstd98.convertIp rpnpy.librmn.fstd98.kindToString rpnpy.vgd.base.vgd_read rpnpy.vgd.base.vgd_get rpnpy.librmn.const rpnpy.vgd.const """ import os, sys, datetime import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd # Restrict to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL,rmn.FSTOPI_MSG_CATAST) # Open file fdate = datetime.date.today().strftime('%Y%m%d') + '00_048' CMCGRIDF = os.getenv('CMCGRIDF').strip() fileName = os.path.join(CMCGRIDF, 'prog', 'regpres', fdate) try: fileId = rmn.fstopenall(fileName, rmn.FST_RO) except: sys.stderr.write("Problem opening the file: %s\n" % fileName) sys.exit(1) try: # Get the vgrid definition present in the file v = vgd.vgd_read(fileId) # Get the list of ip1 on thermo levels in this file tlvl = vgd.vgd_get(v, 'VIPT') # 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" tlvlkeys = [] rshape = None for ip1 in tlvl: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileId, nomvar='TT', ip2=48, ip1=rmn.ip1_all(lval, lkind)) if key is not None: tlvlkeys.append((ip1, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(tlvlkeys)) # Read every level for TT at ip2=48, 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 # Note that for efficiency reasons, if only a profile was needed, # only that profile would be saved instead of the whole 3d field r2d = {'d' : None} r3d = None k = 0 for ip1, key in tlvlkeys: try: r2d = rmn.fstluk(key, dataArray=r2d['d']) 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 except: pass except: pass finally: # Close file even if an error occured above rmn.fstcloseall(fileId) # Add the vgrid and the actual ip1 list in the r3d dict, update shape and nk r3d['vgd'] = v r3d['ip1list'] = [x[0] for x in tlvlkeys] r3d['shape'] = rshape r3d['nk'] = rshape[2] # Print a profile of TT and stats by level (i1, j1) = (rshape[0]//2, rshape[1]//2) print("CB14b: The TT profile at point (%d, %d) is:" % (i1, j1)) for k in xrange(rshape[2]): ip1 = r3d['ip1list'][k] (ldiagval, ldiagkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) print("CB14b: TT(%d, %d, %7.2f %s) = %6.1f C [mean=%6.1f, std=%6.1f, min=%6.1f, max=%6.1f]" % (i1, j1, ldiagval, rmn.kindToString(ldiagkind), r3d['d'][i1,j1,k], r3d['d'][:,:,k].mean(), r3d['d'][:,:,k].std(), r3d['d'][:,:,k].min(), r3d['d'][:,:,k].max()))
def get_levels_keys(fileId, nomvar, datev=-1, ip2=-1, ip3=-1, typvar=' ', etiket=' ', vGrid=None, thermoMom='VIPT', verbose=False): """ Get from file the list of ip1 and fstd-record-key matching provided filters ipkeys = get_levels_keys(fileId, nomvar) Args: fileId : unit number associated to the file obtained with fnom+fstouv nomvar : variable name datev : valid date ip2 : forecast hour ip3 : user defined identifier typvar : type of field etiket : label vGrid : vertical grid descriptor thermoMom : 'VIPT' to get Thermo levels, 'VIPT' for momentum levels verbose : Print some info when true Returns: { 'nomvar' : nomvar, # variable name 'datev' : datev, # valid date 'ip2' : ip2, # forecast hour 'ip3' : ip3, # user defined identifier 'typvar' : typvar, # type of field 'etiket' : etiket, # label 'vgrid' : vGrid, # vertical grid descriptor as returned by vgd_read 'ip1keys': vipkeys # list of ip1 and corresponding FSTD rec key as # ((ip1,key1), (ip1b, key2), ...) } 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) >>> >>> # Find ip1, key for all TT in file >>> ipkeys = fstd3d.get_levels_keys(fileId, 'TT', thermoMom='VIPT', verbose=True) Getting vertical grid description Found 158 VIPT levels of type hyb >>> print('# Found {} levels for TT'.format(len(ipkeys['ip1keys']))) # Found 80 levels for TT >>> rmn.fstcloseall(fileId) See Also: get_levels_press fst_read_3d rpnpy.librmn.fstd98.fstinf rpnpy.librmn.fstd98.fstprm rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.vgd.base.vgd_read """ #TODO: try to get the sorted ip1 list w/o vgrid, because vgrid doesn;t support 2 different vertical coor in the same file (or list of linked files) # Get the vgrid definition present in the file if vGrid is None: if verbose: print("Getting vertical grid description") _vgd.vgd_put_opt('ALLOW_SIGMA', _vgd.VGD_ALLOW_SIGMA) vGrid = _vgd.vgd_read(fileId) vip = _vgd.vgd_get(vGrid, thermoMom) if verbose: vkind = _vgd.vgd_get(vGrid, 'KIND') vver = _vgd.vgd_get(vGrid, 'VERS') vtype = _vgd.VGD_KIND_VER_INV[(vkind, vver)] print("Found %d %s levels of type %s" % (len(vip), thermoMom, vtype)) # Trim the list of ip1 to actual levels in files for nomvar # since the vgrid in the file is a super set of all levels # and get their "key" vipkeys = [] for ip1 in vip: (lval, lkind) = _rmn.convertIp(_rmn.CONVIP_DECODE, ip1) key = _rmn.fstinf(fileId, nomvar=nomvar, datev=datev, ip2=ip2, ip3=ip3, ip1=_rmn.ip1_all(lval, lkind), typvar=typvar, etiket=etiket) if key is not None: vipkeys.append((ip1, key['key'])) if (datev == -1 or ip2 == -1 or ip3 == -1 or typvar.strip() == '' or etiket.strip() == ''): meta = _rmn.fstprm(key) datev = meta['datev'] ip2 = meta['ip2'] ip3 = meta['ip3'] typvar = meta['typvar'] etiket = meta['etiket'] return { 'nomvar': nomvar, 'datev': datev, 'ip2': ip2, 'ip3': ip3, 'typvar': typvar, 'etiket': etiket, 'vgrid': vGrid, 'ip1keys': vipkeys }
def vgd_levels( vgd_ptr, rfld=None, ip1list="VIPM", in_log=_vc.VGD_DIAG_PRES, dpidpis=_vc.VGD_DIAG_DPIS, double_precision=False ): """ Compute level positions (pressure or log(p)) for the given ip1 list and surface field Args: vgd_ptr (VGridDescriptor ref): Reference/Pointer to the VGridDescriptor rfld (mixed) : Reference surface field Possible values: (int) : RPNStd unit where to read the RFLD (float) : RFLD values (list) : RFLD values (ndarray): RFLD values ip11list (mixed) : ip1 list of destination levels (str) : get the ip1 list form the vgd object possible value: 'VIPM' or 'VIPT' (int) or (list): ip1 values in_log (int) : VGD_DIAG_LOGP or VGD_DIAG_PRES dpidpis (int) : VGD_DIAG_DPI or VGD_DIAG_DPIS double_precision (bool) : True for double precision computations Returns: ndarray : numpy array with shape of... if type(rfld) == float: shape = [len(ip11list),] if type(rfld) == list: shape = [len(list), len(ip11list)] if type(rfld) == ndarray: shape = rfld.shape + [len(ip11list)] Raises: TypeError VGDError Examples: >>> import sys >>> import rpnpy.vgd.all as vgd >>> lvls = (0.000, 0.011, 0.027, 0.051, 0.075, \ 0.101, 0.127, 0.155, 0.185, 0.219, \ 0.258, 0.302, 0.351, 0.405, 0.460, \ 0.516, 0.574, 0.631, 0.688, 0.744, \ 0.796, 0.842, 0.884, 0.922, 0.955, \ 0.980, 0.993, 1.000) >>> ptop = 1000. >>> try: >>> myvgd = vgd.vgd_new_eta(lvls, ptop) >>> except vgd.VGDError: >>> sys.stderr.write('There was a problem creating the VGridDescriptor') >>> sys.exit(1) >>> try: >>> levels = vgd.vgd_levels(myvgd, rfld=100130.) >>> except vgd.VGDError: >>> sys.stderr.write("There was a problem computing VGridDescriptor levels") See Also: rpnpy.vgd.const.VGD_DIAG_LOGP rpnpy.vgd.const.VGD_DIAG_PRES rpnpy.vgd.const.VGD_DIAG_DPI rpnpy.vgd.const.VGD_DIAG_DPIS vgd_new vgd_read vgd_free vgd_get """ if isinstance(ip1list, str): ip1list0 = vgd_get(vgd_ptr, ip1list) ip1list1 = _np.array(ip1list0, dtype=_np.int32, order="FORTRAN") elif isinstance(ip1list, _integer_types): ip1list1 = _np.array([ip1list], dtype=_np.int32, order="FORTRAN") elif isinstance(ip1list, (list, tuple)): ip1list1 = _np.array(ip1list, dtype=_np.int32, order="FORTRAN") elif isinstance(ip1list, _np.ndarray): ip1list1 = _np.array(ip1list.flatten(), dtype=_np.int32, order="FORTRAN") else: raise TypeError("ip1list should be string, list or int: {0}".format(str(type(ip1list)))) nip1 = ip1list1.size ip1list = ip1list1.ctypes.data_as(_ct.POINTER(_ct.c_int)) vkind = vgd_get(vgd_ptr, "KIND") vvers = vgd_get(vgd_ptr, "VERS") vcode = int(vkind) * 1000 + int(vvers) rank0 = False if isinstance(rfld, float): rfld = _np.array([rfld], dtype=_np.float32, order="FORTRAN") rank0 = True elif isinstance(rfld, (list, tuple)): rfld = _np.array(rfld, dtype=_np.float32, order="FORTRAN") elif isinstance(rfld, int): if _vc.VGD_VCODE_NEED_RFLD[vcode]: fileId = rfld rfld_name = vgd_get(vgd_ptr, "RFLD") if not rfld_name: raise VGDError("Problem getting RFLD to compute levels") rfld = _rmn.fstlir(fileId, nomvar=rfld_name.strip())["d"] MB2PA = 100.0 rfld = rfld * MB2PA else: rfld = _np.array([float(fileId)], dtype=_np.float32, order="FORTRAN") rank0 = True elif rfld is None: if _vc.VGD_VCODE_NEED_RFLD[vcode]: raise TypeError("RFLD needs to be provided for vcode={0}".format(vcode)) else: rfld = _np.array([1000.0], dtype=_np.float32, order="FORTRAN") rank0 = True elif not isinstance(rfld, _np.ndarray): raise TypeError("rfld should be ndarray, list or float: {0}".format(str(type(ip1list)))) if double_precision: dtype = _np.float64 rfld8 = _np.array(rfld, copy=True, dtype=dtype, order="FORTRAN") else: dtype = _np.float32 rfld8 = rfld shape = list(rfld.shape) + [nip1] levels8 = _np.empty(shape, dtype=dtype, order="FORTRAN") ok = _vc.VGD_OK if vkind == 2: # Workaround for pressure levels for k in xrange(nip1): (value, kind) = _rmn.convertIp(_rmn.CONVIP_DECODE, int(ip1list1[k])) levels8[:, :, k] = value * _MB2PA else: if double_precision: ok = _vp.c_vgd_diag_withref_8(vgd_ptr, rfld8.size, 1, nip1, ip1list, levels8, rfld8, in_log, dpidpis) else: ok = _vp.c_vgd_diag_withref(vgd_ptr, rfld8.size, 1, nip1, ip1list, levels8, rfld8, in_log, dpidpis) if ok != _vc.VGD_OK: raise VGDError("Problem computing levels.") if rank0: levels8 = levels8.flatten() return levels8
# extraction of grid data from fst files try: file_id = rmn.fstopenall(fst) for param in params.keys(): if param in special_params.keys(): var_name = special_params[param] else: var_name = param.upper() grid_data = np.zeros((lev, ni, nj)) v_grid = vgd.vgd_read(file_id) # gets the vgd object ip1s = vgd.vgd_get(v_grid, 'VIPM') # builds pressure levels pres_levs = [ rmn.convertIp(rmn.CONVIP_DECODE, ip1, rmn.KIND_PRESSURE)[0] for ip1 in ip1s ] for k, ip in enumerate(ip1s): rec_key = rmn.fstinf( file_id, ip1=ip, nomvar=var_name) # returns key based on params grid_data[k] = rmn.fstluk(rec_key)['d'] # reads grid data conv_param(param, grid_data) latkey = rmn.fstinf(file_id, nomvar='^^') lonkey = rmn.fstinf(file_id, nomvar='>>') lats = rmn.fstluk(latkey)['d'][0] lats = lats[::-1]
def plotFSTs(season=season, spcs=spcs, spcsFiles=spcsFiles, outputName = outputName, saveDir=saveDir): # print minimum outputs rmn.fstopt(rmn.FSTOP_MSGLVL,rmn.FSTOPI_MSG_CATAST) mInds = [] for m in season: mInds += [monthList.index(m)] if os.path.exists(saveDir) == False: nu.makeDir(saveDir) for spcInd, nomvar in enumerate(spcs): try: filename = os.path.join(saveDir, 'output_file_{0}_{1}.fst'.format(outputName, nomvar)) print('Creating and saving to {}'.format(filename)) tmp = open(filename, 'w+'); tmp.close() output_file = filename file_id = rmn.fnom(output_file) open_fst = rmn.fstouv(file_id, rmn.FST_RW) open_file = spcsFiles[spcInd] print "Parameter: " + nomvar seaSpcData = get_var(pyg.open(open_file), nomvar, mInds) nc_lnsp = pyg.open(lnsp_file) pressures = get_pressures(nc_lnsp, mInds) timelen, levlen, latlen, lonlen = seaSpcData.shape #NOTE: uncomment the following three lines to prep data for basemap use #lonShiftSSData = shift_lon(seaSpcData) #vertInterpSSData = vert_interp(pressures, lonShiftSSData) #meanSSData = np.mean(vertInterpSSData, axis=0) #NOTE: uncommment the following four liness to use for fst plotting vertInterpSSData = vert_interp(pressures, seaSpcData) meanSSData = np.mean(vertInterpSSData, axis=0) # temp for lvl, ray in enumerate(meanSSData): meanSSData[lvl] = np.flipud(ray) scaleFac = scaleSpcs[allSpcs.index(nomvar)] scaledSSData = meanSSData*scaleFac #define grid for this file - note that the MACC grid in the file is #defined for lons -180 to 180, but the python defGrid_L can't deal #with that and defines the grid from 0 to 360 so will have to reorder #the MACC fields a bit, or they end up 180 deg out of phase # Also necessary to add one more longitude to wrap around dlatlon = 360./lonlen # this is equal to the resolution of the grid params0 = { 'grtyp' : 'Z', 'grref' : 'L', 'nj' : latlen, 'ni' : lonlen, 'lat0' : -90., 'lon0' : 0., 'dlat' : dlatlon, 'dlon' : dlatlon } MACC_grid= rmn.encodeGrid(params0) print("Grids created.") print 'Grid Shape:' + str(MACC_grid['shape']) # copies the default record new_record = rmn.FST_RDE_META_DEFAULT.copy() tic_record = rmn.FST_RDE_META_DEFAULT.copy() tac_record = rmn.FST_RDE_META_DEFAULT.copy() try: rmn.writeGrid(file_id, MACC_grid) tac = rmn.fstinl(file_id, nomvar='>>')[0] tic = rmn.fstinl(file_id, nomvar='^^')[0] tic_record.update(rmn.fstprm(tic)) tac_record.update(rmn.fstprm(tac)) tic_record.update({'datyp' : rmn.FST_DATYP_LIST['float']}) tac_record.update({'datyp' : rmn.FST_DATYP_LIST['float']}) rmn.fsteff(tic) rmn.fsteff(tac) tic_record.update({'d': MACC_grid['ay']}) tac_record.update({'d': MACC_grid['ax']}) toc_record = vgd.vgd_new_pres(const_pressure, ip1=MACC_grid['ig1'], ip2=MACC_grid['ig2']) rmn.fstecr(file_id, tic_record) # write the dictionary record to the file as a new record rmn.fstecr(file_id, tac_record) # write the dictionary record to the file as a new record vgd.vgd_write(toc_record, file_id) except: raise for rp1 in xrange(len(const_pressure)): # writes a record for every level (as a different ip1) try: # converts rp1 into a ip1 with pressure kind ip1 = rmn.convertIp(rmn.CONVIP_ENCODE, const_pressure[rp1], rmn.KIND_PRESSURE) new_record.update(MACC_grid) new_record.update({ # Update with specific meta 'nomvar': nomvar, 'typvar': 'C', 'etiket': 'MACCRean', 'ni' : MACC_grid['ni'], 'nj' : MACC_grid['nj'], 'ig1' : tic_record['ip1'], 'ig2' : tic_record['ip2'], 'ig3' : tic_record['ip3'], 'ig4' : tic_record['ig4'], 'dateo' : rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20120101, 0000000), 'deet' : 0, # Timestep in sec 'ip1' : ip1 }) #tmp_nparray = np.asfortranarray(monthly_mean[rp1]) tmp = scaledSSData[rp1] tmp = np.transpose(tmp) # data array is structured as tmp = monthly_mean[level] where monthly_mean is [level, lat, lon] new_record.update({'d': tmp.astype(np.float32)}) # Updates with data array in the form (lon x lat) print "Defined a new record with dimensions ({0}, {1})".format(new_record['ni'], new_record['nj']) rmn.fstecr(file_id, new_record) # write the dictionary record to the file as a new record except: #rmn.closeall(file_id) rmn.fstfrm(file_id) rmn.fclos(file_id) raise rmn.fstfrm(file_id) rmn.fclos(file_id) print('{} complete~'.format(filename)) except: rmn.fstfrm(file_id) rmn.fclos(file_id) raise print('Finished plotting all FSTs. ')
def read_fst(file, var, level, fhour, yy): global field global lat global lon print var print level print fhour print yy try: file = rmn.fstopenall(file, rmn.FST_RO) except: sys.stderr.write("Problem opening the file: %s\n" % file) ###Read in lat/lon data### # Prefered method to get grid lat, lon. Works on any RPNSTD grid except 'x' ##### try: rec = rmn.fstlir(file, nomvar=var) except: sys.stderr.write('Error: Problem reading fields ' + var + ' in file: ' + file + '\n') sys.exit(1) try: rec['iunit'] = file gridid = rmn.ezqkdef(rec) # use ezscint to retreive full grid gridLatLon = rmn.gdll(gridid) lat = gridLatLon['lat'] lon = gridLatLon['lon'] if yy == True: print "This grid is Yin-Yang and the lat/lon arrays need to be constructed from the 2 subgrids" lat1 = gridLatLon['subgrid'][0]['lat'] lat2 = gridLatLon['subgrid'][1]['lat'] lon1 = gridLatLon['subgrid'][0]['lon'] lon2 = gridLatLon['subgrid'][1]['lon'] lat = np.append(lat1, lat2, axis=1) lon = np.append(lon1, lon2, axis=1) except: sys.stderr.write('Error: Problem getting grid info in file') sys.exit(1) ###### ###### try: #Get vertical grid definition from file v = vgd.vgd_read(file) #Get the list of ip1 on thermo levels in this file #tlvl = vgd.vgd_get(v, 'VIPT') tlvl = level # 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" tlvlkeys = [] rshape = None #for ip1 in tlvl: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, level) key = rmn.fstinf(file, nomvar=var, ip2=fhour, ip1=rmn.ip1_all(lval, lkind)) if key is not None: tlvlkeys.append((level, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(tlvlkeys)) r2d = {'d': None} r3d = None k = 0 try: r2d = rmn.fstluk(key, dataArray=r2d['d']) 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 except: raise except: raise finally: # Close file even if an error occured above rmn.fstcloseall(file) # Add the vgrid and the actual ip1 list in the r3d dict, update shape and nk r3d['vgd'] = v r3d['ip1list'] = [x[0] for x in tlvlkeys] r3d['shape'] = rshape r3d['nk'] = rshape[2] field = r3d['d'] return (field, lat, lon)
try: # copies the default record new_record = rmn.FST_RDE_META_DEFAULT.copy() if t < 124: time_int = build_hhmmss(t) new_record.update({ 'dateo': rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20120100 + int(math.floor(t / 4 + 1)), time_int) }) for rp1 in xrange( len(const_pressure) ): # writes a record for every level (as a different ip1) # converts rp1 into a ip1 with pressure kind ip1 = rmn.convertIp(rmn.CONVIP_ENCODE, const_pressure[rp1], rmn.KIND_PRESSURE) new_record.update(MACC_grid) new_record.update({ # Update with specific meta 'nomvar': 'PV', 'typvar': 'C', 'etiket': 'MACCRean', 'ip2': t, 'ni': MACC_grid['ni'], 'nj': MACC_grid['nj'], 'ig1': tic_record['ip1'], 'ig2': tic_record['ip2'], 'ig3': tic_record['ip3'], 'ig4': tic_record['ig4'], 'deet': int(86400 / 4), # timestep in secs 'ip1': ip1 })