Ejemplo n.º 1
0
    def test_ip123_all_val(self):
        """ip123_all, ip123_vall should give known result with known input"""
        for pk1, pk2, pk3, ip1, ip2, ip3 in self.ip123knownValues:
            ip1a1 = rmn.ip1_all(pk1.v1, pk1.kind)
            ip1v1 = rmn.ip1_val(pk1.v1, pk1.kind)
            ip1a2 = rmn.ip1_all(pk1.v2, pk1.kind)
            ip1v2 = rmn.ip1_val(pk1.v2, pk1.kind)
            self.assertEqual(ip1a1, ip1)
            self.assertEqual(ip1v1, ip1)
            self.assertEqual(ip1a2, ip1)
            self.assertEqual(ip1v2, ip1)

            ip2a1 = rmn.ip2_all(pk2.v1, pk2.kind)
            ip2v1 = rmn.ip2_val(pk2.v1, pk2.kind)
            ip2a2 = rmn.ip2_all(pk2.v2, pk2.kind)
            ip2v2 = rmn.ip2_val(pk2.v2, pk2.kind)
            self.assertEqual(ip2a1, ip2)
            self.assertEqual(ip2v1, ip2)
            self.assertEqual(ip2a2, ip2)
            self.assertEqual(ip2v2, ip2)

            ip3a1 = rmn.ip3_all(pk3.v1, pk3.kind)
            ip3v1 = rmn.ip3_val(pk3.v1, pk3.kind)
            ip3a2 = rmn.ip3_all(pk3.v2, pk3.kind)
            ip3v2 = rmn.ip3_val(pk3.v2, pk3.kind)
            self.assertEqual(ip3a1, ip3)
            self.assertEqual(ip3v1, ip3)
            self.assertEqual(ip3a2, ip3)
            self.assertEqual(ip3v2, ip3)
Ejemplo n.º 2
0
    def test_ip123_all_val(self):
        """ip123_all, ip123_vall should give known result with known input"""
        for pk1,pk2,pk3,ip1,ip2,ip3 in self.ip123knownValues:
            ip1a1 = rmn.ip1_all(pk1.v1,pk1.kind)
            ip1v1 = rmn.ip1_val(pk1.v1,pk1.kind)
            ip1a2 = rmn.ip1_all(pk1.v2,pk1.kind)
            ip1v2 = rmn.ip1_val(pk1.v2,pk1.kind)
            self.assertEqual(ip1a1,ip1)
            self.assertEqual(ip1v1,ip1)
            self.assertEqual(ip1a2,ip1)
            self.assertEqual(ip1v2,ip1)
            
            ip2a1 = rmn.ip2_all(pk2.v1,pk2.kind)
            ip2v1 = rmn.ip2_val(pk2.v1,pk2.kind)
            ip2a2 = rmn.ip2_all(pk2.v2,pk2.kind)
            ip2v2 = rmn.ip2_val(pk2.v2,pk2.kind)
            self.assertEqual(ip2a1,ip2)
            self.assertEqual(ip2v1,ip2)
            self.assertEqual(ip2a2,ip2)
            self.assertEqual(ip2v2,ip2)

            ip3a1 = rmn.ip3_all(pk3.v1,pk3.kind)
            ip3v1 = rmn.ip3_val(pk3.v1,pk3.kind)
            ip3a2 = rmn.ip3_all(pk3.v2,pk3.kind)
            ip3v2 = rmn.ip3_val(pk3.v2,pk3.kind)
            self.assertEqual(ip3a1,ip3)
            self.assertEqual(ip3v1,ip3)
            self.assertEqual(ip3a2,ip3)
            self.assertEqual(ip3v2,ip3)
Ejemplo n.º 3
0
 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()))
Ejemplo n.º 4
0
 def test_11bqd(self):
     import os, sys
     import rpnpy.librmn.all as rmn
     ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
     fileId = rmn.fstopenall(ATM_MODEL_DFILES+'/bcmk_p/anlp2015070706_000', rmn.FST_RO)
     for k in rmn.fstinl(fileId, nomvar='TT',
                         ip1=rmn.ip1_all(500., rmn.LEVEL_KIND_PMB),
                         datev=rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20150707, 6000000)):
             m = rmn.fstprm(k)
             print("CB11bqd: %s (%d, %d, %s)" % (m['nomvar'], m['ip1'], m['ip2'], m['datev']))
     rmn.fstcloseall(fileId)
Ejemplo n.º 5
0
    def test_11b(self):
        """
        Queries: List/Find records

        This example shows how to
        * get the list of all records matching selection creterions
        * encode parameters (ip1, datev) values to use selection criteria
                
        See also:
        rpnpy.librmn.fstd98.fstopenall
        rpnpy.librmn.fstd98.ip1_all
        rpnpy.librmn.fstd98.ip2_all
        rpnpy.librmn.fstd98.fstinl
        rpnpy.librmn.fstd98.fstprm
        rpnpy.librmn.fstd98.DecodeIp
        rpnpy.librmn.fstd98.kindToString
        rpnpy.librmn.base.newdate
        rpnpy.librmn.fstd98.fstcloseall
        rpnpy.librmn.const
        """
        import os, sys
        import rpnpy.librmn.all as rmn

        # Open all RPNStd files in $ATM_MODEL_DFILES/bcmk_p/anlp2015070706_000
        ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
        fileName = os.path.join(ATM_MODEL_DFILES, 'bcmk_p',
                                'anlp2015070706_000')
        try:
            fileId = rmn.fstopenall(fileName, rmn.FST_RO)
        except:
            sys.stderr.write("Problem opening the file: %s\n" % fileName)
            sys.exit(1)

        try:
            # Encode selection criteria
            ip1 = rmn.ip1_all(500., rmn.LEVEL_KIND_PMB)
            datev = rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20150707, 6000000)

            # Get the list of record keys matching
            # nomvar='TT' at 500mb and valide date=20150707.06000000
            keylist = rmn.fstinl(fileId, nomvar='TT', ip1=ip1, datev=datev)
            print("CB11b: Found %d records matching TT, ip1=%d, datev=%d" %
                  (len(keylist), ip1, datev))

            # Get every record meta data
            for k in keylist:
                m = rmn.fstprm(k)
                print("CB11b: %s (%d, %d, %s)" %
                      (m['nomvar'], m['ip1'], m['ip2'], m['datev']))
        except:
            pass
        finally:
            # Close file even if an error occured above
            rmn.fstcloseall(fileId)
Ejemplo n.º 6
0
    def test_11b(self):
        """
        Queries: List/Find records

        This example shows how to
        * get the list of all records matching selection creterions
        * encode parameters (ip1, datev) values to use selection criteria
                
        See also:
        rpnpy.librmn.fstd98.fstopenall
        rpnpy.librmn.fstd98.ip1_all
        rpnpy.librmn.fstd98.ip2_all
        rpnpy.librmn.fstd98.fstinl
        rpnpy.librmn.fstd98.fstprm
        rpnpy.librmn.fstd98.DecodeIp
        rpnpy.librmn.fstd98.kindToString
        rpnpy.librmn.base.newdate
        rpnpy.librmn.fstd98.fstcloseall
        rpnpy.librmn.const
        """
        import os, sys
        import rpnpy.librmn.all as rmn

        # Open all RPNStd files in $ATM_MODEL_DFILES/bcmk_p/anlp2015070706_000
        ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
        fileName = os.path.join(ATM_MODEL_DFILES, 'bcmk_p','anlp2015070706_000')
        try:
            fileId = rmn.fstopenall(fileName, rmn.FST_RO)
        except:
            sys.stderr.write("Problem opening the file: %s\n" % fileName)
            sys.exit(1)

        try:
            # Encode selection criteria
            ip1   = rmn.ip1_all(500., rmn.LEVEL_KIND_PMB)
            datev = rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20150707, 6000000)

            # Get the list of record keys matching
            # nomvar='TT' at 500mb and valide date=20150707.06000000
            keylist = rmn.fstinl(fileId, nomvar='TT', ip1=ip1, datev=datev)
            print("CB11b: Found %d records matching TT, ip1=%d, datev=%d" %
                  (len(keylist), ip1, datev))

            # Get every record meta data
            for k in keylist:
                m = rmn.fstprm(k)
                print("CB11b: %s (%d, %d, %s)" % (m['nomvar'], m['ip1'], m['ip2'], m['datev']))
        except:
            pass
        finally:
            # Close file even if an error occured above
            rmn.fstcloseall(fileId)
Ejemplo n.º 7
0
    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))
Ejemplo n.º 8
0
 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()))
Ejemplo n.º 9
0
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
        }
Ejemplo n.º 10
0
 def test_11bqd(self):
     import os, sys
     import rpnpy.librmn.all as rmn
     ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
     fileId = rmn.fstopenall(
         ATM_MODEL_DFILES + '/bcmk_p/anlp2015070706_000', rmn.FST_RO)
     for k in rmn.fstinl(fileId,
                         nomvar='TT',
                         ip1=rmn.ip1_all(500., rmn.LEVEL_KIND_PMB),
                         datev=rmn.newdate(rmn.NEWDATE_PRINT2STAMP,
                                           20150707, 6000000)):
         m = rmn.fstprm(k)
         print("CB11bqd: %s (%d, %d, %s)" %
               (m['nomvar'], m['ip1'], m['ip2'], m['datev']))
     rmn.fstcloseall(fileId)
Ejemplo n.º 11
0
    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))
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    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()))
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
    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()))
Ejemplo n.º 17
0
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'][:, :]
Ejemplo n.º 18
0
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
    }