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 = abf.ABFileArchv(myfile, "r") n_intloop = 1 elif filetype == "regional.depth": ab = abf.ABFileBathy(myfile, "r", idm=idm, jdm=jdm) n_intloop = 1 elif filetype == "forcing": ab = abf.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 = abf.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(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 = abf.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 = []
def main(lon1, lat1, lon2, lat2, variable, files, filetype="archive", clim=None, sectionid="", ijspace=False, xaxis="distance", section_map=False, dens=False, dpi=180): logger.info("Filetype is %s" % filetype) gfile = abf.ABFileGrid("regional.grid", "r") plon = gfile.read_field("plon") plat = gfile.read_field("plat") # 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 print('dit.shae=', dist.shape) slon = sec.longitude slat = sec.latitude 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 = np.maximum(-90., slat.min() - 10.) ur_lat = np.minimum(90., slat.max() + 10.) proj = ccrs.Stereographic(central_latitude=90.0, central_longitude=-40.0) pxy = proj.transform_points(ccrs.PlateCarree(), plon, plat) px = pxy[:, :, 0] py = pxy[:, :, 1] x, y = np.meshgrid(np.arange(slon.shape[0]), np.arange(slat.shape[0])) figure = plt.figure(figsize=(10, 8)) ax = figure.add_subplot(111) ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_extent([-179, 179, 53, 85], ccrs.PlateCarree()) ax.add_feature(cfeature.GSHHSFeature('auto', edgecolor='grey')) ax.add_feature(cfeature.GSHHSFeature('auto', facecolor='grey')) ax.gridlines() ax.plot(slon, slat, "r-", lw=1) pos = ax.get_position() asp = pos.height / pos.width w = figure.get_figwidth() 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 = plt.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 = abf.ABFileArchv(myfile, "r") elif filetype == "restart": i_abfile = abf.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 xx = np.zeros((kdm + 1, I.size)) intfsec = np.zeros((kdm + 1, I.size)) datasec = np.zeros((kdm + 1, I.size)) if dens: datasec_sal = np.zeros((kdm + 1, I.size)) sigma_sec = np.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 = np.ma.filled(dp2d, 0.) / modeltools.hycom.onem data2d = np.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] if dens: data2d_sal = i_abfile.read_field('salin', k + 1) data2d_sal = np.ma.filled(data2d_sal, 1e30) datasec_sal[k + 1, :] = data2d_sal[J, I] i_maxd = np.argmax(np.abs(intfsec[kdm, :])) for k in range(kdm + 1): xx[k, :] = x[:] datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec) print("datasec min, max=", datasec.min(), datasec.max()) if dens: datasec_sal = np.ma.masked_where(datasec_sal > 0.5 * 1e30, datasec_sal) print("datasec_sal min, max=", datasec_sal.min(), datasec_sal.max()) sigma_sec = mod_hyc2plot.sig(datasec, datasec_sal) sigma_sec = np.ma.masked_where(sigma_sec < 0.0, sigma_sec) datasec = sigma_sec # Set up section plot datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec) print("min, max=", datasec.min(), datasec.max()) if clim is None: clim = [datasec.min(), datasec.max()] #clim=[0.0,13] print("clim=", clim[0], clim[1]) if clim is not None: lvls = MaxNLocator(nbins=70).tick_values(clim[0], clim[1]) mf = 'sawtooth_fc100.txt' LinDic = mod_hyc2plot.cmap_dict(mf) my_cmap = matplotlib.colors.LinearSegmentedColormap( 'my_colormap', LinDic) cmap = my_cmap norm = BoundaryNorm(lvls, ncolors=cmap.N, clip=True) P = ax.contourf(xx, -intfsec, datasec, cmap=cmap, levels=lvls) # Plot layer interfaces for k in range(1, kdm + 1): if k % 100 == 0: PL = ax.plot(x, -intfsec[k, :], "-", color="k") 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) elif k % 5 == 0: PL = ax.plot(x, -intfsec[k, :], "--", color="k", linewidth=0.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) else: if k > 2 and k % 2 == 0: PL = ax.plot(x, -intfsec[k, :], "-", color=".5", linewidth=0.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) else: continue # Print figure ax.set_facecolor('xkcd:gray') aspect = 90 pad_fraction = 0.25 divider = make_axes_locatable(ax) width = axes_size.AxesY(ax, aspect=1. / aspect) pad = axes_size.Fraction(pad_fraction, width) cax = divider.append_axes("right", size=width, pad=pad) cb = ax.figure.colorbar(P, cax=cax) if clim is not None: P.set_clim(clim) if dens: ax.set_title('[P. density ]: ' + myfile) else: ax.set_title('[' + variable + ']: ' + myfile) ax.set_ylabel('Depth [m]') ax.set_xlabel(xlab) # Print in different y-lims suff = os.path.basename(myfile) if sectionid: suff = suff + "_" + sectionid if dens: variable = "dens" 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) # Close input file i_abfile.close() # ax.clear() cb.remove()
def main(lon1,lat1,lon2,lat2,variable,files,filetype="archive",clim=None,sectionid="", ijspace=False,xaxis="distance",section_map=False,ncfiles="",dpi=180) : #TP4Grd='/cluster/work/users/aal069/TP4a0.12/mfile/' logger.info("Filetype is %s"% filetype) gfile = abf.ABFileGrid("regional.grid","r") plon=gfile.read_field("plon") plat=gfile.read_field("plat") # 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 print('dit.shae=',dist.shape) 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=np.maximum(-90.,slat.min()-10.) ur_lat=np.minimum(90. ,slat.max()+10.) proj=ccrs.Stereographic(central_latitude=90.0,central_longitude=-40.0) #pxy = proj.transform_points(ccrs.PlateCarree(), plon, plat) #px=pxy[:,:,0] #py=pxy[:,:,1] #x,y=np.meshgrid(np.arange(slon.shape[0]),np.arange(slat.shape[0])) figure =plt.figure(figsize=(8,8)) ax=figure.add_subplot(111,projection=proj) #ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_extent([-179, 179, 53, 85],ccrs.PlateCarree()) #ax = plt.axes(projection=ccrs.Stereographic()) ax.add_feature(cfeature.GSHHSFeature('auto', edgecolor='grey')) ax.add_feature(cfeature.GSHHSFeature('auto', facecolor='grey')) ax.gridlines() #ax.coastlines(resolution='110m') ax.plot(slon,slat,"r-",lw=1,transform=ccrs.PlateCarree()) pos = ax.get_position() asp=pos.height/pos.width w=figure.get_figwidth() h=asp*w figure.set_figheight(h) if sectionid : figure.canvas.print_figure("map_%s.png"%sectionid,dpi=dpi,bbox_inches='tight') else : figure.canvas.print_figure("map.png",dpi=dpi,bbox_inches='tight') # 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]" # get kdm from the first file: # Remove [ab] ending if present print('firstfilw', files[0]) m=re.match("(.*)\.[ab]",files[0]) print('m=',m.group(1)) myf=m.group(1) fi_abfile = abf.ABFileArchv(myf,"r") kdm=max(fi_abfile.fieldlevels) # Loop over archive files figure = plt.figure() ax=figure.add_subplot(111) pos = ax.get_position() count_sum=0 intfsec_sum=np.zeros((kdm+1,I.size)) datasec_sum=np.zeros((kdm+1,I.size)) for fcnt,myfile0 in enumerate(files) : count_sum=count_sum+1 print('count_sum==', count_sum) print('fcnt=', fcnt) print('mfile0=', myfile0) # 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 = abf.ABFileArchv(myfile,"r") elif filetype == "restart" : i_abfile = abf.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 xx=np.zeros((kdm+1,I.size)) intfsec=np.zeros((kdm+1,I.size)) datasec=np.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) #print('---mn,mx data=', data2d.min(),data2d.max()) if (k%kdm==49): print("---Reach bottom layer" ) dp2d=np.ma.filled(dp2d,0.)/modeltools.hycom.onem data2d=np.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] intfsec_sum=intfsec_sum + intfsec datasec_sum=datasec_sum + datasec #print 'prs_intafce=', np.transpose(intfsec[:,15]) i_abfile.close() # end loop over files intfsec_avg=intfsec_sum/count_sum datasec_avg=datasec_sum/count_sum if ncfiles : MLDGS_sum=np.zeros((1,I.size)) count_sum=0 for fcnt,ncfile in enumerate(ncfiles) : count_sum=count_sum+1 print('ncfile count_sum==', count_sum) print('ncfile fcnt=', fcnt) print('ncfilefile=', ncfile) MLDGS=np.zeros((1,I.size)) ncfile0 = netCDF4.Dataset(ncfile,'r') MLD_2D = ncfile0.variables['GS_MLD'][:] #MLD_2D = ncfile0.variables['mlp'][:] MLDGS[0,:]=MLD_2D[0,J,I] MLDGS_sum= MLDGS_sum + MLDGS ncfile0.close() # end loop over files MLDGS_avg=MLDGS_sum/count_sum # #----------------------------------------------------------------- # read from clim mld TP5netcdf if ncfiles : if 'TP2' in files[0]: fh=netCDF4.Dataset('mld_dr003_l3_modif_Interp_TP2grd.nc') else: fh=netCDF4.Dataset('mld_dr003_l3_modif_Interp_TP5grd.nc') fhmldintrp = fh.variables['TP5mld'][:] fh.close() #fhMLDintrp_sum=np.zeros((760,800)) MLDclim_sum=np.zeros((1,I.size)) cunt_sum=0 for ii in range(12) : cunt_sum=cunt_sum +1 MLDclim=np.zeros((1,I.size)) MLDclim[0,:]=fhmldintrp[ii,J,I] MLDclim_sum= MLDclim_sum + MLDclim print('clim count_sum==', cunt_sum) MLDclim_avg=MLDclim_sum/cunt_sum #----------------------------------------------------------------- i_maxd=np.argmax(np.abs(intfsec_avg[kdm,:])) #print i_maxd for k in range(kdm+1) : xx[k,:] = x[:] # Set up section plot #datasec = np.ma.masked_where(datasec==1e30,datasec) datasec_avg = np.ma.masked_where(datasec_avg>0.5*1e30,datasec_avg) #print datasec.min(),datasec.max() #P=ax.pcolormesh(dist/1000.,-intfsec,datasec) #print i_maxd for k in range(kdm+1) : xx[k,:] = x[:] if clim is not None : lvls = MaxNLocator(nbins=30).tick_values(clim[0], clim[1]) #print 'levels=', lvls mf='sawtooth_0-1.txt' LinDic=mod_hyc2plot.cmap_dict(mf) my_cmap = matplotlib.colors.LinearSegmentedColormap('my_colormap',LinDic) cmap=my_cmap #cmap = matplotlib.pyplot.get_cmap('gist_rainbow_r') norm = BoundaryNorm(lvls, ncolors=cmap.N, clip=True) print('x.shape=' , x.shape) print('x.min,xmax=' , x.min(),x.max()) print('xx.shape=' , xx.shape) print('xx.min,xxmax=' , xx.min(),xx.max()) print('intfsec_avg.shape=', intfsec_avg.shape) print('datasec_avg.shape=', datasec_avg.shape) #P=ax.pcolormesh(x,-intfsec,datasec,cmap=cmap) P=ax.contourf(xx,-intfsec_avg,datasec_avg,extend='both',cmap=cmap,levels=lvls) if 'sal' in variable: P1=ax.contour(xx,-intfsec_avg,datasec_avg,levels=[32.0,33.0,34.0,35.0,35.5], colors=('k',),linestyles=('-',),linewidths=(1.5,)) else: P1=ax.contour(xx,-intfsec_avg,datasec_avg,levels=[-1,0.0,2.0], colors=('k',),linestyles=('-',),linewidths=(1.5,)) matplotlib.pyplot.clabel(P1, fmt = '%2.1d', colors = 'k', fontsize=10) #contour line labels # Plot layer interfaces for k in range(1,kdm+1) : if k%100 == 0 : PL=ax.plot(x,-intfsec_avg[k,:],"-",color="k") elif k%5 == 0 and k <= 10: PL=ax.plot(x,-intfsec_avg[k,:],"--",color="k", linewidth=0.5) textx = x[i_maxd] texty = -0.5*(intfsec_avg[k-1,i_maxd] + intfsec_avg[k,i_maxd]) ax.text(textx,texty,str(k),verticalalignment="center",horizontalalignment="center",fontsize=6) elif k%2 and k > 10 : PL=ax.plot(x,-intfsec_avg[k,:],"--",color="k", linewidth=0.5) textx = x[i_maxd] texty = -0.5*(intfsec_avg[k-1,i_maxd] + intfsec_avg[k,i_maxd]) ax.text(textx,texty,str(k),verticalalignment="center",horizontalalignment="center",fontsize=6) if ncfiles : PL=ax.plot(x,-MLDGS_avg[0,:],"-",color="w", linewidth=1.50) PL=ax.plot(x,-MLDclim_avg[0,:],"--",color="r", linewidth=1.50) ### else : ### PL=ax.plot(x,-intfsec_avg[k,:],"-",color=".5") # Print figure and remove wite space. aspect = 50 pad_fraction = 0.25 divider = make_axes_locatable(ax) width = axes_size.AxesY(ax, aspect=1./aspect) pad = axes_size.Fraction(pad_fraction, width) cax = divider.append_axes("right", size=width, pad=pad) cb=ax.figure.colorbar(P,cax=cax,extend='both') #cb=ax.figure.colorbar(P,extend='both') if clim is not None : P.set_clim(clim) #cb=ax.figure.colorbar(P,extend='both') ax.set_title(variable+':'+myfile+'AVG-') ax.set_ylabel('Depth [m]') 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_AVG_%s_full_%s.png"%(variable,suff),dpi=dpi) #ax.set_ylim(-1000,0) if 'Fram' in sectionid or 'Svin' in sectionid: print('sectionid=', sectionid) ax.set_ylim(-600,0) figure.canvas.print_figure("sec_AVG_%s_600m_%s.png"%(variable,suff),dpi=dpi) else: #ax.set_ylim(-2500,0) #figure.canvas.print_figure("sec_AVG_%s_2500m_%s.png"%(variable,suff),dpi=dpi) ax.set_ylim(-3000,0) figure.canvas.print_figure("sec_AVG_%s_3000m_%s.png"%(variable,suff),dpi=dpi) # Close input file #i_abfile.close() # ax.clear() cb.remove()
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 = abf.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(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 = abf.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 = abf.ABFile.strip_ab_ending(psikk_file) m = re.match(pattern, psikk_file) if m: relaxtem = abf.ABFileRelax(m.group(1) + "_tem", "r") relaxsal = abf.ABFileRelax(m.group(1) + "_sal", "r") relaxint = abf.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 = abf.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 = abf.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 = abf.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(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=abf.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=abf.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(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 = abf.ABFileGrid("regional.grid", "r") plon = gfile.read_field("plon") plat = gfile.read_field("plat") # 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 print(slon.shape) print(slat.shape) 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 = np.maximum(-90., slat.min() - 10.) ur_lat = np.minimum(90., slat.max() + 10.) proj = ccrs.Stereographic(central_latitude=90.0, central_longitude=-40.0) pxy = proj.transform_points(ccrs.PlateCarree(), plon, plat) px = pxy[:, :, 0] py = pxy[:, :, 1] x, y = np.meshgrid(np.arange(slon.shape[0]), np.arange(slat.shape[0])) figure = plt.figure(figsize=(10, 8)) ax = figure.add_subplot(111) ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_extent([-179, 179, 53, 85], ccrs.PlateCarree()) ax.add_feature(cfeature.GSHHSFeature('auto', edgecolor='grey')) ax.add_feature(cfeature.GSHHSFeature('auto', facecolor='grey')) ax.gridlines() ax.plot(slon, slat, "r-", lw=1) pos = ax.get_position() asp = pos.height / pos.width w = figure.get_figwidth() 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 = plt.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 = abf.ABFileArchv(myfile, "r") elif filetype == "restart": i_abfile = abf.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 = np.zeros((kdm + 1, I.size)) datasec = np.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 = np.ma.filled(dp2d, 0.) / modeltools.hycom.onem data2d = np.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 = np.argmax(np.abs(intfsec[kdm, :])) # Set up section plot datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec) P = plt.pcolormesh(x, -intfsec, datasec, cmap="jet", shading='auto') 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) # 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()