def main(archv_files,regress_file,opath,depth_file,header_line1=cline1,header_line2=cline2,header_line3=cline3 ) : regr = open(regress_file,'rb') slope,intercept,nemomeandt = pickle.load(regr,encoding="latin1") bp=modeltools.hycom.BlkdatParser("blkdat.input") idm = bp["idm"] jdm = bp["jdm"] kdm = bp["kdm"] iversn = bp["iversn"] yrflag = bp["yrflag"] iexpt = bp["iexpt"] # get domain depth abdepth = abfile.ABFileBathy(depth_file, \ "r",idm=idm,jdm=jdm) depthm=abdepth.read_field("depth") for archv_file in archv_files : logger.debug("Processing %s"%(archv_file)) arcfile=abfile.ABFileArchv(archv_file,"r") srfhgt=arcfile.read_field("srfhgt",0) montg1=arcfile.read_field("montg1",0) montg1=(srfhgt-nemomeandt) * slope + intercept montg1=np.where(np.isnan(montg1), 0, montg1) dummy = arcfile.read_field("temp",1) dummy[~depthm.mask] = montg1[~depthm.mask] # your fixed montg1 logger.info("Montg Minimum") print(dummy.min()) logger.info("Montg Maximum") print(dummy.max()) # logger.info("Estimated montg1 ") fnameout = opath+str(archv_file[-19:]) arcfile_out=abfile.ABFileArchv(fnameout,"w",iversn=iversn,yrflag=yrflag,iexpt=iexpt,mask=False,cline1=header_line1,cline2=header_line2,cline3=header_line3) for keys in sorted( arcfile.fields.keys() ) : fieldname = arcfile.fields[keys]["field"] time_step = arcfile.fields[keys]["step"] model_day = arcfile.fields[keys]["day"] k = arcfile.fields[keys]["k"] dens = arcfile.fields[keys]["dens"] fld = arcfile.read_field(fieldname,k) if fieldname == "montg1" : logger.info("Writing field %10s at level %3d to %s (modified)"%(fieldname,k,fnameout)) arcfile_out.write_field(dummy,None,fieldname,time_step,model_day,k,dens) else : arcfile_out.write_field(fld ,None,fieldname,time_step,model_day,k,dens) logger.info("Finished writing to %s"%fnameout) arcfile_out.close() arcfile.close() archv_file_b = archv_file[0:-1] + 'b' fnameout_b = fnameout[0:-1] + 'b' os.rename(fnameout,archv_file) # replaces the new archive files with the original ones in nest folder os.rename(fnameout_b,archv_file_b)
def test_abfilearchv_read(self): archv = abfile.ABFileArchv("archv.2013_152_00", "r") fld = archv.read_field("salin", 1) #print fld.min(),fld.max() #print archv.fieldnames #print archv.fieldlevels archv.close()
def open_file(myfile0, filetype, fieldname, fieldlevel, datetime1=None, datetime2=None, vector="", idm=None, jdm=None): logger.info("Now processing %s" % myfile0) m = re.match("(.*)\.[ab]", myfile0) if m: myfile = m.group(1) else: myfile = myfile0 ab2 = None rdtimes = [] if filetype == "archive": ab = abfile.ABFileArchv(myfile, "r") n_intloop = 1 #elif filetype == "restart" : # tmp = abfile.ABFileRestart(myfile,"r",idm=gfile.idm,jdm=gfile.jdm) elif filetype == "regional.depth": ab = abfile.ABFileBathy(myfile, "r", idm=idm, jdm=jdm) n_intloop = 1 elif filetype == "forcing": ab = abfile.ABFileForcing(myfile, "r", idm=idm, jdm=jdm) if vector: file2 = myfile.replace(fieldname, vector) logger.info("Opening file %s for vector component nr 2" % file2) ab2 = abfile.ABFileForcing(file2, "r", idm=idm, jdm=jdm) if datetime1 is None or datetime2 is None: raise NameError, "datetime1 and datetime2 must be specified when plotting forcing files" else: iday1, ihour1, isec1 = modeltools.hycom.datetime_to_ordinal( datetime1, 3) rdtime1 = modeltools.hycom.dayfor(datetime1.year, iday1, ihour1, 3) # iday2, ihour2, isec2 = modeltools.hycom.datetime_to_ordinal( datetime2, 3) rdtime2 = modeltools.hycom.dayfor(datetime2.year, iday2, ihour2, 3) rdtimes = sorted([ elem for elem in ab.field_times if elem > rdtime1 and elem < rdtime2 ]) n_intloop = len(rdtimes) else: raise NotImplementedError, "Filetype %s not implemented" % filetype # Check that fieldname is actually in file if fieldname not in ab.fieldnames: logger.error("Unknown field %s at level %d" % (fieldname, fieldlevel)) logger.error("Available fields : %s" % (" ".join(ab.fieldnames))) raise ValueError, "Unknown field %s at level %d" % (fieldname, fieldlevel) return n_intloop, ab, ab2, rdtimes
def main(myfiles, fieldname, fieldlevel, idm=None, jdm=None, clim=None, filetype="archive"): cmap = matplotlib.pyplot.get_cmap("jet") for i, myfile0 in enumerate(myfiles): m = re.match("(.*)\.[ab]", myfile0) if m: myfile = m.group(1) else: myfile = myfile0 if filetype == "archive": ab = abfile.ABFileArchv(myfile, "r") #elif filetype == "restart" : # tmp = abfile.ABFileRestart(myfile,"r",idm=gfile.idm,jdm=gfile.jdm) else: raise NotImplementedError, "Filetype %s not implemented" % filetype if fieldname not in ab.fieldnames: logger.error("Unknown field %s at level %d" % (fieldname, fieldlevel)) logger.error("Available fields : %s" % (" ".join(ab.fieldnames))) raise ValueError, "Unknown field %s at level %d" % (fieldname, fieldlevel) fld = ab.read_field(fieldname, fieldlevel) figure = matplotlib.pyplot.figure(figsize=(8, 8)) ax = figure.add_subplot(111) #P=ax.pcolormesh(fld) #P=ax.pcolormesh(fld[2200:2800,3500:4500],cmap=cmap) P = ax.pcolormesh(fld, cmap=cmap) ax.figure.colorbar(P) if clim is not None: P.set_clim(clim) ax.set_title("%s:%s(%d)" % (myfile0, fieldname, fieldlevel)) #figure.colorbar(P,norm=matplotlib.colors.LogNorm(vmin=w5.min(), vmax=w5.max())) #ax.contour(w5)#,[-10.,-100.,-500.,-1000.]) #ax.set_title("Slope fac in color, depth contours in black") #logger.info("Slope factor in slopefac.png") figure.canvas.print_figure("tst%03d.png" % i)
def main(archv_files, opath, header_line1=cline1, header_line2=cline2, header_line3=cline3): # Open blkdat files. Get some properties bp = modeltools.hycom.BlkdatParser("blkdat.input") idm = bp["idm"] jdm = bp["jdm"] kdm = bp["kdm"] thflag = bp["thflag"] thbase = numpy.float(bp["thbase"]) kapref = bp["kapref"] iversn = bp["iversn"] iexpt = bp["iexpt"] yrflag = bp["yrflag"] #thref=modeltools.hycom.thref thref = 1e-3 if kapref == -1: kapnum = 2 msg = "Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError, msg else: kapnum = 1 if kapnum > 1: msg = "Only kapnum=1 is implemented for now" logger.error(msg) raise ValueError, msg # hycom sigma and kappa, written in python. NB: sigver is not used here. # Modify to use other equations of state. For now we assume sigver is: # 1 (7-term eqs referenced to 0 bar) # 2 (7-term eqs referenced to 2000 bar) if thflag == 0: sigver = 1 else: sigver = 2 sig = modeltools.hycom.Sigma(thflag) if kapref > 0: kappa = modeltools.hycom.Kappa(kapref, thflag * 1000.0e4) # # Loop through archive files for archv_file in archv_files: archv_file = archv_file[:-2] logger.debug("Processing %s" % (archv_file)) arcfile = abfile.ABFileArchv(archv_file, "r") temp = numpy.ma.zeros( (jdm, idm)) # Only needed when calculating density saln = numpy.ma.zeros( (jdm, idm)) # Only needed when calculating density th3d = numpy.ma.zeros((kdm, jdm, idm)) thstar = numpy.ma.zeros((kdm, jdm, idm)) dp = numpy.ma.zeros((jdm, idm)) p = numpy.ma.zeros((kdm + 1, jdm, idm)) pup = numpy.ma.zeros((jdm, idm)) montg = numpy.ma.zeros((jdm, idm)) for k in range(kdm): logger.info("Reading layer %d from %s" % (k, archv_file)) temp = arcfile.read_field("temp", k + 1) saln = arcfile.read_field("salin", k + 1) dp[:, :] = arcfile.read_field("thknss", k + 1) th3d[k, :, :] = sig.sig(temp, saln) - thbase p[k + 1, :, :] = p[k, :, :] + dp[:, :] if k > 0: thstarup = numpy.ma.copy(thstar[k, :, :]) thstar[k, :, :] = numpy.ma.copy(th3d[k, :, :]) if kapref > 0: thstar[k, :, :] = thstar[k, :, :] + kappa.kappaf( temp[:, :], saln[:, :], th3d[k, :, :] + thbase, p[k, :, :]) elif kapref < 0: msg = "Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError, msg if k > 0: montg = montg - p[k, :, :] * (thstar[k, :, :] - thstarup) * thref**2 thkk = thstar[k, :, :] psikk = montg # This part of montg1 does nto depend on pbavg montg1c = montg1_pb(thstar, p) # This part depends linearly on pbavg montg1pb = montg1_no_pb(psikk, thkk, thstar, p) # Barotropic pressure. NB: srfhgt is in geopotential height : srfhgt = arcfile.read_field("srfhgt", 0) pbavg = (srfhgt - montg1c) / (montg1pb + thref) montg1 = montg1pb * pbavg + montg1c logger.info("Estimated montg1 ") # Apply mask #montg1=numpy.ma.masked_where(srfhgt.mask,montg1) #montg1[~msk]=2**100 #montg1 = numpy.ma.masked_where(srfhgt<2.0**99,montg1) msk = numpy.where(srfhgt > 2.0**99, 1, 0) # Open new archive file, and write montg1 to it. fnameout = opath + str(archv_file[-17:]) arcfile_out = abfile.ABFileArchv(fnameout, "w", iversn=iversn, yrflag=yrflag, iexpt=iexpt, mask=False, cline1=header_line1, cline2=header_line2, cline3=header_line3) fields = arcfile.get_fields() for key in sorted(fields.keys()): fieldname = fields[key]["field"] time_step = fields[key]["step"] model_day = fields[key]["day"] k = fields[key]["k"] dens = fields[key]["dens"] fld = arcfile.read_field(fieldname, k) if fieldname == "montg1": logger.info( "Writing field %10s at level %3d to %s (modified)" % (fieldname, k, fnameout)) arcfile_out.write_field(montg1, None, fieldname, time_step, model_day, k, dens) else: arcfile_out.write_field(fld, None, fieldname, time_step, model_day, k, dens) logger.info("Finished writing to %s" % fnameout) arcfile_out.close() arcfile.close()
def main(filemesh, grid2dfiles, first_j=0, mean_file=False, iexpt=10, iversn=22, yrflag=3, makegrid=None, bio_path=None): if mean_file: fnametemplate = "archm.%Y_%j_%H" else: fnametemplate = "archv.%Y_%j_%H" itest = 1 jtest = 200 gdept, gdepw, e3t_ps, e3w_ps, mbathy, hdepw, depth, plon, plat = read_mesh( filemesh) if makegrid is not None: logger.info("Making NEMO grid & bathy [ab] files ...") make_grid(filemesh) mbathy = mbathy - 1 # python indexing starts from 0 nlev = gdept.size mbathy_u, e3u_ps, depthu = depth_u_points(depth, mbathy, gdepw) mbathy_v, e3v_ps, depthv = depth_v_points(depth, mbathy, gdepw) # mbathy_u = sliced(u_to_hycom_u(mbathy_u)) e3u_ps = sliced(u_to_hycom_u(e3u_ps)) depthu = sliced(u_to_hycom_u(depthu)) # mbathy_v = sliced(v_to_hycom_v(mbathy_v)) e3v_ps = sliced(v_to_hycom_v(e3v_ps)) depthv = sliced(v_to_hycom_v(depthv)) dt = gdepw[1:] - gdepw[:-1] # Loop over input files. All must be in same directory for file2d in grid2dfiles: # See if actually a grid2D file dirname = os.path.dirname(file2d) m = re.match("(.*_)(grid2D)(_.*\.nc)", os.path.basename(file2d)) if not m: msg = "File %s is not a grid2D file, aborting" % file2d logger.error(msg) raise ValueError, msg # Construct remaining files filet = os.path.join(dirname, m.group(1) + "gridT" + m.group(3)) files = os.path.join(dirname, m.group(1) + "gridS" + m.group(3)) fileu = os.path.join(dirname, m.group(1) + "gridU" + m.group(3)) filev = os.path.join(dirname, m.group(1) + "gridV" + m.group(3)) filew = os.path.join(dirname, m.group(1) + "gridW" + m.group(3)) fileice = os.path.join(dirname, m.group(1) + "icemod" + m.group(3)) logger.info("grid2D file: %s" % file2d) # P-points logger.info("gridS file: %s" % files) logger.info("gridT file: %s" % filet) ncids = netCDF4.Dataset(files, "r") ncidt = netCDF4.Dataset(filet, "r") # time from gridT file. time = ncidt.variables["time_counter"][0] tunit = ncidt.variables["time_counter"].units tmp = cfunits.Units(tunit) refy, refm, refd = (1958, 1, 1) tmp2 = cfunits.Units("hours since %d-%d-%d 00:00:00" % (refy, refm, refd)) # Units from CF convention tmp3 = cfunits.Units.conform(time, tmp, tmp2) # Transform to new new unit tmp3 = int(numpy.round(tmp3)) mydt = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta( hours=tmp3) # Then calculate dt. Phew! if bio_path: jdm, idm = numpy.shape(plon) points = numpy.transpose(((plat.flatten(), plon.flatten()))) delta = mydt.strftime('%Y-%m-%d') # filename format MERCATOR-BIO-14-2013-01-05-00 idx, biofname = search_biofile(bio_path, delta) if idx > 7: msg = "No available BIO file within a week difference with PHY" logger.error(msg) raise ValueError, msg logger.info( "BIO file %s reading & interpolating to 1/12 deg grid cells ..." % biofname) ncidb = netCDF4.Dataset(biofname, "r") blon = ncidb.variables["longitude"][:] blat = ncidb.variables["latitude"][:] minblat = blat.min() no3 = ncidb.variables["NO3"][0, :, :, :] no3[numpy.abs(no3) > 1e+5] = numpy.nan po4 = ncidb.variables["PO4"][0, :, :, :] si = ncidb.variables["Si"][0, :, :, :] po4[numpy.abs(po4) > 1e+5] = numpy.nan si[numpy.abs(si) > 1e+5] = numpy.nan # TODO: The following piece will be optimised and replaced soon. nz, ny, nx = no3.shape dummy = numpy.zeros((nz, ny, nx + 1)) dummy[:, :, :nx] = no3 dummy[:, :, -1] = no3[:, :, -1] no3 = dummy dummy = numpy.zeros((nz, ny, nx + 1)) dummy[:, :, :nx] = po4 dummy[:, :, -1] = po4[:, :, -1] po4 = dummy dummy = numpy.zeros((nz, ny, nx + 1)) dummy[:, :, :nx] = si dummy[:, :, -1] = si[:, :, -1] si = dummy dummy = numpy.zeros((nx + 1)) dummy[:nx] = blon blon = dummy blon[-1] = -blon[0] # TODO: Note that the coordinate files are for global configuration while # the data file saved for latitude larger than 30. In the case you change your data file coordinate # configuration you need to modify the following lines bio_coordfile = bio_path[:-4] + "/GLOBAL_ANALYSIS_FORECAST_BIO_001_014_COORD/GLO-MFC_001_014_mask.nc" biocrd = netCDF4.Dataset(bio_coordfile, "r") blat2 = biocrd.variables['latitude'][:] index = numpy.where(blat2 >= minblat)[0] depth_lev = biocrd.variables['deptho_lev'][index[0]:, :] # # # dummy = numpy.zeros((ny, nx + 1)) dummy[:, :nx] = depth_lev dummy[:, -1] = depth_lev[:, -1] depth_lev = dummy depth_lev[depth_lev > 50] = 0 depth_lev = depth_lev.astype('i') dummy_no3 = no3 dummy_po4 = po4 dummy_si = si for j in range(ny): for i in range(nx): dummy_no3[depth_lev[j, i]:nz - 2, j, i] = no3[depth_lev[j, i] - 1, j, i] dummy_po4[depth_lev[j, i]:nz - 2, j, i] = po4[depth_lev[j, i] - 1, j, i] dummy_si[depth_lev[j, i]:nz - 2, j, i] = si[depth_lev[j, i] - 1, j, i] no3 = dummy_no3 po4 = dummy_po4 si = dummy_si po4 = po4 * 106.0 * 12.01 si = si * 6.625 * 12.01 no3 = no3 * 6.625 * 12.01 # field_interpolator=FieldInterpolatorBilinear(blon,blat,plon.flatten(),plat.flatten()) # Read and calculculate U in hycom U-points. logger.info("gridU, gridV, gridT & gridS file") ncidu = netCDF4.Dataset(fileu, "r") u = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) ncidv = netCDF4.Dataset(filev, "r") v = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) udummy = ncidu.variables["vozocrtx"][:, :, :, :] vdummy = ncidv.variables["vomecrty"][:, :, :, :] tdummy = ncidt.variables["votemper"][:, :, :, :] tdummy_fill = ncidt.variables["votemper"]._FillValue sdummy = ncids.variables["vosaline"][:, :, :, :] sdummy_fill = ncids.variables["vosaline"]._FillValue for k in range(nlev): u[k, :, :] = sliced(u_to_hycom_u( udummy[0, k, :, :])) # Costly, make more efficient if needed v[k, :, :] = sliced(v_to_hycom_v( vdummy[0, k, :, :])) # Costly, make more efficient if needed u = numpy.where(numpy.abs(u) < 1e10, u, 0.) v = numpy.where(numpy.abs(v) < 1e10, v, 0.) logger.info("Calculate barotropic velocities ...") #Calculate barotropic and baroclinic u usum = numpy.zeros(u.shape[-2:]) dsumu = numpy.zeros(u.shape[-2:]) vsum = numpy.zeros(v.shape[-2:]) dsumv = numpy.zeros(v.shape[-2:]) for k in range(u.shape[0] - 1): # Dont include lowest layer J, I = numpy.where(mbathy_u > k) usum[J, I] = usum[J, I] + u[k, J, I] * dt[k] dsumu[J, I] = dsumu[J, I] + dt[k] J, I = numpy.where(mbathy_v > k) vsum[J, I] = vsum[J, I] + v[k, J, I] * dt[k] dsumv[J, I] = dsumv[J, I] + dt[k] J, I = numpy.where(mbathy >= 0) usum[J, I] = usum[J, I] + u[mbathy_u[J, I], J, I] * e3u_ps[J, I] dsumu[J, I] = dsumu[J, I] + e3u_ps[J, I] dsumu = numpy.where(abs(dsumu) < 1e-2, 0.05, dsumu) ubaro = numpy.where(dsumu > 0.1, usum / dsumu, 0.) J, I = numpy.where(mbathy_v >= 0) vsum[J, I] = vsum[J, I] + v[mbathy_v[J, I], J, I] * e3v_ps[J, I] dsumv[J, I] = dsumv[J, I] + e3v_ps[J, I] dsumv = numpy.where(abs(dsumv) < 1e-2, 0.05, dsumv) vbaro = numpy.where(dsumv > .1, vsum / dsumv, 0.) fnametemplate = "archv.%Y_%j" deltat = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta(hours=tmp3) oname = deltat.strftime(fnametemplate) + "_00" # model day refy, refm, refd = (1900, 12, 31) model_day = deltat - datetime.datetime(refy, refm, refd, 0, 0, 0) model_day = model_day.days logger.info("Model day in HYCOM is %s" % str(model_day)) # Masks (land:True) if mask_method == 1: ip = mbathy == -1 iu = mbathy_u == -1 iv = mbathy_v == -1 else: ip = depth == 0 iu = depthu == 0 iv = depthv == 0 # 2D data ncid2d = netCDF4.Dataset(file2d, "r") ssh = sliced(ncid2d.variables["sossheig"][0, :, :]) ssh = numpy.where(ssh == ncid2d.variables["sossheig"]._FillValue, 0., ssh) ssh = numpy.where(ssh > 1e10, 0., ssh * 9.81) # NB: HYCOM srfhgt is in geopotential ... montg1 = numpy.zeros(ssh.shape) # Write to abfile outfile = abfile.ABFileArchv( "./data/" + oname, "w", iexpt=iexpt, iversn=iversn, yrflag=yrflag, ) logger.info("Writing 2D variables") outfile.write_field(montg1, ip, "montg1", 0, model_day, 1, 0) outfile.write_field(ssh, ip, "srfhgt", 0, model_day, 0, 0) outfile.write_field(numpy.zeros(ssh.shape), ip, "surflx", 0, model_day, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "salflx", 0, model_day, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "bl_dpth", 0, model_day, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "mix_dpth", 0, model_day, 0, 0) # Not used outfile.write_field(ubaro, iu, "u_btrop", 0, model_day, 0, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vbaro, iv, "v_btrop", 0, model_day, 0, 0) # v: nemo in cell j is hycom in cell j+1 ny = mbathy.shape[0] nx = mbathy.shape[1] error = numpy.zeros((ny, nx)) for k in numpy.arange(u.shape[0]): if bio_path: no3k = interpolate2d(blat, blon, no3[k, :, :], points).reshape( (jdm, idm)) no3k = maplev(no3k) po4k = interpolate2d(blat, blon, po4[k, :, :], points).reshape( (jdm, idm)) po4k = maplev(po4k) si_k = interpolate2d(blat, blon, si[k, :, :], points).reshape( (jdm, idm)) si_k = maplev(si_k) if k % 10 == 0: logger.info( "Writing 3D variables including BIO, level %d of %d" % (k + 1, u.shape[0])) else: if k % 10 == 0: logger.info("Writing 3D variables, level %d of %d" % (k + 1, u.shape[0])) # ul = numpy.squeeze(u[k, :, :]) - ubaro # Baroclinic velocity vl = numpy.squeeze(v[k, :, :]) - vbaro # Baroclinic velocity # Layer thickness dtl = numpy.zeros(ul.shape) if k < u.shape[0] - 1: J, I = numpy.where(mbathy > k) dtl[J, I] = dt[k] J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] else: J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] tmpfill = sdummy_fill #ncids.variables["vosaline"]._FillValue sl = sliced(sdummy[0, k, :, :]) tmpfill = tdummy_fill #ncidt.variables["votemper"]._FillValue tl = sliced(tdummy[0, k, :, :]) sl = numpy.where(numpy.abs(sl) < 1e2, sl, numpy.nan) sl = numpy.minimum(numpy.maximum(maplev(sl), 25), 80.) tl = numpy.where(numpy.abs(tl) <= 5e2, tl, numpy.nan) tl = numpy.minimum(numpy.maximum(maplev(tl), -5.), 50.) # Fill empty layers with values from above if k > 0: K = numpy.where(dtl < 1e-4) tl[K] = tl_above[K] onem = 9806. outfile.write_field(ul, iu, "u-vel.", 0, model_day, k + 1, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vl, iv, "v-vel.", 0, model_day, k + 1, 0) # v: nemo in cell j is hycom in cell j+1 outfile.write_field(dtl * onem, ip, "thknss", 0, model_day, k + 1, 0) outfile.write_field(tl, ip, "temp", 0, model_day, k + 1, 0) outfile.write_field(sl, ip, "salin", 0, model_day, k + 1, 0) if bio_path: outfile.write_field(no3k, ip, "ECO_no3", 0, model_day, k + 1, 0) outfile.write_field(po4k, ip, "ECO_pho", 0, model_day, k + 1, 0) outfile.write_field(si_k, ip, "ECO_sil", 0, model_day, k + 1, 0) tl_above = numpy.copy(tl) sl_above = numpy.copy(sl) # TODO: Process ice data ncid2d.close() outfile.close() ncidt.close() ncids.close() ncidu.close() ncidv.close() if bio_path: ncidb.close() nemo_mesh = []
ndays = numpy.size( sorted( fnmatch.filter(os.listdir(directory), 'archm.%s*.b' % ('201[01123456]')))) NX = 760 NY = 800 montg = numpy.zeros((ndays, NX, NY)) ssh = numpy.zeros((ndays, NX, NY)) a = numpy.zeros((NX, NY)) b = numpy.zeros((NX, NY)) for f1 in sorted( fnmatch.filter(os.listdir(directory), 'archm.%s*.b' % ('201[01123456]'))): print(day) f = abfile.ABFileArchv('%s%s' % (directory, f1), "r") mon = getvarib(f, 'montg1', 0) srf = getvarib(f, 'srfhgt', 0) montg[day, :, :] = mon ssh[day, :, :] = srf day = day + 1 f.close t = 0 ssh1 = numpy.ma.masked_where(ssh > 1E10, ssh) meanssh = numpy.mean(ssh1) anomaly = ssh1 - meanssh for II in range(NX):
def main(lon1, lat1, lon2, lat2, variable, files, filetype="archive", clim=None): print filetype gfile = abfile.ABFileGrid("regional.grid", "r") plon = gfile.read_field("plon") plat = gfile.read_field("plat") sec = modeltools.tools.Section([lon1, lon2], [lat1, lat2], plon, plat) I, J = sec.grid_indexes dist = sec.distance slon = sec.longitude slat = sec.latitude m = Basemap(projection='mill', llcrnrlon=-180., llcrnrlat=-90., urcrnrlon=180., urcrnrlat=90., resolution='l') (x, y) = m(slon, slat) figure = matplotlib.pyplot.figure() ax = figure.add_subplot(111) m.drawcoastlines() m.fillcontinents(color='coral', lake_color='aqua') m.drawparallels(numpy.arange(-90., 120., 30.), labels=[1, 0, 0, 0]) # draw parallels m.drawmeridians(numpy.arange(0., 420., 60.), labels=[0, 0, 0, 1]) # draw meridians m.drawmapboundary() # draw a line around the map region #m.plot(x,y,"r",lw=3) m.scatter(x, y, s=20, c=dist) figure.canvas.print_figure("map.png") dpname = modeltools.hycom.layer_thickness_variable[filetype] logger.info("Filetype %s: layer thickness variable is %s" % (filetype, dpname)) for fcnt, myfile0 in enumerate(files): m = re.match("(.*)\.[ab]", myfile0) if m: myfile = m.group(1) else: myfile = myfile0 if filetype == "archive": tmp = abfile.ABFileArchv(myfile, "r") elif filetype == "restart": tmp = abfile.ABFileRestart(myfile, "r", idm=gfile.idm, jdm=gfile.jdm) else: raise NotImplementedError, "Filetype %s not implemented" % filetype kdm = max(tmp.fieldlevels) intfsec = numpy.zeros((kdm + 1, I.size)) datasec = numpy.zeros((kdm + 1, I.size)) for k in range(kdm): logger.info("File %s, layer %03d/%03d" % (myfile, k, kdm)) dp2d = tmp.read_field(dpname, k + 1) data2d = tmp.read_field(variable, k + 1) dp2d = numpy.ma.filled(dp2d, 0.) / modeltools.hycom.onem data2d = numpy.ma.filled(data2d, 1e30) intfsec[k + 1, :] = intfsec[k, :] + dp2d[J, I] if k == 0: datasec[k, :] = data2d[J, I] datasec[k + 1, :] = data2d[J, I] datasec = numpy.ma.masked_where(datasec == 1e30, datasec) figure = matplotlib.pyplot.figure() ax = figure.add_subplot(111) P = ax.pcolormesh(dist / 1000., -intfsec, datasec) if clim is not None: P.set_clim(clim) for k in range(1, kdm + 1): if k % 10 == 0: PL = ax.plot(dist / 1000., -intfsec[k, :], "-", color="k") elif k % 5 == 0: PL = ax.plot(dist / 1000., -intfsec[k, :], "--", color="k") else: PL = ax.plot(dist / 1000., -intfsec[k, :], "-", color=".5") textx = dist[dist.size / 2] / 1000. texty = -0.5 * (intfsec[k - 1, dist.size / 2] + intfsec[k, dist.size / 2]) #print "textx,texty",textx,texty ax.text(textx, texty, str(k), verticalalignment="center", horizontalalignment="center", fontsize=6) ax.figure.colorbar(P) ax.set_title(myfile) ax.set_ylabel(variable) ax.set_xlabel("distance along section [km]") matplotlib.pyplot.tight_layout() figure.canvas.print_figure("sec_%s_full_%s.png" % (variable, os.path.basename(myfile))) ax.set_ylim(-1000, 0) figure.canvas.print_figure("sec_%s_1000m_%s.png" % (variable, os.path.basename(myfile))) ax.set_ylim(-300, 0) figure.canvas.print_figure("sec_%s_300m_%s.png" % (variable, os.path.basename(myfile))) tmp.close()
def main(startdate, enddate, first_j=0): soda_template = "/work/shared/nersc/msc/SODA/3.3.1/monthly/soda3.3.1_mn_ocean_reg_%Y.nc" # open blkdat.input. Get nesting frequency bp = modeltools.hycom.BlkdatParser("blkdat.input") nestfq = bp["nestfq"] bnstfq = bp["bnstfq"] # Read soda-grid and topo from first file fid = netCDF4.Dataset(startdate.strftime(soda_template), "r") depth = fid["depth"][:] soda_to_regional_grid(fid) # Get bathymetry. Set to 0 wherever salinit in top layer is undefined. bathy = numpy.zeros(fid["salt"].shape[-2:]) for k in range(depth.size): bathy[~numpy.squeeze(fid["salt"][0, k, :, :].mask)] = depth[k] abfile.write_bathymetry("SODA", 22, bathy, 0.) fid.close() # TODO: ip = bathy == 0. iu = bathy == 0. iv = bathy == 0. onem = 9806 #if mean_file : # fnametemplate_out="archm.%Y_%j_%H" #else : hycom_template = "archv.%Y_%j_%H" # Loop over nestfq, bnstfq. deltat = enddate - startdate dsec = deltat.days * 86400 + deltat.seconds baroclinic_nest_times = [ startdate + datetime.timedelta(seconds=s) for s in numpy.arange(0, dsec, nestfq * 86400) ] barotropic_nest_times = [ startdate + datetime.timedelta(seconds=s) for s in numpy.arange(0, dsec, bnstfq * 86400) ] tmp = sorted(set(barotropic_nest_times + baroclinic_nest_times)) for dt in tmp: logger.info("Processing time %s" % str(dt)) # Get "mid-month" dates if dt.day >= 15: nm = 1 + dt.month % 12 ny = dt.year + dt.month / 12 mm0 = datetime.datetime(dt.year, dt.month, 15, 0, 0, 0) mm1 = datetime.datetime(ny, nm, 15, 0, 0, 0) else: lm = 1 + (12 + dt.month - 2) % 12 ly = dt.year - lm / 12 print dt.month, lm, ly mm0 = datetime.datetime(ly, lm, 15, 0, 0, 0) mm1 = datetime.datetime(dt.year, dt.month, 15, 0, 0, 0) # Linear interpolation weights deltat = mm1 - mm0 deltat = deltat.days + deltat.seconds / 86400. w1 = dt - mm0 w1 = w1.days + w1.seconds / 86400. w1 = w1 / deltat w0 = 1. - w1 flnm0 = mm0.strftime(soda_template) flnm1 = mm1.strftime(soda_template) logger.info("Time %s, file %s at %s(w=%.4f) , file %s at %s(w=%.4f)" % (str(dt), flnm0, str(mm0), w0, flnm1, str(mm1), w1)) # Open files # TODO: reuse pointers/fields fid0 = netCDF4.Dataset(flnm0, "r") fid1 = netCDF4.Dataset(flnm1, "r") # Calculate temperature, velocity temp = w0 * fid0["temp"][0, :, :, :] + w1 * fid1["temp"][0, :, :, :] salt = w0 * fid0["salt"][0, :, :, :] + w1 * fid1["salt"][0, :, :, :] utot = w0 * fid0["u"][0, :, :, :] + w1 * fid1["u"][0, :, :, :] vtot = w0 * fid0["v"][0, :, :, :] + w1 * fid1["v"][0, :, :, :] #NB: No checks for missing values yet ! ubaro = numpy.sum(utot, 0) vbaro = numpy.sum(vtot, 0) u = utot - ubaro v = vtot - vbaro # 2D vars anompb = w0 * fid0["anompb"][0, :, :] + w1 * fid1["anompb"][0, :, :] ssh = w0 * fid0["ssh"][0, :, :] + w1 * fid1["ssh"][0, :, :] salflx = w0 * fid0["salt_flux_total"][ 0, :, :] + w1 * fid1["salt_flux_total"][0, :, :] surflx = w0 * fid0["net_heating"][ 0, :, :] + w1 * fid1["salt_flux_total"][0, :, :] montg1 = numpy.zeros(ssh.shape) # Write to abfile outfile = abfile.ABFileArchv(dt.strftime(hycom_template), "w", iexpt=10, iversn=22, yrflag=3) logger.info("Writing 2D variables") outfile.write_field(montg1, ip, "montg1", 0, 0, 1, 0) outfile.write_field(ssh, ip, "srfhgt", 0, 0, 0, 0) outfile.write_field(surflx, ip, "surflx", 0, 0, 0, 0) outfile.write_field(salflx, ip, "salflx", 0, 0, 0, 0) outfile.write_field(numpy.zeros(ssh.shape), ip, "bl_dpth", 0, 0, 0, 0) outfile.write_field(numpy.zeros(ssh.shape), ip, "mix_dpth", 0, 0, 0, 0) outfile.write_field(ubaro, iu, "u_btrop", 0, 0, 0, 0) outfile.write_field(vbaro, iv, "v_btrop", 0, 0, 0, 0) #outfile.close() ; raise NameError,"test" for k in numpy.arange(u.shape[0]): if k % 10 == 0: logger.info("Writing 3D variables, level %d of %d" % (k + 1, u.shape[0])) if k == 0: dtl = depth[0] * numpy.where(bathy >= depth[k], 1, 0) else: dtl = (depth[k] - depth[k - 1]) * numpy.where( bathy >= depth[k], 1, 0) print dtl.min(), dtl.max() templ = temp[k, :, :] saltl = salt[k, :, :] # Set to layer above if undefined templ[dtl <= 0.] = 20. saltl[dtl <= 0.] = 35. outfile.write_field(u[k, :, :], iu, "u-vel.", 0, 0, k + 1, 0) outfile.write_field(v[k, :, :], iv, "v-vel.", 0, 0, k + 1, 0) outfile.write_field(dtl * onem, ip, "thknss", 0, 0, k + 1, 0) outfile.write_field(saltl, ip, "salin", 0, 0, k + 1, 0) outfile.write_field(templ, ip, "temp", 0, 0, k + 1, 0) oldsaltl = saltl oldtempl = templ # TODO: reuse pointers/fields outfile.close() fid0.close() fid1.close() raise NameError, "check vals" raise NameError, "test" itest = 1 jtest = 200 logger.info("Mean file:%s" % str(mean_file)) logger.info("Output file template:%s" % str(fnametemplate)) # Write regional files nemo_mesh_to_hycom.main(filemesh, first_j=first_j) nemo_mesh = modeltools.nemo.NemoMesh(filemesh, first_j=first_j) #ncidmesh=netCDF4.Dataset(filemesh,"r") gdept = nemo_mesh["gdept_0"][0, :] # Depth of t points gdepw = nemo_mesh["gdepw_0"][0, :] # Depth of w points e3t_ps = nemo_mesh.sliced( nemo_mesh["e3t_ps"][0, :, :]) # Partial steps of t cell e3w_ps = nemo_mesh.sliced( nemo_mesh["e3w_ps"][0, :, :]) # Partial steps of w cell mbathy = nemo_mesh.sliced(nemo_mesh["mbathy"][0, :, :]) # bathy index hdepw = nemo_mesh.sliced( nemo_mesh["hdepw"][0, :, :]) # Total depth of w points mbathy = mbathy - 1 # python indexing starts from 0 nlev = gdept.size mbathy_u, e3u_ps, depthu = nemo_mesh.depth_u_points() mbathy_v, e3v_ps, depthv = nemo_mesh.depth_v_points() # mbathy_u = nemo_mesh.sliced(nemo_mesh.u_to_hycom_u(mbathy_u)) e3u_ps = nemo_mesh.sliced(nemo_mesh.u_to_hycom_u(e3u_ps)) depthu = nemo_mesh.sliced(nemo_mesh.u_to_hycom_u(depthu)) # mbathy_v = nemo_mesh.sliced(nemo_mesh.v_to_hycom_v(mbathy_v)) e3v_ps = nemo_mesh.sliced(nemo_mesh.v_to_hycom_v(e3v_ps)) depthv = nemo_mesh.sliced(nemo_mesh.v_to_hycom_v(depthv)) # Thickness of t layers (NB: 1 less than gdepw dimension) dt = gdepw[1:] - gdepw[:-1] # Loop over input files. All must be in same directory for file2d in grid2dfiles: # See if actually a grid2D file dirname = os.path.dirname(file2d) m = re.match("(.*_)(grid2D)(_.*\.nc)", os.path.basename(file2d)) if not m: msg = "File %s is not a grid2D file, aborting" % file2d logger.error(msg) raise ValueError, msg # Construct remaining files filet = os.path.join(dirname, m.group(1) + "gridT" + m.group(3)) files = os.path.join(dirname, m.group(1) + "gridS" + m.group(3)) fileu = os.path.join(dirname, m.group(1) + "gridU" + m.group(3)) filev = os.path.join(dirname, m.group(1) + "gridV" + m.group(3)) filew = os.path.join(dirname, m.group(1) + "gridW" + m.group(3)) fileice = os.path.join(dirname, m.group(1) + "icemod" + m.group(3)) logger.info("grid2D file: %s" % file2d) # P-points logger.info("gridS file: %s" % files) logger.info("gridT file: %s" % filet) ncids = netCDF4.Dataset(files, "r") s = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) for k in range(nlev): # Dont include lowest layer s[k, :, :] = nemo_mesh.sliced(ncids.variables["vosaline"][0, k, :, :]) s = numpy.where(s < 1e30, s, 0.) s = numpy.where(s == ncids.variables["vosaline"]._FillValue, 0., s) ncidt = netCDF4.Dataset(filet, "r") t = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) for k in range(nlev): # Dont include lowest layer t[k, :, :] = nemo_mesh.sliced(ncidt.variables["votemper"][0, k, :, :]) t = numpy.where(t == ncidt.variables["votemper"]._FillValue, 0., t) t = numpy.where(t < 1e30, t, 0.) # time from gridT file. time = ncidt.variables["time_counter"][0] tunit = ncidt.variables["time_counter"].units tmp = cfunits.Units(tunit) refy, refm, refd = (1958, 1, 1) tmp2 = cfunits.Units("seconds since %d-%d-%d 00:00:00" % (refy, refm, refd)) # Units from CF convention tmp3 = cfunits.Units.conform(time, tmp, tmp2) # Transform to new new unit mydt = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta( seconds=tmp3) # Then calculate dt. Phew! # Read and calculculate U in hycom U-points. logger.info("gridU file: %s" % fileu) ncidu = netCDF4.Dataset(fileu, "r") u = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) for k in range(nlev): u[k, :, :] = nemo_mesh.sliced( nemo_mesh.u_to_hycom_u(ncidu.variables["vozocrtx"][ 0, k, :, :])) # Costly, make more efficient if needed u = numpy.where(numpy.abs(u) < 1e10, u, 0.) #Calculate barotropic and baroclinic u usum = numpy.zeros(u.shape[-2:]) dsum = numpy.zeros(u.shape[-2:]) for k in range(u.shape[0] - 1): # Dont include lowest layer # TODO: Mid-layer depths seem to be undefined - figure out why ... logger.debug( "k=%3d, u=%10.3g, mbathy_u[jtest,itest]=%3d,gdepw[k]=%8.2f, depthu[jtest,itest]=%8.2f" % (k, u[k, jtest, itest], mbathy_u[jtest, itest], gdepw[k], depthu[jtest, itest])) J, I = numpy.where(mbathy_u > k) usum[J, I] = usum[J, I] + u[k, J, I] * dt[k] dsum[J, I] = dsum[J, I] + dt[k] J, I = numpy.where(mbathy >= 0) usum[J, I] = usum[J, I] + u[mbathy_u[J, I], J, I] * e3u_ps[J, I] dsum[J, I] = dsum[J, I] + e3u_ps[J, I] ubaro = numpy.where(dsum > 0.1, usum / dsum, 0.) # Read and calculculate V in hycom V-points. logger.info("gridV file: %s" % filev) ncidv = netCDF4.Dataset(filev, "r") v = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) for k in range(nlev): v[k, :, :] = nemo_mesh.sliced( nemo_mesh.v_to_hycom_v(ncidv.variables["vomecrty"][ 0, k, :, :])) # Costly, make more efficient if needed v = numpy.where(numpy.abs(v) < 1e10, v, 0.) #Calculate barotropic and baroclinic v vsum = numpy.zeros(v.shape[-2:]) dsum = numpy.zeros(v.shape[-2:]) for k in range(v.shape[0] - 1): # Dont include lowest layer logger.debug( "k=%3d, v=%10.3g, mbathy_v[jtest,itest]=%3d,gdepw[k]=%8.2f, depthv[jtest,itest]=%8.2f" % (k, v[k, jtest, itest], mbathy_v[jtest, itest], gdepw[k], depthv[jtest, itest])) J, I = numpy.where(mbathy_v > k) vsum[J, I] = vsum[J, I] + v[k, J, I] * dt[k] dsum[J, I] = dsum[J, I] + dt[k] J, I = numpy.where(mbathy_u >= 0) vsum[J, I] = vsum[J, I] + v[mbathy_u[J, I], J, I] * e3v_ps[J, I] dsum[J, I] = dsum[J, I] + e3v_ps[J, I] vbaro = numpy.where(dsum > .1, vsum / dsum, 0.) # Masks (land:True) #print mbathy.min(),mbathy.max() ip = mbathy == -1 iu = mbathy_u == -1 iv = mbathy_v == -1 #iu = nemo_mesh.periodic_i_shift_right(iu,1) # u: nemo in cell i is hycom in cell i+1 #iv = nemo_mesh.arctic_patch_shift_up(iu,1) # v: nemo in cell j is hycom in cell j+1 #ip = nemo_mesh.sliced(ip) #iu = nemo_mesh.sliced(iu) #iv = nemo_mesh.sliced(iv) #raise NameError,"test" # 2D data ncid2d = netCDF4.Dataset(file2d, "r") ssh = nemo_mesh.sliced(ncid2d.variables["sossheig"][0, :, :]) ssh = numpy.where(ssh == ncid2d.variables["sossheig"]._FillValue, 0., ssh) ssh = numpy.where(ssh > 1e30, 0., ssh) # Hmmmmm #bar_height = nemo_mesh.sliced(ncid2d.variables["sobarhei"][0,:,:] ) #dyn_height = nemo_mesh.sliced(ncid2d.variables["sodynhei"][0,:,:] montg1 = ssh * 9.81 #* 1e-3 # Approx logger.warning("TODO:montg pot calculation must be checked...") # Write to abfile outfile = abfile.ABFileArchv( mydt.strftime(fnametemplate), "w", iexpt=10, iversn=22, yrflag=3, ) logger.info("Writing 2D variables") outfile.write_field(montg1, ip, "montg1", 0, 0, 1, 0) outfile.write_field(ssh, ip, "srfhgt", 0, 0, 0, 0) outfile.write_field(numpy.zeros(ssh.shape), ip, "surflx", 0, 0, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "salflx", 0, 0, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "bl_dpth", 0, 0, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "mix_dpth", 0, 0, 0, 0) # Not used outfile.write_field(ubaro, iu, "u_btrop", 0, 0, 0, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vbaro, iv, "v_btrop", 0, 0, 0, 0) # v: nemo in cell j is hycom in cell j+1 #outfile.close() ; raise NameError,"test" for k in numpy.arange(u.shape[0]): if k % 10 == 0: logger.info("Writing 3D variables, level %d of %d" % (k + 1, u.shape[0])) ul = numpy.squeeze(u[k, :, :]) - ubaro # Baroclinic velocity vl = numpy.squeeze(v[k, :, :]) - vbaro # Baroclinic velocity sl = numpy.squeeze(s[k, :, :]) tl = numpy.squeeze(t[k, :, :]) # Layer thickness dtl = numpy.zeros(ul.shape) if k < u.shape[0] - 1: J, I = numpy.where(mbathy > k) dtl[J, I] = dt[k] J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] else: J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] onem = 9806. outfile.write_field(ul, iu, "u-vel.", 0, 0, k + 1, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vl, iv, "v-vel.", 0, 0, k + 1, 0) # v: nemo in cell j is hycom in cell j+1 outfile.write_field(dtl * onem, ip, "thknss", 0, 0, k + 1, 0) outfile.write_field(sl, ip, "salin", 0, 0, k + 1, 0) outfile.write_field(tl, ip, "temp", 0, 0, k + 1, 0) # TODO: Process ice data ncid2d.close() ncids.close() ncidt.close() ncidu.close() ncidv.close() outfile.close() logger.info("Finished writing %s.[ab] " % mydt.strftime(fnametemplate)) nemo_mesh = []
def main(lon1,lat1,lon2,lat2,variable,files,filetype="archive",clim=None,sectionid="", ijspace=False,xaxis="distance",section_map=False,dpi=180) : logger.info("Filetype is %s"% filetype) gfile = abfile.ABFileGrid("regional.grid","r") plon=gfile.read_field("plon") plat=gfile.read_field("plat") qlon=gfile.read_field("qlon") qlat=gfile.read_field("qlat") # Set up section info if ijspace : sec = gridxsec.SectionIJSpace([lon1,lon2],[lat1,lat2],plon,plat) else : sec = gridxsec.Section([lon1,lon2],[lat1,lat2],plon,plat) I,J=sec.grid_indexes dist=sec.distance slon=sec.longitude slat=sec.latitude # In testing #J,I,slon,slat,case,dist=sec.find_intersection(qlon,qlat) #print I,J #raise NameError,"test" logger.info("Min max I-index (starts from 0):%d %d"%(I.min(),I.max())) logger.info("Min max J-index (starts from 0):%d %d"%(J.min(),J.max())) if section_map : ll_lon=slon.min()-10. ur_lon=slon.max()+10. ll_lat=numpy.maximum(-90.,slat.min()-10.) ur_lat=numpy.minimum(90. ,slat.max()+10.) m = Basemap(projection='mill', llcrnrlon=ll_lon, llcrnrlat=ll_lat, urcrnrlon=ur_lon, urcrnrlat=ur_lat, resolution='l') (x,y) = m(slon,slat) figure = matplotlib.pyplot.figure() ax=figure.add_subplot(111) m.drawcoastlines() #m.fillcontinents(color='coral',lake_color='aqua') m.drawparallels(numpy.arange(-90.,120.,30.),labels=[1,0,0,0]) # draw parallels m.drawmeridians(numpy.arange(0.,420.,60.),labels=[0,0,0,1]) # draw meridians m.drawmapboundary() # draw a line around the map region m.plot(x,y,"r",lw=3) m.etopo() #m.scatter(x,y,s=20,c=dist) pos = ax.get_position() #print pos asp=pos.height/pos.width #print asp w=figure.get_figwidth() #print w h=asp*w figure.set_figheight(h) if sectionid : figure.canvas.print_figure("map_%s.png"%sectionid,dpi=dpi) else : figure.canvas.print_figure("map.png",dpi=dpi) # Get layer thickness variable used in hycom dpname = modeltools.hycom.layer_thickness_variable[filetype] logger.info("Filetype %s: layer thickness variable is %s"%(filetype,dpname)) if xaxis == "distance" : x=dist/1000. xlab="Distance along section[km]" elif xaxis == "i" : x=I xlab="i-index" elif xaxis == "j" : x=J xlab="j-index" elif xaxis == "lon" : x=slon xlab="longitude" elif xaxis == "lat" : x=slat xlab="latitude" else : logger.warning("xaxis must be i,j,lo,lat or distance") x=dist/1000. xlab="Distance along section[km]" # Loop over archive files figure = matplotlib.pyplot.figure() ax=figure.add_subplot(111) pos = ax.get_position() for fcnt,myfile0 in enumerate(files) : # Remove [ab] ending if present m=re.match("(.*)\.[ab]",myfile0) if m : myfile=m.group(1) else : myfile=myfile0 # Add more filetypes if needed. By def we assume archive if filetype == "archive" : i_abfile = abfile.ABFileArchv(myfile,"r") elif filetype == "restart" : i_abfile = abfile.ABFileRestart(myfile,"r",idm=gfile.idm,jdm=gfile.jdm) else : raise NotImplementedError,"Filetype %s not implemented"%filetype # kdm assumed to be max level in ab file kdm=max(i_abfile.fieldlevels) # Set up interface and daat arrays intfsec=numpy.zeros((kdm+1,I.size)) datasec=numpy.zeros((kdm+1,I.size)) # Loop over layers in file. logger.info("File %s"%(myfile)) for k in range(kdm) : logger.debug("File %s, layer %03d/%03d"%(myfile,k,kdm)) # Get 2D fields dp2d=i_abfile.read_field(dpname,k+1) data2d=i_abfile.read_field(variable,k+1) dp2d=numpy.ma.filled(dp2d,0.)/modeltools.hycom.onem data2d=numpy.ma.filled(data2d,1e30) # Place data into section arrays intfsec[k+1,:] = intfsec[k,:] + dp2d[J,I] if k==0 : datasec[k,:] = data2d[J,I] datasec[k+1,:] = data2d[J,I] i_maxd=numpy.argmax(numpy.abs(intfsec[kdm,:])) #print i_maxd # Set up section plot #datasec = numpy.ma.masked_where(datasec==1e30,datasec) datasec = numpy.ma.masked_where(datasec>0.5*1e30,datasec) #print datasec.min(),datasec.max() #figure = matplotlib.pyplot.figure() #ax=figure.add_subplot(111) #P=ax.pcolormesh(dist/1000.,-intfsec,datasec) P=ax.pcolormesh(x,-intfsec,datasec,cmap="jet") if clim is not None : P.set_clim(clim) # Plot layer interfaces for k in range(1,kdm+1) : if k%10 == 0 : PL=ax.plot(x,-intfsec[k,:],"--",color="k",lw=.5) elif k%5 == 0 : PL=ax.plot(x,-intfsec[k,:],"--",color="k",lw=.5) else : PL=ax.plot(x,-intfsec[k,:],"--",color=".5",lw=.5) textx = x[i_maxd] texty = -0.5*(intfsec[k-1,i_maxd] + intfsec[k,i_maxd]) ax.text(textx,texty,str(k),verticalalignment="center",horizontalalignment="center",fontsize=6) cb=ax.figure.colorbar(P) ax.set_title(myfile) ax.set_ylabel(variable) ax.set_xlabel(xlab) #ax.set_position(pos) #matplotlib.pyplot.tight_layout() # Print in different y-lims suff=os.path.basename(myfile) if sectionid : suff=suff+"_"+sectionid figure.canvas.print_figure("sec_%s_full_%s.png"%(variable,suff),dpi=dpi) ax.set_ylim(-1000,0) figure.canvas.print_figure("sec_%s_1000m_%s.png"%(variable,suff),dpi=dpi) ax.set_ylim(-300,0) figure.canvas.print_figure("sec_%s_300m_%s.png"%(variable,suff),dpi=dpi) # Close input file i_abfile.close() # ax.clear() cb.remove()
def main(archv_files, regress_file, opath, header_line1=cline1, header_line2=cline2, header_line3=cline3): regr = open(regress_file, 'rb') slope, intercept, nemomeandt = pickle.load(regr) bp = modeltools.hycom.BlkdatParser("blkdat.input") idm = bp["idm"] jdm = bp["jdm"] kdm = bp["kdm"] iversn = bp["iversn"] yrflag = bp["yrflag"] iexpt = bp["iexpt"] for archv_file in archv_files: logger.debug("Processing %s" % (archv_file)) arcfile = abfile.ABFileArchv(archv_file, "r") srfhgt = arcfile.read_field("srfhgt", 0) montg1 = (srfhgt - nemomeandt) * slope + intercept # logger.info("Estimated montg1 ") fnameout = opath + str(archv_file[-19:]) arcfile_out = abfile.ABFileArchv(fnameout, "w", iversn=iversn, yrflag=yrflag, iexpt=iexpt, mask=False, cline1=header_line1, cline2=header_line2, cline3=header_line3) for keys in sorted(arcfile.fields.keys()): fieldname = arcfile.fields[keys]["field"] time_step = arcfile.fields[keys]["step"] model_day = arcfile.fields[keys]["day"] k = arcfile.fields[keys]["k"] dens = arcfile.fields[keys]["dens"] fld = arcfile.read_field(fieldname, k) if fieldname == "montg1": logger.info( "Writing field %10s at level %3d to %s (modified)" % (fieldname, k, fnameout)) arcfile_out.write_field(montg1, None, fieldname, time_step, model_day, k, dens) else: arcfile_out.write_field(fld, None, fieldname, time_step, model_day, k, dens) logger.info("Finished writing to %s" % fnameout) arcfile_out.close() arcfile.close() archv_file_b = archv_file[0:-1] + 'b' fnameout_b = fnameout[0:-1] + 'b' os.rename( fnameout, archv_file ) # replaces the new archive files with the original ones in nest folder os.rename(fnameout_b, archv_file_b)
def main(psikk_file, archv_files, psikk_file_type="restart", month=1): logger.info("psikk file type is %s" % psikk_file_type) from_relax_archv = psikk_file_type == "relax_archv" from_relax = psikk_file_type == "relax" from_restart = psikk_file_type == "restart" if not from_relax_archv and not from_relax and not from_restart: msg = "psikk_file_type must be either restart relax or relax_archv" logger.error(msg) raise ValueError, msg # Open blkdat files. Get some properties bp = modeltools.hycom.BlkdatParser("blkdat.input") idm = bp["idm"] jdm = bp["jdm"] kdm = bp["kdm"] thflag = bp["thflag"] thbase = bp["thbase"] kapref = bp["kapref"] iversn = bp["iversn"] iexpt = bp["iexpt"] yrflag = bp["yrflag"] thref = modeltools.hycom.thref if kapref == -1: kapnum = 2 msg = "Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError, msg else: kapnum = 1 if kapnum > 1: msg = "Only kapnum=1 is implemented for now" logger.error(msg) raise ValueError, msg path0 = os.path.join(".", "montg1") if os.path.exists(path0) and os.path.isdir(path0): pass else: os.mkdir(path0) # hycom sigma and kappa, written in python. NB: sigver is not used here. # Modify to use other equations of state. For now we assume sigver is: # 1 (7-term eqs referenced to 0 bar) # 2 (7-term eqs referenced to 2000 bar) if thflag == 0: sigver = 1 else: sigver = 2 sig = modeltools.hycom.Sigma(thflag) if kapref > 0: kappa = modeltools.hycom.Kappa(kapref, thflag * 1000.0e4) # # Option 1: Get psikk and thkk directly from a restart file if from_restart: # Read input variables from lowest layer of a restart file m = re.match("^(.*)(\.[ab])", psikk_file) if m: psikk_file = m.group(1) rfile = abfile.ABFileRestart(psikk_file, "r", idm=idm, jdm=jdm) psikk = rfile.read_field("psikk", 0) thkk = rfile.read_field("thkk", 0) rfile.close() # Option 2: Get temp, salinity and dp from relaxaiton fields. Estimate thkk and psikk elif from_relax: pattern = "^(.*)_(tem|int|sal)" psikk_file = abfile.ABFile.strip_ab_ending(psikk_file) m = re.match(pattern, psikk_file) if m: relaxtem = abfile.ABFileRelax(m.group(1) + "_tem", "r") relaxsal = abfile.ABFileRelax(m.group(1) + "_sal", "r") relaxint = abfile.ABFileRelax(m.group(1) + "_int", "r") else: msg = """Input hycom relaxation file %s does not match pattern %s""" % (psikk_file, pattern) logger.error(msg) raise ValueError, msg # Option 3: Get temp, salinity and dp from relaxation fields (archive files generated during relaxation setup). Estimate thkk and psikk elif from_relax_archv: arcfile0 = abfile.ABFileArchv(psikk_file, "r") else: msg = "No way of estimating psikk and thkk. Aborting ..." logger(msg) raise ValueError, msg # Estimate psikk, thkk from climatology. (Option 1 or option 2) if from_relax or from_relax_archv: logger.info("Estimating psikk and thkk from climatology") p = numpy.ma.zeros((jdm, idm)) pup = numpy.ma.zeros((jdm, idm)) montg = numpy.ma.zeros((jdm, idm)) for k in range(kdm): logger.debug("Reading layer %d from climatology" % k) if k > 0: thstarup = numpy.ma.copy(thstar) if from_relax: saln = relaxsal.read_field("sal", k + 1, month) temp = relaxtem.read_field("tem", k + 1, month) plo = relaxint.read_field("int", k + 1, month) # lowest interface of layer dp = plo - pup pup = numpy.copy(plo) # Next loop, pup = plo of this loop elif from_relax_archv: saln = arcfile0.read_field("salin", k + 1) temp = arcfile0.read_field("temp", k + 1) dp = arcfile0.read_field("thknss", k + 1) else: msg = "No way of estimating sal, tem and dp. Aborting ..." logger(msg) raise ValueError, msg th3d = sig.sig(temp, saln) - thbase thstar = numpy.ma.copy(th3d) if kapref > 0: thstar = thstar + kappa.kappaf(temp[:, :], saln[:, :], th3d[:, :] + thbase, p[:, :]) elif kapref < 0: msg = "Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError, msg # From hycom inicon.f # montg(i,j,1,kkap)=0.0 # do k=1,kk-1 # montg(i,j,k+1,kkap)=montg(i,j,k,kkap)- # & p(i,j,k+1)*(thstar(i,j,k+1,kkap)-thstar(i,j,k,kkap))*thref**2 # enddo #c # thkk( i,j,kkap)=thstar(i,j,kk,kkap) # psikk(i,j,kkap)=montg( i,j,kk,kkap) if k > 0: #print (thstar - thstarup).min(), (thstar - thstarup).min() montg = montg - p * (thstar - thstarup) * thref**2 p = p + dp thkk = thstar psikk = montg if from_relax: relaxtem.close() relaxsal.close() relaxint.close() elif from_relax_archv: arcfile0.close() else: pass logger.info("Min max of thkk: %12.6g %12.6g" % (thkk.min(), thkk.max())) logger.info("Min max of psikk: %12.6g %12.6g" % (psikk.min(), psikk.max())) # Loop through archive files for archv_file in archv_files: logger.debug("Processing %s" % (archv_file)) arcfile = abfile.ABFileArchv(archv_file, "r") # Read all layers .. (TODO: If there is memory problems, read and estimate sequentially) temp = numpy.ma.zeros( (jdm, idm)) # Only needed when calculating density saln = numpy.ma.zeros( (jdm, idm)) # Only needed when calculating density th3d = numpy.ma.zeros((kdm, jdm, idm)) thstar = numpy.ma.zeros((kdm, jdm, idm)) dp = numpy.ma.zeros((jdm, idm)) p = numpy.ma.zeros((kdm + 1, jdm, idm)) for k in range(kdm): logger.info("Reading layer %d from %s" % (k, archv_file)) temp = arcfile.read_field("temp", k + 1) saln = arcfile.read_field("salin", k + 1) #dp [k ,:,:]=arcfile.read_field("thknss",k+1) dp[:, :] = arcfile.read_field("thknss", k + 1) th3d[k, :, :] = sig.sig(temp, saln) - thbase p[k + 1, :, :] = p[k, :, :] + dp[:, :] thstar[k, :, :] = numpy.ma.copy(th3d[k, :, :]) if kapref > 0: thstar[k, :, :] = thstar[k, :, :] + kappa.kappaf( temp[:, :], saln[:, :], th3d[k, :, :] + thbase, p[k, :, :]) elif kapref < 0: msg = "Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError, msg # This part of montg1 does nto depend on pbavg montg1c = modeltools.hycom.montg1_pb(thstar, p) # This part depends linearly on pbavg montg1pb = modeltools.hycom.montg1_no_pb(psikk, thkk, thstar, p) print montg1c.min(), montg1c.max() print montg1pb.min(), montg1pb.max() # ... we have ... # montg1 = montgc + montgpb * pbavg # srfhgt = montg1 + thref*pbavg = montgc + montgpb * pbavg + thref*pbavg # ... which gives new montg1n for srfhgtn # pbavgn = (srfhgtn-montgc) / (montgpb+thref) # montg1n = montgc + montgpb*pbavgn # Systematic differences due to choice of sigma and or eq of state is not taken into account ... # Barotropic pressure. NB: srfhgt is in geopotential height : srfhgt = arcfile.read_field("srfhgt", 0) pbavg = (srfhgt - montg1c) / (montg1pb + thref) print pbavg.min(), pbavg.max() montg1 = montg1pb * pbavg + montg1c logger.info("Estimated montg1 ") print montg1.min(), montg1.max() # Open new archive file, and write montg1 to it. fnameout = os.path.join(path0, os.path.basename(arcfile.basename)) arcfile_out = abfile.ABFileArchv(fnameout, "w", iversn=iversn, yrflag=yrflag, iexpt=iexpt, mask=False) for key in sorted(arcfile.fields.keys()): fieldname = arcfile.fields[key]["field"] time_step = arcfile.fields[key]["step"] model_day = arcfile.fields[key]["day"] k = arcfile.fields[key]["k"] dens = arcfile.fields[key]["dens"] fld = arcfile.read_field(fieldname, k) if fieldname == "montg1": logger.info( "Writing field %10s at level %3d to %s (modified)" % (fieldname, k, fnameout)) arcfile_out.write_field(montg1, None, fieldname, time_step, model_day, sigver, thbase) else: arcfile_out.write_field(fld, None, fieldname, time_step, model_day, k, dens) #logger.info("Writing field %10s at level %3d to %s (copy from original)"%(fieldname,k,fnameout)) logger.info("Finished writing to %s" % fnameout) arcfile_out.close() arcfile.close() logger.warning("Sigver assumed to be those of 7 term eqs") logger.warning(" 1 for sigma-0/thflag=0, 2 for sigma-2/thflag=2") logger.warning( "For other eqs, you need to modify the code so that sigver is set correctly in the archv file" "") logger.warning( "psikk and thkk from relaxation fields is beta. Preferred method is restart" ) logger.info("Finito")
def main(meshfile, file, iexpt=10, iversn=22, yrflag=3, bio_path=None): # # Trim input netcdf file name being appropriate for reading # meshfile = str(meshfile)[2:-2] logger.info("Reading mesh information from %s." % (meshfile)) # # Read mesh file containing grid and coordinate information. # Note that for now, we are using T-grid in vertical which may need # to be improved by utilizing W-point along the vertical axis. # hdept, gdept, mbathy, mbathy_u, mbathy_v, mask, e3t, plon, plat = read_grid( meshfile) logger.warning( "Reading grid information from regional.grid.[ab] (not completed)") # # Convert from P-point (i.e. NEMO grid) to U and V HYCOM grids # mask_u = p2u_2d(mask) mask_v = p2v_2d(mask) # # Read regional.grid.[ab] # Grid angle is not used for this product because all quantities are # on regular rectangular grid points. # angle = numpy.zeros(plon.shape) # # Number vertical layers in T-point. # nlev = gdept.size # # layer thickness in the absence of layer partial steps. # dt = gdept[1:] - gdept[:-1] # # Prepare/read input data file (in netcdf format). Reference time is 1950-01-01 # logger.info("Reading data files.") file = str(file).strip()[2:-2] dirname = os.path.dirname(file) logger.debug("file name is {}".format(file)) logger.debug("dirname is {}".format(dirname)) logger.debug("basename is {}".format(os.path.basename(file))) m = re.match("(MERCATOR-PHY-24-)(.*\.nc)", os.path.basename(file)) logger.debug("file prefix is {}".format(file_pre)) ### m=re.match(file_pre,os.path.basename(file)) if not m: msg = "File %s is not a grid2D file, aborting" % file logger.error(msg) raise ValueError, msg #fileinput0=os.path.join(dirname+"/"+"MERCATOR-PHY-24-"+m.group(2)) file_date = file[-16:-6] fileinput0 = file print file_date, file next_day = datetime.datetime.strptime( file_date, '%Y-%m-%d') + datetime.timedelta(days=1) fileinput1 = datetime.datetime.strftime(next_day, '%Y%m%d') fileinput1 = os.path.join(dirname + "/" + file_pre + fileinput1 + '.nc') logger.info("Reading from %s" % (fileinput0)) ncid0 = netCDF4.Dataset(fileinput0, "r") if timeavg_method == 1 and os.path.isfile(fileinput1): logger.info("timeavg_method=1, Reading from %s" % (fileinput1)) ncid1 = netCDF4.Dataset(fileinput1, "r") # # Calculate temporal averaged temperature, salinity, and velocity # uo = 0.5 * (ncid0.variables["uo"][0, :, :, :] + ncid1.variables["uo"][0, :, :, :]) vo = 0.5 * (ncid0.variables["vo"][0, :, :, :] + ncid1.variables["vo"][0, :, :, :]) salt = 0.5 * (ncid0.variables["so"][0, :, :, :] + ncid1.variables["so"][0, :, :, :]) temp = 0.5 * (ncid0.variables["thetao"][0, :, :, :] + ncid1.variables["thetao"][0, :, :, :]) ssh = numpy.squeeze(0.5 * (ncid0.variables["zos"][0, :, :] + ncid1.variables["zos"][0, :, :])) else: # # Set variables based on current file when timeavg_method ~=1 or the next netcdf file is not available logger.debug("time average method set to {}".format(timeavg_method)) uo = ncid0.variables["uo"][0, :, :, :] vo = ncid0.variables["vo"][0, :, :, :] salt = ncid0.variables["so"][0, :, :, :] temp = ncid0.variables["thetao"][0, :, :, :] ssh = numpy.squeeze(ncid0.variables["zos"][0, :, :]) # # I will account these values afterward. Because in the current version, I am accounting for missing values using a gap-filling methodology. # logger.debug("getting _FillValue") uofill = ncid0.variables["uo"]._FillValue vofill = ncid0.variables["vo"]._FillValue slfill = ncid0.variables["so"]._FillValue tlfill = ncid0.variables["thetao"]._FillValue shfill = ncid0.variables["zos"]._FillValue # Set time logger.info("Set time.") time = ncid0.variables["time"][0] unit = ncid0.variables["time"].units tmp = cfunits.Units(unit) refy, refm, refd = (1950, 1, 1) tmp2 = cfunits.Units("hours since %d-%d-%d 00:00:00" % (refy, refm, refd)) tmp3 = int(numpy.round(cfunits.Units.conform(time, tmp, tmp2))) mydt = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta( hours=tmp3) # Then calculate dt. Phew! if timeavg_method == 1 and os.path.isfile(fileinput1): fnametemplate = "archv.%Y_%j_%H" deltat=datetime.datetime(refy,refm,refd,0,0,0) + \ datetime.timedelta(hours=tmp3) + \ datetime.timedelta(hours=12) oname = deltat.strftime(fnametemplate) else: # # I am assuming that daily mean can be set at 00 instead of 12 # for cases that there is no information of next day. # fnametemplate = "archv.%Y_%j" deltat=datetime.datetime(refy,refm,refd,0,0,0) + \ datetime.timedelta(hours=tmp3) oname = deltat.strftime(fnametemplate) + '_00' # model day refy, refm, refd = (1900, 12, 31) model_day = deltat - datetime.datetime(refy, refm, refd, 0, 0, 0) model_day = model_day.days logger.info("Model day in HYCOM is %s" % str(model_day)) if bio_path: jdm, idm = numpy.shape(plon) points = numpy.transpose(((plat.flatten(), plon.flatten()))) delta = mydt.strftime('%Y-%m-%d') # filename format MERCATOR-BIO-14-2013-01-05-00 print bio_path, delta idx, biofname = search_biofile(bio_path, delta) if idx > 7: msg = "No available BIO file within a week difference with PHY" logger.error(msg) raise ValueError, msg logger.info( "BIO file %s reading & interpolating to 1/12 deg grid cells ..." % biofname) ncidb = netCDF4.Dataset(biofname, "r") blon = ncidb.variables["longitude"][:] blat = ncidb.variables["latitude"][:] minblat = blat.min() no3 = ncidb.variables["NO3"][0, :, :, :] no3[numpy.abs(no3) > 1e+10] = numpy.nan po4 = ncidb.variables["PO4"][0, :, :, :] si = ncidb.variables["Si"][0, :, :, :] po4[numpy.abs(po4) > 1e+10] = numpy.nan si[numpy.abs(si) > 1e+10] = numpy.nan # TODO: Ineed to improve this part nz, ny, nx = no3.shape dummy = numpy.zeros((nz, ny, nx + 1)) dummy[:, :, :nx] = no3 dummy[:, :, -1] = no3[:, :, -1] no3 = dummy dummy = numpy.zeros((nz, ny, nx + 1)) dummy[:, :, :nx] = po4 dummy[:, :, -1] = po4[:, :, -1] po4 = dummy dummy = numpy.zeros((nz, ny, nx + 1)) dummy[:, :, :nx] = si dummy[:, :, -1] = si[:, :, -1] si = dummy dummy = numpy.zeros((nx + 1)) dummy[:nx] = blon blon = dummy blon[-1] = -blon[0] # TODO: Note that the coordinate files are for global configuration while # the data file saved for latitude larger than 30. In the case you change your data file coordinate # configuration you need to modify the following lines bio_coordfile = bio_path[:-4] + "/GLOBAL_ANALYSIS_FORECAST_BIO_001_014_COORD/GLO-MFC_001_014_mask.nc" biocrd = netCDF4.Dataset(bio_coordfile, "r") blat2 = biocrd.variables['latitude'][:] index = numpy.where(blat2 >= minblat)[0] depth_lev = biocrd.variables['deptho_lev'][index[0]:, :] # # # dummy = numpy.zeros((ny, nx + 1)) dummy[:, :nx] = depth_lev dummy[:, -1] = depth_lev[:, -1] depth_lev = dummy depth_lev[depth_lev > 50] = 0 depth_lev = depth_lev.astype('i') dummy_no3 = no3 dummy_po4 = po4 dummy_si = si for j in range(ny): for i in range(nx): dummy_no3[depth_lev[j, i]:nz - 2, j, i] = no3[depth_lev[j, i] - 1, j, i] dummy_po4[depth_lev[j, i]:nz - 2, j, i] = po4[depth_lev[j, i] - 1, j, i] dummy_si[depth_lev[j, i]:nz - 2, j, i] = si[depth_lev[j, i] - 1, j, i] no3 = dummy_no3 po4 = dummy_po4 si = dummy_si # po4 = po4 * 106.0 * 12.01 si = si * 6.625 * 12.01 no3 = no3 * 6.625 * 12.01 logger.info("Read, trim, rotate NEMO velocities.") u = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) v = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) utmp = numpy.zeros((mbathy.shape)) vtmp = numpy.zeros((mbathy.shape)) # # Metrices to detect carrefully bottom at p-, u-, and v-grid points.While I have used 3D, mask data,following methods are good enough for now. # if mbathy_method == 1: ip = mbathy == -1 iu = mbathy_u == -1 iv = mbathy_v == -1 else: ip = mask == 0 iu = mask_u == 0 iv = mask_v == 0 # # Read 3D velocity field to calculate barotropic velocity # # Estimate barotropic velocities using partial steps along the vertical axis. Note that for the early version of this code, # I used dt = gdept[1:] - gdept[:-1] on NEMO t-grid. Furthermore, you may re-calculate this part on vertical grid cells for future. # logger.info("Calculate barotropic velocities.") ubaro, vbaro = calc_uvbaro(uo, vo, e3t, iu, iv) # # Save 2D fields (here only ubaro & vbaro) # zeros = numpy.zeros(mbathy.shape) #flnm = open(oname+'.txt', 'w') #flnm.write(oname) #flnm.close() ssh = numpy.where(numpy.abs(ssh) > 1000, 0., ssh * 9.81) # NB: HYCOM srfhgt is in geopotential ... # outfile = abfile.ABFileArchv( "./data/" + oname, "w", iexpt=iexpt, iversn=iversn, yrflag=yrflag, ) outfile.write_field(zeros, ip, "montg1", 0, model_day, 1, 0) outfile.write_field(ssh, ip, "srfhgt", 0, model_day, 0, 0) outfile.write_field(zeros, ip, "surflx", 0, model_day, 0, 0) # Not used outfile.write_field(zeros, ip, "salflx", 0, model_day, 0, 0) # Not used outfile.write_field(zeros, ip, "bl_dpth", 0, model_day, 0, 0) # Not used outfile.write_field(zeros, ip, "mix_dpth", 0, model_day, 0, 0) # Not used outfile.write_field(ubaro, iu, "u_btrop", 0, model_day, 0, 0) outfile.write_field(vbaro, iv, "v_btrop", 0, model_day, 0, 0) # if bio_path: logger.info( "Calculate baroclinic velocities, temperature, and salinity data as well as BIO field." ) else: logger.info( "Calculate baroclinic velocities, temperature, and salinity data.") for k in numpy.arange(u.shape[0]): if bio_path: no3k = interpolate2d(blat, blon, no3[k, :, :], points).reshape( (jdm, idm)) no3k = maplev(no3k) po4k = interpolate2d(blat, blon, po4[k, :, :], points).reshape( (jdm, idm)) po4k = maplev(po4k) si_k = interpolate2d(blat, blon, si[k, :, :], points).reshape( (jdm, idm)) si_k = maplev(si_k) if k % 10 == 0: logger.info( "Writing 3D variables including BIO, level %d of %d" % (k + 1, u.shape[0])) else: if k % 10 == 0: logger.info("Writing 3D variables, level %d of %d" % (k + 1, u.shape[0])) # # uo[k, :, :] = numpy.where(numpy.abs(uo[k, :, :]) < 10, uo[k, :, :], 0) vo[k, :, :] = numpy.where(numpy.abs(vo[k, :, :]) < 10, vo[k, :, :], 0) # Baroclinic velocity (in HYCOM U- and V-grid) ul = p2u_2d(numpy.squeeze(uo[k, :, :])) - ubaro vl = p2v_2d(numpy.squeeze(vo[k, :, :])) - vbaro ul[iu] = spval vl[iv] = spval # Layer thickness dtl = numpy.zeros(mbathy.shape) # Use dt for the water column except the nearest cell to bottom if thickness_method == 1: if k < u.shape[0] - 1: J, I = numpy.where(mbathy > k) e3 = (e3t[k, :, :]) dtl[J, I] = dt[k] J, I = numpy.where(mbathy == k) dtl[J, I] = e3[J, I] else: e3 = (e3t[k, :, :]) J, I = numpy.where(mbathy == k) dtl[J, I] = e3[J, I] # Use partial cells for the whole water column. else: J, I = numpy.where(mbathy >= k) dtl[J, I] = e3t[k, J, I] # Salinity sl = salt[k, :, :] # Temperature tl = temp[k, :, :] # Need to be carefully treated in order to minimize artifacts to the resulting [ab] files. if fillgap_method == 1: J, I = numpy.where(mbathy < k) sl = maplev(numpy.where(numpy.abs(sl) < 1e2, sl, numpy.nan)) sl[J, I] = spval J, I = numpy.where(mbathy < k) tl = maplev(numpy.where(numpy.abs(tl) < 1e2, tl, numpy.nan)) tl[J, I] = spval else: sl = numpy.where(numpy.abs(sl) < 1e2, sl, numpy.nan) sl = numpy.minimum(numpy.maximum(maplev(sl), 25), 80.) tl = numpy.where(numpy.abs(tl) <= 5e2, tl, numpy.nan) tl = numpy.minimum(numpy.maximum(maplev(tl), -5.), 50.) # Thickness dtl = maplev(dtl) if k > 0: with numpy.errstate(invalid='ignore'): K = numpy.where(dtl < 1e-4) sl[K] = sl_above[K] tl[K] = tl_above[K] # sl[ip] = spval tl[ip] = spval # Save 3D fields outfile.write_field(ul, iu, "u-vel.", 0, model_day, k + 1, 0) outfile.write_field(vl, iv, "v-vel.", 0, model_day, k + 1, 0) outfile.write_field(dtl * onem, ip, "thknss", 0, model_day, k + 1, 0) outfile.write_field(tl, ip, "temp", 0, model_day, k + 1, 0) outfile.write_field(sl, ip, "salin", 0, model_day, k + 1, 0) if bio_path: outfile.write_field(no3k, ip, "ECO_no3", 0, model_day, k + 1, 0) outfile.write_field(po4k, ip, "ECO_pho", 0, model_day, k + 1, 0) outfile.write_field(si_k, ip, "ECO_sil", 0, model_day, k + 1, 0) tl_above = numpy.copy(tl) sl_above = numpy.copy(sl) outfile.close() ncid0.close() if timeavg_method == 1 and os.path.isfile(fileinput1): ncid1.close() if bio_path: ncidb.close()
def main(filemesh, grid2dfiles, first_j=0, mean_file=False, iexpt=10, iversn=22, yrflag=3, makegrid=None): if mean_file: fnametemplate = "archm.%Y_%j_%H" else: fnametemplate = "archv.%Y_%j_%H" itest = 1 jtest = 200 gdept, gdepw, e3t_ps, e3w_ps, mbathy, hdepw, depth = read_mesh(filemesh) if makegrid is not None: logger.info("Making NEMO grid & bathy [ab] files ...") make_grid(filemesh) mbathy = mbathy - 1 # python indexing starts from 0 nlev = gdept.size mbathy_u, e3u_ps, depthu = depth_u_points(depth, mbathy, gdepw) mbathy_v, e3v_ps, depthv = depth_v_points(depth, mbathy, gdepw) # mbathy_u = sliced(u_to_hycom_u(mbathy_u)) e3u_ps = sliced(u_to_hycom_u(e3u_ps)) depthu = sliced(u_to_hycom_u(depthu)) # mbathy_v = sliced(v_to_hycom_v(mbathy_v)) e3v_ps = sliced(v_to_hycom_v(e3v_ps)) depthv = sliced(v_to_hycom_v(depthv)) # Thickness of t layers (NB: 1 less than gdepw dimension) dt = gdepw[1:] - gdepw[:-1] # Loop over input files. All must be in same directory for file2d in grid2dfiles: # See if actually a grid2D file dirname = os.path.dirname(file2d) m = re.match("(.*_)(grid2D)(_.*\.nc)", os.path.basename(file2d)) if not m: msg = "File %s is not a grid2D file, aborting" % file2d logger.error(msg) raise ValueError, msg # Construct remaining files filet = os.path.join(dirname, m.group(1) + "gridT" + m.group(3)) files = os.path.join(dirname, m.group(1) + "gridS" + m.group(3)) fileu = os.path.join(dirname, m.group(1) + "gridU" + m.group(3)) filev = os.path.join(dirname, m.group(1) + "gridV" + m.group(3)) filew = os.path.join(dirname, m.group(1) + "gridW" + m.group(3)) fileice = os.path.join(dirname, m.group(1) + "icemod" + m.group(3)) logger.info("grid2D file: %s" % file2d) # P-points logger.info("gridS file: %s" % files) logger.info("gridT file: %s" % filet) ncids = netCDF4.Dataset(files, "r") ncidt = netCDF4.Dataset(filet, "r") # time from gridT file. time = ncidt.variables["time_counter"][0] tunit = ncidt.variables["time_counter"].units tmp = cfunits.Units(tunit) refy, refm, refd = (1958, 1, 1) tmp2 = cfunits.Units("hours since %d-%d-%d 00:00:00" % (refy, refm, refd)) # Units from CF convention tmp3 = cfunits.Units.conform(time, tmp, tmp2) # Transform to new new unit tmp3 = int(numpy.round(tmp3)) mydt = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta( hours=tmp3) # Then calculate dt. Phew! # Read and calculculate U in hycom U-points. logger.info("gridU, gridV, gridT & gridS file") ncidu = netCDF4.Dataset(fileu, "r") u = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) ncidv = netCDF4.Dataset(filev, "r") v = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) udummy = ncidu.variables["vozocrtx"][:, :, :, :] vdummy = ncidv.variables["vomecrty"][:, :, :, :] tdummy = ncidt.variables["votemper"][:, :, :, :] tdummy_fill = ncidt.variables["votemper"]._FillValue sdummy = ncids.variables["vosaline"][:, :, :, :] sdummy_fill = ncids.variables["vosaline"]._FillValue for k in range(nlev): u[k, :, :] = sliced(u_to_hycom_u( udummy[0, k, :, :])) # Costly, make more efficient if needed v[k, :, :] = sliced(v_to_hycom_v( vdummy[0, k, :, :])) # Costly, make more efficient if needed u = numpy.where(numpy.abs(u) < 1e10, u, 0.) v = numpy.where(numpy.abs(v) < 1e10, v, 0.) logger.info("Calculate barotropic velocities ...") #Calculate barotropic and baroclinic u usum = numpy.zeros(u.shape[-2:]) dsumu = numpy.zeros(u.shape[-2:]) vsum = numpy.zeros(v.shape[-2:]) dsumv = numpy.zeros(v.shape[-2:]) for k in range(u.shape[0] - 1): # Dont include lowest layer J, I = numpy.where(mbathy_u > k) usum[J, I] = usum[J, I] + u[k, J, I] * dt[k] dsumu[J, I] = dsumu[J, I] + dt[k] J, I = numpy.where(mbathy_v > k) vsum[J, I] = vsum[J, I] + v[k, J, I] * dt[k] dsumv[J, I] = dsumv[J, I] + dt[k] J, I = numpy.where(mbathy >= 0) usum[J, I] = usum[J, I] + u[mbathy_u[J, I], J, I] * e3u_ps[J, I] dsumu[J, I] = dsumu[J, I] + e3u_ps[J, I] dsumu = numpy.where(abs(dsumu) < 1e-2, 0.05, dsumu) ubaro = numpy.where(dsumu > 0.1, usum / dsumu, 0.) J, I = numpy.where(mbathy_v >= 0) vsum[J, I] = vsum[J, I] + v[mbathy_v[J, I], J, I] * e3v_ps[J, I] dsumv[J, I] = dsumv[J, I] + e3v_ps[J, I] dsumv = numpy.where(abs(dsumv) < 1e-2, 0.05, dsumv) vbaro = numpy.where(dsumv > .1, vsum / dsumv, 0.) fnametemplate = "archv.%Y_%j" deltat = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta(hours=tmp3) oname = deltat.strftime(fnametemplate) + "_00" # model day refy, refm, refd = (1900, 12, 31) model_day = deltat - datetime.datetime(refy, refm, refd, 0, 0, 0) model_day = model_day.days logger.info("Model day in HYCOM is %s" % str(model_day)) # Masks (land:True) if mask_method == 1: ip = mbathy == -1 iu = mbathy_u == -1 iv = mbathy_v == -1 else: ip = depth == 0 iu = depthu == 0 iv = depthv == 0 flnm = open('archvname.txt', 'w') flnm.write(oname) flnm.close() # 2D data ncid2d = netCDF4.Dataset(file2d, "r") ssh = sliced(ncid2d.variables["sossheig"][0, :, :]) ssh = numpy.where(ssh == ncid2d.variables["sossheig"]._FillValue, 0., ssh) ssh = numpy.where(ssh > 1e10, 0., ssh * 9.81) # NB: HYCOM srfhgt is in geopotential ... montg1 = numpy.zeros(ssh.shape) # Write to abfile outfile = abfile.ABFileArchv( "./data/" + oname, "w", iexpt=iexpt, iversn=iversn, yrflag=yrflag, ) logger.info("Writing 2D variables") outfile.write_field(montg1, ip, "montg1", 0, model_day, 1, 0) outfile.write_field(ssh, ip, "srfhgt", 0, model_day, 0, 0) outfile.write_field(numpy.zeros(ssh.shape), ip, "surflx", 0, model_day, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "salflx", 0, model_day, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "bl_dpth", 0, model_day, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "mix_dpth", 0, model_day, 0, 0) # Not used outfile.write_field(ubaro, iu, "u_btrop", 0, model_day, 0, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vbaro, iv, "v_btrop", 0, model_day, 0, 0) # v: nemo in cell j is hycom in cell j+1 for k in numpy.arange(u.shape[0]): if k % 10 == 0: logger.info("Writing 3D variables, level %d of %d" % (k + 1, u.shape[0])) ul = numpy.squeeze(u[k, :, :]) - ubaro # Baroclinic velocity vl = numpy.squeeze(v[k, :, :]) - vbaro # Baroclinic velocity # Layer thickness dtl = numpy.zeros(ul.shape) if k < u.shape[0] - 1: J, I = numpy.where(mbathy > k) dtl[J, I] = dt[k] J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] else: J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] tmpfill = sdummy_fill #ncids.variables["vosaline"]._FillValue sl = sliced(sdummy[0, k, :, :]) tmpfill = tdummy_fill #ncidt.variables["votemper"]._FillValue tl = sliced(tdummy[0, k, :, :]) sl = numpy.where(numpy.abs(sl) < 1e2, sl, numpy.nan) sl = numpy.minimum(numpy.maximum(maplev(sl), 25), 80.) tl = numpy.where(numpy.abs(tl) <= 5e2, tl, numpy.nan) tl = numpy.minimum(numpy.maximum(maplev(tl), -5.), 50.) # Fill empty layers with values from above if k > 0: K = numpy.where(dtl < 1e-4) tl[K] = tl_above[K] onem = 9806. outfile.write_field(ul, iu, "u-vel.", 0, model_day, k + 1, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vl, iv, "v-vel.", 0, model_day, k + 1, 0) # v: nemo in cell j is hycom in cell j+1 outfile.write_field(dtl * onem, ip, "thknss", 0, model_day, k + 1, 0) outfile.write_field(tl, ip, "temp", 0, model_day, k + 1, 0) outfile.write_field(sl, ip, "salin", 0, model_day, k + 1, 0) tl_above = numpy.copy(tl) sl_above = numpy.copy(sl) # TODO: Process ice data ncid2d.close() outfile.close() ncidt.close() ncids.close() ncidu.close() ncidv.close() logger.info("Finished writing %s.[ab] " % mydt.strftime(fnametemplate)) nemo_mesh = []
def main(filemesh, grid2dfiles, first_j=0, mean_file=False): if mean_file: fnametemplate = "archm.%Y_%j_%H" else: fnametemplate = "archv.%Y_%j_%H" itest = 1 jtest = 200 logger.info("Mean file:%s" % str(mean_file)) logger.info("Output file template:%s" % str(fnametemplate)) # Write regional files nemo_mesh_to_hycom.main(filemesh, first_j=first_j) nemo_mesh = modeltools.nemo.NemoMesh(filemesh, first_j=first_j) #ncidmesh=netCDF4.Dataset(filemesh,"r") gdept = nemo_mesh["gdept_0"][0, :] # Depth of t points gdepw = nemo_mesh["gdepw_0"][0, :] # Depth of w points e3t_ps = nemo_mesh.sliced( nemo_mesh["e3t_ps"][0, :, :]) # Partial steps of t cell e3w_ps = nemo_mesh.sliced( nemo_mesh["e3w_ps"][0, :, :]) # Partial steps of w cell mbathy = nemo_mesh.sliced(nemo_mesh["mbathy"][0, :, :]) # bathy index hdepw = nemo_mesh.sliced( nemo_mesh["hdepw"][0, :, :]) # Total depth of w points mbathy = mbathy - 1 # python indexing starts from 0 nlev = gdept.size mbathy_u, e3u_ps, depthu = nemo_mesh.depth_u_points() mbathy_v, e3v_ps, depthv = nemo_mesh.depth_v_points() # mbathy_u = nemo_mesh.sliced(nemo_mesh.u_to_hycom_u(mbathy_u)) e3u_ps = nemo_mesh.sliced(nemo_mesh.u_to_hycom_u(e3u_ps)) depthu = nemo_mesh.sliced(nemo_mesh.u_to_hycom_u(depthu)) # mbathy_v = nemo_mesh.sliced(nemo_mesh.v_to_hycom_v(mbathy_v)) e3v_ps = nemo_mesh.sliced(nemo_mesh.v_to_hycom_v(e3v_ps)) depthv = nemo_mesh.sliced(nemo_mesh.v_to_hycom_v(depthv)) # Thickness of t layers (NB: 1 less than gdepw dimension) dt = gdepw[1:] - gdepw[:-1] # Loop over input files. All must be in same directory for file2d in grid2dfiles: # See if actually a grid2D file dirname = os.path.dirname(file2d) m = re.match("(.*_)(grid2D)(_.*\.nc)", os.path.basename(file2d)) if not m: msg = "File %s is not a grid2D file, aborting" % file2d logger.error(msg) raise ValueError, msg # Construct remaining files filet = os.path.join(dirname, m.group(1) + "gridT" + m.group(3)) files = os.path.join(dirname, m.group(1) + "gridS" + m.group(3)) fileu = os.path.join(dirname, m.group(1) + "gridU" + m.group(3)) filev = os.path.join(dirname, m.group(1) + "gridV" + m.group(3)) filew = os.path.join(dirname, m.group(1) + "gridW" + m.group(3)) fileice = os.path.join(dirname, m.group(1) + "icemod" + m.group(3)) logger.info("grid2D file: %s" % file2d) # P-points logger.info("gridS file: %s" % files) logger.info("gridT file: %s" % filet) ncids = netCDF4.Dataset(files, "r") ncidt = netCDF4.Dataset(filet, "r") # time from gridT file. time = ncidt.variables["time_counter"][0] tunit = ncidt.variables["time_counter"].units tmp = cfunits.Units(tunit) refy, refm, refd = (1958, 1, 1) tmp2 = cfunits.Units("hours since %d-%d-%d 00:00:00" % (refy, refm, refd)) # Units from CF convention tmp3 = cfunits.Units.conform(time, tmp, tmp2) # Transform to new new unit tmp3 = int(numpy.round(tmp3)) mydt = datetime.datetime(refy, refm, refd, 0, 0, 0) + datetime.timedelta( hours=tmp3) # Then calculate dt. Phew! logger.info("Valid time from gridT file:%s" % str(mydt)) # Read and calculculate U in hycom U-points. logger.info("gridU file: %s" % fileu) ncidu = netCDF4.Dataset(fileu, "r") u = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) for k in range(nlev): u[k, :, :] = nemo_mesh.sliced( nemo_mesh.u_to_hycom_u(ncidu.variables["vozocrtx"][ 0, k, :, :])) # Costly, make more efficient if needed u = numpy.where(numpy.abs(u) < 1e10, u, 0.) #Calculate barotropic and baroclinic u usum = numpy.zeros(u.shape[-2:]) dsum = numpy.zeros(u.shape[-2:]) for k in range(u.shape[0] - 1): # Dont include lowest layer # TODO: Mid-layer depths seem to be undefined - figure out why ... logger.debug( "k=%3d, u=%10.3g, mbathy_u[jtest,itest]=%3d,gdepw[k]=%8.2f, depthu[jtest,itest]=%8.2f" % (k, u[k, jtest, itest], mbathy_u[jtest, itest], gdepw[k], depthu[jtest, itest])) J, I = numpy.where(mbathy_u > k) usum[J, I] = usum[J, I] + u[k, J, I] * dt[k] dsum[J, I] = dsum[J, I] + dt[k] J, I = numpy.where(mbathy >= 0) usum[J, I] = usum[J, I] + u[mbathy_u[J, I], J, I] * e3u_ps[J, I] dsum[J, I] = dsum[J, I] + e3u_ps[J, I] ubaro = numpy.where(dsum > 0.1, usum / dsum, 0.) # Read and calculculate V in hycom V-points. logger.info("gridV file: %s" % filev) ncidv = netCDF4.Dataset(filev, "r") v = numpy.zeros((nlev, mbathy.shape[0], mbathy.shape[1])) for k in range(nlev): v[k, :, :] = nemo_mesh.sliced( nemo_mesh.v_to_hycom_v(ncidv.variables["vomecrty"][ 0, k, :, :])) # Costly, make more efficient if needed v = numpy.where(numpy.abs(v) < 1e10, v, 0.) #Calculate barotropic and baroclinic v vsum = numpy.zeros(v.shape[-2:]) dsum = numpy.zeros(v.shape[-2:]) for k in range(v.shape[0] - 1): # Dont include lowest layer logger.debug( "k=%3d, v=%10.3g, mbathy_v[jtest,itest]=%3d,gdepw[k]=%8.2f, depthv[jtest,itest]=%8.2f" % (k, v[k, jtest, itest], mbathy_v[jtest, itest], gdepw[k], depthv[jtest, itest])) J, I = numpy.where(mbathy_v > k) vsum[J, I] = vsum[J, I] + v[k, J, I] * dt[k] dsum[J, I] = dsum[J, I] + dt[k] J, I = numpy.where(mbathy_u >= 0) vsum[J, I] = vsum[J, I] + v[mbathy_u[J, I], J, I] * e3v_ps[J, I] dsum[J, I] = dsum[J, I] + e3v_ps[J, I] vbaro = numpy.where(dsum > .1, vsum / dsum, 0.) # Masks (land:True) #print mbathy.min(),mbathy.max() ip = mbathy == -1 iu = mbathy_u == -1 iv = mbathy_v == -1 #iu = nemo_mesh.periodic_i_shift_right(iu,1) # u: nemo in cell i is hycom in cell i+1 #iv = nemo_mesh.arctic_patch_shift_up(iu,1) # v: nemo in cell j is hycom in cell j+1 #ip = nemo_mesh.sliced(ip) #iu = nemo_mesh.sliced(iu) #iv = nemo_mesh.sliced(iv) #raise NameError,"test" # 2D data ncid2d = netCDF4.Dataset(file2d, "r") ssh = nemo_mesh.sliced(ncid2d.variables["sossheig"][0, :, :]) ssh = numpy.where(ssh == ncid2d.variables["sossheig"]._FillValue, 0., ssh) ssh = numpy.where(ssh > 1e30, 0., ssh * 9.81) # NB: HYCOM srfhgt is in geopotential ... #bar_height = nemo_mesh.sliced(ncid2d.variables["sobarhei"][0,:,:] ) #dyn_height = nemo_mesh.sliced(ncid2d.variables["sodynhei"][0,:,:] #montg1 = ssh * 9.81 #* 1e-3 # Approx montg1 = numpy.zeros(ssh.shape) logger.warning("montg1 set to zero") logger.warning("srfhgt set to sossheigh*9.81 (Geopotential height)") # Write to abfile outfile = abfile.ABFileArchv( mydt.strftime(fnametemplate), "w", iexpt=10, iversn=22, yrflag=3, ) logger.info("Writing 2D variables") outfile.write_field(montg1, ip, "montg1", 0, 0, 1, 0) outfile.write_field(ssh, ip, "srfhgt", 0, 0, 0, 0) outfile.write_field(numpy.zeros(ssh.shape), ip, "surflx", 0, 0, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "salflx", 0, 0, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "bl_dpth", 0, 0, 0, 0) # Not used outfile.write_field(numpy.zeros(ssh.shape), ip, "mix_dpth", 0, 0, 0, 0) # Not used outfile.write_field(ubaro, iu, "u_btrop", 0, 0, 0, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vbaro, iv, "v_btrop", 0, 0, 0, 0) # v: nemo in cell j is hycom in cell j+1 #outfile.close() ; raise NameError,"test" for k in numpy.arange(u.shape[0]): if k % 10 == 0: logger.info("Writing 3D variables, level %d of %d" % (k + 1, u.shape[0])) ul = numpy.squeeze(u[k, :, :]) - ubaro # Baroclinic velocity vl = numpy.squeeze(v[k, :, :]) - vbaro # Baroclinic velocity # Layer thickness dtl = numpy.zeros(ul.shape) if k < u.shape[0] - 1: J, I = numpy.where(mbathy > k) dtl[J, I] = dt[k] J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] else: J, I = numpy.where(mbathy == k) dtl[J, I] = e3t_ps[J, I] tmpfill = ncids.variables["vosaline"]._FillValue sl = nemo_mesh.sliced(ncids.variables["vosaline"][0, k, :, :]) sl = numpy.where( numpy.abs(sl - tmpfill) <= 1e-4 * numpy.abs(tmpfill), 35., sl) tmpfill = ncidt.variables["votemper"]._FillValue tl = nemo_mesh.sliced(ncidt.variables["votemper"][0, k, :, :]) tl = numpy.where( numpy.abs(tl - tmpfill) <= 1e-4 * numpy.abs(tmpfill), 15., tl) # Fill empty layers with values from above if k > 0: K = numpy.where(dtl < 1e-4) sl[K] = sl_above[K] tl[K] = tl_above[K] onem = 9806. outfile.write_field(ul, iu, "u-vel.", 0, 0, k + 1, 0) # u: nemo in cell i is hycom in cell i+1 outfile.write_field(vl, iv, "v-vel.", 0, 0, k + 1, 0) # v: nemo in cell j is hycom in cell j+1 outfile.write_field(dtl * onem, ip, "thknss", 0, 0, k + 1, 0) outfile.write_field(sl, ip, "salin", 0, 0, k + 1, 0) outfile.write_field(tl, ip, "temp", 0, 0, k + 1, 0) tl_above = numpy.copy(tl) sl_above = numpy.copy(sl) # TODO: Process ice data ncid2d.close() outfile.close() ncidt.close() ncids.close() ncidu.close() ncidv.close() logger.info("Finished writing %s.[ab] " % mydt.strftime(fnametemplate)) nemo_mesh = []
def main(region,experiment,tracer,month,axis,layer,cmap,clim,workdir,\ section,ijspace): user = getpass.getuser() if region == 'TP0' or region == 'TP2' or region == 'TP5' or region == 'NAT': version = 'new' elif region == 'TP4' or region == 'NA2': version = 'old' else: print('wrong or not implemented domain is provided') quit() if axis == 'horizontal' or axis == 'vertical': pass else: print('provide arguments "horizontal" or "vertical"') quit() if region == "TP0": region = "TP0a1.00" if region == "TP2": region = "TP2a0.10" if region == "TP4": region = "TP4a0.12" if region == "TP5": region = "TP5a0.06" if region == "NAT": region = "NATa1.00" if region == "NA2": region = "NA2a0.80" if tracer == "nitrate" or tracer == 'phosphate' or \ tracer == 'silicate' or tracer == "oxygen" or \ tracer == 'dic' or tracer == "alkalinity" or \ tracer == 'temperature' or tracer == "salinity" : pass else: print('tracer name not correct') print('choose: nitrate, phosphate, silicate, \ oxygen, dic, alkalinity, temperature, salinity') quit() units = "(mgC m$^{-2}$ s$^{-1}$), tracer converted to C" key = "trc" # trc for tracers, below tem and sal is set if necessary if version == "new": if tracer == "nitrate": name = "relax.ECO_no3" elif tracer == "phosphate": name = "relax.ECO_pho" elif tracer == "silicate": name = "relax.ECO_sil" elif tracer == "oxygen": name = "relax.ECO_oxy" units = "mmol m$^{-3}$" elif tracer == "dic": name = "relax.CO2_dic" units = "mmol m$^{-3}$" elif tracer == "alkalinity": name = "relax.CO2_alk" units = "mEq m$^{-3}$" elif tracer == "temperature": name = "relax_tem" key = "tem" units = "$^{o}C$" elif tracer == "salinity": name = "relax_sal" key = "sal" units = "psu" if version == "old": if tracer == "nitrate": name = "relax_nit" elif tracer == "phosphate": name = "relax_pho" elif tracer == "silicate": name = "relax_sil" elif tracer == "oxygen": name = "relax_oxy" units = "mmol m$^{-3}$" elif tracer == "dic": name = "relax_dic" units = "mmol m$^{-3}$" elif tracer == "alkalinity": name = "relax_alk" units = "mEq m$^{-3}$" elif tracer == "temperature": name = "relax_tem" key = "tem" units = "$^{o}C$" elif tracer == "salinity": name = "relax_sal" key = "sal" units = "psu" abgrid = abfile.ABFileGrid(workdir + user + "/" + \ region + "/topo/regional.grid","r") plon = abgrid.read_field("plon") plat = abgrid.read_field("plat") jdm, idm = plon.shape abdepth = abfile.ABFileBathy(workdir + user + "/" + \ region + "/relax/" + experiment + "/SCRATCH/regional.depth.b", \ "r",idm=idm,jdm=jdm) depthm = abdepth.read_field("depth") abrelax = abfile.ABFileRelax(workdir + user + "/" + \ region + "/relax/" + experiment + \ "/" + name + ".a","r") # now plot fig = plt.figure(figsize=(6, 5), facecolor='w') ax = fig.add_subplot(1, 1, 1) ax.set_position([0.01, 0.02, 0.865, 0.96]) cmap = plt.get_cmap(cmap) ax.set_facecolor('xkcd:gray') if axis == 'horizontal': if layer is None: print(" ") print("provide the layer number to be plotted, e.g. --layer=1") print("quitting ...") print(" ") quit() else: relax = abrelax.read_field(key, np.int(layer), np.int(month) - 1) abrelax.close() pmesh = plt.pcolormesh(relax, cmap=cmap) cb = ax.figure.colorbar(pmesh) if clim is not None: pmesh.set_clim(clim) if axis == 'vertical': if section is None: print(" ") print("provide the section to be plotted") print("--section='lon1,lon2,lat1,lat2'") print("--section='-30.1,2.5,50.0,75.5'") print("quitting ...") print(" ") quit() else: lon1 = section[0] lon2 = section[1] lat1 = section[2] lat2 = section[3] # pick up indexes if ijspace: sec = gridxsec.SectionIJSpace([lon1, lon2], [lat1, lat2], plon, plat) else: sec = gridxsec.Section([lon1, lon2], [lat1, lat2], plon, plat) I, J = sec.grid_indexes dist = sec.distance slon = sec.longitude slat = sec.latitude dpname = modeltools.hycom.layer_thickness_variable["archive"] # get arbitrary relaxation thicknesses dummy = sorted(fnmatch.filter(\ os.listdir(workdir + user + "/" + \ region + "/relax/" + experiment), \ 'relax.0000_[012]*_00.a')) dummyarch = workdir + user + "/" + \ region + "/relax/" + experiment + \ "/" + dummy[np.int(month)-1] dummyfile = abfile.ABFileArchv(dummyarch, "r") kdm = max(dummyfile.fieldlevels) intfsec = np.zeros((kdm + 1, I.size)) datasec = np.zeros((kdm + 1, I.size)) for k in range(kdm): dp2d = dummyfile.read_field(dpname, k + 1) data2d = abrelax.read_field(key, k + 1, np.int(month) - 1) dp2d = np.ma.filled(dp2d, 0.) dp2d = dp2d / modeltools.hycom.onem data2d = np.ma.filled(data2d, 1e30) intfsec[k + 1, :] = intfsec[k, :] + dp2d[J, I] if k == 0: datasec[k, :] = data2d[J, I] datasec[k + 1, :] = data2d[J, I] datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec) x = dist / 1000. # km pmesh = ax.pcolormesh(x, -intfsec, datasec, cmap=cmap) cb = ax.figure.colorbar(pmesh) if clim is not None: pmesh.set_clim(clim) axm = fig.add_subplot(212) axm.set_position([0.85, 0.85, 0.15, 0.15]) axm.set_facecolor('xkcd:gray') pmesh2 = plt.pcolormesh(dummyfile.read_field(dpname, 1) * 0., cmap=cmap) pltsec = plt.plot(I, J, 'r', lw=2) plt.xticks([]) plt.yticks([]) plt.text(0.015,1.05, "%s %s %s" %(tracer, "relaxation month:",\ month.zfill(2)),transform=ax.transAxes,FontSize=13) if axis == 'horizontal': plt.text(0.015, 1.005, units + " @layer=" + layer, transform=ax.transAxes, FontSize=8) else: plt.text(0.015, 1.005, units, transform=ax.transAxes, FontSize=8) # save figure counter = 0 plottemp = workdir + user + "/" + \ region + "/relax/" + experiment + \ "/" + name + "_" + axis + "_%s" + ".png" plotname = plottemp % (np.str(counter).zfill(3)) while os.path.isfile(plotname): counter += 1 plotname = plottemp % (np.str(counter).zfill(3)) fig.canvas.print_figure(plotname, dpi=180) print(" ") print("figure: " + plotname) print(" ")
def main(tide_file,archv_files,include_uv=False): # 1) If this routine is called without any archive files (empty list), then # Files suitable for barotropic nesting only are created. The new archive files are then # chosen to match times in tide file. # 2) If routines are called with archive files, then times matching the archive file times are # sought from the tide file. It they are found, srfhgt and montg1 are adjusted # to match the new tidal data. # Read plon,plat and depth from regional files. Mainly used to check that # grid is ok ... logger.info("Opening regional.grid.[ab]") gfile=abfile.ABFileGrid("regional.grid","r") plon=gfile.read_field("plon") plat=gfile.read_field("plat") pang=gfile.read_field("pang") # For rotation of tidal current gfile.close() logger.info("Opening regional.depth.[ab]") bathyfile=abfile.ABFileBathy("regional.depth","r",idm=gfile.idm,jdm=gfile.jdm,mask=True) depth=bathyfile.read_field("depth") bathyfile.close() depth = depth.filled(0.) ip=depth>0.0 iu=numpy.copy(ip) iu[:,1:] = numpy.logical_and(iu[:,1:],iu[:,0:-1]) iv=numpy.copy(ip) iv[1:,:] = numpy.logical_and(iv[1:,:],iv[0:-1,:]) # Open netcdf file, get time variable and some basic stuff print os.getcwd(),tide_file logger.info("Opening %s"%tide_file) nc_h = netCDF4.Dataset(tide_file,"r") plon_h=nc_h.variables["longitude"][:] plat_h=nc_h.variables["latitude"][:] depth_h=nc_h.variables["depth"][:] check_grids(plon,plon_h,plat,plat_h) check_depths(depth,depth_h) # Time processing for tidal elevations time_h=nc_h.variables["time"][:] tunit = nc_h.variables["time"].units mydt_h = cf_time_to_datetime(time_h,tunit) if include_uv : m=re.match("^(.*)_h.nc$",tide_file) if m : tide_file_u = m.group(1)+"_u.nc" else : msg="Unable to guesstimate tidal u component from tidsl heights file %s "%tide_file_h logger.error(msg) raise ValueError,msg m=re.match("^(.*)_h.nc$",tide_file) if m : tide_file_v = m.group(1)+"_v.nc" else : msg="Unable to guesstimate tidal u component from tidsl heights file %s "%tide_file_h logger.error(msg) raise ValueError,msg logger.info("Opening %s"%tide_file_u) nc_u = netCDF4.Dataset(tide_file_u,"r") plon_u=nc_u.variables["longitude"][:] plat_u=nc_u.variables["latitude"][:] depth_u=nc_u.variables["depth"][:] check_grids(plon,plon_u,plat,plat_u) check_depths(depth,depth_u) # Time processing for tidal elevations time_u=nc_u.variables["time"][:] tunit = nc_u.variables["time"].units mydt_u = cf_time_to_datetime(time_u,tunit) logger.info("Opening %s"%tide_file_v) nc_v = netCDF4.Dataset(tide_file_v,"r") plon_v=nc_v.variables["longitude"][:] plat_v=nc_v.variables["latitude"][:] depth_v=nc_v.variables["depth"][:] check_grids(plon,plon_v,plat,plat_v) check_depths(depth,depth_v) # Time processing for tidal elevations time_v=nc_v.variables["time"][:] tunit = nc_v.variables["time"].units mydt_v = cf_time_to_datetime(time_v,tunit) # restriction for now, u and v must have same time steps as h # TODO: Loosen restriction try : difftu=[abs(diff_in_seconds(elem[0]-elem[1])) for elem in zip(mydt_h,mydt_u)] difftv=[abs(diff_in_seconds(elem[0]-elem[1])) for elem in zip(mydt_h,mydt_v)] except: # Probably due to size mismatch, but could be more descriptive. # TODO: Add more descriptive error message msg="Error when subtracting times from u/v from h. Check your data" logger.error(msg) raise ValueError,msg #print difftu #print difftv if any([ elem > 10. for elem in difftu]) or any([ elem > 10. for elem in difftv]): msg="Times in tidal u/v vs tidal h mismatch. Time series must be estimated at the same times" logger.error(msg) raise ValueError,msg # Create output dir. path0=os.path.join(".","archv_with_tide") if os.path.exists(path0) and os.path.isdir(path0) : pass else : os.mkdir(path0) # Open blkdat files. Get some properties bp=modeltools.hycom.BlkdatParser("blkdat.input") idm = bp["idm"] jdm = bp["jdm"] kdm = bp["kdm"] thflag = bp["thflag"] thbase = bp["thbase"] kapref = bp["kapref"] iversn = bp["iversn"] iexpt = bp["iexpt"] yrflag = bp["yrflag"] thref=1e-3 if kapref == -1 : kapnum = 2 msg="Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError,msg else : kapnum = 1 if kapnum > 1 : msg="Only kapnum=1 is implemented for now" logger.error(msg) raise ValueError,msg # hycom sigma and kappa, written in python. NB: sigver is not used here. # Modify to use other equations of state. For now we assume sigver is: # 1 (7-term eqs referenced to 0 bar) # 2 (7-term eqs referenced to 2000 bar) if thflag == 0 : sigver=1 else : sigver=2 sig = modeltools.hycom.Sigma(thflag) if kapref > 0 : kappa = modeltools.hycom.Kappa(kapref,thflag*1000.0e4) # # Now loop through tide_times for rec,tide_time in enumerate(mydt_h) : # Construct archive file name to create iy = tide_time.year id,ih,isec = modeltools.hycom.datetime_to_ordinal(tide_time,yrflag) archv_file_in_string = "archv.%04d_%03d_%02d"%(iy,id,ih) # Is there match for this file name in list of archive files? I=[elem for elem in archv_files if os.path.basename(elem)[:17] == archv_file_in_string ] state_from_archv=len(I)>0 if state_from_archv : archv_file_in =I[0] # Output file name fnameout = os.path.join(path0,os.path.basename(archv_file_in_string)) arcfile_out=abfile.ABFileArchv(fnameout,"w", iversn=iversn, yrflag=yrflag, iexpt=iexpt,mask=False, cline1="TIDAL data has been added") tide_h=numpy.copy(nc_h.variables["h"][rec,:,:]) tide_h=numpy.where(tide_h==nc_h.variables["h"]._FillValue,0.,tide_h) #print tide_h.min(),tide_h.max() if include_uv : tide_u=numpy.copy(nc_u.variables["u"][rec,:,:]) tide_v=numpy.copy(nc_v.variables["v"][rec,:,:]) #print tide_u.min(),tide_u.max() #print tide_v.min(),tide_u.max() tide_u=numpy.where(tide_u==nc_u.variables["u"]._FillValue,0.,tide_u) tide_v=numpy.where(tide_v==nc_v.variables["v"]._FillValue,0.,tide_v) # Rotate vectors to align with grid tide_u= tide_u*numpy.cos(pang) + tide_v*numpy.sin(pang) tide_v=-tide_u*numpy.sin(pang) + tide_v*numpy.cos(pang) #tide_v=tide_u*numpy.cos(pang+.5*numpy.pi) + tide_v*numpy.sin(pang+.5*numpy.pi) # From P-point to u. 2nd dim in python = 1st dim in Fortran tide_u[:,1:] =.5*(tide_u[:,1:] + tide_u[:,0:-1]) tide_u=numpy.where(iu,tide_u,0.) # From P-point to v. 1st dim in python = 2nd dim in Fortran tide_v[1:,:] =.5*(tide_v[1:,:] + tide_v[0:-1,:]) tide_v=numpy.where(iv,tide_v,0.) if state_from_archv : logger.info("Adding tidal values to existing state:%s"%arcfile_out.basename) arcfile=abfile.ABFileArchv(archv_file_in,"r") if arcfile.idm <> plon.shape[1] or arcfile.jdm <> plon.shape[0] : msg="Grid size mismatch between %s and %s "%(tide_file,archv_file_in) # Read all layers .. (TODO: If there are memory problems, read and estimate sequentially) temp = numpy.ma.zeros((jdm,idm)) # Only needed when calculating density saln = numpy.ma.zeros((jdm,idm)) # Only needed when calculating density th3d =numpy.ma.zeros((kdm,jdm,idm)) thstar=numpy.ma.zeros((kdm,jdm,idm)) dp =numpy.ma.zeros((jdm,idm)) p =numpy.ma.zeros((kdm+1,jdm,idm)) logger.info("Reading layers to get thstar and p") for k in range(kdm) : logger.debug("Reading layer %d from %s"%(k,archv_file_in)) temp =arcfile.read_field("temp",k+1) saln =arcfile.read_field("salin",k+1) #dp [k ,:,:]=arcfile.read_field("thknss",k+1) dp [:,:]=arcfile.read_field("thknss",k+1) th3d [k ,:,:]=sig.sig(temp,saln) - thbase p [k+1,:,:]= p[k,:,:] + dp[:,:] thstar[k ,:,:]=numpy.ma.copy(th3d [k ,:,:]) if kapref > 0 : thstar[k ,:,:]=thstar [k ,:,:] + kappa.kappaf( temp[:,:], saln[:,:], th3d[k,:,:]+thbase, p[k,:,:]) elif kapref < 0 : msg="Only kapref>=0 is implemented for now" logger.error(msg) raise ValueError,msg # Read montg1 and srfhgt, and set new values # ... we have ... # montg1 = montgc + montgpb * pbavg # srfhgt = montg1 + thref*pbavg # ... montg1 = arcfile.read_field("montg1",thflag) srfhgt = arcfile.read_field("srfhgt",0) # New surface height - montg1pb=modeltools.hycom.montg1_pb(thstar,p) montg1 = montg1 + montg1pb * modeltools.hycom.onem * tide_h srfhgt = montg1 + thref*tide_h*modeltools.hycom.onem # Barotrpic velocities if include_uv : ubavg = arcfile.read_field("u_btrop",0) vbavg = arcfile.read_field("v_btrop",0) ubavg = ubavg + tide_u vbavg = vbavg + tide_v # Loop through original fields and write for key in sorted(arcfile.fields.keys()) : fieldname = arcfile.fields[key]["field"] time_step = arcfile.fields[key]["step"] model_day = arcfile.fields[key]["day"] k = arcfile.fields[key]["k"] dens = arcfile.fields[key]["dens"] fld =arcfile.read_field(fieldname,k) if fieldname == "montg1" : logger.info("Writing field %10s at level %3d to %s (modified)"%(fieldname,k,fnameout)) arcfile_out.write_field(montg1,None,fieldname,time_step,model_day,sigver,thbase) elif fieldname == "srfhgt" : logger.info("Writing field %10s at level %3d to %s (modified)"%(fieldname,k,fnameout)) arcfile_out.write_field(srfhgt,None,fieldname,time_step,model_day,sigver,thbase) elif fieldname == "u_btrop" and include_uv : logger.info("Writing field %10s at level %3d to %s (modified)"%(fieldname,k,fnameout)) arcfile_out.write_field(ubavg,None,fieldname,time_step,model_day,sigver,thbase) elif fieldname == "v_btrop" and include_uv : logger.info("Writing field %10s at level %3d to %s (modified)"%(fieldname,k,fnameout)) arcfile_out.write_field(vbavg,None,fieldname,time_step,model_day,sigver,thbase) else : arcfile_out.write_field(fld ,None,fieldname,time_step,model_day,k,dens) #logger.info("Writing field %10s at level %3d to %s (copy from original)"%(fieldname,k,fnameout)) arcfile.close() else : logger.info("Crating archv file with tidal data :%s"%arcfile_out.basename) montg1=numpy.zeros((jdm,idm,)) srfhgt=tide_h*modeltools.hycom.onem*thref arcfile_out.write_field(montg1,None,"montg1",0,0.,sigver,thbase) arcfile_out.write_field(srfhgt,None,"srfhgt",0,0.,0,0.0) # Write 9 empty surface fields so that forfun.F can understand these files .... TODO: Fix in hycom arcfile_out.write_field(montg1,None,"surflx",0,0.,0,0.0) arcfile_out.write_field(montg1,None,"salflx",0,0.,0,0.0) arcfile_out.write_field(montg1,None,"bl_dpth",0,0.,0,0.0) arcfile_out.write_field(montg1,None,"mix_dpth",0,0.,0,0.0) if include_uv : ubavg = tide_u vbavg = tide_v arcfile_out.write_field(ubavg ,None,"u_btrop" ,0,0.,0,0.0) arcfile_out.write_field(vbavg ,None,"v_btrop" ,0,0.,0,0.0) logger.info("Finished writing to %s"%fnameout) arcfile_out.close() logger.info("Files containing tidal data in directory %s"%path0) logger.warning("Sigver assumed to be those of 7 term eqs") logger.warning(" 1 for sigma-0/thflag=0, 2 for sigma-2/thflag=2")