def testNewPres(self): # pres = [x*self.MB2PA for x in (500.,850.,1000.)] pres = (500.,850.,1000.) vgd0ptr = vgd.vgd_new_pres(pres) vkind = vgd.vgd_get(vgd0ptr, 'KIND') vvers = vgd.vgd_get(vgd0ptr, 'VERS') self.assertEqual((vkind,vvers),vgd.VGD_KIND_VER['pres'])
def test_24qd(self): import os, sys import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd g = rmn.defGrid_ZE(90, 45, 35., 250., 0.5, 0.5, 0., 180., 1., 270.) lvls = (500.,850.,1000.) v = vgd.vgd_new_pres(lvls) ip1list = vgd.vgd_get(v, 'VIPT') datyp = rmn.FST_DATYP_LIST['float_IEEE_compressed'] npdtype = rmn.dtype_fst2numpy(datyp) rshape = (g['ni'], g['nj'], len(ip1list)) r = rmn.FST_RDE_META_DEFAULT.copy() r.update(g) r.update({ 'nomvar': 'MASK', 'nk' : len(ip1list), 'dateo' : rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20160302, 1800000), 'ip2' : 6, 'deet' : 3600, 'npas' : 6, 'etiket': 'my_etk', 'datyp' : datyp, 'd' : np.empty(rshape, dtype=npdtype, order='FORTRAN') }) r['d'][:,:,:] = 0. r['d'][10:-11,5:-6,:] = 1. fileNameOut = 'newfromscratch.fst' fileIdOut = rmn.fstopenall(fileNameOut, rmn.FST_RW) r2d = r.copy() for k in range(len(ip1list)): r2d.update({'nk':1, 'ip1':ip1list[k], 'd':np.asfortranarray(r['d'][:,:,k])}) rmn.fstecr(fileIdOut, r2d['d'], r2d) rmn.writeGrid(fileIdOut, g) vgd.vgd_write(v, fileIdOut) rmn.fstcloseall(fileIdOut) os.unlink(fileNameOut) # Remove test file
def test_24qd(self): import os, sys import numpy as np import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd g = rmn.defGrid_ZE(90, 45, 35., 250., 0.5, 0.5, 0., 180., 1., 270.) lvls = (500., 850., 1000.) v = vgd.vgd_new_pres(lvls) ip1list = vgd.vgd_get(v, 'VIPT') datyp = rmn.FST_DATYP_LIST['float_IEEE_compressed'] npdtype = rmn.dtype_fst2numpy(datyp) rshape = (g['ni'], g['nj'], len(ip1list)) r = rmn.FST_RDE_META_DEFAULT.copy() r.update(g) r.update({ 'nomvar': 'MASK', 'nk': len(ip1list), 'dateo': rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20160302, 1800000), 'ip2': 6, 'deet': 3600, 'npas': 6, 'etiket': 'my_etk', 'datyp': datyp, 'd': np.empty(rshape, dtype=npdtype, order='FORTRAN') }) r['d'][:, :, :] = 0. r['d'][10:-11, 5:-6, :] = 1. fileNameOut = 'newfromscratch.fst' fileIdOut = rmn.fstopenall(fileNameOut, rmn.FST_RW) r2d = r.copy() for k in range(len(ip1list)): r2d.update({ 'nk': 1, 'ip1': ip1list[k], 'd': np.asfortranarray(r['d'][:, :, k]) }) rmn.fstecr(fileIdOut, r2d['d'], r2d) rmn.writeGrid(fileIdOut, g) vgd.vgd_write(v, fileIdOut) rmn.fstcloseall(fileIdOut) os.unlink(fileNameOut) # Remove test file
def build_fst(params, y_int, m_int): ''' (dict) -> (int, dict) builds the file as per the parameters defined in the params dict returns the file_id ''' # makes an empty .fst file day = time.gmtime() temp = '' for x in day: temp += str(x) #new_nc = '/home/ords/aq/alh002/pyscripts/workdir/pv_files/TEST5.fst' new_nc = '/home/ords/aq/alh002/pyscripts/workdir/pv_files/SHIFTED_POTVOR_file_{0}_{1}.fst'.format( y_int + 2008, m_int + 1) tmp = open(new_nc, 'w+') tmp.close() output_file = new_nc try: file_id = rmn.fnom(output_file) open_fst = rmn.fstouv(file_id, rmn.FST_RW) print(file_id, open_fst) MACC_grid = rmn.encodeGrid(params) print("Grids created.") print 'Grid Shape:' + str(MACC_grid['shape']) rmn.writeGrid(file_id, MACC_grid) toc_record = vgd.vgd_new_pres(const_pressure, ip1=MACC_grid['ig1'], ip2=MACC_grid['ig2']) vgd.vgd_write(toc_record, file_id) return file_id, MACC_grid except: rmn.fstfrm(file_id) rmn.fclos(file_id) raise
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 test_51(self): """ Vertical Interpolation See also: scipy.interpolate.interp1d """ import os, sys, datetime import numpy as np from scipy.interpolate import interp1d as scipy_interp1d import rpnpy.librmn.all as rmn import rpnpy.vgd.all as vgd MB2PA = 100. # Restrict to the minimum the number of messages printed by librmn rmn.fstopt(rmn.FSTOP_MSGLVL, rmn.FSTOPI_MSG_CATAST) # Open Input file hour = 48 fdate = datetime.date.today().strftime('%Y%m%d') + '00_0' + str(hour) CMCGRIDF = os.getenv('CMCGRIDF').strip() fileNameOut = os.path.join(CMCGRIDF, 'prog', 'regeta', fdate) try: fileIdIn = rmn.fstopenall(fileNameOut, rmn.FST_RO) except: sys.stderr.write("Problem opening the input file: %s\n" % fileNameOut) sys.exit(1) try: # Get the vgrid def present in the file # and the full list of ip1 # and the surface reference field name for the coor vIn = vgd.vgd_read(fileIdIn) ip1listIn0 = vgd.vgd_get(vIn, 'VIPT') rfldNameIn = vgd.vgd_get(vIn, 'RFLD') vkind = vgd.vgd_get(vIn, 'KIND') vver = vgd.vgd_get(vIn, 'VERS') VGD_KIND_VER_INV = dict( (v, k) for k, v in vgd.VGD_KIND_VER.items()) vtype = VGD_KIND_VER_INV[(vkind, vver)] print( "CB51: Found vgrid type=%s (kind=%d, vers=%d) with %d levels, RFLD=%s" % (vtype, vkind, vver, len(ip1listIn0), rfldNameIn)) # Trim the list of thermo ip1 to actual levels in files for TT # since the vgrid in the file is a super set of all levels # and get their "key" ip1Keys = [] rshape = None for ip1 in ip1listIn0: (lval, lkind) = rmn.convertIp(rmn.CONVIP_DECODE, ip1) key = rmn.fstinf(fileIdIn, nomvar='TT', ip2=hour, ip1=rmn.ip1_all(lval, lkind)) if key is not None: print("CB51: Found TT at ip1=%d, ip2=%d" % (ip1, hour)) ip1Keys.append((ip1, key['key'])) if rshape is None: rshape = key['shape'] rshape = (rshape[0], rshape[1], len(ip1Keys)) # Read every level for TT at ip2=hour, re-use 2d array while reading # and store the data in a 3d array # with lower level at nk, top at 0 as in the model r2d = {'d': None} r3d = None k = 0 gIn = None for ip1, key in ip1Keys: try: r2d = rmn.fstluk(key, dataArray=r2d['d']) print("CB51: Read TT at ip1=%d, ip2=%d" % (ip1, hour)) if r3d is None: r3d = r2d.copy() r3d['d'] = np.empty(rshape, dtype=r2d['d'].dtype, order='FORTRAN') r3d['d'][:, :, k] = r2d['d'][:, :] k += 1 if gIn is None: gIn = rmn.readGrid(fileIdIn, r2d) print("CB51: Read the horizontal grid descriptors") except: pass # Add the vgrid and the actual ip1 list in the r3d dict, update shape and nk r3d['vgd'] = vIn r3d['ip1list'] = [x[0] for x in ip1Keys] r3d['shape'] = rshape r3d['nk'] = rshape[2] # Read the Input reference fields rfldIn = None if rfldNameIn: rfldIn = rmn.fstlir(fileIdIn, nomvar=rfldNameIn, ip2=hour) if rfldNameIn.strip() == 'P0': rfldIn['d'][:] *= MB2PA print( "CB51: Read input RFLD=%s at ip2=%d [min=%7.0f, max=%7.0f]" % (rfldNameIn, hour, rfldIn['d'].min(), rfldIn['d'].max())) except: raise # pass finally: # Close file even if an error occured above rmn.fstcloseall(fileIdIn) # Define the destination vertical grid/levels try: lvlsOut = (500., 850., 1000.) vOut = vgd.vgd_new_pres(lvlsOut) ip1listOut = vgd.vgd_get(vOut, 'VIPT') rfldNameOut = vgd.vgd_get(vIn, 'RFLD') rfldOut = None # in this case, Pressure levels, there are no RFLD print("CB51: Defined a Pres vgrid with lvls=%s" % str(lvlsOut)) except: sys.stderr.write("Problem creating a new vgrid\n") sys.exit(1) # Get input and output 3d pressure cubes try: ## if rfldIn is None: ## rfldIn = pIn = vgd.vgd_levels(vIn, ip1list=r3d['ip1list'], rfld=rfldIn['d']) print( "CB51: Computed input pressure cube, k0:[min=%7.0f, max=%7.0f], nk:[min=%7.0f, max=%7.0f]" % (pIn[:, :, 0].min(), pIn[:, :, 0].max(), pIn[:, :, -1].min(), pIn[:, :, -1].max())) if rfldOut is None: rfldOut = rfldIn # provide a dummy rfld for array shape pOut = vgd.vgd_levels(vOut, ip1list=ip1listOut, rfld=rfldOut['d']) print( "CB51: Computed output pressure cube, k0:[min=%7.0f, max=%7.0f], nk:[min=%7.0f, max=%7.0f]" % (pOut[:, :, 0].min(), pOut[:, :, 0].max(), pOut[:, :, -1].min(), pOut[:, :, -1].max())) except: raise sys.stderr.write("Problem computing pressure cubes\n") sys.exit(1) # Use scipy.interpolate.interp1d to vertically interpolate try: ## f = scipy_interp1d(fromLvls, toLvls, kind='cubic', ## assume_sorted=True, bounds_error=False, ## fill_value='extrapolate', copy=False) ## # Unfortunately, looks like interp1d take colomn data ## f = scipy_interp1d(pIn, r3d['d'], kind='cubic', ## bounds_error=False, ## fill_value='extrapolate', copy=False) ## r3dout = f(pOut) ## # Unfortunately, assume_sorted, 'extrapolate' not support in my version ## extrap_value = 'extrapolate' # -99999. ## # Way too slow, needs a C implementation extrap_value = -999. ## for j in range(rshape[1]): ## for i in range(rshape[0]): ## f = scipy_interp1d(pIn[i,j,:], r3d['d'][i,j,:], ## kind='cubic', ## bounds_error=False, ## fill_value=extrap_value, copy=False) ## r1d = f(pOut[i,j,:]) ## #print i,j,r1d except: raise sys.stderr.write("Problem Interpolating data\n") sys.exit(1)
def test_24(self): """ Edit: New file from scratch This example shows how to * Create a record meta and data from scratch * Create grid descriptors for the data * Create vgrid descriptor for the data * write the recod data + meta * write the grid descriptors * write the vgrid descriptor See also: rpnpy.librmn.fstd98.fstopt rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.fsrecr rpnpy.librmn.fstd98.dtype_fst2numpy rpnpy.librmn.grids.encodeGrid rpnpy.librmn.grids.defGrid_ZE rpnpy.librmn.grids.writeGrid rpnpy.librmn.base.newdate rpnpy.vgd.base.vgd_new rpnpy.vgd.base.vgd_new_pres rpnpy.vgd.base.vgd_new_get rpnpy.vgd.base.vgd_write rpnpy.librmn.const rpnpy.vgd.const """ import os, sys 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) # Create Record grid gp = { 'grtyp': 'Z', 'grref': 'E', 'ni': 90, 'nj': 45, 'lat0': 35., 'lon0': 250., 'dlat': 0.5, 'dlon': 0.5, 'xlat1': 0., 'xlon1': 180., 'xlat2': 1., 'xlon2': 270. } g = rmn.encodeGrid(gp) print("CB24: Defined a %s/%s grid of shape=%d, %d" % (gp['grtyp'], gp['grref'], gp['ni'], gp['nj'])) # Create Record vgrid lvls = (500., 850., 1000.) v = vgd.vgd_new_pres(lvls) ip1list = vgd.vgd_get(v, 'VIPT') print("CB24: Defined a Pres vgrid with lvls=%s" % str(lvls)) # Create Record data + meta datyp = rmn.FST_DATYP_LIST['float_IEEE_compressed'] npdtype = rmn.dtype_fst2numpy(datyp) rshape = (g['ni'], g['nj'], len(ip1list)) r = rmn.FST_RDE_META_DEFAULT.copy() # Copy default record meta r.update(g) # Update with grid info r.update({ # Update with specific meta and data array 'nomvar': 'MASK', 'dateo': rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20160302, 1800000), 'nk': len(ip1list), 'ip1': 0, # level, will be set later, level by level 'ip2': 6, # Forecast of 6h 'deet': 3600, # Timestep in sec 'npas': 6, # Step number 'etiket': 'my_etk', 'nbits': 32, # Keep full 32 bits precision for that field 'datyp': datyp, # datyp (above) float_IEEE_compressed 'd': np.empty(rshape, dtype=npdtype, order='FORTRAN') }) print("CB24: Defined a new record of shape=%d, %d" % (r['ni'], r['nj'])) # Compute record values r['d'][:, :, :] = 0. r['d'][10:-11, 5:-6, :] = 1. # Open Files fileNameOut = 'newfromscratch.fst' try: fileIdOut = rmn.fstopenall(fileNameOut, rmn.FST_RW) except: sys.stderr.write("Problem opening the file: %s, %s\n" % fileNameOut) sys.exit(1) # Write record data + meta + grid + vgrid to file try: r2d = r.copy() r2d['nk'] = 1 for k in range(len(ip1list)): r2d['ip1'] = ip1list[k] r2d['d'] = np.asfortranarray(r['d'][:, :, k]) rmn.fstecr(fileIdOut, r2d['d'], r2d) print("CB24: wrote %s at ip1=%d" % (r2d['nomvar'], r2d['ip1'])) rmn.writeGrid(fileIdOut, g) print("CB24: wrote the grid descriptors") vgd.vgd_write(v, fileIdOut) print("CB24: wrote the vgrid descriptor") except: raise finally: # Properly close files even if an error occured above # This is important when editing to avoid corrupted files rmn.fstcloseall(fileIdOut) os.unlink(fileNameOut) # Remove test file
def test_24(self): """ Edit: New file from scratch This example shows how to * Create a record meta and data from scratch * Create grid descriptors for the data * Create vgrid descriptor for the data * write the recod data + meta * write the grid descriptors * write the vgrid descriptor See also: rpnpy.librmn.fstd98.fstopt rpnpy.librmn.fstd98.fstopenall rpnpy.librmn.fstd98.fstcloseall rpnpy.librmn.fstd98.fsrecr rpnpy.librmn.fstd98.dtype_fst2numpy rpnpy.librmn.grids.encodeGrid rpnpy.librmn.grids.defGrid_ZE rpnpy.librmn.grids.writeGrid rpnpy.librmn.base.newdate rpnpy.vgd.base.vgd_new rpnpy.vgd.base.vgd_new_pres rpnpy.vgd.base.vgd_new_get rpnpy.vgd.base.vgd_write rpnpy.librmn.const rpnpy.vgd.const """ import os, sys 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) # Create Record grid gp = { 'grtyp' : 'Z', 'grref' : 'E', 'ni' : 90, 'nj' : 45, 'lat0' : 35., 'lon0' : 250., 'dlat' : 0.5, 'dlon' : 0.5, 'xlat1' : 0., 'xlon1' : 180., 'xlat2' : 1., 'xlon2' : 270. } g = rmn.encodeGrid(gp) print("CB24: Defined a %s/%s grid of shape=%d, %d" % (gp['grtyp'], gp['grref'], gp['ni'], gp['nj'])) # Create Record vgrid lvls = (500.,850.,1000.) v = vgd.vgd_new_pres(lvls) ip1list = vgd.vgd_get(v, 'VIPT') print("CB24: Defined a Pres vgrid with lvls=%s" % str(lvls)) # Create Record data + meta datyp = rmn.FST_DATYP_LIST['float_IEEE_compressed'] npdtype = rmn.dtype_fst2numpy(datyp) rshape = (g['ni'], g['nj'], len(ip1list)) r = rmn.FST_RDE_META_DEFAULT.copy() # Copy default record meta r.update(g) # Update with grid info r.update({ # Update with specific meta and data array 'nomvar': 'MASK', 'dateo' : rmn.newdate(rmn.NEWDATE_PRINT2STAMP, 20160302, 1800000), 'nk' : len(ip1list), 'ip1' : 0, # level, will be set later, level by level 'ip2' : 6, # Forecast of 6h 'deet' : 3600, # Timestep in sec 'npas' : 6, # Step number 'etiket': 'my_etk', 'nbits' : 32, # Keep full 32 bits precision for that field 'datyp' : datyp, # datyp (above) float_IEEE_compressed 'd' : np.empty(rshape, dtype=npdtype, order='FORTRAN') }) print("CB24: Defined a new record of shape=%d, %d" % (r['ni'], r['nj'])) # Compute record values r['d'][:,:,:] = 0. r['d'][10:-11,5:-6,:] = 1. # Open Files fileNameOut = 'newfromscratch.fst' try: fileIdOut = rmn.fstopenall(fileNameOut, rmn.FST_RW) except: sys.stderr.write("Problem opening the file: %s, %s\n" % fileNameOut) sys.exit(1) # Write record data + meta + grid + vgrid to file try: r2d = r.copy() r2d['nk'] = 1 for k in range(len(ip1list)): r2d['ip1'] = ip1list[k] r2d['d'] = np.asfortranarray(r['d'][:,:,k]) rmn.fstecr(fileIdOut, r2d['d'], r2d) print("CB24: wrote %s at ip1=%d" % (r2d['nomvar'], r2d['ip1'])) rmn.writeGrid(fileIdOut, g) print("CB24: wrote the grid descriptors") vgd.vgd_write(v, fileIdOut) print("CB24: wrote the vgrid descriptor") except: raise finally: # Properly close files even if an error occured above # This is important when editing to avoid corrupted files rmn.fstcloseall(fileIdOut) os.unlink(fileNameOut) # Remove test file
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)