Пример #1
0
 def testLevels8_prof(self):
     vgd0ptr = self._newReadBcmk()
     MB2PA = 100.
     p0_stn_mb = 1013.  * MB2PA
     prof = vgd.vgd_levels(vgd0ptr, p0_stn_mb, double_precision=True)
     self.assertEqual([int(x) for x in prof[0:5]*10000.],
                      [100000, 138426, 176879, 241410, 305984])
     self.assertEqual(len(prof.shape),1)
     self.assertEqual(prof.dtype,np.float64)
Пример #2
0
 def testLevels8_prof(self):
     vgd0ptr = self._newReadBcmk()
     MB2PA = 100.
     p0_stn_mb = 1013.  * MB2PA
     prof = vgd.vgd_levels(vgd0ptr, p0_stn_mb, double_precision=True)
     self.assertEqual([int(x) for x in prof[0:5]*10000.],
                      [100000, 138426, 176879, 241410, 305984])
     self.assertEqual(len(prof.shape),1)
     self.assertEqual(prof.dtype,np.float64)
Пример #3
0
 def testDiag_withref8_3d(self):
     ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
     fileName = os.path.join(ATM_MODEL_DFILES,'bcmk_toctoc','2009042700_000')
     fileId = rmn.fstopenall(fileName, rmn.FST_RO)
     vgd0ptr = vgd.vgd_read(fileId)
     levels8 = vgd.vgd_levels(vgd0ptr, fileId, double_precision=True)
     rmn.fstcloseall(fileId)
     (ni,nj,nk) = levels8.shape
     self.assertEqual([int(x) for x in levels8[ni//2,nj//2,0:5]*10000.],
                      [100000, 138425, 176878, 241408, 305980])
     self.assertEqual(len(levels8.shape),3)
     self.assertEqual(levels8.dtype,np.float64)
Пример #4
0
 def testDiag_withref8_3d(self):
     ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
     fileName = os.path.join(ATM_MODEL_DFILES,'bcmk_toctoc','2009042700_000')
     fileId = rmn.fstopenall(fileName, rmn.FST_RO)
     vgd0ptr = vgd.vgd_read(fileId)
     levels8 = vgd.vgd_levels(vgd0ptr, fileId, double_precision=True)
     rmn.fstcloseall(fileId)
     (ni,nj,nk) = levels8.shape
     self.assertEqual([int(x) for x in levels8[ni//2,nj//2,0:5]*10000.],
                      [100000, 138425, 176878, 241408, 305980])
     self.assertEqual(len(levels8.shape),3)
     self.assertEqual(levels8.dtype,np.float64)
Пример #5
0
def get_levels_press(fileId, vGrid, shape, ip1list,
                     datev=-1, ip2=-1, ip3=-1, typvar=' ', etiket=' ',
                     verbose=False):
    """
    """
    rfldName = _vgd.vgd_get(vGrid, 'RFLD')
    rfld     = _np.empty(shape, dtype=_np.float32, order='F')
    rfld[:]  = 1000. * _cst.MB2PA
    if rfldName:
        r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2, ip3=ip3,
                         typvar=typvar, etiket=etiket)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2,
                             typvar=typvar, etiket=etiket)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2,
                             etiket=etiket)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName)
        if not r2d is None:
            if verbose:
                print("Read {nomvar} ip1={ip1} ip2={ip2} ip3={ip3} typv={typvar} etk={etiket}".format(**r2d))
            ## g = _rmn.readGrid(fileId, r2d)
            ## if len(xpts) > 0:
            ##     v1 = _rmn.gdxysval(g['id'], xpts, ypts, r2d['d'])
            ##     rfld[0:len(xy)] = v1[:]
            ## if len(lats) > 0:
            ##     v1 = _rmn.gdllsval(g['id'], lats, lons, r2d['d'])
            ##     rfld[len(xy):len(xy)+len(ll)] = v1[:]
            rfld[:,:] = r2d['d'][:,:] * _cst.MB2PA
    phPa = _vgd.vgd_levels(vGrid, rfld, ip1list)
    phPa[:,:,:] /= _cst.MB2PA
    return {
        'rfld' : rfld,
        'phPa' : phPa
        }
Пример #6
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)
Пример #7
0
def get_levels_press(fileId,
                     vGrid,
                     shape,
                     ip1list,
                     datev=-1,
                     ip2=-1,
                     ip3=-1,
                     typvar=' ',
                     etiket=' ',
                     verbose=False):
    """
    Read the reference surface field and computer the pressure cube

    press = get_levels_press(fileId, vGrid, shape, ip1list)
    press = get_levels_press(fileId, vGrid, shape, ip1list,
                             datev, ip2, ip3, typvar, etiket)

    Args:
        fileId  : unit number associated to the file
                  obtained with fnom+fstouv
        vGrid   : vertical grid descriptor
        shape   : shape of the field
        ip1list : vertical levels ip lists
        datev   : valid date
        ip2     : forecast hour
        ip3     : user defined identifier
        typvar  : type of field
        etiket  : label
        verbose : Print some info when true
    Returns:
        {
            'rfld' : rfld,  # 2d field reference value
            'phPa' : phPa   # 3d pressure values
        }
    Raises:
        TypeError  on wrong input arg types
        ValueError on invalid input arg value
        FSTDError  on any other error

    Examples:
    >>> import os, os.path
    >>> import rpnpy.librmn.all as rmn
    >>> import rpnpy.utils.fstd3d as fstd3d
    >>> ATM_MODEL_DFILES = os.getenv('ATM_MODEL_DFILES').strip()
    >>> filename = os.path.join(ATM_MODEL_DFILES,'bcmk')
    >>>
    >>> # Open existing file in Rear Only mode
    >>> fileId = rmn.fstopenall(filename, rmn.FST_RO)
    >>>
    >>> # Get the pressure cube
    >>> ipkeys  = fstd3d.get_levels_keys(fileId, 'TT', thermoMom='VIPT')
    >>> ip1list = [ip1 for ip1,key in ipkeys['ip1keys']]
    >>> shape   = rmn.fstinf(fileId, nomvar='TT')['shape'][0:2]
    >>> press   = fstd3d.get_levels_press(fileId, ipkeys['vgrid'], shape, ip1list)
    >>> print('# {} {} {}'.format(shape, press['rfld'].shape, press['phPa'].shape))
    # (200, 100) (200, 100) (200, 100, 80)
    >>> rmn.fstcloseall(fileId)

    See Also:
        get_levels_keys
        fst_read_3d
        rpnpy.librmn.fstd98.fstlir
        rpnpy.librmn.fstd98.fstprm
        rpnpy.librmn.fstd98.fstluk
        rpnpy.librmn.fstd98.fstopenall
        rpnpy.librmn.fstd98.fstcloseall
        rpnpy.vgd.base.vgd_levels
    """
    rfldName = _vgd.vgd_get(vGrid, 'RFLD')
    rfld = _np.empty(shape, dtype=_np.float32, order='F')
    rfld[:] = 1000. * _cst.MB2PA
    if rfldName:
        r2d = _rmn.fstlir(fileId,
                          nomvar=rfldName,
                          datev=datev,
                          ip2=ip2,
                          ip3=ip3,
                          typvar=typvar,
                          etiket=etiket)
        if r2d is None:
            r2d = _rmn.fstlir(fileId,
                              nomvar=rfldName,
                              datev=datev,
                              ip2=ip2,
                              typvar=typvar,
                              etiket=etiket)
        if r2d is None:
            r2d = _rmn.fstlir(fileId,
                              nomvar=rfldName,
                              datev=datev,
                              ip2=ip2,
                              etiket=etiket)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev, ip2=ip2)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName, datev=datev)
        if r2d is None:
            r2d = _rmn.fstlir(fileId, nomvar=rfldName)
        if not r2d is None:
            if verbose:
                print(
                    "Read {nomvar} ip1={ip1} ip2={ip2} ip3={ip3} typv={typvar} etk={etiket}"
                    .format(**r2d))
            ## g = _rmn.readGrid(fileId, r2d)
            ## if len(xpts) > 0:
            ##     v1 = _rmn.gdxysval(g['id'], xpts, ypts, r2d['d'])
            ##     rfld[0:len(xy)] = v1[:]
            ## if len(lats) > 0:
            ##     v1 = _rmn.gdllsval(g['id'], lats, lons, r2d['d'])
            ##     rfld[len(xy):len(xy)+len(ll)] = v1[:]
            rfld[:, :] = r2d['d'][:, :] * _cst.MB2PA
    phPa = _vgd.vgd_levels(vGrid, rfld, ip1list)
    phPa[:, :, :] /= _cst.MB2PA
    return {'rfld': rfld, 'phPa': phPa}
Пример #8
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)