├── .gitignore ├── .readthedocs.yaml ├── @gcmfaces ├── abs.m ├── and.m ├── angle.m ├── atan.m ├── atand.m ├── cat.m ├── convn.m ├── cos.m ├── cosd.m ├── cumsum.m ├── cut_T_N.m ├── diff.m ├── display.m ├── double.m ├── end.m ├── eq.m ├── exch_T_N.m ├── exch_UV.m ├── exch_UV_N.m ├── exch_Z.m ├── exp.m ├── find.m ├── gcmfaces.m ├── ge.m ├── get.m ├── gt.m ├── imag.m ├── isinf.m ├── isnan.m ├── le.m ├── log10.m ├── log2.m ├── lt.m ├── m_ll2xy.m ├── max.m ├── mean.m ├── median.m ├── min.m ├── minus.m ├── mk3D.m ├── mrdivide.m ├── mtimes.m ├── nanmax.m ├── nanmean.m ├── nanmedian.m ├── nanmin.m ├── nanstd.m ├── nansum.m ├── ne.m ├── not.m ├── ones.m ├── or.m ├── plus.m ├── power.m ├── prctile.m ├── rdivide.m ├── real.m ├── repmat.m ├── reshape.m ├── set.m ├── sin.m ├── sind.m ├── single.m ├── sparse.m ├── sqrt.m ├── squeeze.m ├── std.m ├── subsasgn.m ├── subsref.m ├── sum.m ├── tan.m ├── tand.m ├── times.m ├── uminus.m ├── uplus.m └── zeros.m ├── LICENSE.txt ├── README.md ├── docs ├── Makefile ├── bibli.bib ├── biblirefs.rst ├── conf.py ├── figs │ ├── fig12-eccov4.pdf │ ├── plot_m_map.pdf │ └── sphere_all.pdf ├── gcmfaces_demo_dirtree.rst ├── index.rst ├── make.bat ├── prep_basic.rst ├── prep_demo.rst ├── prep_diags.rst ├── prep_install.rst └── requirements.txt ├── ecco_v4 ├── alldiag_load.m ├── bp_ECCO_GRACE.m ├── cost_altimeter.m ├── cost_altimeter_disp.m ├── cost_bp.m ├── cost_read.m ├── cost_seaicearea.m ├── cost_sst.m ├── cost_summary.m ├── cost_xx.m ├── extend_xx.m ├── gcmfaces_remap.m ├── map_grace.m ├── rads_noice_mad.m ├── rads_noice_mad_plot.m ├── rads_noice_mad_recompose.m ├── read_grace_fld.m ├── v4_basin.bin ├── v4_basin.m ├── v4_basin_one.m └── v4_read_data.m ├── gcmfaces.pdf ├── gcmfaces_IO ├── check_mygrid.m ├── convert2gcmfaces.m ├── convert2widefaces.m ├── grid_add_time.m ├── grid_load.m ├── grid_load_native.m ├── grid_load_native_RAZ.m ├── interp2nctiles.m ├── ncaddAtt.m ├── ncaddVar.m ├── ncatts.m ├── ncclose.m ├── nccreateFile.m ├── ncdefDim.m ├── ncdefVar.m ├── ncgetFillVal.m ├── ncgetvar.m ├── ncload.m ├── ncopen.m ├── ncputAtt.m ├── ncputvar.m ├── ncsave.m ├── ncvars.m ├── prep2nctiles.m ├── process2UEVN.m ├── process2UVSTAR.m ├── process2interp.m ├── process2nctiles.m ├── rdmds.m ├── rdmds2gcmfaces.m ├── rdmds2workspace.m ├── rdmds2workspace_list.m ├── rdmds_meta.m ├── rdmds_search_subdirs.m ├── read2memory.m ├── read_bin.m ├── read_nctiles.m ├── struct2nctiles.m ├── write2file.m ├── write2meta.m └── write2nctiles.m ├── gcmfaces_calc ├── calc_MeridionalTransport.m ├── calc_T_grad.m ├── calc_UEVNfromUXVY.m ├── calc_UV_conv.m ├── calc_UV_curl.m ├── calc_UV_zonmer.m ├── calc_barostream.m ├── calc_bolus.m ├── calc_boxmean_T.m ├── calc_budget_heat.m ├── calc_budget_mass.m ├── calc_budget_salt.m ├── calc_mermean_T.m ├── calc_mskmean_T.m ├── calc_overturn.m ├── calc_transports.m ├── calc_zonmean_T.m ├── calc_zonmedian_T.m ├── disp_transport.m ├── gcmfaces_bindata.m ├── gcmfaces_close_basin.m ├── gcmfaces_edge_mask.m ├── gcmfaces_interp_1d.m ├── gcmfaces_interp_2d.m ├── gcmfaces_lines_pairs.m ├── gcmfaces_lines_transp.m ├── gcmfaces_lines_zonal.m ├── gcmfaces_loc_tile.m ├── gcmfaces_map_2d.m ├── gcmfaces_phitheta.m ├── gcmfaces_remap_2d.m ├── gcmfaces_remap_3d.m ├── gcmfaces_section.m ├── gcmfaces_subset.m ├── gcmfaces_timestep.m ├── layers_remap.m ├── regrid_dblres.m └── regrid_sum.m ├── gcmfaces_convert ├── convert2arctic.m ├── convert2array.m ├── convert2array_cube.m ├── convert2array_ll.m ├── convert2array_llc.m ├── convert2array_llpc.m ├── convert2cube.m ├── convert2pcol.m ├── convert2pcol_cube.m ├── convert2pcol_ll.m ├── convert2pcol_llc.m ├── convert2pcol_llpc.m ├── convert2southern.m └── convert2vector.m ├── gcmfaces_demo.m ├── gcmfaces_devel ├── README ├── budget_mom_vort.STDOUT ├── budget_mom_vort.m ├── calc_UV_geos.m ├── calc_uvw_nodiv.m ├── example_reformat.m ├── flt_traj_init.m ├── flt_traj_plot.m ├── flt_traj_read.m ├── flt_traj_sel.m ├── gcmfaces_lines_transp_lat.m └── idma_plot_budgets.m ├── gcmfaces_diags ├── diags_budg_geothermal.m ├── diags_diff_snapshots.m ├── diags_display.m ├── diags_driver.m ├── diags_driver_tex.m ├── diags_grid.m ├── diags_grid_parms.m ├── diags_inifin_D.m ├── diags_list_times.m ├── diags_pre_process.m ├── diags_read_from_mat.m ├── diags_select.m ├── diags_set_A.m ├── diags_set_B.m ├── diags_set_C.m ├── diags_set_D.m ├── diags_set_E.m ├── diags_set_F.m ├── diags_set_LAYERS.m ├── diags_set_MLD.m ├── diags_set_SEAICE.m ├── diags_set_user.m └── diags_store_to_mat.m ├── gcmfaces_exch ├── exch_T_N_cube.m ├── exch_T_N_ll.m ├── exch_T_N_llc.m ├── exch_T_N_llpc.m ├── exch_UV_N_cube.m ├── exch_UV_N_ll.m ├── exch_UV_N_llc.m ├── exch_UV_N_llpc.m ├── exch_UV_cube.m ├── exch_UV_ll.m ├── exch_UV_llc.m ├── exch_UV_llpc.m ├── exch_Z_cube.m ├── exch_Z_ll.m └── exch_Z_llc.m ├── gcmfaces_global.m ├── gcmfaces_init.m ├── gcmfaces_maps ├── gcmfaces_cmap_cbar.m ├── gcmfaces_sphere.m ├── gcmfaces_stereoproj.m ├── m_map_1face.m ├── m_map_1face_uv.m ├── m_map_fix_range.m ├── m_map_gcmfaces.m ├── m_map_gcmfaces_movie.m ├── m_map_gcmfaces_uv.m ├── m_map_gcmfaces_uvrotate.m └── qwckplot.m ├── gcmfaces_misc ├── annualmean.m ├── ccaa.m ├── check_budg.m ├── check_loop.m ├── check_snap.m ├── convertR4toR4nonan.m ├── convertR8toR4.m ├── density.m ├── depthStretch.m ├── depthStretchPlot.m ├── diff_mat.m ├── disp_budget_mean_mask.m ├── disp_budget_mean_zonal.m ├── figureL.m ├── gcmfaces_caption.m ├── gcmfaces_interp_coeffs.m ├── gcmfaces_msg.m ├── gcmfaces_polygonangle.m ├── gcmfaces_quadmap.m ├── imagescnan.m ├── input_list_check.m ├── runmean.m ├── sym_g.m └── write2tex.m ├── gcmfaces_smooth ├── diffrotated.m ├── diffsmooth2D.m ├── diffsmooth2D_div_inv.m ├── diffsmooth2D_extrap_fwd.m ├── diffsmooth2D_extrap_inv.m └── diffsmooth2Drotated.m ├── sample_analysis ├── example_IO.m ├── example_MITprof.m ├── example_budget.m ├── example_display.m ├── example_transports.m ├── example_transports_disp.m ├── line_greatC_TUV_MASKS_core2_antarctic.m ├── line_greatC_TUV_MASKS_core2_arctic.m ├── line_greatC_TUV_MASKS_v3.m └── line_greatC_TUV_MASKS_v4.m └── sample_processing ├── example_bin_average.m ├── example_interp.m ├── example_remap.m ├── example_smooth.m └── prep_remap.m /.gitignore: -------------------------------------------------------------------------------- 1 | docs/_build 2 | .ipynb_checkpoints 3 | octave-workspace 4 | release2_climatology 5 | GRID 6 | devel 7 | 8 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Sphinx projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Set the OS, Python version and other tools you might need 8 | build: 9 | os: ubuntu-22.04 10 | tools: 11 | python: "3.12" 12 | 13 | # Build documentation in the "docs/" directory with Sphinx 14 | sphinx: 15 | configuration: docs/conf.py 16 | # fail_on_warning: true 17 | 18 | formats: 19 | - pdf 20 | 21 | python: 22 | install: 23 | - requirements: docs/requirements.txt 24 | -------------------------------------------------------------------------------- /@gcmfaces/abs.m: -------------------------------------------------------------------------------- 1 | function r = abs(p) 2 | %overloaded gcmfaces abs function : 3 | % simply calls double abs function for each face data 4 | 5 | r=p; 6 | for iFace=1:r.nFaces; 7 | iF=num2str(iFace); 8 | eval(['r.f' iF '=abs(p.f' iF ');']); 9 | end; 10 | 11 | 12 | -------------------------------------------------------------------------------- /@gcmfaces/and.m: -------------------------------------------------------------------------------- 1 | function r = and(p,q) 2 | %overloaded gcmfaces and function : 3 | % simply calls double and function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '&q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '&q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p&q.f' iF ';']); 15 | else; 16 | error('gcmfaces and: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/angle.m: -------------------------------------------------------------------------------- 1 | function r = angle(p) 2 | %overloaded gcmfaces angle function : 3 | % simply calls double angle function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=angle(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/atan.m: -------------------------------------------------------------------------------- 1 | function r = atan(p) 2 | %overloaded gcmfaces atan function : 3 | % simply calls double atan function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=atan(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/atand.m: -------------------------------------------------------------------------------- 1 | function r = atand(p) 2 | %overloaded gcmfaces atand function : 3 | % simply calls double atand function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=atand(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/cat.m: -------------------------------------------------------------------------------- 1 | function r = cat(nDim,p,q) 2 | %overloaded gcmfaces cat function : 3 | % simply calls double cat function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=cat(nDim,p.f' iF ',q.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/convn.m: -------------------------------------------------------------------------------- 1 | function r = convn(p,varargin) 2 | % CONVN gcmfaces convn function : 3 | % simply calls double convn function for each face data 4 | % if the first arguments is a gcmfaces object 5 | % passing over the other arguments 6 | 7 | r=p; 8 | 9 | for iFace=1:r.nFaces; 10 | iF=num2str(iFace); 11 | eval(['r.f' iF '=convn(p.f' iF ',varargin{:});']); 12 | end; 13 | 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/cos.m: -------------------------------------------------------------------------------- 1 | function r = cos(p) 2 | %overloaded gcmfaces cos function : 3 | % simply calls double cos function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=cos(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/cosd.m: -------------------------------------------------------------------------------- 1 | function r = cosd(p) 2 | %overloaded gcmfaces cosd function : 3 | % simply calls double cosd function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=cosd(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/cumsum.m: -------------------------------------------------------------------------------- 1 | function r = cumsum(p,varargin) 2 | %overloaded gcmfaces cumsum function : 3 | % simply calls double cumsum function for each face data 4 | % if the first arguments is a gcmfaces object 5 | % passing over the other arguments 6 | 7 | r=p; 8 | 9 | for iFace=1:r.nFaces; 10 | iF=num2str(iFace); 11 | eval(['r.f' iF '=cumsum(p.f' iF ',varargin{:});']); 12 | end; 13 | 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/cut_T_N.m: -------------------------------------------------------------------------------- 1 | function r = cut_T_N(p,varargin) 2 | %object : remove N points at the edge of each face (opposite of exch_T_N). 3 | %input: b is a gcmfaces object 4 | %optional: N (1 by default) is the halo region width 5 | %output: a is the reduced gcmfaces object 6 | % 7 | 8 | r=p; 9 | 10 | if nargin==1; N=1; else; N=varargin{1}; end; 11 | 12 | for iFace=1:r.nFaces; 13 | iF=num2str(iFace); 14 | eval(['r.f' iF '=p.f' iF '(1+N:end-N,1+N:end-N,:,:);']); 15 | end; 16 | 17 | 18 | -------------------------------------------------------------------------------- /@gcmfaces/diff.m: -------------------------------------------------------------------------------- 1 | function r = diff(p,varargin) 2 | %overloaded gcmfaces diff function : 3 | % simply calls double diff function for each face data 4 | % if the first arguments is a gcmfaces object 5 | % passing over the other arguments 6 | 7 | r=p; 8 | 9 | for iFace=1:r.nFaces; 10 | iF=num2str(iFace); 11 | eval(['r.f' iF '=diff(p.f' iF ',varargin{:});']); 12 | end; 13 | 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/display.m: -------------------------------------------------------------------------------- 1 | function display(a) 2 | %overloaded gcmfaces display function : 3 | % displays the gcmfaces object content and attributes 4 | 5 | stg = sprintf(' nFaces: %d\n',a.nFaces); 6 | for iFace=1:a.nFaces; 7 | eval(['tmp1=a.f' num2str(iFace) ';']); 8 | tmp0=class(tmp1); 9 | tmp1=size(tmp1); 10 | tmp2='['; 11 | for ii=1:length(tmp1); tmp2=[tmp2 num2str(tmp1(ii)) 'x']; end; 12 | tmp2=[tmp2(1:end-1) ' ' tmp0 ']']; 13 | stg=strvcat(stg,[' f' num2str(iFace) ': ' tmp2]); 14 | end; 15 | disp(stg) 16 | 17 | -------------------------------------------------------------------------------- /@gcmfaces/double.m: -------------------------------------------------------------------------------- 1 | function r = double(p) 2 | %overloaded gcmfaces double function : 3 | % simply calls double double function for each face data 4 | 5 | r=p; 6 | for iFace=1:r.nFaces; 7 | iF=num2str(iFace); 8 | eval(['r.f' iF '=double(p.f' iF ');']); 9 | end; 10 | 11 | 12 | -------------------------------------------------------------------------------- /@gcmfaces/end.m: -------------------------------------------------------------------------------- 1 | function ind = end(self,k,n); 2 | %overloaded gcmfaces end function : 3 | % simply calls double end function for face #1 if the first argument is a gcmfaces object 4 | % Note: is only valid for dimensions>=3 5 | 6 | if k<3; error('@gcmfaces/end.m is only valid for dimensions>=3'); end; 7 | ind = builtin('end', self.f1, k, n); 8 | 9 | -------------------------------------------------------------------------------- /@gcmfaces/eq.m: -------------------------------------------------------------------------------- 1 | function r = eq(p,q) 2 | %overloaded gcmfaces eq function : 3 | % simply calls double eq function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '==q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '==q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p==q.f' iF ';']); 15 | else; 16 | error('gcmfaces eq: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/exch_T_N.m: -------------------------------------------------------------------------------- 1 | function [a]=exch_T_N(b,varargin); 2 | %object : add halo region data; exchange data between faces. 3 | %input: b is a gcmfaces object 4 | %optional: N (1 by default) is the halo region width 5 | %output: a is the augmented gcmfaces object 6 | % 7 | %notes: 8 | % - This routine adds N points at the edge of each face, which 9 | % are obtained from the neighboring faces edge points; those are necessary to 10 | % operations such as neighbor averaging, or computing gradients over a face. 11 | % - Applying this routine recursively will likely lead to errors. 12 | % - The connectivity between faces depends on the grid topology and needs 13 | % to be implemented by hand for any new grid topology (see gcmfaces_exch). 14 | 15 | if strcmp(b.gridType,'llc'); 16 | a=exch_T_N_llc(b,varargin{:}); 17 | elseif strcmp(b.gridType,'cube'); 18 | a=exch_T_N_cube(b,varargin{:}); 19 | elseif strcmp(b.gridType,'llpc'); 20 | a=exch_T_N_llpc(b,varargin{:}); 21 | elseif strcmp(b.gridType,'ll'); 22 | a=exch_T_N_ll(b,varargin{:}); 23 | else; 24 | error(['exch_T_N not implemented for ' b.gridType '!?']); 25 | end; 26 | 27 | -------------------------------------------------------------------------------- /@gcmfaces/exch_UV.m: -------------------------------------------------------------------------------- 1 | function [aU,aV]=exch_UV(bU,bV); 2 | %special exchange routine for velocity points 3 | 4 | if strcmp(bU.gridType,'llc'); 5 | [aU,aV]=exch_UV_llc(bU,bV); 6 | elseif strcmp(bU.gridType,'cube'); 7 | [aU,aV]=exch_UV_cube(bU,bV); 8 | elseif strcmp(bU.gridType,'llpc'); 9 | [aU,aV]=exch_UV_llpc(bU,bV); 10 | elseif strcmp(bU.gridType,'ll'); 11 | [aU,aV]=exch_UV_ll(bU,bV); 12 | else; 13 | error(['exch_UV not implemented for ' bU.gridType '!?']); 14 | end; 15 | 16 | -------------------------------------------------------------------------------- /@gcmfaces/exch_UV_N.m: -------------------------------------------------------------------------------- 1 | function [aU,aV]=exch_UV_N(bU,bV,varargin); 2 | %special exchange routine for velocity points 3 | 4 | if strcmp(bU.gridType,'llc'); 5 | [aU,aV]=exch_UV_N_llc(bU,bV,varargin{:}); 6 | elseif strcmp(bU.gridType,'cube'); 7 | [aU,aV]=exch_UV_N_cube(bU,bV,varargin{:}); 8 | elseif strcmp(bU.gridType,'llpc'); 9 | [aU,aV]=exch_UV_N_llpc(bU,bV,varargin{:}); 10 | elseif strcmp(bU.gridType,'ll'); 11 | [aU,aV]=exch_UV_N_ll(bU,bV,varargin{:}); 12 | else; 13 | error(['exch_UV_N not implemented for ' bU.gridType '!?']); 14 | end; 15 | 16 | -------------------------------------------------------------------------------- /@gcmfaces/exch_Z.m: -------------------------------------------------------------------------------- 1 | function [FLD]=exch_Z(fld); 2 | %[FLD]=exch_Z(fld); 3 | %adds vorticity points (to north and east of center points) 4 | 5 | if strcmp(fld.gridType,'llc'); 6 | FLD=exch_Z_llc(fld); 7 | elseif strcmp(fld.gridType,'cube'); 8 | FLD=exch_Z_cube(fld); 9 | elseif strcmp(fld.gridType,'ll'); 10 | FLD=exch_Z_ll(fld); 11 | else; 12 | error(['exch_Z not implemented for ' fld.gridType '!?']); 13 | end; 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/exp.m: -------------------------------------------------------------------------------- 1 | function r = exp(p) 2 | %overloaded gcmfaces exp function : 3 | % simply calls double exp function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=exp(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/find.m: -------------------------------------------------------------------------------- 1 | function r = find(p,varargin) 2 | %overloaded gcmfaces find function : 3 | % simply calls double find function for each face data 4 | % if the first arguments is a gcmfaces object 5 | % passing over the other arguments 6 | 7 | r=p; 8 | 9 | for iFace=1:r.nFaces; 10 | iF=num2str(iFace); 11 | eval(['r.f' iF '=find(p.f' iF ',varargin{:});']); 12 | end; 13 | 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/gcmfaces.m: -------------------------------------------------------------------------------- 1 | function s=gcmfaces(varargin); 2 | %object: create an empty gcmfaces object 3 | %input: fld cell array containing each face data 4 | % OR nFaces number of faces (empty faces in output) 5 | % OR (none; results in empty face data, with nFaces=mygrid.nFaces) 6 | %output: gcmfaces object 7 | 8 | 9 | %object: create an empty gcmfaces object 10 | %input: fld cell array containing each face data 11 | % OR nFaces,fld (to add consistency check) 12 | % OR nFaces number of faces (empty faces in output) 13 | % OR (none) (empty faces in output) 14 | %output: gcmfaces object formatted/filled accordingly 15 | 16 | 17 | global mygrid; 18 | 19 | if nargin==2; 20 | nFaces=varargin{1}; 21 | fld=varargin{2}; 22 | if ~iscell(fld)|length(fld)~=nFaces; 23 | error('inconsistent spec. of nFaces,fld'); 24 | end; 25 | elseif nargin==1; 26 | tmp1=varargin{1}; 27 | if iscell(tmp1); 28 | fld=tmp1; 29 | nFaces=length(fld); 30 | else; 31 | nFaces=varargin{1}; 32 | fld=[]; 33 | end; 34 | elseif isfield(mygrid,'nFaces'); 35 | nFaces=mygrid.nFaces; 36 | fld=[]; 37 | else; 38 | nFaces=1; 39 | fld=[]; 40 | warning('nFaces set to 1 by default'); 41 | end; 42 | 43 | if nFaces==1; gridType='ll'; 44 | elseif nFaces==4; gridType='llpc'; 45 | elseif nFaces==5; gridType='llc'; 46 | elseif nFaces==6; gridType='cube'; 47 | else; error('wrong gcmfaces definition'); 48 | end; 49 | 50 | nFacesMax=6; 51 | 52 | if iscell(fld); 53 | s.nFaces=length(fld); 54 | s.gridType=gridType; 55 | for iF=1:s.nFaces; 56 | eval(['s.f' num2str(iF) '=fld{iF};']); 57 | end; 58 | for iF=s.nFaces+1:nFacesMax; 59 | eval(['s.f' num2str(iF) '=[];']); 60 | end; 61 | else; 62 | s.nFaces=nFaces; 63 | s.gridType=gridType; 64 | for iF=1:nFacesMax; 65 | eval(['s.f' num2str(iF) '=[];']); 66 | end; 67 | end; 68 | 69 | s = class(s,'gcmfaces'); 70 | 71 | -------------------------------------------------------------------------------- /@gcmfaces/ge.m: -------------------------------------------------------------------------------- 1 | function r = ge(p,q) 2 | %overloaded gcmfaces ge function : 3 | % simply calls double ge function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '>=q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '>=q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p>=q.f' iF ';']); 15 | else; 16 | error('gcmfaces ge: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/get.m: -------------------------------------------------------------------------------- 1 | function val = get(a, propName) 2 | %overloaded gcmfaces get function : 3 | % V = GET(H,'PropertyName') returns the value of the specified 4 | % attribute (e.g. nFaces and gridType) of a gcmfaces object H. 5 | 6 | eval(['val = a.' propName ';']); 7 | 8 | -------------------------------------------------------------------------------- /@gcmfaces/gt.m: -------------------------------------------------------------------------------- 1 | function r = gt(p,q) 2 | %overloaded gcmfaces gt function : 3 | % simply calls double gt function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '>q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '>q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p>q.f' iF ';']); 15 | else; 16 | error('gcmfaces gt: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/imag.m: -------------------------------------------------------------------------------- 1 | function r = imag(p) 2 | %overloaded gcmfaces imag function : 3 | % simply calls double imag function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=imag(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/isinf.m: -------------------------------------------------------------------------------- 1 | function r = isinf(p) 2 | %overloaded gcmfaces isinf function : 3 | % simply calls double isinf function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=isinf(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/isnan.m: -------------------------------------------------------------------------------- 1 | function r = isnan(p) 2 | %overloaded gcmfaces isnan function : 3 | % simply calls double isnan function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=isnan(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/le.m: -------------------------------------------------------------------------------- 1 | function r = le(p,q) 2 | %overloaded gcmfaces le function : 3 | % simply calls double le function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '<=q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '<=q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p<=q.f' iF ';']); 15 | else; 16 | error('gcmfaces le: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/log10.m: -------------------------------------------------------------------------------- 1 | function r = log10(p) 2 | %overloaded gcmfaces log10 function : 3 | % simply calls double log10 function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=log10(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/log2.m: -------------------------------------------------------------------------------- 1 | function r = log2(p) 2 | %overloaded gcmfaces log2 function : 3 | % simply calls double log2 function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=log2(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/lt.m: -------------------------------------------------------------------------------- 1 | function r = lt(p,q) 2 | %overloaded gcmfaces lt function : 3 | % simply calls double lt function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '0; 29 | r=p; 30 | for iFace=1:r.nFaces; 31 | iF=num2str(iFace); 32 | eval(['r.f' iF '=max(p.f' iF ',varargin{:});']); 33 | end; 34 | else; 35 | tmp1=convert2gcmfaces(p); 36 | [n1,n2,n3,n4]=size(tmp1); 37 | tmp1=reshape(tmp1,n1*n2,n3,n4); 38 | r=max(tmp1,[],1); 39 | end; 40 | 41 | 42 | -------------------------------------------------------------------------------- /@gcmfaces/mean.m: -------------------------------------------------------------------------------- 1 | function r = mean(p,varargin) 2 | % MEAN(p,varargin) 3 | % 4 | %overloaded gcmfaces mean function : 5 | % 1) if single gcmfaces argument, then returns the global mean over all faces 6 | % 2) if more than one argument, then simply calls double mean function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=mean(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{1}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=mean(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=mean(tmp1,1); 30 | end; 31 | 32 | -------------------------------------------------------------------------------- /@gcmfaces/median.m: -------------------------------------------------------------------------------- 1 | function r = median(p,varargin) 2 | % MEDIAN(p,varargin) 3 | % 4 | %overloaded gcmfaces median function : 5 | % 1) if single gcmfaces argument, then returns the global median over all faces 6 | % 2) if more than one argument, then simply calls double median function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=median(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{1}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=median(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=median(tmp1,1); 30 | end; 31 | 32 | 33 | -------------------------------------------------------------------------------- /@gcmfaces/min.m: -------------------------------------------------------------------------------- 1 | function r = min(p,varargin) 2 | % MIN(p,varargin) 3 | % 4 | %overloaded gcmfaces min function : 5 | % 1) if single gcmfaces argument, then returns the global min over all faces 6 | % 2) if two gcmfaces arguments, then returns the min of the two at each point 7 | % 3) otherwise calls double min function for each face, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=min(tmp1); 16 | return; 17 | end; 18 | 19 | if isa(varargin{1},'gcmfaces'); 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=min(p.f' iF ',varargin{1}.f' iF ');']); 24 | end; 25 | return; 26 | end; 27 | 28 | if varargin{2}>0; 29 | r=p; 30 | for iFace=1:r.nFaces; 31 | iF=num2str(iFace); 32 | eval(['r.f' iF '=min(p.f' iF ',varargin{:});']); 33 | end; 34 | else; 35 | tmp1=convert2gcmfaces(p); 36 | [n1,n2,n3,n4]=size(tmp1); 37 | tmp1=reshape(tmp1,n1*n2,n3,n4); 38 | r=min(tmp1,[],1); 39 | end; 40 | 41 | 42 | -------------------------------------------------------------------------------- /@gcmfaces/minus.m: -------------------------------------------------------------------------------- 1 | function r = minus(p,q) 2 | %overloaded gcmfaces minus function : 3 | % simply calls double minus function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '-q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '-q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p-q.f' iF ';']); 15 | else; 16 | error('gcmfaces minus: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/mk3D.m: -------------------------------------------------------------------------------- 1 | function a = mk3D(b,c) 2 | %function a = mk3D(b,c) 3 | % => makes a 3D field of the same format as c, based on b, which may be 4 | % either [A] a 2D field consistent with c(:,:,1) 5 | % or [B] a 1D vector concistent 6 | % 7 | % in case [A], if b has more that 2D, then the first 2D field is used 8 | % in case [B], if the length of b is n3=size(c.f1,3), then we map b(k) to 9 | % a(:,:,k). Otherwise we map b(1) to a(:,:,k) and issue a warning. 10 | 11 | a=c; 12 | n3=size(a.f1,3); 13 | 14 | if isa(b,'gcmfaces'); 15 | %go from 2D field to 3D field 16 | for iFace=1:a.nFaces; 17 | iF=num2str(iFace); 18 | eval(['tmp1=b.f' iF ';']); [n1,n2]=size(tmp1); tmp1=tmp1(:); 19 | tmp1=tmp1*ones(1,size(a.f1,3)); tmp1=reshape(tmp1,[n1 n2 n3]); 20 | eval(['a.f' iF '=tmp1;']); 21 | end; 22 | elseif isa(b,'double'); 23 | if length(b)~=1&length(b)~=n3; fprintf(' mk3D warning: b(1) is used \n'); end; 24 | if length(b)~=n3; b=b(1)*ones(1,n3); end; 25 | if size(b,1)~=1; b=b'; end; 26 | for iFace=1:a.nFaces; 27 | iF=num2str(iFace); 28 | eval(['tmp1=c.f' iF ';']); tmp2=size(tmp1); n1=tmp2(1); n2=tmp2(2); 29 | tmp1=reshape(ones(n1*n2,1)*b,[n1 n2 n3]);; 30 | eval(['a.f' iF '=tmp1;']); 31 | end; 32 | else 33 | error('indexing not supported by gcmfaces objects') 34 | end 35 | 36 | 37 | -------------------------------------------------------------------------------- /@gcmfaces/mrdivide.m: -------------------------------------------------------------------------------- 1 | function r = rdivide(p,q) 2 | %overloaded gcmfaces mrdivide function : 3 | % simply calls double mrdivide function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '/q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '/q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p/q.f' iF ';']); 15 | else; 16 | error('gcmfaces rdivide: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/mtimes.m: -------------------------------------------------------------------------------- 1 | function r = times(p,q) 2 | %overloaded gcmfaces mtimes function : 3 | % simply calls double mtimes function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '*q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '*q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p*q.f' iF ';']); 15 | else; 16 | error('gcmfaces times: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/nanmax.m: -------------------------------------------------------------------------------- 1 | function r = nanmax(p,varargin) 2 | % NANMAX(p,varargin) 3 | % 4 | %overloaded gcmfaces nanmax function : 5 | % 1) if single gcmfaces argument, then returns the global nanmax over all faces 6 | % 2) if two gcmfaces arguments, then returns the nanmax of the two at each point 7 | % 3) otherwise calls double nanmax function for each face, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=nanmax(tmp1); 16 | return; 17 | end; 18 | 19 | if isa(varargin{1},'gcmfaces'); 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=nanmax(p.f' iF ',varargin{1}.f' iF ');']); 24 | end; 25 | return; 26 | end; 27 | 28 | if varargin{2}>0; 29 | r=p; 30 | for iFace=1:r.nFaces; 31 | iF=num2str(iFace); 32 | eval(['r.f' iF '=nanmax(p.f' iF ',varargin{:});']); 33 | end; 34 | else; 35 | tmp1=convert2gcmfaces(p); 36 | [n1,n2,n3,n4]=size(tmp1); 37 | tmp1=reshape(tmp1,n1*n2,n3,n4); 38 | r=nanmax(tmp1,[],1); 39 | end; 40 | 41 | 42 | -------------------------------------------------------------------------------- /@gcmfaces/nanmean.m: -------------------------------------------------------------------------------- 1 | function r = nanmean(p,varargin) 2 | % NANMEAN(p,varargin) 3 | % 4 | %overloaded gcmfaces nanmean function : 5 | % 1) if single gcmfaces argument, then returns the global nanmean over all faces 6 | % 2) if more than one argument, then simply calls double nanmean function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=nanmean(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{1}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=nanmean(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=nanmean(tmp1,1); 30 | end; 31 | 32 | -------------------------------------------------------------------------------- /@gcmfaces/nanmedian.m: -------------------------------------------------------------------------------- 1 | function r = nanmedian(p,varargin) 2 | % NANMEDIAN(p,varargin) 3 | % 4 | %overloaded gcmfaces nanmedian function : 5 | % 1) if single gcmfaces argument, then returns the global nanmedian over all faces 6 | % 2) if more than one argument, then simply calls double nanmedian function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=nanmedian(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{1}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=nanmedian(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=nanmedian(tmp1,1); 30 | end; 31 | 32 | 33 | -------------------------------------------------------------------------------- /@gcmfaces/nanmin.m: -------------------------------------------------------------------------------- 1 | function r = nanmin(p,varargin) 2 | % NANMIN(p,varargin) 3 | % 4 | %overloaded gcmfaces nanmin function : 5 | % 1) if single gcmfaces argument, then returns the global nanmin over all faces 6 | % 2) if two gcmfaces arguments, then returns the nanmin of the two at each point 7 | % 3) otherwise calls double nanmin function for each face, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=nanmin(tmp1); 16 | return; 17 | end; 18 | 19 | if isa(varargin{1},'gcmfaces'); 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=nanmin(p.f' iF ',varargin{1}.f' iF ');']); 24 | end; 25 | return; 26 | end; 27 | 28 | if varargin{2}>0; 29 | r=p; 30 | for iFace=1:r.nFaces; 31 | iF=num2str(iFace); 32 | eval(['r.f' iF '=nanmin(p.f' iF ',varargin{:});']); 33 | end; 34 | else; 35 | tmp1=convert2gcmfaces(p); 36 | [n1,n2,n3,n4]=size(tmp1); 37 | tmp1=reshape(tmp1,n1*n2,n3,n4); 38 | r=nanmin(tmp1,[],1); 39 | end; 40 | 41 | 42 | -------------------------------------------------------------------------------- /@gcmfaces/nanstd.m: -------------------------------------------------------------------------------- 1 | function r = nanstd(p,varargin) 2 | % NANSTD(p,varargin) 3 | % 4 | %overloaded gcmfaces nanstd function : 5 | % 1) if single gcmfaces argument, then returns the global nanstd over all faces 6 | % 2) if more than one argument, then simply calls double nanstd function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=nanstd(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{2}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=nanstd(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=nanstd(tmp1,varargin{1},1); 30 | end; 31 | 32 | 33 | -------------------------------------------------------------------------------- /@gcmfaces/nansum.m: -------------------------------------------------------------------------------- 1 | function r = nansum(p,varargin); 2 | % NANSUM(p,varargin) 3 | % 4 | %overloaded gcmfaces nansum function : 5 | % 1) if single gcmfaces argument, then returns the global nansum over all faces 6 | % 2) if more than one argument, then simply calls double nansum function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=nansum(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{1}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=nansum(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=nansum(tmp1,1); 30 | end; 31 | 32 | -------------------------------------------------------------------------------- /@gcmfaces/ne.m: -------------------------------------------------------------------------------- 1 | function r = ne(p,q) 2 | %overloaded gcmfaces ne function : 3 | % simply calls double ne function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '~=q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '~=q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p~=q.f' iF ';']); 15 | else; 16 | error('gcmfaces ne: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/not.m: -------------------------------------------------------------------------------- 1 | function r = not(p) 2 | %overloaded gcmfaces not function : 3 | % simply calls double not function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=~p.f' iF ';']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/ones.m: -------------------------------------------------------------------------------- 1 | function r = ones(p,varargin) 2 | %overloaded gcmfaces ones function : 3 | % if the first arguments is a gcmfaces object 4 | % we call the double ones function for each face data 5 | % using face dimensions for the first two arguments and 6 | % passing over the other arguments 7 | 8 | r=p; 9 | 10 | for iFace=1:r.nFaces; 11 | iF=num2str(iFace); 12 | eval(['[n1,n2]=size(p.f' iF '(:,:,1));']); 13 | eval(['r.f' iF '=ones(n1,n2,varargin{:});']); 14 | end; 15 | 16 | 17 | -------------------------------------------------------------------------------- /@gcmfaces/or.m: -------------------------------------------------------------------------------- 1 | function r = or(p,q) 2 | %overloaded gcmfaces or function : 3 | % simply calls double or function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '|q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '|q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p|q.f' iF ';']); 15 | else; 16 | error('gcmfaces or: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/plus.m: -------------------------------------------------------------------------------- 1 | function r = plus(p,q) 2 | %overloaded gcmfaces plus function : 3 | % simply calls double plus function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '+q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '+q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p+q.f' iF ';']); 15 | else; 16 | error('gcmfaces plus: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/power.m: -------------------------------------------------------------------------------- 1 | function r = power(p,q) 2 | %overloaded gcmfaces power function : 3 | % simply calls double power function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '.^q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '.^q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p.^q.f' iF ';']); 15 | else; 16 | error('gcmfaces power: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/prctile.m: -------------------------------------------------------------------------------- 1 | function r = prctile(p,varargin) 2 | %overloaded gcmfaces prctile function (operates on full domain) 3 | 4 | tmp1=convert2gcmfaces(p); 5 | r=prctile(tmp1(:),varargin{1}); 6 | 7 | -------------------------------------------------------------------------------- /@gcmfaces/rdivide.m: -------------------------------------------------------------------------------- 1 | function r = rdivide(p,q) 2 | %overloaded gcmfaces rdivide function : 3 | % simply calls double rdivide function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF './q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF './q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p./q.f' iF ';']); 15 | else; 16 | error('gcmfaces rdivide: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/real.m: -------------------------------------------------------------------------------- 1 | function r = real(p) 2 | %overloaded gcmfaces real function : 3 | % simply calls double real function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=real(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/repmat.m: -------------------------------------------------------------------------------- 1 | function r = repmat(p,varargin) 2 | %overloaded gcmfaces repmat function : 3 | % simply calls double repmat function for each face data 4 | % if the first arguments is a gcmfaces object 5 | % passing over the other arguments 6 | 7 | r=p; 8 | 9 | for iFace=1:r.nFaces; 10 | iF=num2str(iFace); 11 | eval(['r.f' iF '=repmat(p.f' iF ',varargin{:});']); 12 | end; 13 | 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/reshape.m: -------------------------------------------------------------------------------- 1 | function r = reshape(p,varargin) 2 | % RESHAPE Reshape gcmfaces object 3 | % Calls usual reshape for each face in a loop. 4 | % The first two dimensions sizes (that differ amongst faces) 5 | % are left unchanged; the others are set according to the 6 | % input parameter specification (see help reshape). 7 | 8 | r=p; 9 | 10 | for iFace=1:r.nFaces; 11 | iF=num2str(iFace); 12 | eval(['tmpsiz=size(p.f' iF ');']); 13 | if nargin>2; 14 | tmpsiz=[tmpsiz(1:2) varargin{3:end}]; 15 | else; 16 | tmpsiz=[tmpsiz(1:2) varargin{1}(3:end)]; 17 | end; 18 | eval(['r.f' iF '=reshape(p.f' iF ',tmpsiz);']); 19 | end; 20 | 21 | 22 | -------------------------------------------------------------------------------- /@gcmfaces/set.m: -------------------------------------------------------------------------------- 1 | function a = set(a,varargin) 2 | %overloaded gcmfaces set function : 3 | % V = SET(H,'PropertyName',PropertyValue) sets the value of the specified 4 | % attribute (e.g. nFaces and gridType) of a gcmfaces object H. 5 | 6 | propertyArgIn = varargin; 7 | while length(propertyArgIn) >= 2, 8 | propName = propertyArgIn{1}; 9 | val = propertyArgIn{2}; 10 | propertyArgIn = propertyArgIn(3:end); 11 | eval(['a.' propName '=val;']); 12 | end 13 | 14 | -------------------------------------------------------------------------------- /@gcmfaces/sin.m: -------------------------------------------------------------------------------- 1 | function r = sin(p) 2 | %overloaded gcmfaces sin function : 3 | % simply calls double sin function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=sin(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/sind.m: -------------------------------------------------------------------------------- 1 | function r = sind(p) 2 | %overloaded gcmfaces sind function : 3 | % simply calls double sind function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=sind(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/single.m: -------------------------------------------------------------------------------- 1 | function r = single(p) 2 | %overloaded gcmfaces single function : 3 | % simply calls double single function for each face data 4 | 5 | r=p; 6 | for iFace=1:r.nFaces; 7 | iF=num2str(iFace); 8 | eval(['r.f' iF '=single(p.f' iF ');']); 9 | end; 10 | 11 | 12 | -------------------------------------------------------------------------------- /@gcmfaces/sparse.m: -------------------------------------------------------------------------------- 1 | function r = sparse(p,varargin) 2 | %overloaded gcmfaces sparse function : 3 | % simply calls double sparse function for each face data 4 | % if the first arguments is a gcmfaces object 5 | % passing over the other arguments 6 | 7 | r=p; 8 | 9 | for iFace=1:r.nFaces; 10 | iF=num2str(iFace); 11 | eval(['r.f' iF '=sparse(p.f' iF ',varargin{:});']); 12 | end; 13 | 14 | 15 | -------------------------------------------------------------------------------- /@gcmfaces/sqrt.m: -------------------------------------------------------------------------------- 1 | function r = sqrt(p) 2 | %overloaded gcmfaces sqrt function : 3 | % simply calls double sqrt function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=sqrt(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/squeeze.m: -------------------------------------------------------------------------------- 1 | function r = squeeze(p) 2 | %overloaded gcmfaces squeeze function : 3 | % simply calls double squeeze function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=squeeze(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/std.m: -------------------------------------------------------------------------------- 1 | function r = std(p,varargin) 2 | % STD(p,varargin) 3 | % 4 | %overloaded gcmfaces std function : 5 | % 1) if single gcmfaces argument, then returns the global std over all faces 6 | % 2) if more than one argument, then simply calls double std function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=std(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{2}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=std(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=std(tmp1,varargin{1},1); 30 | end; 31 | 32 | 33 | -------------------------------------------------------------------------------- /@gcmfaces/subsasgn.m: -------------------------------------------------------------------------------- 1 | function a = subsasgn(a,index,val) 2 | %overloaded gcmfaces subsasgn function : subscripted assignment according to 3 | % beta{n} will return the n^{th} face data (array). 4 | % beta(:,:,n) will return the n^{th} vertical level (gcmfaces). 5 | % beta.nFaces will return the nFaces attribute (double). 6 | 7 | switch index(1).type 8 | case '{}' 9 | if length(index)>1; 10 | aa=subsref(a,index(1)); val=subsasgn(aa,index(2:end),val); 11 | end; 12 | 13 | nFaces=get(a,'nFaces'); 14 | iFace=index(1).subs{:}; 15 | if iFace<=nFaces&iFace>0; 16 | eval(['a.f' num2str(iFace) '=val;']); 17 | else 18 | error('Index out of range') 19 | end 20 | case '.' 21 | if length(index)>1; 22 | aa=subsref(a,index(1)); val=subsasgn(aa,index(2:end),val); 23 | end; 24 | 25 | a=set(a,index(1).subs,val); 26 | case '()' 27 | if length(index)>1; error('indexing not supported by gcmfaces objects'); end; 28 | 29 | for iFace=1:a.nFaces; iF=num2str(iFace); 30 | if isa(index.subs{1},'gcmfaces'); 31 | if isa(val,'gcmfaces'); 32 | eval(['a.f' iF '(index.subs{1}.f' iF ')=val.f' iF ';']); 33 | else; 34 | eval(['a.f' iF '(index.subs{1}.f' iF ')=val;']); 35 | end; 36 | else; 37 | if isa(val,'gcmfaces'); 38 | eval(['a.f' iF '=subsasgn(a.f' iF ',index,val.f' iF ');']); 39 | else; 40 | eval(['a.f' iF '=subsasgn(a.f' iF ',index,val);']); 41 | end; 42 | end; 43 | end; 44 | otherwise 45 | error('indexing not supported by gcmfaces objects') 46 | end 47 | 48 | %if length(index)>1; b=subsref(b,index(2:end)); end; 49 | 50 | -------------------------------------------------------------------------------- /@gcmfaces/subsref.m: -------------------------------------------------------------------------------- 1 | function b = subsref(a,index) 2 | %overloaded gcmfaces subsref function : subscripted reference according to 3 | % beta{n} will return the n^{th} face data (array). 4 | % beta(:,:,n) will return the n^{th} vertical level (gcmfaces). 5 | % beta.nFaces will return the nFaces attribute (double). 6 | 7 | switch index(1).type 8 | case '{}' 9 | nFaces=get(a,'nFaces'); 10 | iFace=index(1).subs{:}; 11 | if iFace<=nFaces&iFace>0; 12 | eval(['b=a.f' num2str(iFace) ';']); 13 | else 14 | error('Index out of range') 15 | end 16 | 17 | if length(index)>1; b=subsref(b,index(2:end)); end; 18 | case '.' 19 | b = get(a,index(1).subs); 20 | 21 | if length(index)>1; b=subsref(b,index(2:end)); end; 22 | case '()' 23 | if length(index)>1; error('indexing not supported by gcmfaces objects'); end; 24 | 25 | b=a; 26 | for iFace=1:a.nFaces; iF=num2str(iFace); 27 | if isa(index.subs{1},'gcmfaces'); 28 | eval(['b.f' iF '=a.f' iF '(index.subs{1}.f' iF ');']); 29 | else; 30 | eval(['b.f' iF '=subsref(a.f' iF ',index);']); 31 | end; 32 | end; 33 | otherwise 34 | error('indexing not supported by gcmfaces objects') 35 | end 36 | 37 | 38 | -------------------------------------------------------------------------------- /@gcmfaces/sum.m: -------------------------------------------------------------------------------- 1 | function r = sum(p,varargin); 2 | % SUM(p,varargin) 3 | % 4 | %overloaded gcmfaces sum function : 5 | % 1) if single gcmfaces argument, then returns the global sum over all faces 6 | % 2) if more than one argument, then simply calls double sum function for 7 | % each face data, passing over the other arguments 8 | 9 | if nargin==1; 10 | tmp1=[]; 11 | for iFace=1:p.nFaces; 12 | iF=num2str(iFace); 13 | eval(['tmp1=[tmp1;p.f' iF '(:)];']); 14 | end; 15 | r=sum(tmp1); 16 | return; 17 | end; 18 | 19 | if varargin{1}>0; 20 | r=p; 21 | for iFace=1:r.nFaces; 22 | iF=num2str(iFace); 23 | eval(['r.f' iF '=sum(p.f' iF ',varargin{:});']); 24 | end; 25 | else; 26 | tmp1=convert2gcmfaces(p); 27 | [n1,n2,n3,n4]=size(tmp1); 28 | tmp1=reshape(tmp1,n1*n2,n3,n4); 29 | r=sum(tmp1,1); 30 | end; 31 | 32 | -------------------------------------------------------------------------------- /@gcmfaces/tan.m: -------------------------------------------------------------------------------- 1 | function r = tan(p) 2 | %overloaded gcmfaces tan function : 3 | % simply calls double tan function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=tan(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/tand.m: -------------------------------------------------------------------------------- 1 | function r = tand(p) 2 | %overloaded gcmfaces tand function : 3 | % simply calls double tand function for each face data 4 | 5 | r=p; 6 | 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | eval(['r.f' iF '=tand(p.f' iF ');']); 10 | end; 11 | 12 | 13 | -------------------------------------------------------------------------------- /@gcmfaces/times.m: -------------------------------------------------------------------------------- 1 | function r = times(p,q) 2 | %overloaded gcmfaces times function : 3 | % simply calls double times function for each face data 4 | % if any of the two arguments is a gcmfaces object 5 | 6 | if isa(p,'gcmfaces'); r=p; else; r=q; end; 7 | for iFace=1:r.nFaces; 8 | iF=num2str(iFace); 9 | if isa(p,'gcmfaces')&isa(q,'gcmfaces'); 10 | eval(['r.f' iF '=p.f' iF '.*q.f' iF ';']); 11 | elseif isa(p,'gcmfaces')&isa(q,'double'); 12 | eval(['r.f' iF '=p.f' iF '.*q;']); 13 | elseif isa(p,'double')&isa(q,'gcmfaces'); 14 | eval(['r.f' iF '=p.*q.f' iF ';']); 15 | else; 16 | error('gcmfaces times: types are incompatible') 17 | end; 18 | end; 19 | 20 | 21 | -------------------------------------------------------------------------------- /@gcmfaces/uminus.m: -------------------------------------------------------------------------------- 1 | function r = uminus(p) 2 | %overloaded gcmfaces uminus function : 3 | % simply calls double uminus function for each face data 4 | 5 | r=p; 6 | for iFace=1:r.nFaces; 7 | iF=num2str(iFace); 8 | eval(['r.f' iF '=-p.f' iF ';']); 9 | end; 10 | 11 | 12 | -------------------------------------------------------------------------------- /@gcmfaces/uplus.m: -------------------------------------------------------------------------------- 1 | function r = uplus(p) 2 | %overloaded gcmfaces uplus function : 3 | % simply calls double uplus function for each face data 4 | 5 | r=p; 6 | for iFace=1:r.nFaces; 7 | iF=num2str(iFace); 8 | eval(['r.f' iF '=+p.f' iF ';']); 9 | end; 10 | 11 | 12 | -------------------------------------------------------------------------------- /@gcmfaces/zeros.m: -------------------------------------------------------------------------------- 1 | function r = zeros(p,varargin) 2 | %overloaded gcmfaces zeros function : 3 | % if the first arguments is a gcmfaces object 4 | % we call the double zeros function for each face data 5 | % using face dimensions for the first two arguments and 6 | % passing over the other arguments 7 | 8 | r=p; 9 | 10 | for iFace=1:r.nFaces; 11 | iF=num2str(iFace); 12 | eval(['[n1,n2]=size(p.f' iF '(:,:,1));']); 13 | eval(['r.f' iF '=zeros(n1,n2,varargin{:});']); 14 | end; 15 | 16 | 17 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Gael Forget and Contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gcmfaces 2 | 3 | [This repository][] contains the gcmfaces Matlab / Octave toolbox and [its documentation](http://gcmfaces.readthedocs.io/). For user support, if needed, contact or . Citation for this repository: 4 | 5 | [![DOI](https://zenodo.org/badge/62541910.svg)](https://zenodo.org/badge/latestdoi/62541910) 6 | 7 | [This repository]: https://github.com/gaelforget/gcmfaces 8 | 9 | **gcmfaces** is a Matlab toolbox designed to analyze results of [MITgcm](http://mitgcm.org/) simulations, including [ECCOv4 solutions](http://eccov4.readthedocs.io/), and to handle gridded earth variables in generic fashion (Forget et al 2015). It allows users to seamlessly deal with various gridding approaches (e.g., all grids distributed via [this FTP server](ftp://mit.ecco-group.org/ecco_for_las/version_4/grids/)) using compact and generic codes as explained in [the toolbox documentation](http://gcmfaces.readthedocs.io/). It includes many basic and more evolved functionalities for plotting global maps, computing transports and budgets, etc. as illustrated by [gcmfaces_demo.m](gcmfaces_demo.m) and the standard analysis (see Forget et al., 2015, 2016). 10 | 11 | Forget, G., J.-M. Campin, P. Heimbach, C. N. Hill, R. M. Ponte, and C. Wunsch, 2015: ECCO version 4: an integrated framework for nonlinear inverse modeling and global ocean state estimation. Geoscientific Model Development, 8 (10), 3071–3104, doi:10.5194/gmd-8-3071-2015, URL 12 | 13 | Forget, G., J.-M. Campin, P. Heimbach, C. N. Hill, R. M. Ponte, and C. Wunsch, 2016: ECCO Version 4: Second Release, http://hdl.handle.net/1721.1/102062, URL 14 | 15 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = gcmfaces 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/biblirefs.rst: -------------------------------------------------------------------------------- 1 | .. _references: 2 | 3 | .. only:: html 4 | 5 | References 6 | ********** 7 | 8 | .. bibliography:: bibli.bib 9 | :all: 10 | 11 | -------------------------------------------------------------------------------- /docs/figs/fig12-eccov4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITgcm/gcmfaces/0b9132b739bb88c07de9398ffbda09505ba25d83/docs/figs/fig12-eccov4.pdf -------------------------------------------------------------------------------- /docs/figs/plot_m_map.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITgcm/gcmfaces/0b9132b739bb88c07de9398ffbda09505ba25d83/docs/figs/plot_m_map.pdf -------------------------------------------------------------------------------- /docs/figs/sphere_all.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITgcm/gcmfaces/0b9132b739bb88c07de9398ffbda09505ba25d83/docs/figs/sphere_all.pdf -------------------------------------------------------------------------------- /docs/gcmfaces_demo_dirtree.rst: -------------------------------------------------------------------------------- 1 | 2 | :: 3 | 4 | gcmfaces/ (Matlab / Octave toolbox) 5 | MITprof/ (Matlab / Octave toolbox) 6 | m_map/ (Matlab / Octave toolbox) 7 | nctiles_grid/ (downloaded data) 8 | release2_climatology/ 9 | nctiles_climatology/ (downloaded data) 10 | mat/ (created by software) 11 | tex/ (created by software) 12 | release2/ 13 | nctiles_monthly/ (downloaded data) 14 | nctiles_remotesensing/ (downloaded data) 15 | profiles/ (downloaded data) 16 | mat/ (created by software) 17 | tex/ (created by software) 18 | 19 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. gcmfaces documentation master file, created by 2 | sphinx-quickstart on Tue Jan 16 02:04:13 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to gcmfaces' documentation! 7 | =================================== 8 | 9 | .. A Generic Treatment Of Gridded Earth Variables In Matlab And Octave. 10 | 11 | Here, you will learn about the `gcmfaces` toolbox that provides a generic 12 | treatment of gridded Earth variables in Matlab and Octave. 13 | 14 | The `gcmfaces` toolbox handles gridded Earth variables as sets of connected 15 | arrays. This object-oriented approach allows users to 16 | write generic, compact analysis codes that readily become applicable 17 | to a wide variety of grids (e.g., those in :numref:`sphere_all`). 18 | `gcmfaces` notably allows for analysis of MITgcm output on any of its 19 | `familiar grids `__. 20 | It was originally developed as part the `ECCO version 4` framework along with 21 | the companion `MITprof` toolbox that handles unevenly 22 | distributed in-situ ocean observations :cite:`for-eta:15`. 23 | 24 | This user manual provides an installation guide for `gcmfaces` and `MITprof` 25 | (:numref:`install`), a documentation of the basic `gcmfaces` features 26 | (:numref:`features`), and an overview of higher-level `gcmfaces` functionalities 27 | for mapping, transport, etc. operations (:numref:`demo` and :numref:`standard`). 28 | 29 | .. toctree:: 30 | :maxdepth: 3 31 | :caption: Contents 32 | :numbered: 4 33 | 34 | prep_install.rst 35 | prep_basic.rst 36 | prep_demo.rst 37 | prep_diags.rst 38 | biblirefs.rst 39 | 40 | Sample grids 41 | ============ 42 | 43 | .. figure:: figs/sphere_all.pdf 44 | :width: 95% 45 | :align: center 46 | :alt: TBD 47 | :name: sphere_all 48 | 49 | Four approaches to gridding the Earth which are all commonly used in numerical models. Top left: lat-lon grid; mapping the Earth to a single rectangular array (`face`). Top right: cube-sphere grid; mapping the earth to the six faces of a cube. Bottom right: lat-lon-cap, `LLC`, grid (five faces). Bottom left: quadripolar grid (four faces). In this depiction, faces are color-coded, only grid line subsets are shown, and gaps are introduced between faces to highlight the defining characteristics of each grid. 50 | 51 | Indices and tables 52 | ================== 53 | 54 | * :ref:`genindex` 55 | * :ref:`modindex` 56 | * :ref:`search` 57 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=gcmfaces 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/prep_demo.rst: -------------------------------------------------------------------------------- 1 | .. _demo: 2 | 3 | Tutorial Examples 4 | ================= 5 | 6 | To proceed with the tutorial examples, user is expected to have completed the software 7 | installation and data downloads from :numref:`install` (including 8 | ``nctiles_climatology/`` and ``m_map/``). The full suite of tutorial examples 9 | can then be executed via ``gcmfaces_demo.m`` by opening Matlab and typing 10 | 11 | :: 12 | 13 | p = genpath('gcmfaces/'); addpath(p); 14 | p = genpath('m_map/'); addpath(p); 15 | gcmfaces_demo; 16 | 17 | As prompted by ``gcmfaces_demo.m``, specify the desired amount of explanatory 18 | text output. Various examples then proceed and display comments in 19 | the Matlab or Octave command window. The Matlab GUI and debugger can also 20 | be used to run each example line by line. This can be useful to learn more 21 | about the inner workings of `gcmfaces` functions. 22 | 23 | The first section in ``gcmfaces_demo.m`` illustrates I/O and plotting 24 | capabilities (``grid_load.m`` and ``example_display.m``). The second 25 | section focuses on data processing capabilities such 26 | as interpolation and smoothing. 27 | ``example_interp.m`` interpolates fields to a lat-lon grid and vice versa. 28 | ``example_smooth.m`` integrates a diffusion equation which involves tracer 29 | gradient and flux convergence computations. The final section in 30 | ``gcmfaces_demo.m`` computes oceanic transports (``example_transports.m``). 31 | 32 | .. figure:: figs/plot_m_map.pdf 33 | :width: 95% 34 | :align: center 35 | :alt: Ocean topography on the LLC90 grid displayed in geographical coordinates 36 | :name: plot_one_field_M_MAP 37 | 38 | Same as :numref:`plot_one_field_FACES` but 39 | plotted in geographical coordinates using ``m_map_gcmfaces.m``. This plot 40 | is generated by calling example_display(4). 41 | 42 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx_rtd_theme 3 | sphinxcontrib-bibtex>=2 4 | sphinxcontrib-programoutput 5 | -------------------------------------------------------------------------------- /ecco_v4/gcmfaces_remap.m: -------------------------------------------------------------------------------- 1 | function []=gcmfaces_remap(dirIn,fileIn,gridIn,dirOut,fileOut); 2 | %object: use bin average to remap a lat-lon grid product to a gcmfaces grid 3 | %inputs: dirIn is the input directory 4 | % fileIn is the input file name without the final four year characters 5 | % (e.g. 'SST_monthly_r2_' to process 'SST_monthly_r2_1992' etc.) 6 | % gridIn states the originating grid. It can be set to 7 | % 1 implying that the grid is [0.5:359.5] & [-89.5:89.5] 8 | % 2 implying that the grid is [0.5:359.5] & [-79.5:79.5] 9 | % 3 implying that the grid is [.125:.25:360-.125] & [-90+.125:.25:90-.125] 10 | % {x,y} where x and y are the position arrays 11 | % dirOut and filOut are the corresponding output names 12 | % 13 | %assumption: mygrid has been read using grid_load 14 | % for the input grid, lon must be 0-360 (see gcmfaces_remap_2d) 15 | 16 | global mygrid mytri; 17 | %create triangulation 18 | gcmfaces_bindata; 19 | %list files to be processed 20 | listFiles=dir([dirIn fileIn '*']); 21 | 22 | %case of user defined grid 23 | if iscell(gridIn); x=gridIn{1}; y=gridIn{2}; [nx,ny]=size(x); mis=0; 24 | else; 25 | %standard cases 26 | if gridIn==1;%gloabl 1 degree grid 27 | x=[0.5:359.5]'*ones(1,180); 28 | y=ones(360,1)*[-89.5:89.5]; 29 | [nx,ny]=size(x); 30 | mis=0; 31 | elseif gridIn==2;%ECCO 1 degree grid 32 | x=[0.5:359.5]'*ones(1,160); 33 | y=ones(360,1)*[-79.5:79.5]; 34 | [nx,ny]=size(x); 35 | mis=0; 36 | elseif gridIn==3;%1/4 degree grid (e.g. REMSS) 37 | x=[.125:.25:360-.125]'*ones(1,180*4); 38 | y=ones(360*4,1)*[-90+.125:.25:90-.125]; 39 | [nx,ny]=size(x); 40 | mis=-9999; 41 | else; 42 | error('unknown grid'); 43 | end; 44 | end; 45 | 46 | %process one file after the other 47 | for ii=1:length(listFiles); 48 | yy=listFiles(ii).name(end-3:end); fprintf(['processing ' fileIn ' for year ' yy '\n']); 49 | nt=listFiles(ii).bytes/nx/ny/4; if round(nt)~=nt; error('inconsistent sizes'); end; 50 | %read data 51 | fld=reshape(read2memory([dirIn listFiles(ii).name],[nx*ny*nt 1]),[nx ny nt]); 52 | %mask land 53 | fld(fld==mis)=NaN; 54 | %map to v4 grid 55 | FLD=convert2array(zeros(360,360,nt)); 56 | for tt=1:nt; FLD(:,:,tt)=gcmfaces_remap_2d(x,y,fld(:,:,tt),3); end; 57 | %set missing value 58 | FLD(find(isnan(FLD)))=mis; 59 | %write data 60 | write2file([dirOut fileOut yy],convert2gcmfaces(FLD)); 61 | end; 62 | 63 | -------------------------------------------------------------------------------- /ecco_v4/map_grace.m: -------------------------------------------------------------------------------- 1 | 2 | xC1=[0.5:359.5]'*ones(1,180); 3 | yC1=ones(360,1)*[-89.5:89.5]; 4 | v4_reclen=convert2gcmfaces(mygrid.RAC); v4_reclen=size(v4_reclen); v4_reclen=v4_reclen(1)*v4_reclen(2); 5 | 6 | dir_out='./'; %output directory 7 | dir_in='./'; %input directory 8 | file_pref='GRACE_CSR_withland_'; 9 | 10 | %load error field 11 | [fieldErr_nosmooth,fieldErr]=read_grace_fld([dir_in 'GRACE_CSR_Error.asc']); 12 | 13 | %process grace fields 14 | for yy=1992:2012; 15 | for mm=1:12; 16 | tt=sprintf('%4i%02i',yy,mm); 17 | 18 | file0=dir([dir_in file_pref tt '.asc']); 19 | if ~isempty(file0); 20 | 21 | %read 22 | file0=file0.name; 23 | field0=read_grace_fld([dir_in file0]); 24 | 25 | %map 26 | x=[xC1-360;xC1]; y=[yC1;yC1]; z=[field0;field0]; 27 | x=[x x x]; y=[y-180 y y+180]; z=[flipdim(z,2) z flipdim(z,2)]; 28 | 29 | field1=0*mygrid.XC; 30 | for ii=1:5; 31 | xi=mygrid.XC{ii}; yi=mygrid.YC{ii}; 32 | zi = interp2(x',y',z',xi,yi); 33 | %zi = griddata(x,y,z,xi,yi); 34 | field1{ii}=zi; 35 | end; 36 | 37 | %mask the model poles 38 | tmp1=find(mygrid.RAC<8e8&mygrid.YC>0); field1(tmp1)=NaN; 39 | tmp1=find(mygrid.RAC<2e8&mygrid.YC<0); field1(tmp1)=NaN; 40 | 41 | else; 42 | fprintf(['did not find : ' file_pref tt '.asc \n']); 43 | field1=NaN*mygrid.RAC; 44 | end; 45 | 46 | %use -999 for mask 47 | field1(isnan(field1))=-999; 48 | 49 | %write to file 50 | if mm==1; fid=fopen([dir_out file_pref num2str(yy)],'w','b'); end; 51 | fwrite(fid,convert2gcmfaces(field1),'float32'); 52 | if mm==12; fclose(fid); end; 53 | 54 | end; 55 | end; 56 | 57 | %process error estimate 58 | z=[fieldErr;fieldErr]; z=[flipdim(z,2) z flipdim(z,2)]; 59 | 60 | field1=0*mygrid.XC; 61 | for ii=1:5; 62 | xi=mygrid.XC{ii}; yi=mygrid.YC{ii}; 63 | zi = interp2(x',y',z',xi,yi); 64 | %zi = griddata(x,y,z,xi,yi); 65 | field1{ii}=zi; 66 | end; 67 | 68 | %mask the model poles 69 | tmp1=find(mygrid.RAC<8e8&mygrid.YC>0); field1(tmp1)=NaN; 70 | tmp1=find(mygrid.RAC<2e8&mygrid.YC<0); field1(tmp1)=NaN; 71 | 72 | %use 0 for mask 73 | field1(isnan(field1))=0; 74 | 75 | %write to file 76 | write2file([dir_out file_pref 'err'],convert2gcmfaces(field1)); 77 | 78 | -------------------------------------------------------------------------------- /ecco_v4/read_grace_fld.m: -------------------------------------------------------------------------------- 1 | function [fld,fldsm]=read_grace_fld(fname); 2 | 3 | %[fld]=read_grace_fld('GRACE_CSR_Error.asc'); 4 | 5 | fid=fopen(fname,'rt'); 6 | fgetl(fid); 7 | fgetl(fid); 8 | 9 | fld4columns=zeros(1e5,4); 10 | ii=1; 11 | while ~feof(fid); 12 | fld4columns(ii,:)=str2num(fgetl(fid)); 13 | ii=ii+1; 14 | end; 15 | fclose(fid); 16 | 17 | ii=find(fld4columns(:,2)>0&fld4columns(:,2)<360); 18 | jj=(fld4columns(ii,1)+89.5)*360+fld4columns(ii,2)+0.5; 19 | fld=NaN*zeros(360,180); 20 | fld(jj)=fld4columns(ii,3); 21 | fldsm=NaN*zeros(360,180); 22 | fldsm(jj)=fld4columns(ii,4); 23 | 24 | 25 | -------------------------------------------------------------------------------- /ecco_v4/v4_basin.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITgcm/gcmfaces/0b9132b739bb88c07de9398ffbda09505ba25d83/ecco_v4/v4_basin.bin -------------------------------------------------------------------------------- /ecco_v4/v4_read_data.m: -------------------------------------------------------------------------------- 1 | function [fld]=v4_read_data(fileName,irec); 2 | %usage: fld=v4_read_data(fileName,irec); 'fast' read of 2D fields no irec in all [fileName '*.data'] 3 | 4 | gcmfaces_global; 5 | 6 | dir0=strfind(fileName,filesep); if isempty(dir0); dir0='./'; else; dir0=fileName(1:dir0(end)); end; 7 | fileList=dir([fileName '.data']); 8 | 9 | nn=length(fileList); 10 | fld=zeros(90,1170,nn); 11 | for ii=1:nn; 12 | fid_cur=fopen([dir0 fileList(ii).name],'r','b'); 13 | recl=90*1170*4; position0=recl*(irec-1); 14 | status=fseek(fid_cur,position0,'bof'); 15 | fld(:,:,ii)=fread(fid_cur,[90 1170],'float32'); 16 | fclose(fid_cur); 17 | end; 18 | 19 | fld=convert2gcmfaces(fld); 20 | 21 | -------------------------------------------------------------------------------- /gcmfaces.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITgcm/gcmfaces/0b9132b739bb88c07de9398ffbda09505ba25d83/gcmfaces.pdf -------------------------------------------------------------------------------- /gcmfaces_IO/check_mygrid.m: -------------------------------------------------------------------------------- 1 | 2 | %expected result: 3 | % 4 | %difference in dirGrid 5 | %difference in fileFormat 6 | %difference in RF 7 | %structure LATS_MASKS remains to be checked 8 | %structure LINES_MASKS remains to be checked 9 | 10 | clear all; 11 | 12 | load mygrid_nctiles.mat; 13 | %load mygrid_new.mat; 14 | mygrid1=mygrid; mygrid=[]; 15 | load mygrid_old.mat; 16 | mygrid2=mygrid; mygrid=[]; 17 | 18 | list1=fieldnames(mygrid1); 19 | list2=fieldnames(mygrid2); 20 | if length(list1)~=length(list2); 21 | error('missing variables'); 22 | end; 23 | 24 | for ii=1:length(list1); 25 | if sum(strcmp(list2,list1{ii}))~=1; 26 | error('missing variable'); 27 | end; 28 | tmp1=getfield(mygrid1,list1{ii}); 29 | tmp2=getfield(mygrid2,list1{ii}); 30 | if ischar(tmp1); 31 | if ~strcmp(tmp1,tmp2); fprintf(['\n difference in ' list1{ii} '\n']); end; 32 | elseif isstruct(tmp1); 33 | fprintf(['\n structure ' list1{ii} ' remains to be checked\n']); 34 | %disp(tmp1); disp(tmp2); 35 | elseif isnumeric(tmp1); 36 | if sum(size(tmp1)~=size(tmp2))>0; 37 | fprintf(['\n size difference in ' list1{ii} '\n']); 38 | else; 39 | tmp3=max(abs(tmp1(:)-tmp2(:))); 40 | tmp4=max(abs(isnan(tmp1(:))-isnan(tmp2(:)))); 41 | if tmp3~=0|tmp4~=0; fprintf(['\n difference in ' list1{ii} '\n']); end; 42 | end; 43 | elseif islogical(tmp1)|isa(tmp1,'gcmfaces'); 44 | tmp3=max(abs(tmp1(:)-tmp2(:))); 45 | tmp4=max(abs(isnan(tmp1(:))-isnan(tmp2(:)))); 46 | if tmp3~=0|tmp4~=0; fprintf(['\n difference in ' list1{ii} '\n']); end; 47 | else; 48 | error('missing type'); 49 | end; 50 | end; 51 | 52 | -------------------------------------------------------------------------------- /gcmfaces_IO/convert2widefaces.m: -------------------------------------------------------------------------------- 1 | function [v0]=convert2widefaces(v0); 2 | %object: when mygrid.facesSize is non standard (i.e. 3 | % some faces were troncated in the files) this 4 | % routine expands them back to dimensions that 5 | % allow e.g. the exchanges to work 6 | 7 | gcmfaces_global; 8 | 9 | if ~isempty(mygrid.facesExpand); 10 | 11 | nn=mygrid.facesExpand(1); mm=mygrid.facesExpand(2); 12 | widefacesSize=[[nn mm];[nn mm];[nn nn];[mm nn];[mm nn]]; 13 | 14 | v0facesSize=[size(v0{1});size(v0{2});size(v0{3});size(v0{4});size(v0{5})]; 15 | v0facesSize=v0facesSize(:,1:2); 16 | 17 | test0=0 3'); 30 | end 31 | end; 32 | 33 | 34 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncatts.m: -------------------------------------------------------------------------------- 1 | function [atts]=ncatts(ncid,varid); 2 | %input: ncid is a netcdf file id 3 | % varid is a netcdf variable id 4 | %output: atts is the list of its attributes name (in cell) 5 | 6 | [varname,xtype,dimids,natts] = netcdf.inqVar(ncid,varid); 7 | 8 | for ii=1:natts; 9 | aa=netcdf.inqAttName(ncid,varid,ii-1); 10 | if ii==1; atts={aa}; else; atts=[atts aa]; end; 11 | end; 12 | 13 | if natts==0; atts=[]; end; 14 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncclose.m: -------------------------------------------------------------------------------- 1 | function [] = ncclose(ncid); 2 | % close a netcdf file. 3 | 4 | global useNativeMatlabNetcdf; 5 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 6 | 7 | 8 | if useNativeMatlabNetcdf; 9 | netcdf.close(ncid); 10 | else;%try to use old mex stuff 11 | close(ncid); 12 | end; 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /gcmfaces_IO/nccreateFile.m: -------------------------------------------------------------------------------- 1 | function [nc] = nccreateFile(theNetCDFFile, varargin); 2 | % create a new netcdf file. 3 | % mode: 'write','nowrite' 4 | 5 | global useNativeMatlabNetcdf; 6 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 7 | 8 | mode='NC_NOCLOBBER'; 9 | if nargin>1, 10 | mode=varargin{1}; 11 | end 12 | 13 | if useNativeMatlabNetcdf; 14 | nc=netcdf.create(theNetCDFFile,mode); 15 | else;%try to use old mex stuff 16 | nc=netcdf(theNetCDFFile,mode); 17 | end; 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncdefDim.m: -------------------------------------------------------------------------------- 1 | function ncdefDim(ncid,dimname,dimlen); 2 | % add a dimension in a netcdf file. 3 | 4 | global useNativeMatlabNetcdf; 5 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 6 | 7 | if useNativeMatlabNetcdf; 8 | netcdf.defDim(ncid,dimname,dimlen); 9 | else;%try to use old mex stuff 10 | eval(sprintf('ncid(''%s'')=%d;',dimname,dimlen)); 11 | end; 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncdefVar.m: -------------------------------------------------------------------------------- 1 | function varid = ncdefVar(ncid,varname,xtype,dimlist); 2 | % add a variable in a netcdf file. 3 | 4 | global useNativeMatlabNetcdf; 5 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 6 | 7 | if useNativeMatlabNetcdf; 8 | if isempty(dimlist), error('ncdefVar error: no dimension allocated'); end 9 | iDim=[]; 10 | for ii=1:length(dimlist), 11 | iDim(ii)=netcdf.inqDimID(ncid,dimlist{ii}); 12 | end 13 | netcdf.defVar(ncid,varname,xtype,iDim); 14 | else;%try to use old mex stuff 15 | % inverse the order of list dimensions 16 | dimlist=fliplr(dimlist); 17 | switch length(dimlist) 18 | case 1, 19 | eval(sprintf('ncid{''%s''}=nc%s(''%s'');',varname,xtype,dimlist{1})); 20 | case 2, 21 | eval(sprintf('ncid{''%s''}=nc%s(''%s'',''%s'');',varname,xtype,dimlist{1},dimlist{2})); 22 | case 3, 23 | eval(sprintf('ncid{''%s''}=nc%s(''%s'',''%s'',''%s'');',varname,xtype,dimlist{1},dimlist{2},dimlist{3})); 24 | otherwise 25 | error('ncdefVar: number of dimension > 3'); 26 | end 27 | end; 28 | 29 | 30 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncgetFillVal.m: -------------------------------------------------------------------------------- 1 | function [FillVal]=ncgetFillVal(ncid,varname); 2 | % [FillVal]=ncgetFillVal(ncid,varname) 3 | % return the missing_value or _FillValue of varname 4 | % return an error if varname does not exist 5 | 6 | global useNativeMatlabNetcdf; 7 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 8 | 9 | FillVal=[]; 10 | if useNativeMatlabNetcdf; 11 | varid = netcdf.inqVarID(ncid,varname); 12 | [varname,xtype,dimids,natts] = netcdf.inqVar(ncid,varid); 13 | [atts]=ncatts(ncid,varid); 14 | if any(ismember(atts,'missing_value')) 15 | FillVal = netcdf.getAtt(ncid,varid,'missing_value'); 16 | elseif any(ismember(atts,'_FillValue')) 17 | FillVal = netcdf.getAtt(ncid,varid,'_FillValue'); 18 | end 19 | if strcmp(xtype,'single') | strcmp(xtype,'double') 20 | FillVal=double(FillVal); 21 | end 22 | else 23 | eval(['FillVal = ncid{''' varname '''}.missing_value(:);']); 24 | if isempty(FillVal); 25 | eval(['FillVal = ncid{''' varname '''}.FillValue_(:);']); 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncgetvar.m: -------------------------------------------------------------------------------- 1 | function [VARvalue]=ncgetvar(nc,VARname,varargin) 2 | % function [VARvalue]=ncgetvar(nc,VARname, [index_prof, index_depth] ) 3 | % get data to MITprof netcdf file 4 | 5 | global useNativeMatlabNetcdf; 6 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 7 | 8 | if useNativeMatlabNetcdf 9 | 10 | %get variable id: 11 | vv = netcdf.inqVarID(nc,VARname); 12 | if nargin>2; 13 | %get and flip position vectors: 14 | VARpos=fliplr(varargin); 15 | %convert VARpos to start,count: 16 | start=[]; count=[]; 17 | for ii=1:length(VARpos); 18 | start=[start VARpos{ii}(1)-1]; 19 | count=[count VARpos{ii}(end)-VARpos{ii}(1)+1]; 20 | end; 21 | %write to file: 22 | VARvalue=netcdf.getVar(nc,vv,start,count); 23 | else; 24 | %write to file: 25 | VARvalue=netcdf.getVar(nc,vv); 26 | end; 27 | %flip order of dimensions: 28 | bb=length(size(VARvalue)); VARvalue=permute(VARvalue,[bb:-1:1]); 29 | 30 | 31 | else;%try to use old mex stuff 32 | 33 | if nargin==3; 34 | eval(['VARvalue=nc{''' VARname '''}([' num2str(varargin{1}) ']);']); 35 | elseif nargin==4, 36 | eval(['VARvalue=nc{''' VARname '''}([' num2str(varargin{1}) '],[' num2str(varargin{2}) ']);']); 37 | else; 38 | eval(['VARvalue=nc{''' VARname '''}(:);']); 39 | end; 40 | 41 | end; 42 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncopen.m: -------------------------------------------------------------------------------- 1 | function [nc] = ncopen(theNetCDFFile, varargin); 2 | % open a netcdf file. 3 | % mode: 'write','nowrite' 4 | 5 | global useNativeMatlabNetcdf; 6 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 7 | 8 | mode=0; 9 | if nargin>1, 10 | mode=varargin{1}; 11 | end 12 | 13 | if useNativeMatlabNetcdf; 14 | nc=netcdf.open(theNetCDFFile,mode); 15 | else;%try to use old mex stuff 16 | if mode==0, 17 | nc=netcdf(theNetCDFFile); 18 | else 19 | nc=netcdf(theNetCDFFile,mode); 20 | end 21 | end; 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncputAtt.m: -------------------------------------------------------------------------------- 1 | function [nc] = ncputAtt(ncid,varname,attrname,attrvalue); 2 | % add an attribute to a variable in a netcdf file. 3 | 4 | global useNativeMatlabNetcdf; 5 | if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 6 | 7 | if isempty(varname), 8 | if useNativeMatlabNetcdf; 9 | netcdf.putAtt(ncid,-1,attrname,attrvalue); 10 | else;%try to use old mex stuff 11 | if ischar(attrvalue) 12 | attrvalue(find(double(attrvalue)==10))=[]; 13 | eval(['ncid.' attrname '=''' attrvalue ''';']); 14 | else 15 | eval(['ncid.' attrname '=' num2str(attrvalue) ';']); 16 | end 17 | end; 18 | else 19 | if useNativeMatlabNetcdf; 20 | varid=netcdf.inqVarID(ncid,varname); 21 | netcdf.putAtt(ncid,varid,attrname,attrvalue); 22 | else;%try to use old mex stuff 23 | if strcmp(attrname,'_FillValue'), 24 | attrname='FillValue_'; 25 | end 26 | if ischar(attrvalue) 27 | attrvalue(find(double(attrvalue)==10))=[]; 28 | eval(['ncid{''' varname '''}.' attrname '=''' attrvalue ''';']); 29 | else 30 | eval(['ncid{''' varname '''}.' attrname '=' num2str(attrvalue) ';']); 31 | end 32 | end; 33 | end 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncputvar.m: -------------------------------------------------------------------------------- 1 | function []=ncputvar(nc,VARname,VARvalue,varargin); 2 | % []=ncputvar(ncid,varid,data,start,count) 3 | % write data to MITprof netcdf file 4 | 5 | global useNativeMatlabNetcdf; if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 6 | 7 | if useNativeMatlabNetcdf 8 | 9 | %get variable id: 10 | vv = netcdf.inqVarID(nc,VARname); 11 | %flip order of dimensions: 12 | bb=length(size(VARvalue)); VARvalue=permute(VARvalue,[bb:-1:1]); 13 | if nargin>3; 14 | %get and flip position vectors: 15 | start=fliplr(varargin{1}); 16 | count=fliplr(varargin{2}); 17 | %convert VARpos to start,count: 18 | % start=[]; count=[]; 19 | % for ii=1:length(VARpos{1}); 20 | % start=[start VARpos{ii}(1)-1]; 21 | % count=[count VARpos{ii}(end)-VARpos{ii}(1)+1]; 22 | % end; 23 | %write to file: 24 | netcdf.putVar(nc,vv,start,count,VARvalue); 25 | else; 26 | %write to file: 27 | netcdf.putVar(nc,vv,VARvalue); 28 | end; 29 | 30 | 31 | else;%try to use old mex stuff 32 | 33 | if nargin==4; 34 | eval(['nc{''' VARname '''}([' num2str(varargin{1}) '])=VARvalue;']); 35 | elseif nargin==5, 36 | eval(['nc{''' VARname '''}([' num2str(varargin{1}) '],[' num2str(varargin{2}) '])=VARvalue;']); 37 | else; 38 | eval(['nc{''' VARname '''}(:)=VARvalue;']); 39 | end; 40 | 41 | end; 42 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncsave.m: -------------------------------------------------------------------------------- 1 | function [] = ncsave(theNetCDFFile, varargin); 2 | 3 | global useNativeMatlabNetcdf; if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 4 | 5 | if useNativeMatlabNetcdf; 6 | nc=netcdf.open(theNetCDFFile,'write'); 7 | else;%try to use old mex stuff 8 | nc=netcdf(theNetCDFFile,'write'); 9 | end; 10 | 11 | for ii=1:nargin-1; 12 | nameCur=inputname(ii+1); 13 | if useNativeMatlabNetcdf; 14 | vv = netcdf.inqVarID(nc,nameCur); netcdf.putVar(nc,vv,varargin{ii}'); 15 | else;%try to use old mex stuff 16 | nc{nameCur}(:)=varargin{ii}; 17 | end; 18 | end; 19 | 20 | 21 | if useNativeMatlabNetcdf; 22 | netcdf.close(nc); 23 | else;%try to use old mex stuff 24 | close(nc); 25 | end; 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gcmfaces_IO/ncvars.m: -------------------------------------------------------------------------------- 1 | function [vars]=ncvars(ncid); 2 | %input: ncid is a netcdf file id 3 | %output: vars is the list of its variables name (in cell) 4 | 5 | global useNativeMatlabNetcdf; if isempty(useNativeMatlabNetcdf); useNativeMatlabNetcdf = ~isempty(which('netcdf.open')); end; 6 | 7 | if useNativeMatlabNetcdf; 8 | 9 | [numdims, numvars, numglobalatts, unlimdimID] = netcdf.inq(ncid); 10 | for ii=1:numvars; 11 | aa=netcdf.inqVar(ncid,ii-1); 12 | if ii==1; vars={aa}; else; vars=[vars aa]; end; 13 | end; 14 | 15 | else;%try to use old mex stuff 16 | vars=ncnames(var(ncid)); 17 | end; 18 | -------------------------------------------------------------------------------- /gcmfaces_IO/process2UVSTAR.m: -------------------------------------------------------------------------------- 1 | function []=process2UVSTAR(dirDiags,fileDiags); 2 | % PROCESS2UVstar computes bolus velocity vector components (U,V,WVELSTAR) from 3 | % GM_PsiX,Y in fileDiags (trsp_3d_set1) and output result to 'diags_post_tmp/' 4 | 5 | gcmfaces_global; 6 | 7 | dirOut=[dirDiags filesep 'diags_UVstar_tmp' filesep]; 8 | if ~isdir(dirOut); mkdir(dirOut); end; 9 | 10 | pairsIn={{'GM_PsiX ' 'GM_PsiY '}}; 11 | pairsOut={{'UVELSTAR','VVELSTAR','WVELSTAR'}}; 12 | 13 | %% ======== PART 1 ======= 14 | 15 | %search for fileDiags in subdirectories 16 | [subDir]=rdmds_search_subdirs(dirDiags,fileDiags); 17 | %read meta file to get list of variables 18 | [meta]=rdmds_meta([dirDiags subDir fileDiags]); 19 | 20 | listIn=dir([dirDiags subDir fileDiags '*meta']); 21 | for tt=1:length(listIn); 22 | disp([tt length(listIn)]); 23 | fldsOut=gcmfaces; 24 | listOut={}; 25 | for pp=1:length(pairsIn); 26 | pIn=pairsIn{pp}; pOut=pairsOut{pp}; 27 | filIn=listIn(tt).name(1:end-5); 28 | metaIn=rdmds_meta([dirDiags subDir filIn]); 29 | i1=find(strcmp(metaIn.fldList,pIn{1})); 30 | i2=find(strcmp(metaIn.fldList,pIn{2})); 31 | %[i1 i2] 32 | % 33 | GM_PsiX=rdmds2gcmfaces([dirDiags subDir filIn],'rec',i1); 34 | GM_PsiY=rdmds2gcmfaces([dirDiags subDir filIn],'rec',i2); 35 | [fldUbolus,fldVbolus,fldWbolus]=calc_bolus(GM_PsiX,GM_PsiY); 36 | %store binary 37 | fldsOut=cat(3,fldsOut,fldUbolus); 38 | fldsOut=cat(3,fldsOut,fldVbolus); 39 | fldsOut=cat(3,fldsOut,fldWbolus); 40 | listOut={listOut{:},pOut{:}}; 41 | end; 42 | %output binary file 43 | filOut=['star_' filIn]; 44 | tmp1=convert2gcmfaces(fldsOut); 45 | tmp1(isnan(tmp1))=0; 46 | if ~isdir(dirOut); mkdir(dirOut); end; 47 | write2file([dirOut filOut '.data'],tmp1,32); 48 | %create meta file 49 | tmp2=size(tmp1); tmp2(end)=tmp2(end)/3; 50 | write2meta([dirOut filOut '.data'],tmp2,32,listOut); 51 | end; 52 | 53 | 54 | -------------------------------------------------------------------------------- /gcmfaces_IO/rdmds2gcmfaces.m: -------------------------------------------------------------------------------- 1 | function [fldOut,IT,M]=rdmds2gcmfaces(varargin); 2 | %object: read with rmds then apply convert2gcmfaces 3 | %input: varargin are the options to pass to rdmds (type help rdmds) 4 | %output: fldOut is a gcmfaces object 5 | % 6 | %note: an earlier version was expecting nFaces to be passed 7 | % as the last argument; this is not the case anymore. 8 | 9 | gcmfaces_global; 10 | 11 | [v0,IT,M]=rdmds(varargin{1:end}); 12 | 13 | nn=size(v0); 14 | test1=isfield(mygrid,'xtrct'); 15 | test1=test1&(prod(mygrid.ioSize)~=prod(nn(1:2))); 16 | if test1; 17 | if length(nn)==2; nn=[nn 1]; end; 18 | v0=reshape(v0,[nn(1)*nn(2) nn(3:end)]); 19 | v0=v0(mygrid.xtrct_inFull,:,:,:); 20 | v0=reshape(v0,[mygrid.ioSize nn(3:end)]); 21 | end; 22 | 23 | fldOut=convert2gcmfaces(v0); 24 | -------------------------------------------------------------------------------- /gcmfaces_IO/rdmds2workspace.m: -------------------------------------------------------------------------------- 1 | function []=rdmds2workspace(varargin); 2 | %object: read with rmds2gcmfaces then pass variables to workspace 3 | %input: varargin are the options to pass to rdmds (type help rdmds) 4 | %output: no output needs to be specified 5 | % 6 | 7 | data=rdmds2gcmfaces(varargin{:}); 8 | 9 | tmp1=dir([varargin{1} '*.meta']); tmp1=tmp1(1).name; 10 | tmp2=strfind(varargin{1},filesep); 11 | if ~isempty(tmp2); tmp2=tmp2(end); else; tmp2=0; end; 12 | tmp1=[varargin{1}(1:tmp2) tmp1]; fid=fopen(tmp1); 13 | while 1; 14 | tline = fgetl(fid); 15 | if ~ischar(tline), break, end 16 | if isempty(whos('tmp3')); tmp3=tline; else; tmp3=[tmp3 ' ' tline]; end; 17 | end 18 | fclose(fid); 19 | 20 | tmp1=who;%list current workspace variables 21 | eval(tmp3);%add meta variables to workspace 22 | tmp3=who;%also list meta variables 23 | for ii=1:length(tmp3);%store in structure (meta) 24 | if sum(strcmp(tmp1,tmp3(ii)))==0; 25 | eval(['meta.' tmp3{ii} '=' tmp3{ii} ';']); 26 | end; 27 | end; 28 | 29 | %export the various fields to caller workspace: 30 | assignin('caller','meta',meta); 31 | 32 | %export the various fields to caller workspace: 33 | for ii=1:meta.nFlds; 34 | if meta.nDims==3; 35 | assignin('caller',deblank(meta.fldList{ii}),squeeze(data(:,:,:,ii,:))); 36 | else; 37 | assignin('caller',deblank(meta.fldList{ii}),squeeze(data(:,:,ii,:))); 38 | end; 39 | % fprintf([deblank(meta.fldList{ii}) ' loaded into workspace \n']); 40 | end; 41 | 42 | -------------------------------------------------------------------------------- /gcmfaces_IO/rdmds_meta.m: -------------------------------------------------------------------------------- 1 | function [meta]=rdmds_meta(fileName); 2 | 3 | %read meta file 4 | tmp1=dir([fileName '.meta']); 5 | if isempty(tmp1)&~strcmp(fileName(end),'*'); tmp1=dir([fileName '*.meta']); end; 6 | if isempty(tmp1) 7 | warning(['file not found: ' fileName '*. Trying one level up.']) 8 | fpath = strsplit(fileName,filesep); 9 | fileName2 = [strjoin(fpath(1:end-1),filesep) filesep '..' filesep fpath{end}]; 10 | tmp1=dir([fileName2 '*.meta']); 11 | if isempty(tmp1) 12 | error(['file not found: ' fileName2 '*']) 13 | else 14 | fileName = fileName2; 15 | end 16 | end; 17 | tmp1=tmp1(1).name; 18 | tmp2=strfind(fileName,filesep); 19 | if ~isempty(tmp2); tmp2=tmp2(end); else; tmp2=0; end; 20 | tmp1=[fileName(1:tmp2) tmp1]; fid=fopen(tmp1); 21 | while 1; 22 | tline = fgetl(fid); 23 | if ~ischar(tline), break, end 24 | if isempty(whos('tmp3')); tmp3=tline; else; tmp3=[tmp3 ' ' tline]; end; 25 | end 26 | fclose(fid); 27 | 28 | %add meta variables to workspace 29 | eval(tmp3); 30 | 31 | %reformat to meta structure 32 | meta.dataprec=dataprec; 33 | meta.nDims=nDims; 34 | meta.nFlds=nFlds; 35 | meta.nrecords=nrecords; 36 | meta.fldList=fldList; 37 | meta.dimList=dimList; 38 | if ~isempty(who('timeInterval')); meta.timeInterval=timeInterval; end; 39 | if ~isempty(who('timeStepNumber')); meta.timeStepNumber=timeStepNumber; end; 40 | 41 | -------------------------------------------------------------------------------- /gcmfaces_IO/rdmds_search_subdirs.m: -------------------------------------------------------------------------------- 1 | function [subDir]=rdmds_search_subdirs(dirDiags,fileDiags); 2 | % [subDir]=rdmds_search_subdirs(dirDiags,fileDiags); 3 | % searches for fileDiags within the subdirectories of dirDiags 4 | % and returns the result (subDir). If fileDiags is not found 5 | % then subDir is left empty. If fileDiags if found in several 6 | % subdirectories the rdmds_search_subdirs returns an error message. 7 | 8 | listDirs=dir(dirDiags); 9 | jj=find([listDirs(:).isdir]&[~strcmp({listDirs(:).name},'.')]&[~strcmp({listDirs(:).name},'..')]); 10 | listDirs=listDirs(jj); 11 | 12 | if ~isempty(dir([dirDiags fileDiags '*.data'])); 13 | subDir='./'; 14 | else; 15 | subDir=''; 16 | end; 17 | 18 | alldirs = {}; 19 | 20 | for ff=1:length(listDirs); 21 | tmp1=dir([dirDiags listDirs(ff).name '/' fileDiags '.*.data']); 22 | if ~isempty(tmp1)&isempty(subDir); subDir=[listDirs(ff).name '/']; alldirs = [alldirs {listDirs(ff).name}]; 23 | elseif ~isempty(tmp1); 24 | alldirs = [alldirs {listDirs(ff).name}]; 25 | end; 26 | end; 27 | 28 | if length(alldirs) > 1 29 | warning('fileDiags were found in multiple different locations. Selecting first location:'); 30 | disp(['Selecting ' subDir ' of:' char(10) strjoin(alldirs,',')]) 31 | end 32 | 33 | -------------------------------------------------------------------------------- /gcmfaces_IO/read2memory.m: -------------------------------------------------------------------------------- 1 | function [fldOut]=read2memory(fileIn,varargin); 2 | %purpose: load binary file to memory 3 | % 4 | %inputs: fileIn is the file name 5 | %(optional) sizeOut is the output array size (or [] if not known) 6 | % prec is the file precision (32, by default, or 64) 7 | % 8 | %output: fldOut is the binary vector (default) or array (if sizeOut is spec.) 9 | 10 | if nargin>1; sizeOut=varargin{1}; else; sizeOut=[]; end; 11 | if nargin>2; prec=varargin{2}; else; prec=32; end; 12 | 13 | if ~strcmp(fileIn(end-2:end),'txt'); 14 | nn=dir(fileIn); nn=nn.bytes/(prec/8); fid=fopen(fileIn,'r','b'); fldOut=fread(fid,nn,['float' num2str(prec)]); fclose(fid); 15 | else; 16 | error('text read is not implemented\n'); 17 | % fid=fopen(fileIn,'rt'); fread(fid,fldOut); fclose(fid); 18 | end; 19 | 20 | if ~isempty(sizeOut); fldOut=reshape(fldOut,sizeOut); end; 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /gcmfaces_IO/read_bin.m: -------------------------------------------------------------------------------- 1 | function [fld]=read_bin(fileName,varargin); 2 | %usage: fld=read_bin(fileName); reads 3D field (N levels in 3rd dim) 3 | %usage: fld=read_bin(fileName,trec); reads 3D field, at trec (50 levels) 4 | %usage: fld=read_bin(fileName,trec,k); reads 2D field, at level k, at trec (50 levels) 5 | %usage: fld=read_bin(fileName,trec,0); reads 2D field, at trec (1 level) 6 | %usage: fld=read_bin(fileName,trec,0,prec); prec can be set to 32 (default) or 64 (double precision) 7 | 8 | gcmfaces_global; 9 | 10 | if nargin>1; tt=varargin{1}; else; tt=1; end; 11 | if nargin>2; kk=varargin{2}; else; kk=[]; end; 12 | if nargin>3; prec=varargin{3}; else; prec=32; end; 13 | 14 | myprec=['float' num2str(prec)]; 15 | n1=mygrid.ioSize(1); n2=mygrid.ioSize(2); n3=length(mygrid.RC); nF=mygrid.nFaces; 16 | recl2D=n1*n2*(prec/8); recl3D=n1*n2*n3*(prec/8); 17 | 18 | if nargin==1; n3=dir(fileName); n3=n3.bytes/recl2D; recl3D=recl2D*n3; end; 19 | 20 | fid=fopen(fileName,'r','b'); 21 | if ~isempty(kk); 22 | if kk==0;%meaning the field is only two dimensional 23 | status=fseek(fid,(tt-1)*recl2D,'bof'); 24 | fld=reshape(fread(fid,n1*n2,myprec),[n1 n2]); 25 | else; 26 | status=fseek(fid,(tt-1)*recl3D+(kk-1)*recl2D,'bof'); 27 | fld=reshape(fread(fid,n1*n2,myprec),[n1 n2]); 28 | end; 29 | else; 30 | status=fseek(fid,(tt-1)*recl3D,'bof'); 31 | fld=reshape(fread(fid,n1*n2*n3,myprec),[n1 n2 n3]); 32 | end; 33 | fclose(fid); 34 | 35 | fld=convert2gcmfaces(fld); 36 | 37 | -------------------------------------------------------------------------------- /gcmfaces_IO/write2file.m: -------------------------------------------------------------------------------- 1 | function []=write2file(fileOut,fldIn,varargin); 2 | %purpose: write array to binary file 3 | % 4 | %inputs: fileOut is the file name 5 | % fldIn is the array to write to disk 6 | %(optional) prec is the file precision (32, by default, or 64) 7 | 8 | if nargin>2; prec=varargin{1}; else; prec=32; end; 9 | if nargin>3; omitNaNs=varargin{2}; else; omitNaNs=1; end; 10 | 11 | if ~ischar(fldIn); 12 | fid=fopen(fileOut,'w','b'); tmp1=fldIn; 13 | if omitNaNs; tmp1(isnan(tmp1))=0; end; 14 | fwrite(fid,tmp1,['float' num2str(prec)]); 15 | fclose(fid); 16 | else; 17 | fid=fopen(fileOut,'wt'); fwrite(fid,fldIn); fclose(fid); 18 | end; 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /gcmfaces_IO/write2meta.m: -------------------------------------------------------------------------------- 1 | function []=write2meta(myFile,myDim,varargin); 2 | %purpose: write meta file to match binary file 3 | % 4 | %inputs: myFile is the file name (must finish with '.data') 5 | % myDim is the size of a field (2D or 3D integer vector) 6 | %(optional 1) myPrec is the file myPrecision (32, by default, or 64) 7 | %(optional 2) fldList is the list of field names (cell array) 8 | 9 | %precision: 10 | if nargin>2; myPrec=varargin{1}; else; myPrec=32; end; 11 | if nargin>3; fldList=varargin{2}; else; fldList=[]; end; 12 | %number of dimensions 13 | nDim=length(myDim); 14 | %number of records: 15 | tmp1=dir(myFile); 16 | nRec=tmp1.bytes/myDim(1)/myDim(2)/myPrec*8; 17 | if nDim>2; nRec=nRec/myDim(3); end; 18 | if nRec<1|floor(nRec)~=nRec; error('inconsistent dimensions'); end; 19 | %check that creating a meta file makes sense w\r\t rdmds 20 | if ~strcmp(myFile(end-4:end),'.data'); 21 | error('file name must finish in ''.data''\n'); 22 | else; 23 | myFile=[myFile(1:end-5) '.meta']; 24 | end; 25 | 26 | %create the meta file: 27 | fid=fopen(myFile,'wt'); 28 | %% 29 | fprintf(fid,'nDims = [ %i ];\n',min(nDim,3)); 30 | fprintf(fid,' dimList = [\n'); 31 | fprintf(fid,' %5i, %5i, %5i,\n',myDim(1),1,myDim(1)); 32 | fprintf(fid,' %5i, %5i, %5i,\n',myDim(2),1,myDim(2)); 33 | if nDim>2; fprintf(fid,' %5i, %5i, %5i,\n',myDim(3),1,myDim(3)); end; 34 | fprintf(fid,' ];\n'); 35 | fprintf(fid,' dataprec = [ ''float%2i'' ];\n',myPrec); 36 | fprintf(fid,' nrecords = [ %5i ];\n',nRec); 37 | if ~isempty(fldList); 38 | nFlds=length(fldList); 39 | fprintf(fid,' nFlds = [ %i ];\n',nFlds); 40 | fprintf(fid,' fldList = {\n'); 41 | txt=' '; for ii=1:length(fldList); txt=[txt '''' fldList{ii} '''' ' ']; end; 42 | fprintf(fid,[txt '\n']); 43 | fprintf(fid,' };\n'); 44 | end; 45 | %% 46 | fclose(fid); 47 | 48 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_MeridionalTransport.m: -------------------------------------------------------------------------------- 1 | function [FLD]=calc_MeridionalTransport(fldU,fldV,varargin); 2 | %object: compute net meridional transports of e.g. heat or fresh water 3 | %inputs: fldU and fldV are the fields of grid point transport 4 | %optional: doScaleWithArea, if 1 then multiply fldU by 5 | % dyg.*drf and accordingly for fldV. 6 | % If 0 (default) then it is assumed that those factors 7 | % have already been included (e.g. by pkg/diagnostics). 8 | %output: FLD is the integrated transport vector (one point per latitude). 9 | % 10 | %notes: mygrid.LATS_MASKS is the set of quasi longitudinal lines along which 11 | % transports will integrated, as computed in gcmfaces_lines_zonal 12 | 13 | gcmfaces_global; 14 | 15 | if nargin==3; doScaleWithArea=varargin{1}; else; doScaleWithArea=0; end; 16 | 17 | %check that LATS_MASKS has already been defined: 18 | if ~isfield(mygrid,'LATS_MASKS'); 19 | fprintf('one-time initialization of gcmfaces_lines_zonal: begin\n'); 20 | gcmfaces_lines_zonal; 21 | fprintf('one-time initialization of gcmfaces_lines_zonal: end\n'); 22 | end; 23 | 24 | %initialize output: 25 | n3=max(size(fldU.f1,3),1); n4=max(size(fldV.f1,4),1); 26 | FLD=NaN*squeeze(zeros(length(mygrid.LATS_MASKS),n4)); 27 | 28 | %prepare fldU/fldV: 29 | fldU(isnan(fldU))=0; fldV(isnan(fldV))=0; 30 | 31 | if doScaleWithArea; 32 | dxg=mk3D(mygrid.DXG,fldU); dyg=mk3D(mygrid.DYG,fldU); drf=mk3D(mygrid.DRF,fldU); 33 | for k4=1:n4; 34 | fldU(:,:,:,k4)=fldU(:,:,:,k4).*dyg.*drf; 35 | fldV(:,:,:,k4)=fldV(:,:,:,k4).*dxg.*drf; 36 | end; 37 | end; 38 | 39 | %use array format to speed up computation below: 40 | fldU=convert2array(fldU); fldV=convert2array(fldV); 41 | 42 | for iy=1:length(mygrid.LATS_MASKS); 43 | 44 | %get list ofpoints that form a zonal band: 45 | mskW=mygrid.LATS_MASKS(iy).mskWedge; 46 | vecW=gcmfaces_subset(mskW,fldU); 47 | mskS=mygrid.LATS_MASKS(iy).mskSedge; 48 | vecS=gcmfaces_subset(mskS,fldV); 49 | 50 | %store vertically integrated transport: 51 | FLD(iy,:)=nansum(nansum(vecW,1)+nansum(vecS,1),2); 52 | 53 | end; 54 | 55 | 56 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_T_grad.m: -------------------------------------------------------------------------------- 1 | function [varargout]=calc_T_grad(fld,putGradOnTpoints); 2 | % CALC_T_GRAD(fld) computes horizontal gradients of a 2D field (fld) 3 | % 4 | % inputs: fld is the two-dimensional field (at grid cell centers) 5 | % [optional] putGradOnTpoints states wherther to return the gradients 6 | % at velocity points (0; default) or on tracer points (1) 7 | % outputs: [dFLDdx,dFLDdy] are the gradient fields 8 | % [optional] [...,dFLDdxdx,dFLDdydy] are the second order 9 | % derivatives at tracer points. 10 | % 11 | 12 | % development notes: 13 | % - should be extended to 3D case 14 | 15 | gcmfaces_global; 16 | 17 | msk=fld; msk(~isnan(fld))=1; 18 | 19 | FLD=exch_T_N(fld); 20 | dFLDdx=fld; dFLDdy=fld; 21 | for iF=1:FLD.nFaces; 22 | tmpA=FLD{iF}(2:end-1,2:end-1); 23 | tmpB=FLD{iF}(1:end-2,2:end-1); 24 | dFLDdx{iF}=(tmpA-tmpB)./mygrid.DXC{iF}; 25 | tmpA=FLD{iF}(2:end-1,2:end-1); 26 | tmpB=FLD{iF}(2:end-1,1:end-2); 27 | dFLDdy{iF}=(tmpA-tmpB)./mygrid.DYC{iF}; 28 | end; 29 | 30 | if nargout>2; %compute second order derivatives 31 | [DX,DY]=exch_UV(dFLDdx,dFLDdy); 32 | dFLDdxdx=fld; dFLDdydy=fld; dFLDdxdy=fld; dFLDdydx=fld; 33 | for iF=1:FLD.nFaces; 34 | tmpA=DX{iF}(2:end,:); 35 | tmpB=DX{iF}(1:end-1,:); 36 | dFLDdxdx{iF}=(tmpA-tmpB)./mygrid.DXF{iF}; 37 | tmpA=DY{iF}(:,2:end); 38 | tmpB=DY{iF}(:,1:end-1); 39 | dFLDdydy{iF}=(tmpA-tmpB)./mygrid.DYF{iF}; 40 | end; 41 | end; 42 | 43 | if putGradOnTpoints; 44 | dFLDdx(isnan(dFLDdx))=0; dFLDdy(isnan(dFLDdy))=0; 45 | dFLDdx0=dFLDdx; dFLDdy0=dFLDdy; 46 | [dFLDdx,dFLDdy]=exch_UV(dFLDdx,dFLDdy); 47 | for iF=1:FLD.nFaces; 48 | dFLDdx{iF}=0.5*(dFLDdx{iF}(1:end-1,:)+dFLDdx{iF}(2:end,:)); 49 | dFLDdy{iF}=0.5*(dFLDdy{iF}(:,1:end-1)+dFLDdy{iF}(:,2:end)); 50 | end; 51 | dFLDdx=dFLDdx.*msk; dFLDdy=dFLDdy.*msk; 52 | %remakr: dFLDdxdx and dFLDdydy are on T points already 53 | end; 54 | 55 | varargout{1}=dFLDdx; 56 | varargout{2}=dFLDdy; 57 | if nargout>2; 58 | varargout{3}=dFLDdxdx; 59 | varargout{4}=dFLDdydy; 60 | end; 61 | 62 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_UEVNfromUXVY.m: -------------------------------------------------------------------------------- 1 | function [fldUe,fldVn]=calc_UEVNfromUXVY(fldU,fldV); 2 | %object: compute Eastward/Northward vectors form X/Y vectors 3 | %inputs: fldU/fldV are the X/Y vector fields at velocity points 4 | %outputs: fldUe/fldVn are the Eastward/Northward vectors at tracer points 5 | 6 | gcmfaces_global; 7 | 8 | %fldU(mygrid.hFacW==0)=NaN; fldV(mygrid.hFacS==0)=NaN; 9 | nr=size(fldU.f1,3); fldU(mygrid.hFacW(:,:,1:nr)==0)=NaN; fldV(mygrid.hFacS(:,:,1:nr)==0)=NaN; 10 | 11 | [fldUe,fldVn]=calc_UV_zonmer(fldU,fldV); -------------------------------------------------------------------------------- /gcmfaces_calc/calc_UV_conv.m: -------------------------------------------------------------------------------- 1 | function [fldDIV]=calc_UV_conv(fldU,fldV,varargin); 2 | %object: compute flow field convergent part (i.e. minus the divergence) 3 | %inputs: fldU and fldV are transport or velocity fields 4 | %optional: list_factors is the list of factors that need to 5 | % be applied to fldU,fldV. By default it is empty (i.e. {}). 6 | % The most complete list would be {'dh','dz','hfac'}. 7 | %output: fldDIV is the convergence (integrated, not averaged, over grid cell area) 8 | % 9 | %notes: fldU,fldV that may be 10 | % either [A] a 3D vector field 11 | % or [B] a 2D vector field 12 | % 13 | % in case [A], layer thicknesses = mygrid.DRF; in case [B] layer thickness = 1 14 | % in any case, the global variable mygrid is supposed to be available 15 | 16 | global mygrid; 17 | 18 | %initialize output: 19 | n3=max(size(fldU.f1,3),1); n4=max(size(fldV.f1,4),1); 20 | 21 | %prepare fldU/fldV: 22 | fldU(isnan(fldU))=0; fldV(isnan(fldV))=0; 23 | 24 | %if nargin==3; list_factors=varargin; else; list_factors={'dh','dz','hfac'}; end; 25 | if nargin==3; list_factors=varargin{1}; else; list_factors={}; end; 26 | 27 | dxg=mk3D(mygrid.DXG,fldU); dyg=mk3D(mygrid.DYG,fldU); 28 | if size(fldU.f1,3)==length(mygrid.DRF); drf=mk3D(mygrid.DRF,fldU); 29 | elseif size(fldU.f1,3)==1; drf=fldU; drf(:)=1; 30 | else; error('error in calc_UV_conv: non supported field size\n'); 31 | end; 32 | facW=drf; facW(:)=1; facS=facW; 33 | for ii=1:length(list_factors); 34 | tmp1=list_factors{ii}; 35 | if strcmp(tmp1,'dh'); facW=facW.*dyg; facS=facS.*dxg; 36 | elseif strcmp(tmp1,'dz'); facW=facW.*drf; facS=facS.*drf; 37 | elseif strcmp(tmp1,'hfac'); facW=facW.*mygrid.hFacW; facS=facS.*mygrid.hFacS; 38 | elseif isempty(tmp1); 1; 39 | else; fprintf('error in calc_UV_conv: non supported factor\n'); return; 40 | end; 41 | end; 42 | 43 | for k4=1:n4; 44 | fldU(:,:,:,k4)=fldU(:,:,:,k4).*facW; 45 | fldV(:,:,:,k4)=fldV(:,:,:,k4).*facS; 46 | end; 47 | 48 | [FLDU,FLDV]=exch_UV(fldU,fldV); 49 | FLDU(isnan(FLDU))=0; FLDV(isnan(FLDV))=0; 50 | 51 | fldDIV=fldU; 52 | for iFace=1:fldDIV.nFaces; 53 | fldDIV{iFace}=FLDU{iFace}(1:end-1,:,:,:)-FLDU{iFace}(2:end,:,:,:)+... 54 | FLDV{iFace}(:,1:end-1,:,:)-FLDV{iFace}(:,2:end,:,:); 55 | end; 56 | 57 | 58 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_UV_zonmer.m: -------------------------------------------------------------------------------- 1 | function [fldUe,fldVn]=calc_UV_zonmer(fldU,fldV); 2 | %object: compute Eastward/Northward vectors form X/Y vectors 3 | %inputs: fldU/fldV are the X/Y vector fields at velocity points 4 | %outputs: fldUe/fldVn are the Eastward/Northward vectors at tracer points 5 | % 6 | %note: this routine does no apply any mask -- unlike the old calc_UEVNfromUXVY.m 7 | 8 | gcmfaces_global; 9 | 10 | [FLDU,FLDV]=exch_UV(fldU,fldV); 11 | 12 | fldUe=fldU; fldVn=fldV; 13 | for iF=1:fldU.nFaces; 14 | tmp1=FLDU{iF}(1:end-1,:,:); tmp2=FLDU{iF}(2:end,:,:); 15 | fldUe{iF}=reshape(nanmean([tmp1(:) tmp2(:)],2),size(tmp1)); 16 | tmp1=FLDV{iF}(:,1:end-1,:); tmp2=FLDV{iF}(:,2:end,:); 17 | fldVn{iF}=reshape(nanmean([tmp1(:) tmp2(:)],2),size(tmp1)); 18 | end; 19 | 20 | FLDU=fldUe; FLDV=fldVn; 21 | cs=mk3D(mygrid.AngleCS,FLDU); sn=mk3D(mygrid.AngleSN,FLDU); 22 | 23 | fldUe=+FLDU.*cs-FLDV.*sn; 24 | fldVn=FLDU.*sn+FLDV.*cs; 25 | 26 | 27 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_bolus.m: -------------------------------------------------------------------------------- 1 | function [bolusU,bolusV,bolusW]=calc_bolus(GM_PsiX,GM_PsiY); 2 | %object: compute bolus velocty field (bolusU,bolusV,bolusW) 3 | % from gm streamfunction (GM_PsiX,GM_PsiY). 4 | %input: GM_PsiX,GM_PsiY 5 | %output: bolusU,bolusV,bolusW 6 | 7 | gcmfaces_global; 8 | nr=length(mygrid.RC); 9 | 10 | %replace NaNs with 0s: 11 | GM_PsiX(isnan(GM_PsiX))=0; 12 | GM_PsiY(isnan(GM_PsiY))=0; 13 | 14 | %compute bolus velocity: 15 | GM_PsiX(:,:,nr+1)=0*GM_PsiX(:,:,end); 16 | GM_PsiY(:,:,nr+1)=0*GM_PsiY(:,:,end); 17 | bolusU=0*mygrid.hFacW; 18 | bolusV=0*mygrid.hFacS; 19 | for k=1:nr; 20 | bolusU(:,:,k)=(GM_PsiX(:,:,k+1)-GM_PsiX(:,:,k))/mygrid.DRF(k); 21 | bolusV(:,:,k)=(GM_PsiY(:,:,k+1)-GM_PsiY(:,:,k))/mygrid.DRF(k); 22 | end; 23 | bolusU=bolusU.*(~isnan(mygrid.mskW)); 24 | bolusV=bolusV.*(~isnan(mygrid.mskS)); 25 | 26 | %and its vertical part 27 | % (seems correct, leading to 0 divergence) 28 | tmp_x=GM_PsiX(:,:,1:nr).*repmat(mygrid.DYG,[1 1 nr]); 29 | tmp_y=GM_PsiY(:,:,1:nr).*repmat(mygrid.DXG,[1 1 nr]); 30 | [tmp_x,tmp_y]=exch_UV(tmp_x,tmp_y); 31 | tmp_a=repmat(mygrid.RAC,[1 1 nr]); 32 | tmp_w=0*tmp_x; 33 | for iFace=1:mygrid.nFaces; 34 | tmp_w{iFace}=( tmp_x{iFace}(2:end,:,:)-tmp_x{iFace}(1:end-1,:,:) )+... 35 | ( tmp_y{iFace}(:,2:end,:)-tmp_y{iFace}(:,1:end-1,:) ); 36 | tmp_w{iFace}=tmp_w{iFace}./tmp_a{iFace}; 37 | end; 38 | bolusW=tmp_w.*(~isnan(mygrid.mskC)); 39 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_mskmean_T.m: -------------------------------------------------------------------------------- 1 | function [fldOut,area]=calc_mskmean_T(fldIn,mask,fldType); 2 | % CALC_MSKMEAN_T(budgIn,mask,fldType) 3 | % computes average over a region (mask) of fldIn (or its fields recursively). 4 | % If fldType is 'intensive' (default) then fldIn is mutliplies by RAC. 5 | 6 | gcmfaces_global; 7 | 8 | if isempty(who('fldType')); fldType='intensive'; end; 9 | 10 | if isa(fldIn,'struct'); 11 | list0=fieldnames(fldIn); 12 | fldOut=[]; 13 | for vv=1:length(list0); 14 | tmp1=getfield(fldIn,list0{vv}); 15 | if isa(tmp1,'gcmfaces'); 16 | [tmp2,area]=calc_mskmean_T(tmp1,mask,fldType); 17 | fldOut=setfield(fldOut,list0{vv},tmp2); 18 | end; 19 | end; 20 | return; 21 | end; 22 | 23 | nr=size(fldIn{1},3); 24 | nr2=size(mask{1},3); 25 | if nr2~=nr; mask=repmat(mask,[1 1 nr]); end; 26 | mask(mask==0)=NaN; mask(isnan(fldIn))=NaN; 27 | areaMask=repmat(mygrid.RAC,[1 1 nr]).*mask; 28 | if strcmp(fldType,'intensive'); 29 | fldOut=nansum(fldIn.*areaMask,0)./nansum(areaMask,0); 30 | area=nansum(areaMask,0); 31 | else; 32 | fldOut=nansum(fldIn.*mask,0)./nansum(areaMask,0); 33 | area=nansum(areaMask,0); 34 | end; 35 | 36 | 37 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_transports.m: -------------------------------------------------------------------------------- 1 | function [FLD]=calc_transports(fldU,fldV,SECTIONS_MASKS,list_factors); 2 | %object: compute transports through pre-defined sections 3 | %inputs: fldU and fldV are the fields of grid point transport 4 | % SECTIONS_MASKS is the set of sections along 5 | % which transports will integrated (SECTIONS_MASKS should 6 | % have been produced by line_greatC_TUV_mask.m) 7 | %optional: list_factors is the list of factors that need to 8 | % be applied to fldU,fldV. By default it is empty (i.e. {}). 9 | % The most complete list would be {'dh','dz','hfac'}. 10 | %output: FLD is the array of transport profiles 11 | 12 | global mygrid; 13 | 14 | %initialize output: 15 | n3=max(size(fldU.f1,3),1); n4=max(size(fldV.f1,4),1); 16 | FLD=NaN*squeeze(zeros(length(SECTIONS_MASKS),n3,n4)); 17 | 18 | %prepare fldU/fldV: 19 | fldU(isnan(fldU))=0; fldV(isnan(fldV))=0; 20 | 21 | if isempty(who('list_factors')); list_factors={}; end; 22 | 23 | if sum(strcmp(list_factors,'dh'))>0; 24 | dxg=mk3D(mygrid.DXG,fldU); dyg=mk3D(mygrid.DYG,fldU); 25 | else; 26 | dxg=1; dyg=1; 27 | end; 28 | if sum(strcmp(list_factors,'dz'))>0; 29 | drf=mk3D(mygrid.DRF,fldU); 30 | else; 31 | drf=1; 32 | end; 33 | facW=1; facS=1; 34 | for ii=1:length(list_factors); 35 | tmp1=list_factors{ii}; 36 | if strcmp(tmp1,'dh'); facW=facW.*dyg; facS=facS.*dxg; 37 | elseif strcmp(tmp1,'dz'); facW=facW.*drf; facS=facS.*drf; 38 | elseif strcmp(tmp1,'hfac'); facW=facW.*mygrid.hFacW; facS=facS.*mygrid.hFacS; 39 | elseif isempty(tmp1); 1; 40 | else; fprintf('error in calc_transports : non supported factor\n'); return; 41 | end; 42 | end; 43 | 44 | for k4=1:n4; 45 | fldU(:,:,:,k4)=fldU(:,:,:,k4).*facW; 46 | fldV(:,:,:,k4)=fldV(:,:,:,k4).*facS; 47 | end; 48 | 49 | %use array format to speed up computation below: 50 | fldU=convert2array(fldU); fldV=convert2array(fldV); 51 | 52 | for iy=1:length(SECTIONS_MASKS); 53 | 54 | %get list ofpoints that form a zonal band: 55 | mskW=SECTIONS_MASKS(iy).mskWedge; 56 | vecW=gcmfaces_subset(mskW,fldU); 57 | mskS=SECTIONS_MASKS(iy).mskSedge; 58 | vecS=gcmfaces_subset(mskS,fldV); 59 | 60 | %store: 61 | FLD(iy,:)=nansum(vecW,1)+nansum(vecS,1); 62 | 63 | end; 64 | 65 | 66 | -------------------------------------------------------------------------------- /gcmfaces_calc/calc_zonmedian_T.m: -------------------------------------------------------------------------------- 1 | function [FLD]=calc_zonmedian_T(fld); 2 | %object: compute zonal median 3 | %inputs: fld is the field of interest 4 | %output: FLD is the zonal median field 5 | % 6 | %notes: mygrid.LATS_MASKS is the set of quasi longitudinal lines along which 7 | % medians will be computed, as computed in gcmfaces_lines_zonal 8 | 9 | gcmfaces_global; 10 | 11 | %check that LATS_MASKS has already been defined: 12 | if ~isfield(mygrid,'LATS_MASKS'); 13 | fprintf('one-time initialization of gcmfaces_lines_zonal: begin\n'); 14 | gcmfaces_lines_zonal; 15 | fprintf('one-time initialization of gcmfaces_lines_zonal: end\n'); 16 | end; 17 | 18 | %initialize output: 19 | n3=max(size(fld.f1,3),1); n4=max(size(fld.f1,4),1); 20 | FLD=NaN*squeeze(zeros(length(mygrid.LATS_MASKS),n3,n4)); 21 | 22 | %apply mask: 23 | nr=size(mygrid.mskC.f1,3); 24 | if n3==nr; 25 | for i4=1:n4; fld(:,:,:,i4)=fld(:,:,:,i4).*mygrid.mskC; end; 26 | else; 27 | for i3=1:n3; for i4=1:n4; fld(:,:,i3,i4)=fld(:,:,i3,i4).*mygrid.mskC(:,:,1); end; end; 28 | end; 29 | 30 | %use array format to speed up computation below: 31 | fld=convert2array(fld); 32 | n1=size(fld,1); n2=size(fld,2); 33 | fld=reshape(fld,n1*n2,n3*n4); 34 | 35 | for iy=1:length(mygrid.LATS_MASKS); 36 | 37 | %get list ofpoints that form a zonal band: 38 | mm=convert2array(mygrid.LATS_MASKS(iy).mskCedge); 39 | mm=find(~isnan(mm)&mm~=0); 40 | 41 | %do the median along this band: 42 | tmp1=nanmedian(fld(mm,:),1); 43 | 44 | %store: 45 | if ~isempty(mm); 46 | FLD(iy,:,:)=reshape(tmp1,n3,n4); 47 | end; 48 | 49 | end; 50 | 51 | 52 | -------------------------------------------------------------------------------- /gcmfaces_calc/gcmfaces_edge_mask.m: -------------------------------------------------------------------------------- 1 | function [mskCedge,mskWedge,mskSedge]=gcmfaces_edge_mask(mskCint); 2 | %object: computes the edge mask corresponding with 3 | % an ocean basin interior mask 4 | %inputs: mskCint is the 0/1 mask defining an ocean basin interior 5 | %outputs: mskCedge is the tracer edge mask (1 point outside interior) 6 | % mskWedge/mskSedge is the U/V velocity mask (1 for entering 7 | % flow, -1 for exiting flow, and 0 otherwise) 8 | 9 | gcmfaces_global; 10 | 11 | %treat the case of blank tiles: 12 | mskCint(mygrid.RAC==0)=NaN; 13 | 14 | %add one point at edges: 15 | mskCplus=exch_T_N(mskCint); 16 | 17 | %edge tracer mask: 18 | mskCedge=mskCint; 19 | for iF=1:mskCint.nFaces; 20 | tmp1=mskCplus{iF}; 21 | tmp2=tmp1(2:end-1,1:end-2)+tmp1(2:end-1,3:end)... 22 | +tmp1(1:end-2,2:end-1)+tmp1(3:end,2:end-1); 23 | mskCedge{iF}=1*(tmp2>0&tmp1(2:end-1,2:end-1)==0); 24 | end; 25 | 26 | %edge velocity mask: 27 | mskWedge=mskCint; mskSedge=mskCint; 28 | for iF=1:mskCplus.nFaces; 29 | mskWedge{iF}=mskCplus{iF}(2:end-1,2:end-1) - mskCplus{iF}(1:end-2,2:end-1); 30 | mskSedge{iF}=mskCplus{iF}(2:end-1,2:end-1) - mskCplus{iF}(2:end-1,1:end-2); 31 | end; 32 | 33 | %treat the case of blank tiles: 34 | mskCedge(isnan(mskCedge))=0; 35 | mskWedge(isnan(mskWedge))=0; 36 | mskSedge(isnan(mskSedge))=0; 37 | -------------------------------------------------------------------------------- /gcmfaces_calc/gcmfaces_interp_1d.m: -------------------------------------------------------------------------------- 1 | function [Vq]=gcmfaces_interp_1d(xDim,X,V,Xq); 2 | %[Vq]=GCMFACES_INTERP_1D(xDim,X,V,Xq); 3 | % Linearly interpolates a field (V; array or gcmfaces) along a 4 | % selected dimension (xDim) from locations specified in 5 | % vector X to locations specified in vector Xq 6 | 7 | gcmfaces_global; 8 | 9 | %change format if needed 10 | isagcmfaces=isa(V,'gcmfaces'); 11 | if isagcmfaces; V=convert2gcmfaces(V); end; 12 | 13 | %move interpolation dimension to first 14 | ndim=length(size(V)); 15 | tmp1=circshift([1:ndim],[0 1-xDim]); 16 | V=permute(V,tmp1); 17 | if size(X,1)==1; X=X'; end; 18 | if size(Xq,1)==1; Xq=Xq'; end; 19 | 20 | %the interpolation itself 21 | Kq=interp1(X,[1:length(X)]',Xq,'linear'); 22 | Kqne=interp1(X,[1:length(X)]',Xq,'nearest','extrap'); 23 | 24 | %use bilinear; then extrapolate with nearest neighbor 25 | Vq=NaN*repmat(V(1,:,:),[length(Xq) 1 1]); 26 | for kk=1:length(Xq); 27 | if ~isnan(Kq(kk)); 28 | k0=floor(Kq(kk)); 29 | k1=min(k0+1,length(X)); 30 | a0=Kq(kk)-k0; 31 | tmp1=(1-a0)*V(k0,:,:)+a0*V(k1,:,:); 32 | else; 33 | tmp1=NaN*V(1,:,:); 34 | end; 35 | tmp2=V(Kqne(kk),:,:); 36 | tmp1(isnan(tmp1))=tmp2(isnan(tmp1)); 37 | Vq(kk,:,:)=tmp1; 38 | end; 39 | 40 | %move interpolation dimension to first 41 | tmp1=circshift([1:ndim],[0 xDim-1]); 42 | Vq=permute(Vq,tmp1); 43 | 44 | %change format if needed 45 | if isagcmfaces; Vq=convert2gcmfaces(Vq); end; 46 | 47 | -------------------------------------------------------------------------------- /gcmfaces_calc/gcmfaces_lines_pairs.m: -------------------------------------------------------------------------------- 1 | function [lonPairs,latPairs,names]=gcmfaces_lines_pairs(); 2 | % GCMFACES_LINES_PAIRS returns a set of predefined section 3 | % end points [lonPairs,latPairs,names]=gcmfaces_lines_pairs(); 4 | 5 | gcmfaces_global; 6 | 7 | for iy=1:23; 8 | 9 | switch iy; 10 | case 1; lonPair=[-173 -164]; latPair=[65.5 65.5]; name='Bering Strait'; 11 | case 2; lonPair=[-5 -5]; latPair=[34 40]; name='Gibraltar'; 12 | case 3; lonPair=[-81 -77]; latPair=[28 26]; name='Florida Strait'; 13 | case 4; lonPair=[-81 -79]; latPair=[28 22]; name='Florida Strait W1'; 14 | case 5; lonPair=[-76 -76]; latPair=[21 8]; name='Florida Strait S1'; 15 | case 6; lonPair=[-77 -77]; latPair=[26 24]; name='Florida Strait E1'; 16 | case 7; lonPair=[-77 -77]; latPair=[24 22]; name='Florida Strait E2'; 17 | case 8; lonPair=[-65 -50]; latPair=[66 66]; name='Davis Strait'; 18 | case 9; lonPair=[-35 -20]; latPair=[67 65]; name='Denmark Strait'; 19 | case 10; lonPair=[-16 -7]; latPair=[65 62.5]; name='Iceland Faroe'; 20 | case 11; lonPair=[-6.5 -4]; latPair=[62.5 57]; name='Faroe Scotland'; 21 | case 12; lonPair=[-4 8]; latPair=[57 62]; name='Scotland Norway'; 22 | case 13; lonPair=[-68 -63]; latPair=[-54 -66]; name='Drake Passage'; 23 | case 14; lonPair=[103 103]; latPair=[4 -1]; name='Indonesia W1'; 24 | case 15; lonPair=[104 109]; latPair=[-3 -8]; name='Indonesia W2'; 25 | case 16; lonPair=[113 118]; latPair=[-8.5 -8.5]; name='Indonesia W3'; 26 | case 17; lonPair=[118 127 ]; latPair=[-8.5 -15]; name='Indonesia W4'; 27 | case 18; lonPair=[127 127]; latPair=[-25 -68]; name='Australia Antarctica'; 28 | case 19; lonPair=[38 46]; latPair=[-10 -22]; name='Madagascar Channel'; 29 | case 20; lonPair=[46 46]; latPair=[-22 -69]; name='Madagascar Antarctica'; 30 | case 21; lonPair=[20 20]; latPair=[-30 -69.5]; name='South Africa Antarctica'; 31 | case 22; lonPair=[-76 -72]; latPair=[21 18.5]; name='Florida Strait E3'; 32 | case 23; lonPair=[-72 -72]; latPair=[18.5 10]; name='Florida Strait E4'; 33 | end; 34 | 35 | if iy==1; lonPairs=lonPair; latPairs=latPair; names={name}; 36 | else; lonPairs(iy,:)=lonPair; latPairs(iy,:)=latPair; names{iy}=name; 37 | end; 38 | 39 | end; 40 | 41 | -------------------------------------------------------------------------------- /gcmfaces_calc/gcmfaces_lines_zonal.m: -------------------------------------------------------------------------------- 1 | function []=gcmfaces_lines_zonal(varargin); 2 | %object: define the set of quasi longitudinal lines 3 | % along which transports will integrated; 4 | % LATS_MASKS that will be added to mygrid. 5 | % LONS_MASKS that will be added to mygrid. 6 | %optional input: 7 | % LATS_VAL is the latitudes vector ([-89:89]' by default) 8 | % LONS_VAL is the latitudes vector ([-179.5:179.5]' by default) 9 | 10 | gcmfaces_global; 11 | 12 | if nargin>0; LATS_VAL=varargin{1}; else; LATS_VAL=[-89:89]'; end; 13 | if nargin>1; LONS_VAL=varargin{2}; else; LONS_VAL=[-179.5:179.5]'; end; 14 | 15 | if iscell(LONS_VAL); 16 | warning('gcmfaces_lines_zonal now takes LONS_VAL as 2nd argument'); 17 | LONS_VAL=[-179.5:179.5]'; 18 | end; 19 | 20 | MSKS_NAM={'mskCint','mskCedge','mskWedge','mskSedge'}; 21 | 22 | for iy=1:length(LATS_VAL); 23 | 24 | mskCint=1*(mygrid.YC>=LATS_VAL(iy)); 25 | [mskCedge,mskWedge,mskSedge]=gcmfaces_edge_mask(mskCint); 26 | 27 | for im=1:length(MSKS_NAM); 28 | eval(['tmp1.' MSKS_NAM{im} '=' MSKS_NAM{im} ';']); 29 | end; 30 | tmp1.lat=LATS_VAL(iy); 31 | 32 | %store: 33 | if iy==1; 34 | LATS_MASKS=tmp1; 35 | else; 36 | LATS_MASKS(iy)=tmp1; 37 | end; 38 | 39 | end; 40 | 41 | d2r=pi/180; 42 | for iy=1:length(LONS_VAL); 43 | 44 | mskCint=1*(sin(d2r*(mygrid.XC-LONS_VAL(iy)))>=0); 45 | [mskCedge,mskWedge,mskSedge]=gcmfaces_edge_mask(mskCint); 46 | tmp1=1*(cos(d2r*(mygrid.XC-LONS_VAL(iy)))>0); 47 | mskCedge=mskCedge.*tmp1; 48 | tmp1=1*(cos(d2r*(mygrid.XG-LONS_VAL(iy)))>0); 49 | mskWedge=mskWedge.*tmp1; 50 | tmp1=1*(cos(d2r*(mygrid.XC-LONS_VAL(iy)))>0); 51 | mskSedge=mskSedge.*tmp1; 52 | 53 | clear tmp1; 54 | for im=1:length(MSKS_NAM); 55 | eval(['tmp1.' MSKS_NAM{im} '=' MSKS_NAM{im} ';']); 56 | end; 57 | tmp1.lon=LONS_VAL(iy); 58 | 59 | %store: 60 | if iy==1; 61 | LONS_MASKS=tmp1; 62 | else; 63 | LONS_MASKS(iy)=tmp1; 64 | end; 65 | 66 | end; 67 | 68 | mygrid.LATS_MASKS=LATS_MASKS; 69 | mygrid.LONS_MASKS=LONS_MASKS; 70 | mygrid.LATS=[mygrid.LATS_MASKS.lat]'; 71 | mygrid.LONS=[mygrid.LONS_MASKS.lon]'; 72 | 73 | -------------------------------------------------------------------------------- /gcmfaces_calc/gcmfaces_map_2d.m: -------------------------------------------------------------------------------- 1 | function [fldOut,varargout]=gcmfaces_map_2d(lon,lat,fldIn,nExtrap,wRepeat); 2 | %object: use bin average to remap ONE lat-lon grid FIELD to a gcmfaces grid 3 | %input: lon,lat are the lat-lon grid, or vectors 4 | % fldIn is the gcmfaces field to be interpolated to lon,lat 5 | %optional: nExtrap (0 by default) is the number of points to extrapolate ocean field (into 6 | % the land mask before interpolation to the lat-lon grid. 7 | % wRepeat (2 degrees by default) is the width of repeats at 8 | % lat-lon global domain edges (needed to avoid missing values) 9 | %output: fldOut is the interpolated file 10 | %optional: lon,lat corresponding with fldOut 11 | %assumption : fldIn is nan-masked 12 | 13 | gcmfaces_global; 14 | 15 | if isempty(lon); lon=[-180:0.5:180]; lat=[-90:0.5:90]; end; 16 | if size(lon,1)==1|size(lon,2)==1; [lat,lon]=meshgrid(lat,lon); end; 17 | if isempty(whos('nExtrap')); nExtrap=0; end; 18 | if isempty(whos('wRepeat')); wRepeat=2; end; 19 | 20 | %1) extrapolate if needed 21 | if nExtrap>0; 22 | mskExtrap=~isnan(fldIn); 23 | for ii=1:nExtrap; 24 | mskExtrap=exch_T_N(mskExtrap); 25 | for iF=1:mskExtrap.nFaces; 26 | tmp1=mskExtrap{iF}; tmp1(isnan(tmp1))=0; 27 | tmp2=tmp1(2:end-1,2:end-1)+tmp1(1:end-2,2:end-1)+tmp1(3:end,2:end-1)+tmp1(2:end-1,1:end-2)+tmp1(2:end-1,3:end); 28 | tmp2(tmp2~=0)=1; mskExtrap{iF}=tmp2; 29 | end; 30 | end; 31 | mskExtrap(find(mskExtrap==0))=NaN; 32 | % 33 | fldIn=diffsmooth2D_extrap_inv(fldIn,mskExtrap); 34 | end; 35 | 36 | %2) extract vector of ocean points 37 | x=convert2vector(mygrid.XC); 38 | y=convert2vector(mygrid.YC); 39 | v=convert2vector(fldIn); 40 | % ii=find(~isnan(v)); 41 | ii=find(~isnan(x)); 42 | x=x(ii); y=y(ii); v=v(ii); 43 | 44 | %3) add points at lat-lon global domain edges 45 | ii=find(y>90-wRepeat); x=[x;x(ii)]; y=[y;180-y(ii)]; v=[v;v(ii)]; 46 | ii=find(y<-90+wRepeat); x=[x;x(ii)]; y=[y;-180-y(ii)]; v=[v;v(ii)]; 47 | ii=find(x>180-wRepeat&x<180); x=[x;x(ii)-360]; y=[y;y(ii)]; v=[v;v(ii)]; 48 | ii=find(x<-180+wRepeat&x>-180); x=[x;x(ii)+360]; y=[y;y(ii)]; v=[v;v(ii)]; 49 | 50 | %4) generate the interpolant 51 | F = TriScatteredInterp(x,y,v); 52 | 53 | %5) target grid 54 | fldOut = F(lon,lat); 55 | 56 | %6) optional outputs: 57 | if nargout>1; varargout={lon,lat}; end; 58 | 59 | 60 | -------------------------------------------------------------------------------- /gcmfaces_calc/gcmfaces_subset.m: -------------------------------------------------------------------------------- 1 | function [vec]=gcmfaces_subset(msk,fld,applyMsk); 2 | %object: extract the subset of points from fld(.*msk) such that msk~=0 3 | %inputs: msk is the gcmfaces subdomain mask (one vertical level) 4 | % fld is the complete field (gcmfaces or array version) 5 | %optional: applyMsk is a flag that stated whether to multiply with 6 | % msk (applyMsk==1; default) or not (applyMsk==0); 7 | %output: vec is the subset field 8 | % 9 | %note: - if fld is an array, then it must be a result of convert2array 10 | % - for velocity subsets, msk may be -1 or +1, depending on 11 | % directionality, e.g. when msk delineates a transport section. 12 | 13 | if isempty(whos('applyMsk')); applyMsk=1; end; 14 | 15 | if isa(fld,'gcmfaces'); fld=convert2array(fld); end; 16 | nn=size(fld); nn=[nn ones(1,4-length(nn))]; 17 | fld=reshape(fld,nn(1)*nn(2),nn(3)*nn(4)); 18 | 19 | msk=convert2array(msk); msk=msk(:); 20 | 21 | ii=find(msk~=0&~isnan(msk)); mm=length(ii); 22 | if mm==0; 23 | vec=zeros(1,nn(3),nn(4)); 24 | else; 25 | if applyMsk; 26 | vec=fld(ii,:).*(msk(ii)*ones(1,nn(3)*nn(4))); 27 | else; 28 | vec=fld(ii,:); 29 | end; 30 | vec=reshape(vec,[mm nn(3) nn(4)]); 31 | end; 32 | 33 | 34 | -------------------------------------------------------------------------------- /gcmfaces_calc/regrid_dblres.m: -------------------------------------------------------------------------------- 1 | function [P]=regrid_dblres(P,pType,nDblRes); 2 | %object : double the resolution (only along 3rd dimension for now) 3 | % for a variable P (extensive or intensive) a number of times. 4 | %input : P is the variable of interest 5 | % pType is 'extensive' or 'intensive' 6 | % nDblRes is the number of resolution doublings. 7 | %output : P is the input variable but with 2^nDblRes resolution 8 | 9 | gcmfaces_global; 10 | 11 | for ii=1:nDblRes; 12 | %start with repmat 13 | tmp1=repmat(P,[1 1 2]); 14 | nn=size(P{1},3); 15 | tmp1(:,:,1:2:2*nn)=P; 16 | tmp1(:,:,2:2:2*nn)=P; 17 | %interpolate (in grid point space) 18 | tmp2=NaN*tmp1; 19 | tmp2(:,:,2:2:2*nn-2)=3/4*P(:,:,1:nn-1)+1/4*P(:,:,2:nn); 20 | tmp2(:,:,3:2:2*nn-1)=1/4*P(:,:,1:nn-1)+3/4*P(:,:,2:nn); 21 | tmp1(~isnan(tmp2))=tmp2(~isnan(tmp2)); 22 | %if extensive then we want to conserve the sum over grid points 23 | if strcmp(pType,'extensive'); tmp1=tmp1/2; end; 24 | %overwite P 25 | P=tmp1; 26 | end; 27 | 28 | -------------------------------------------------------------------------------- /gcmfaces_calc/regrid_sum.m: -------------------------------------------------------------------------------- 1 | function [trP]=regrid_sum(P,tracer,trGrid); 2 | %object : add 3rd dimension elements of extensive variable P, 3 | % according to values of a tracer field collocated with P, 4 | % to the tracer grid defined by trGrid (1D vector) 5 | %input : P is the extensive variable of interest 6 | % tracer is the associated tracer field 7 | % trGrid is the vector of tracer values at 8 | % bins center of the tracer grid bins. 9 | %output : trP is the counterpart to P on the tracer grid 10 | 11 | trP=NaN*repmat(P(:,:,1),[1 1 length(trGrid)-1]); 12 | trBounds=[-Inf (trGrid(1:end-1)+trGrid(2:end))/2 Inf]; 13 | for kk=1:length(trGrid); 14 | tmp1=P.*(tracer>=trBounds(kk)).*(tracer1; fprintf('not implemented yet\n'); return; end; 32 | %fill the corners of fld0: 33 | warning('off','MATLAB:interp1:NaNinY'); 34 | for pp=1:4; 35 | %do the interpolation in polar coordinates... 36 | ii=[0:nn]'*ones(1,nn+1); jj=ones(nn+1,1)*[0:nn]; 37 | aa=angle(ii+i*jj); bb=min(abs(ii+i*jj),nn); 38 | % 39 | v0=fld0(end-nn:end,end-nn:end); 40 | k1=find(aa==0); k2=find(aa>0&aa<=pi/4); v0(k2)=interp1(bb(k1),v0(k1),bb(k2)); 41 | k1=find(aa==pi/2); k2=find(aa>pi/4&aa<=pi/2); v0(k2)=interp1(bb(k1),v0(k1),bb(k2)); 42 | fld0(end-nn+1:end,end-nn+1:end)=v0(2:end,2:end); 43 | fld0=sym_g(fld0,5,0); 44 | % 45 | end; 46 | warning('on','MATLAB:interp1:NaNinY'); 47 | 48 | end;%if doFill; 49 | 50 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2array.m: -------------------------------------------------------------------------------- 1 | function [a]=convert2array(b,varargin); 2 | %object: gcmfaces to array format conversion (if gcmfaces input) 3 | % or: array to gcmfaces format conversion (if array input) 4 | % 5 | %notes: - if array input, the gcmfaces format will be the one of mygrid.XC, so 6 | % the array input must have originally been created according to convert2array 7 | % - global mygrid parameters (mygrid.XC.gridType) are used 8 | 9 | input_list_check('convert2array',nargin); 10 | 11 | gcmfaces_global; 12 | 13 | if isfield(mygrid,'xtrct'); 14 | a=convert2array_xtrct(b); 15 | elseif strcmp(mygrid.XC.gridType,'llc'); 16 | a=convert2array_llc(b); 17 | elseif strcmp(mygrid.XC.gridType,'cube'); 18 | a=convert2array_cube(b); 19 | elseif strcmp(mygrid.XC.gridType,'llpc'); 20 | a=convert2array_llpc(b); 21 | elseif strcmp(mygrid.XC.gridType,'ll'); 22 | a=convert2array_ll(b); 23 | else; 24 | error(['convert2array not implemented for ' mygrid.XC.gridType '!?']); 25 | end; 26 | 27 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2array_cube.m: -------------------------------------------------------------------------------- 1 | function [FLD]=convert2array_cube(fld); 2 | %object: gcmfaces to array format conversion (if gcmfaces input) 3 | % or: array to gcmfaces format conversion (if array input) 4 | % 5 | %notes: if array input, the gcmfaces format will be the one of mygrid.XC, so 6 | % the array input must have originally been created according to convert2array 7 | 8 | global mygrid; 9 | 10 | if isa(fld,'gcmfaces'); do_gcmfaces2array=1; else; do_gcmfaces2array=0; end; 11 | 12 | if do_gcmfaces2array; 13 | n3=max(size(fld.f1,3),1); n4=max(size(fld.f1,4),1); 14 | n1=size(fld.f1,1)*4; n2=size(fld.f1,2)+2*size(fld.f1,1); 15 | FLD=squeeze(zeros(n1,n2,n3,n4)); 16 | else; 17 | n3=max(size(fld,3),1); n4=max(size(fld,4),1); 18 | FLD=NaN*mygrid.XC; 19 | for k3=1:n3; for k4=1:n4; for iFace=1:FLD.nFaces; 20 | iF=num2str(iFace); eval(['FLD.f' iF '(:,:,k3,k4)=FLD.f' iF '(:,:,1,1);']); 21 | end; end; end; 22 | end; 23 | 24 | for k3=1:n3; for k4=1:n4; 25 | 26 | if do_gcmfaces2array; 27 | %ASSEMBLE SIDE FACES: 28 | %---------------------- 29 | FLD0=[fld.f1(:,:,k3,k4);fld.f2(:,:,k3,k4);sym_g(fld.f4(:,:,k3,k4),7,0);sym_g(fld.f5(:,:,k3,k4),7,0)]; 30 | %ADD NORTH FACE: 31 | %-------------- 32 | pp=fld.f3(:,:,k3,k4); FLDp=[sym_g(pp,5,0);pp.*NaN;sym_g(pp.*NaN,7,0);sym_g(pp.*NaN,6,0)]; 33 | FLD1=[FLD0 FLDp]; 34 | %ADD NORTH FACE: 35 | %-------------- 36 | pp=fld.f6(:,:,k3,k4); FLDp=[pp.*NaN;sym_g(pp*NaN,5,0);sym_g(pp.*NaN,6,0);sym_g(pp,7,0)]; 37 | FLD1=[FLDp FLD1]; 38 | %store: 39 | %------ 40 | FLD(:,:,k3,k4)=FLD1; 41 | else; 42 | n1=size(FLD.f1,1); n2=size(FLD.f1,2); 43 | FLD.f1(:,:,k3,k4)=fld(1:n1,n1+1:n1+n2,k3,k4); 44 | FLD.f2(:,:,k3,k4)=fld(n1+[1:n1],n1+1:n1+n2,k3,k4); 45 | FLD.f3(:,:,k3,k4)=sym_g(fld([1:n1],n1+n2+1:n1+n2+n1,k3,k4),7,0); 46 | FLD.f4(:,:,k3,k4)=sym_g(fld(n1*2+[1:n1],n1+1:n1+n2,k3,k4),5,0); 47 | FLD.f5(:,:,k3,k4)=sym_g(fld(n1*3+[1:n1],n1+1:n1+n2,k3,k4),5,0); 48 | FLD.f6(:,:,k3,k4)=sym_g(fld(n1*3+[1:n1],1:n1,k3,k4),5,0); 49 | end; 50 | 51 | end; end; 52 | 53 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2array_ll.m: -------------------------------------------------------------------------------- 1 | function [FLD]=convert2array_ll(fld); 2 | %object: gcmfaces to array format conversion (if gcmfaces input) 3 | % or: array to gcmfaces format conversion (if array input) 4 | % 5 | %notes: if array input, the gcmfaces format will be the one of mygrid.XC, so 6 | % the array input must have originally been created according to convert2array 7 | 8 | global mygrid; 9 | 10 | if isa(fld,'gcmfaces'); do_gcmfaces2array=1; else; do_gcmfaces2array=0; end; 11 | 12 | if do_gcmfaces2array; 13 | FLD=fld.f1; 14 | else; 15 | FLD=NaN*mygrid.XC; 16 | FLD.f1=fld; 17 | end; 18 | 19 | 20 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2array_llc.m: -------------------------------------------------------------------------------- 1 | function [FLD]=convert2array_llc(fld); 2 | %object: gcmfaces to array format conversion (if gcmfaces input) 3 | % or: array to gcmfaces format conversion (if array input) 4 | % 5 | %notes: if array input, the gcmfaces format will be the one of mygrid.XC, so 6 | % the array input must have originally been created according to convert2array 7 | 8 | global mygrid; 9 | 10 | if isa(fld,'gcmfaces'); do_gcmfaces2array=1; else; do_gcmfaces2array=0; end; 11 | 12 | if do_gcmfaces2array; 13 | n3=max(size(fld.f1,3),1); n4=max(size(fld.f1,4),1); 14 | n1=size(fld.f1,1)*4; n2=size(fld.f1,2)+size(fld.f1,1); 15 | FLD=squeeze(zeros(n1,n2,n3,n4)); 16 | else; 17 | n3=max(size(fld,3),1); n4=max(size(fld,4),1); 18 | FLD=repmat(NaN*mygrid.XC,[1 1 n3 n4]); 19 | end; 20 | 21 | if do_gcmfaces2array; 22 | %ASSEMBLE "LATLON" FACES: 23 | %---------------------- 24 | FLD0=[fld.f1(:,:,:,:);fld.f2(:,:,:,:);sym_g(fld.f4(:,:,:,:),7,0);sym_g(fld.f5(:,:,:,:),7,0)]; 25 | %ADD POLAR CAP: 26 | %-------------- 27 | pp=fld.f3(:,:,:,:); FLDp=[sym_g(pp,5,0);pp.*NaN;sym_g(pp.*NaN,7,0);sym_g(pp.*NaN,6,0)]; 28 | FLD1=[FLD0 FLDp]; 29 | %store: 30 | %------ 31 | FLD(:,:,:,:)=FLD1; 32 | else; 33 | n1=size(FLD.f1,1); n2=size(FLD.f1,2); 34 | FLD.f1(:,:,:,:)=fld(1:n1,1:n2,:,:); 35 | FLD.f2(:,:,:,:)=fld(n1+[1:n1],1:n2,:,:); 36 | FLD.f3(:,:,:,:)=sym_g(fld([1:n1],n2+1:n2+n1,:,:),7,0); 37 | FLD.f4(:,:,:,:)=sym_g(fld(n1*2+[1:n1],1:n2,:,:),5,0); 38 | FLD.f5(:,:,:,:)=sym_g(fld(n1*3+[1:n1],1:n2,:,:),5,0); 39 | end; 40 | 41 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2array_llpc.m: -------------------------------------------------------------------------------- 1 | function [FLD]=convert2array_llpc(fld); 2 | %object: gcmfaces to array format conversion (if gcmfaces input) 3 | % or: array to gcmfaces format conversion (if array input) 4 | % 5 | %notes: if array input, the gcmfaces format will be the one of mygrid.XC, so 6 | % the array input must have originally been created according to convert2array 7 | 8 | global mygrid; 9 | 10 | if isa(fld,'gcmfaces'); do_gcmfaces2array=1; else; do_gcmfaces2array=0; end; 11 | 12 | if do_gcmfaces2array; 13 | n3=max(size(fld.f1,3),1); n4=max(size(fld.f1,4),1); 14 | n1=size(fld.f1,1)*4; n2=size(fld.f1,2); 15 | FLD=squeeze(zeros(n1,n2,n3,n4)); 16 | else; 17 | n3=max(size(fld,3),1); n4=max(size(fld,4),1); 18 | FLD=NaN*mygrid.XC; 19 | for k3=1:n3; for k4=1:n4; for iFace=1:FLD.nFaces; 20 | iF=num2str(iFace); eval(['FLD.f' iF '(:,:,k3,k4)=FLD.f' iF '(:,:,1,1);']); 21 | end; end; end; 22 | end; 23 | 24 | for k3=1:n3; for k4=1:n4; 25 | 26 | if do_gcmfaces2array; 27 | %ASSEMBLE SIDE FACES: 28 | %---------------------- 29 | FLD1=[fld.f1(:,:,k3,k4);fld.f2(:,:,k3,k4);sym_g(fld.f3(:,:,k3,k4),7,0);sym_g(fld.f4(:,:,k3,k4),7,0)]; 30 | %store: 31 | %------ 32 | FLD(:,:,k3,k4)=FLD1; 33 | else; 34 | n1=size(FLD.f1,1); n2=size(FLD.f1,2); 35 | FLD.f1(:,:,k3,k4)=fld(1:n1,1:n2,k3,k4); 36 | FLD.f2(:,:,k3,k4)=fld(n1+[1:n1],1:n2,k3,k4); 37 | FLD.f3(:,:,k3,k4)=sym_g(fld(n1*2+[1:n1],1:n2,k3,k4),5,0); 38 | FLD.f4(:,:,k3,k4)=sym_g(fld(n1*3+[1:n1],1:n2,k3,k4),5,0); 39 | end; 40 | 41 | end; end; 42 | 43 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2cube.m: -------------------------------------------------------------------------------- 1 | function [fld11]=convert2cube(fld00); 2 | %convert2cube takes a 1 face object and format it as a cube object 3 | 4 | if ~(fld00.nFaces==1&mod(size(fld00{1},1),4)==0); 5 | error('unsupported option'); 6 | end; 7 | 8 | fld11=gcmfaces(6); 9 | n1=size(fld00{1},1)/4; n2=size(fld00{1},2); 10 | fld11{1}=fld00{1}(1:n1,:,:,:); 11 | fld11{2}=fld00{1}(n1+1:2*n1,:,:,:); 12 | fld11{3}=NaN*fld00{1}(1:n1,1:n1,:,:); 13 | fld11{4}=flipdim(permute(fld00{1}(2*n1+1:3*n1,:,:,:),[2 1 3 4]),1); 14 | fld11{5}=flipdim(permute(fld00{1}(3*n1+1:4*n1,:,:,:),[2 1 3 4]),1); 15 | fld11{6}=NaN*fld00{1}(1:n1,1:n1,:,:); 16 | 17 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2pcol.m: -------------------------------------------------------------------------------- 1 | function [X,Y,FLD]=convert2pcol(varargin); 2 | %object: gcmfaces to 'pcolor format' conversion 3 | %inputs: x is longitude (e.g. mygrid.XC) 4 | % y is latitude (e.g. mygrid.YC) 5 | % fld is the 2D field of interest (e.g. mygrid.hFacC(:,:,1)) 6 | %outputs: X,Y,FLD are array versions of x,y,fld 7 | % 8 | %note: this function is designed so that one may readily 9 | % plot the output in geographic coordinates 10 | % using e.g. 'figure; pcolor(X,Y,FLD);' 11 | 12 | input_list_check('convert2pcol',nargin); 13 | 14 | gcmfaces_global; 15 | 16 | c=varargin{1}; 17 | 18 | if isfield(mygrid,'xtrct'); 19 | [X,Y,FLD]=convert2pcol_xtrct(varargin{:}); 20 | elseif strcmp(c.gridType,'llc'); 21 | [X,Y,FLD]=convert2pcol_llc(varargin{:}); 22 | elseif strcmp(c.gridType,'cube'); 23 | [X,Y,FLD]=convert2pcol_cube(varargin{:}); 24 | elseif strcmp(c.gridType,'llpc'); 25 | [X,Y,FLD]=convert2pcol_llpc(varargin{:}); 26 | elseif strcmp(c.gridType,'ll'); 27 | [X,Y,FLD]=convert2pcol_ll(varargin{:}); 28 | else; 29 | error(['convert2pcol not implemented for ' c.gridType '!?']); 30 | end; 31 | 32 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2pcol_ll.m: -------------------------------------------------------------------------------- 1 | function [X,Y,FLD]=convert2pcol_ll(x,y,fld,varargin); 2 | %object: gcmfaces to 'pcolor format' conversion 3 | %inputs: x is longitude (e.g. mygrid.XC) 4 | % y is latitude (e.g. mygrid.YC) 5 | % fld is the 2D field of interest (e.g. mygrid.hFacC(:,:,1)) 6 | %outputs: X,Y,FLD are array versions of x,y,fld 7 | % 8 | %note: this function is designed so that one may readily 9 | % plot the output in geographic coordinates 10 | % using e.g. 'figure; pcolor(X,Y,FLD);' 11 | 12 | k3=1; k4=1; 13 | 14 | global regularizeXC; 15 | if isempty(regularizeXC); 16 | fprintf('\n\nconvert2pcol_ll.m init: by default gcmfaces assumes\n'); 17 | fprintf(' that XC is longitude in the [-180 180] range, and \n'); 18 | fprintf(' if XC shows values outside this range, gcmfaces \n'); 19 | fprintf(' will to enforce this convention in graphs. If this is \n'); 20 | fprintf(' inadequate, you may try to set regularizeXC to 0 below \n\n'); 21 | regularizeXC=1; 22 | end; 23 | 24 | %ASSEMBLE "LATLON" FACES: 25 | %---------------------- 26 | X=x{1}; Y=y{1}; FLD=fld{1}(:,:,k3,k4); 27 | 28 | %FIX DATE CHANGE LINE IN LATLON PART: 29 | %-------------------------------------- 30 | if regularizeXC; 31 | ii=max(find(X(:,1)<=180)); 32 | X=circshift(X,[-ii 0]); X(X>180)=X(X>180)-360; 33 | Y=circshift(Y,[-ii 0]); 34 | FLD=circshift(FLD,[-ii 0]); 35 | end; 36 | 37 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2pcol_llc.m: -------------------------------------------------------------------------------- 1 | function [X,Y,FLD]=convert2pcol_llc(x,y,fld,varargin); 2 | %object: gcmfaces to 'pcolor format' conversion 3 | %inputs: x is longitude (e.g. mygrid.XC) 4 | % y is latitude (e.g. mygrid.YC) 5 | % fld is the 2D field of interest (e.g. mygrid.hFacC(:,:,1)) 6 | %outputs: X,Y,FLD are array versions of x,y,fld 7 | % 8 | %note: this function is designed so that one may readily 9 | % plot the output in geographic coordinates 10 | % using e.g. 'figure; pcolor(X,Y,FLD);' 11 | 12 | k3=1; k4=1; 13 | 14 | %ASSEMBLE "LATLON" FACES: 15 | %---------------------- 16 | X=[x{1};x{2};sym_g(x{4},7,0); sym_g(x{5},7,0)]; 17 | Y=[y{1};y{2};sym_g(y{4},7,0); sym_g(y{5},7,0)]; 18 | FLD=[fld{1}(:,:,k3,k4);fld{2}(:,:,k3,k4);sym_g(fld{4}(:,:,k3,k4),7,0);sym_g(fld{5}(:,:,k3,k4),7,0)]; 19 | 20 | %ADD POLAR CAP: 21 | %-------------- 22 | pp=x{3}; 23 | M1=pp; M1(M1>M1(1,1))=NaN; M1(M1M2(end,1))=NaN; M2(~isnan(M2))=1; 26 | M2=pp; M2(pp<0)=NaN; M2(pp>=0)=1; 27 | M3=pp; M3(M3M3(end,end))=NaN; M3(~isnan(M3))=1; 28 | %M3=NaN*pp; 29 | %M4=pp; M4(M4M4(1,end))=NaN; M4(~isnan(M4))=1; 30 | M4=pp; M4(pp>=0)=NaN; M4(pp<0)=1; 31 | 32 | pp=x{3}; Xp=[sym_g(pp.*M1,5,0);pp.*M2;sym_g(pp.*M3,7,0);sym_g(pp.*M4,6,0)]; X=[X Xp]; 33 | pp=y{3}; Yp=[sym_g(pp.*M1,5,0);pp.*M2;sym_g(pp.*M3,7,0);sym_g(pp.*M4,6,0)]; Y=[Y Yp]; 34 | pp=fld{3}(:,:,k3,k4); FLDp=[sym_g(pp.*M1,5,0);pp.*M2;sym_g(pp.*M3,7,0);sym_g(pp.*M4,6,0)]; FLD=[FLD FLDp]; 35 | 36 | %FIX DATE CHANGE LINE IN LATLON PART: 37 | %-------------------------------------- 38 | s1=size(X); s1=round(s1(2)/2); s2=find(diff(X(:,s1))<-180); 39 | X=circshift(X,[-s2 0]); 40 | Y=circshift(Y,[-s2 0]); 41 | FLD=circshift(FLD,[-s2 0]); 42 | 43 | %ADD POINTS TO FIX DATE CHANGE LINE ELSEWHERE: 44 | %--------------------------------------------- 45 | s1=size(X); s1=round(s1(1)/12); 46 | tmp1=X(1:2*s1,:); tmp1(tmp1>0)=tmp1(tmp1>0)-360; X(1:2*s1,:)=tmp1; 47 | tmp1=X(end-2*s1+1:end,:); tmp1(tmp1<0)=tmp1(tmp1<0)+360; X(end-2*s1+1:end,:)=tmp1; 48 | 49 | X=[X-360;X;X+360]; Y=[Y;Y;Y]; FLD=[FLD;FLD;FLD]; 50 | 51 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2pcol_llpc.m: -------------------------------------------------------------------------------- 1 | function [X,Y,FLD]=convert2pcol_llpc(x,y,fld,varargin); 2 | %object: gcmfaces to 'pcolor format' conversion 3 | %inputs: x is longitude (e.g. mygrid.XC) 4 | % y is latitude (e.g. mygrid.YC) 5 | % fld is the 2D field of interest (e.g. mygrid.hFacC(:,:,1)) 6 | %outputs: X,Y,FLD are array versions of x,y,fld 7 | % 8 | %note: this function is designed so that one may readily 9 | % plot the output in geographic coordinates 10 | % using e.g. 'figure; pcolor(X,Y,FLD);' 11 | 12 | k3=1; k4=1; 13 | 14 | %ASSEMBLE "LATLON" FACES: 15 | %---------------------- 16 | X=[x{1};x{2};sym_g(x{3},7,0); sym_g(x{4},7,0)]; 17 | Y=[y{1};y{2};sym_g(y{3},7,0); sym_g(y{4},7,0)]; 18 | FLD=[fld{1}(:,:,k3,k4);fld{2}(:,:,k3,k4);sym_g(fld{3}(:,:,k3,k4),7,0);sym_g(fld{4}(:,:,k3,k4),7,0)]; 19 | 20 | %FIX DATE CHANGE LINE IN LATLON PART: 21 | %-------------------------------------- 22 | X=circshift(X,[55 0]); 23 | Y=circshift(Y,[55 0]); 24 | FLD=circshift(FLD,[55 0]); 25 | 26 | %ADD POINTS TO FIX DATE CHANGE LINE ELSEWHERE: 27 | %--------------------------------------------- 28 | X=[X(353:end,:);X;X(1:32,:)]; 29 | Y=[Y(353:end,:);Y;Y(1:32,:)]; 30 | FLD=[FLD(353:end,:);FLD;FLD(1:32,:)]; 31 | 32 | tmp1=X(1:64,:); tmp1(tmp1>0)=tmp1(tmp1>0)-360; X(1:64,:)=tmp1; 33 | tmp1=X(353:end,:); tmp1(tmp1<0)=tmp1(tmp1<0)+360; X(353:end,:)=tmp1; 34 | 35 | 36 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2southern.m: -------------------------------------------------------------------------------- 1 | function [fld0]=convert2southern(fld00,varargin); 2 | 3 | if fld00.nFaces==1; fld00=convert2cube(fld00); end; 4 | 5 | n1=size(fld00{1},1); 6 | n2=size(fld00{1},2); 7 | n3=size(fld00{1},3); 8 | n4=size(fld00{1},4); 9 | 10 | %rotate the cube to bring f6 to f3 position 11 | fld11=fld00; fld11.nFaces=6; 12 | fld11{1}=flipdim(permute(fld00{5},[2 1 3 4]),1); 13 | fld11{2}=flipdim(permute(fld00{4},[2 1 3 4]),1); 14 | if ~isempty(fld00.f6); 15 | fld11{3}=fld00{6}; 16 | else; 17 | fld11{3}=NaN*zeros(n1,n1,n3,n4); 18 | end; 19 | fld11{4}=flipdim(permute(fld00{2},[2 1 3 4]),2); 20 | fld11{5}=flipdim(permute(fld00{1},[2 1 3 4]),2); 21 | if ~isempty(fld00.f3); 22 | fld11{6}=fld00{3}; 23 | else; 24 | fld11{6}=NaN*zeros(n1,n1,n3,n4); 25 | end; 26 | 27 | %then call convert2arctic 28 | [fld0]=convert2arctic(fld11,varargin{:}); 29 | 30 | -------------------------------------------------------------------------------- /gcmfaces_convert/convert2vector.m: -------------------------------------------------------------------------------- 1 | function [a]=convert2vector(b,method); 2 | %[a]=CONVERT2VECTOR(b,method); 3 | % converts gcmfaces object b to vector format a -- and vice versa 4 | % when b is instead a vector obtained ealier using convert2vector. 5 | % 6 | % With the 'new' method (default): each 2D field becomes a column vector, 7 | % while the other dimensions remain the same; convert2gcmfaces is used. 8 | % With the 'old' method : convert2array is used and the third+ 9 | % dimensions of b get conflated in the column vector length. 10 | % 11 | % The 'old' method will get removed after updating routines that use convert2vector. 12 | 13 | global mygrid; 14 | 15 | if isa(b,'gcmfaces'); do_gcmfaces2vector=1; else; do_gcmfaces2vector=0; end; 16 | if isempty(whos('method')); method='new'; end; 17 | 18 | if strcmp(method,'new'); 19 | if do_gcmfaces2vector; 20 | bb=convert2gcmfaces(b); 21 | siz=size(bb); if length(siz)==2; siz=[siz 1]; end; 22 | a=reshape(bb,[prod(siz(1:2)) siz(3:end)]); 23 | else; 24 | bb=convert2gcmfaces(mygrid.XC); 25 | siz=size(b); 26 | bb=reshape(b,[size(bb) siz(2:end)]); 27 | a=convert2gcmfaces(bb); 28 | end; 29 | end; 30 | 31 | if strcmp(method,'old'); 32 | if do_gcmfaces2vector; 33 | bb=convert2array(b); 34 | a=bb(:); 35 | else; 36 | bb=convert2array(mygrid.XC); 37 | if mod(length(b(:)),length(bb(:)))~=0; 38 | error('vector length is inconsistent with gcmfaces objects'); 39 | else; 40 | n3=length(b(:))/length(bb(:)); 41 | end; 42 | b=reshape(b,[size(bb) n3]); 43 | a=convert2array(b); 44 | end; 45 | end; 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /gcmfaces_devel/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is meant for routines that are in early stage 3 | development -- until they find a place in another directory. 4 | 5 | -------------------------------------------------------------------------------- /gcmfaces_devel/calc_uvw_nodiv.m: -------------------------------------------------------------------------------- 1 | function [Unodiv,Vnodiv,Wnodiv]=calc_uvw_nodiv(UVELMASS,VVELMASS); 2 | %[Unodiv,Vnodiv,Wnodiv]=calc_uvw_nodiv(UVELMASS,VVELMASS); 3 | % calculates non-divergent U,V,W fields from UVELMASS,VVELMASS 4 | 5 | gcmfaces_global; 6 | 7 | drf=mk3D(mygrid.DRF,UVELMASS); 8 | dxg=mk3D(mygrid.DXG,drf); dyg=mk3D(mygrid.DYG,drf); 9 | facW=drf.*dyg; facS=drf.*dxg; 10 | 11 | %integrate vertically and apply surface mask: 12 | tmpU=nansum(facW.*UVELMASS,3).*mygrid.mskW(:,:,1); 13 | tmpV=nansum(facS.*VVELMASS,3).*mygrid.mskS(:,:,1); 14 | 15 | %compute divergent transport: 16 | [tmpUdiv,tmpVdiv,tmpDivPot]=diffsmooth2D_div_inv(tmpU,tmpV); 17 | 18 | %compute divergent velocity: 19 | tmpU=sum(facW.*mygrid.hFacW,3).*mygrid.mskW(:,:,1); 20 | tmpV=sum(facS.*mygrid.hFacS,3).*mygrid.mskS(:,:,1); 21 | tmpUdiv=tmpUdiv./tmpU; tmpVdiv=tmpVdiv./tmpV; 22 | 23 | Udiv=mk3D(tmpUdiv,drf).*mygrid.hFacW; 24 | Vdiv=mk3D(tmpVdiv,drf).*mygrid.hFacS; 25 | Unodiv=UVELMASS-Udiv; 26 | Vnodiv=VVELMASS-Vdiv; 27 | 28 | %verify result: 29 | %tmpU=nansum(facW.*Unodiv,3).*mygrid.mskW(:,:,1); 30 | %tmpV=nansum(facS.*Vnodiv,3).*mygrid.mskS(:,:,1); 31 | %[tmpUdiv2,tmpVdiv2,tmpDivPot2]=diffsmooth2D_div_inv(tmpU,tmpV); 32 | 33 | %compute vertical component: 34 | tmp=calc_UV_conv(facW.*Unodiv,facS.*Vnodiv); 35 | Wnodiv=cumsum(tmp,3,'reverse')./mk3D(mygrid.RAC,drf); 36 | 37 | 38 | -------------------------------------------------------------------------------- /gcmfaces_devel/example_reformat.m: -------------------------------------------------------------------------------- 1 | 2 | %%%%%%%%%%%%%%%%%%%%%%%% 3 | %format conversions 4 | if myenv.verbose>0; 5 | gcmfaces_msg('* call convert2array : convert from gcmfaces to array format'); 6 | end; 7 | obsArray=convert2array(obsMap);%put in gcmfaces format 8 | if myenv.verbose>0; 9 | gcmfaces_msg('* call convert2array : convert back to gcmfaces'); 10 | end; 11 | obsMap2=convert2array(obsArray);%put in gcmfaces format 12 | if myenv.verbose>0; 13 | gcmfaces_msg('* call convert2gcmfaces : convert from gcmfaces to file format'); 14 | end; 15 | obsOut=convert2gcmfaces(obsMap); %put in gcm input format 16 | if myenv.verbose>0; 17 | gcmfaces_msg('* summarizing data formats:'); 18 | aa=whos('obs*'); 19 | aaa=aa(4); bb=['[' num2str(aaa.size(1)) 'x' num2str(aaa.size(2)) ']']; 20 | bb=fprintf(' %8s %8s %12s : data points (vector)\n',aaa.name,aaa.class,bb); 21 | aaa=aa(2); bb=['[' num2str(aaa.size(1)) 'x' num2str(aaa.size(2)) ']']; 22 | bb=fprintf(' %8s %8s %12s : gridded data (gcmfaces)\n',aaa.name,aaa.class,bb); 23 | aaa=aa(1); bb=['[' num2str(aaa.size(1)) 'x' num2str(aaa.size(2)) ']']; 24 | bb=fprintf(' %8s %8s %12s : array format\n',aaa.name,aaa.class,bb); 25 | aaa=aa(3); bb=['[' num2str(aaa.size(1)) 'x' num2str(aaa.size(2)) ']']; 26 | bb=fprintf(' %8s %8s %12s : output format\n',aaa.name,aaa.class,bb); 27 | end; 28 | 29 | -------------------------------------------------------------------------------- /gcmfaces_devel/flt_traj_init.m: -------------------------------------------------------------------------------- 1 | function []=prep_flt_init(dirOut); 2 | % prep_flt_init(dirOut) creates initial conditions for MITgcm/pkg/flt 3 | % that will be stored into dirOut ('init_flt/' by default). 4 | 5 | %in summary: 6 | %- get tile map 7 | %- skip blank tiles 8 | %- loop over tile 9 | %- select all ocean points 10 | %- add uniform noise to i,j (in the -0.5 to 0.5 I think) 11 | %- output to file (single prec for ini or double for pickup) 12 | 13 | %to do list: 14 | %- add lon, lat (vector?) input arguments and get i,j, etc using `gcmfaces_interp_coeffs` 15 | 16 | if isempty(whos('dirOut')); dirOut=[pwd filesep 'init_flt' filesep]; end; 17 | if ~isdir(dirOut); mkdir(dirOut); end; 18 | 19 | %% 20 | 21 | gcmfaces_global; if isempty(mygrid); grid_load; end; 22 | map_tile=gcmfaces_loc_tile(30,30); 23 | 24 | tmp1=convert2vector(mygrid.mskC(:,:,1).*map_tile); 25 | tmp1=unique(tmp1); 26 | list_tile=tmp1(find(~isnan(tmp1))); 27 | 28 | map_i=NaN*map_tile; map_j=NaN*map_tile; 29 | [tmp_j,tmp_i]=meshgrid(1:30,1:30); 30 | for ff=1:map_i.nFaces; 31 | [m,n]=size(map_i{ff}); 32 | map_i{ff}=repmat(tmp_i,[m/30 n/30]); 33 | map_j{ff}=repmat(tmp_j,[m/30 n/30]); 34 | end; 35 | 36 | %% 37 | 38 | vec_i=convert2vector(map_i); 39 | vec_j=convert2vector(map_j); 40 | vec_tile=convert2vector(map_tile.*mygrid.mskC(:,:,1)); 41 | 42 | kk=0; 43 | for ii=1:length(list_tile); 44 | jj=find(vec_tile==list_tile(ii)); 45 | tmp_i=vec_i(jj); tmp_j=vec_j(jj); 46 | nn=length(jj); 47 | % 48 | tmp1=[nn 1 3600 0 0 9000 9 0 0]; 49 | tmp2=[kk+[1:nn]' -ones(nn,1) tmp_i tmp_j ones(nn,1) zeros(nn,3) -ones(nn,1)]; 50 | arrOut=[tmp1;tmp2]'; 51 | % 52 | filOut=sprintf('%s/init_flt.%03d.001.data',dirOut,ii); 53 | write2file(filOut,arrOut,32); 54 | kk=kk+nn; 55 | end; 56 | 57 | 58 | -------------------------------------------------------------------------------- /gcmfaces_devel/flt_traj_plot.m: -------------------------------------------------------------------------------- 1 | function []=flt_traj_plot(flts,proj,bgrd); 2 | % flt_traj_plot(flts) plots trajectories generated using pkg/flt 3 | % 4 | %A possible calling sequence: 5 | % 6 | %grid_load; 7 | %dirRun='run/'; 8 | %[flts,data,header]=flt_traj_read([dirRun 'float_trajectories'],4); 9 | %flt_traj_plot(flts); 10 | 11 | gcmfaces_global; 12 | 13 | if isempty(whos('proj')); proj=0; end; 14 | 15 | if proj==0; 16 | figure; orient landscape; 17 | col='rgbrgb'; 18 | for ii=1:5; 19 | plot(mygrid.XC{ii}(1:5:end,1:5:end),mygrid.YC{ii}(1:5:end,1:5:end),[col(ii) 'x']); hold on; 20 | end; 21 | for ii=1:length(flts); 22 | x=flts(ii).x; y=flts(ii).y; 23 | jj=find(abs(diff(x))>90); x(jj)=NaN; y(jj)=NaN; 24 | x(end)=NaN; y(end)=NaN; 25 | plot(x,y,'k-'); hold on; 26 | end; 27 | end; 28 | 29 | if proj>0; 30 | 31 | figure; orient landscape; 32 | if isempty(whos('bgrd')); bgrd=mygrid.Depth; end; 33 | m_map_gcmfaces(bgrd,proj,{'myCmap','gray'},{'doCbar',0}); 34 | for jj=1:3; 35 | if jj==1; mrk='r.'; 36 | elseif jj==2; mrk='g.'; 37 | else; mrk='b.'; 38 | end; 39 | mrk='k.'; mrkini='go'; mrkend='co'; 40 | for ii=jj:3:length(flts); 41 | lon=flts(ii).x; lat=flts(ii).y; 42 | if proj==1.2; lon(lon<20)=lon(lon<20)+360; end; 43 | m_map_gcmfaces({'plot',lon,lat,mrk,'MarkerSize',0.5},proj,{'doHold',1}); 44 | m_map_gcmfaces({'plot',lon(1),lat(1),mrkini,'MarkerSize',2},proj,{'doHold',1}); 45 | m_map_gcmfaces({'plot',lon(end-1),lat(end-1),mrkend,'MarkerSize',2},proj,{'doHold',1}); 46 | end; 47 | end; 48 | end; 49 | 50 | -------------------------------------------------------------------------------- /gcmfaces_devel/flt_traj_sel.m: -------------------------------------------------------------------------------- 1 | function [jj]=flt_traj_sel(flts,lons,lats,days); 2 | %lons, lats, days are all pairs 3 | 4 | test0=zeros(size(flts)); 5 | for ii=1:length(flts) 6 | lon=flts(ii).x(1:end-1); 7 | lat=flts(ii).y(1:end-1); 8 | %day=mod(flts(ii).time(1:end-1)/86400,365); 9 | day=flts(ii).time(1:end-1)/86400; 10 | kk=find(lon>lons(1)&lonlats(1)&latdays(1)&daytan(pi/4/2))=NaN;%mask points outside of pi/4 cone 46 | 47 | -------------------------------------------------------------------------------- /gcmfaces_maps/m_map_1face.m: -------------------------------------------------------------------------------- 1 | function []=m_map_1face(fld,iFace,varargin); 2 | %purpose: 3 | % use m_map to display one face in a chosen projection 4 | %synthax: 5 | % m_map_1face(fld,iFace,choiceProj); 6 | %inputs: 7 | % fld is a 2D field in gcmfaces format 8 | % iFace is the face number 9 | % choiceProj is the projection choice (0, 1, 2, or 3) 10 | % if it is not stated, the default is mollweide (0) 11 | 12 | %check that m_map is in the path 13 | aa=which('m_proj'); if isempty(aa); error('this function requires m_map that is missing'); end; 14 | 15 | %get parameters: 16 | if nargin>2; choiceProj=varargin{1}; else; choiceProj=0; end; 17 | if nargin>3; cc=varargin{2}; else; cc=[]; end; 18 | if nargin>4; doPlotCoast=varargin{3}; else; doPlotCoast=1; end; 19 | 20 | global mygrid; 21 | 22 | %extract face: 23 | x=mygrid.XC{iFace}(:,:); 24 | y=mygrid.YC{iFace}(:,:); 25 | z=fld{iFace}(:,:); 26 | m1=mygrid.mskC{iFace}(:,:,1); 27 | if length(size(z))~=2; error('input must be a 2D field in gcmfaces format'); end; 28 | 29 | %put mask on x and y: 30 | x(isnan(m1))=NaN; y(isnan(m1))=NaN; 31 | 32 | %enforce [-180 180] longitude convention; 33 | x(find(x>180))=x(find(x>180))-360; 34 | 35 | %select lat/lon range: 36 | ii=find(~isnan(m1)); 37 | ll=[min(x(ii)) max(x(ii))]; 38 | LL=[min(y(ii)) max(y(ii))]; 39 | 40 | if choiceProj==0; 41 | %%m_proj('Miller Cylindrical','lon',ll,'lat',LL); 42 | %%m_proj('Equidistant cylindrical','lon',ll,'lat',LL); 43 | m_proj('mollweide','lon',ll,'lat',LL); 44 | elseif choiceProj==1; 45 | m_proj('Mercator','lon',ll,'lat',LL); 46 | elseif choiceProj==2; 47 | m_proj('Stereographic','lon',0,'lat',90,'rad',90-LL(1)); 48 | elseif choiceProj==3; 49 | m_proj('Stereographic','lon',0,'lat',-90,'rad',90+LL(2) ); 50 | end; 51 | 52 | [x,y]=m_ll2xy(x,y); 53 | pcolor(x,y,z); shading flat; if ~isempty(cc); caxis(cc); end; colorbar; 54 | if doPlotCoast; m_coast('patch',[1 1 1]*.7,'edgecolor','none'); end; m_grid; 55 | 56 | 57 | -------------------------------------------------------------------------------- /gcmfaces_maps/m_map_fix_range.m: -------------------------------------------------------------------------------- 1 | function [x,y]=m_map_fix_range(x,y); 2 | % [x,y]=M_MAP_FIX_RANGE(x,y) adjust the longitude range depening on MAP_VAR_LIST.ulongs 3 | 4 | global MAP_VAR_LIST; 5 | 6 | if isfield(MAP_VAR_LIST,'ulongs'); 7 | lmin=MAP_VAR_LIST.ulongs(1); 8 | lmax=MAP_VAR_LIST.ulongs(2); 9 | x(find(x>lmax))=x(find(x>lmax))-360; 10 | x(find(xlmax))=x(find(x>lmax))-360; 14 | x(find(x=2); lYear=1; myTimes=[1:length(myTimes)]; end; 23 | 24 | %determine the number of full years (nYears) 25 | nYears=floor(length(myTimes)/lYear); 26 | 27 | %determine records that correspond to myYear, which 28 | % may be 'first','last',n (an integer) or 'all' 29 | if ischar(myYear); 30 | if strcmp(myYear,'first'); 31 | recInAve=[1:lYear]; 32 | elseif strcmp(myYear,'last'); 33 | recInAve=[1:lYear]+(nYears-1)*lYear; 34 | elseif strcmp(myYear,'all'); 35 | recInAve=[1:nYears*lYear]; 36 | else; 37 | error('inconsistent specification of myYear'); 38 | end; 39 | elseif (myYear>=1)&(myYear<=nYears); 40 | recInAve=[1:lYear]+(myYear-1)*lYear; 41 | else; 42 | error('inconsistent specification of myYear'); 43 | end; 44 | nRecs=length(recInAve); 45 | 46 | %determine last dimension, which need to match the length myTimes 47 | if strcmp(class(myFld),'gcmfaces'); nDim=size(myFld{1}); else; nDim=size(myFld); end; 48 | if length(myTimes)>1; 49 | if nDim(end)~=length(myTimes); 50 | error('last dimension should match the length of myTimes'); 51 | end; 52 | nDim=length(nDim); tt=''; for jj=1:nDim-1; tt=[tt ':,']; end; 53 | else; 54 | nDim=length(nDim)+1; tt=''; for jj=1:nDim-1; tt=[tt ':,']; end; 55 | end; 56 | 57 | %compute time mean: 58 | eval(['myMean=mean(myFld(' tt 'recInAve),nDim);']); 59 | 60 | %compute anomaly: 61 | if nargout>1; 62 | myAnom=myFld-repmat(myMean,[ones(1:nDim-1) length(myTimes)]); 63 | end; 64 | 65 | -------------------------------------------------------------------------------- /gcmfaces_misc/ccaa.m: -------------------------------------------------------------------------------- 1 | %abbreviation for clear all; close all; 2 | clear all; close all; 3 | -------------------------------------------------------------------------------- /gcmfaces_misc/check_budg.m: -------------------------------------------------------------------------------- 1 | function [prec]=check_budg(budgIn,kk); 2 | %function [prec]=check_budg(budgIn,kk); 3 | % 4 | %inputs: budgIn is a structure containting tend, trU, trV, trWtop, 5 | % trWbot (calling sequence reported in check_loop.m) 6 | % kk is a vertical level (0 for all levels) 7 | %outputs: prec contains 3 measures of residual errors 8 | 9 | gcmfaces_global; 10 | 11 | tend=budgIn.tend; 12 | trU=budgIn.trU; 13 | trV=budgIn.trV; 14 | trWtop=budgIn.trWtop; 15 | trWbot=budgIn.trWbot; 16 | 17 | dt=1; 18 | units='1'; 19 | %dt=budgIn.t1-budgIn.t0; 20 | %units = budgIn.specs.units; 21 | 22 | %define northern hemisphere as domain of integration 23 | nameMask='Northern Hemisphere'; 24 | mask=mygrid.mskC.*mk3D(mygrid.YC>0,mygrid.mskC); 25 | if length(size(tend{1}))<3; mask=mask(:,:,1); end; 26 | 27 | %focus on one level 28 | if kk>0; 29 | mask=mask(:,:,kk); 30 | tend=tend(:,:,kk); 31 | trU=trU(:,:,kk); 32 | trV=trV(:,:,kk); 33 | trWtop=trWtop(:,:,kk); 34 | trWbot=trWbot(:,:,kk); 35 | end; 36 | 37 | %edit plot title accordingly 38 | descr=nameMask; 39 | 40 | %compute northern hemisphere integrals 41 | budg.tend=NaN*dt; 42 | budg.hconv=NaN*dt; 43 | budg.zconv=NaN*dt; 44 | 45 | %compute flux convergence 46 | hconv=calc_UV_conv(trU,trV,{}); 47 | zconv=(trWbot-trWtop); 48 | 49 | %compute local residuals 50 | hconv(tend==0)=NaN; 51 | zconv(tend==0)=NaN; 52 | tend(tend==0)=NaN; 53 | 54 | %compute local residuals 55 | norm=sqrt(tend.^2+hconv.^2+zconv.^2); 56 | res=abs(tend-hconv-zconv); 57 | 58 | %compute sum over domain 59 | budg.tend=nansum(tend.*mask); 60 | budg.hconv=nansum(hconv.*mask); 61 | budg.zconv=nansum(zconv.*mask); 62 | % 63 | budg.res=abs(budg.tend-budg.hconv-budg.zconv); 64 | budg.norm=sqrt(budg.tend.^2+budg.hconv.^2+budg.zconv.^2); 65 | 66 | %output result 67 | prec(1,1)=nanmedian(res)/nanmedian(norm); 68 | prec(1,2)=nanmax(res./norm); 69 | prec(1,3)=budg.res/budg.norm; 70 | 71 | -------------------------------------------------------------------------------- /gcmfaces_misc/check_loop.m: -------------------------------------------------------------------------------- 1 | 2 | dirIn='release1/nctiles_budg/budgMo/' 3 | 4 | for tt=1:238; 5 | tt 6 | budgIn.tend=read_nctiles([dirIn 'tend/tend'],'tend',tt); 7 | budgIn.trU=read_nctiles([dirIn 'trU/trU'],'trU',tt); 8 | budgIn.trV=read_nctiles([dirIn 'trV/trV'],'trV',tt); 9 | if dirIn(end-1)=='o'; 10 | budgIn.trW=read_nctiles([dirIn 'trW/trW'],'trW',tt); 11 | % 12 | budgIn.trWtop=budgIn.trW; 13 | budgIn.trWbot=budgIn.trW(:,:,2:50); 14 | budgIn.trWbot(:,:,50)=0; 15 | % 16 | %budgIn.tend(isnan(tend))=0; 17 | %budgIn.trU(isnan(trU))=0; budgIn.trV(isnan(trV))=0; 18 | %budgIn.trWtop(isnan(trWtop))=0; budgIn.trWbot(isnan(trWbot))=0; 19 | else; 20 | budgIn.trWtop=read_nctiles([dirIn 'trWtop/trWtop'],'trWtop',tt); 21 | budgIn.trWbot=read_nctiles([dirIn 'trWbot/trWbot'],'trWbot',tt); 22 | end; 23 | % 24 | nr=size(budgIn.tend{1},3); 25 | for kk=1:nr; prec(kk,:)=check_budg(budgIn,kk); end; 26 | if 0; 27 | figureL; 28 | plot(log10(prec(:,1)),'b'); 29 | hold on; 30 | plot(log10(prec(:,2)),'r'); 31 | plot(log10(prec(:,3)),'k'); 32 | title(num2str(tt)); 33 | end;%if 0; 34 | if tt==1; 35 | store_prec=prec; 36 | else; 37 | store_prec(:,:,tt)=prec; 38 | end; 39 | end;%for tt=[1 119 238]; 40 | 41 | max(store_prec(:)) 42 | eval(['save ' dirIn 'residuals.mat store_prec;']); 43 | 44 | -------------------------------------------------------------------------------- /gcmfaces_misc/check_snap.m: -------------------------------------------------------------------------------- 1 | 2 | listBudgs={'budgMo','budgHo','budgSo','budgMi','budgHi','budgSi'}; 3 | dt=(0000174564-0000000732)*3600; 4 | for ii=1:length(listBudgs); 5 | budgName=listBudgs{ii}; 6 | fil=['r4it11.c65i/nctiles_budg/' budgName '/tend/tend']; 7 | ncload([fil '.0001.nc'],'t0'); ncload([fil '.0001.nc'],'t1'); 8 | tend=0*mygrid.hFacC; 9 | if ii>3; tend=tend(:,:,1); end; 10 | 11 | for tt=1:length(t0); 12 | tmp1=read_nctiles(['r4it11.c65i/nctiles_budg/' budgName '/tend/tend'],'tend',tt); 13 | tend=tend+(t1(tt)-t0(tt))*tmp1; 14 | end; 15 | ini=read_nctiles(['r4it11.c65i/nctiles_budg/' budgName '/initial/snapshot'],'snapshot'); 16 | fin=read_nctiles(['r4it11.c65i/nctiles_budg/' budgName '/final/snapshot'],'snapshot'); 17 | 18 | test0=nanstd((fin-ini)-tend)/nanstd(tend); 19 | fprintf('%s : %3.2g \n',budgName,test0); 20 | 21 | end; 22 | 23 | 24 | -------------------------------------------------------------------------------- /gcmfaces_misc/convertR4toR4nonan.m: -------------------------------------------------------------------------------- 1 | function []=convertR4toR4nonan(fileIn,fileOut); 2 | %object: read R4 fileIn, replace NaN with 0, write R4 fileOut 3 | %inputs: fileIn and fileOut 4 | 5 | tmp1=dir(fileIn); 6 | tmp1=tmp1.bytes/4; 7 | fid=fopen(fileIn,'r','b'); tmp2=fread(fid,tmp1,'float32'); fclose(fid); 8 | tmp2(find(isnan(tmp2)))=0; 9 | fid=fopen(fileOut,'w','b'); fwrite(fid,tmp2,'float32'); fclose(fid); 10 | 11 | 12 | -------------------------------------------------------------------------------- /gcmfaces_misc/convertR8toR4.m: -------------------------------------------------------------------------------- 1 | function []=convertR8toR4(fileIn,fileOut); 2 | %object: read R8 fileIn, write R4 fileOut 3 | %inputs: fileIn and fileOut 4 | 5 | tmp1=dir(fileIn); 6 | tmp1=tmp1.bytes/8; 7 | fid=fopen(fileIn,'r','b'); tmp2=fread(fid,tmp1,'float64'); fclose(fid); 8 | fid=fopen(fileOut,'w','b'); fwrite(fid,tmp2,'float32'); fclose(fid); 9 | 10 | 11 | -------------------------------------------------------------------------------- /gcmfaces_misc/depthStretch.m: -------------------------------------------------------------------------------- 1 | function [z]=depthStretch(d,varargin) 2 | %object: compute stretched depth coordinate 3 | %inputs: d is the depth vector (>=0) 4 | %optional: depthStretchLim are the stretching depth limits ([0 500 6000] by default) 5 | % 6 | %this routine maps 7 | %[depthStretchLim(1) depthStretchLim(2)] to [1 0] 8 | %[depthStretchLim(2) depthStretchLim(3)] to [0 -1] 9 | 10 | if nargin>1; depthStretchLim=varargin{1}; else; depthStretchLim=[0 500 6000]; end; 11 | 12 | zStretchLim=[1 0 -1]; 13 | 14 | %make sure depth is positive 15 | d=abs(d); 16 | 17 | %initialize stretched vertical coordinate 18 | z=zeros(size(d)); 19 | 20 | %values between 0 and depthStretchLim(2) get half the range of z 21 | tmp1=find(d<=depthStretchLim(2)); 22 | tmp2=(depthStretchLim(2)-d(tmp1))./(depthStretchLim(2)-depthStretchLim(1))... 23 | .*(zStretchLim(1)-zStretchLim(2))+zStretchLim(2); 24 | z(tmp1)=tmp2; 25 | 26 | %values between depthStretchLim(2) and depthStretchLim(3) get the other half z range 27 | tmp1=find(d>depthStretchLim(2)); 28 | tmp2=(d(tmp1)-depthStretchLim(2))./(depthStretchLim(3)-depthStretchLim(2))... 29 | .*(zStretchLim(3)-zStretchLim(2))+zStretchLim(2); 30 | z(tmp1)=tmp2; 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /gcmfaces_misc/depthStretchPlot.m: -------------------------------------------------------------------------------- 1 | function [varargout]=depthStretchPlot(plotName,plotData,varargin); 2 | %object: front end to plot/pcolor/etc. using a stretched depth coordinate (see depthStretch.m) 3 | %inputs: plotName is the name of the plotting routine (e.g. 'pcolor') 4 | % plotData is the list or arguments to pass over to the plotting routine 5 | % in a cell array (e.g. {depth,time,temperature}), with the 6 | % depth coordinate coming second (as usual for plot/pcolor/etc.) 7 | %optional: depthTics is the vector of yTics depths 8 | % depthStretchLim are the stretching depth limits ([0 500 6000] by default) 9 | % to pass over to depthStretch (type 'help depthStretch' for details). 10 | % 11 | %notes: the depth coordinate must be first in plotData 12 | 13 | %get depthStretchDef if provided 14 | if nargin>2; depthTics=varargin{1}; else; depthTics=[0:100:500 750 1000:500:6000]; end; 15 | if nargin>3; depthStretchDef=varargin{2}; else; depthStretchDef=[0 500 6000]; end; 16 | 17 | %replace it with stretched coordinate: 18 | plotData{2}=depthStretch(abs(plotData{2}),depthStretchDef); 19 | 20 | %do the very plot: 21 | eval(['h=' plotName '(plotData{:});']); 22 | 23 | %take care of depth tics in stretched coordinate: 24 | depthTics=sort(depthTics,'descend'); 25 | 26 | depthTicsLabel=[]; 27 | for kkk=1:length(depthTics) 28 | depthTicsLabel=strvcat(depthTicsLabel,num2str(depthTics(kkk))); 29 | end 30 | 31 | depthTics=depthStretch(depthTics,depthStretchDef); 32 | set(gca,'YTick',depthTics); 33 | set(gca,'YTickLabel',depthTicsLabel); 34 | 35 | %output plot handle: 36 | if nargout>0; varargout={h}; end; 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /gcmfaces_misc/disp_budget_mean_mask.m: -------------------------------------------------------------------------------- 1 | function []=disp_budget_mean_mask(tim,budg,uni,tit); 2 | %object : plot a budget from budget_integr 3 | %inputs: tim is the time vector (in days) 4 | % budg is the result of budget_integr (in e.g. m^3/s) 5 | % uni is the unit to be displayed 6 | % tit is the variable description to be displayed 7 | %display: cumulative sum of budg*median(dt) 8 | 9 | %scale the budget terms, and integrate in time: 10 | dt=365.25*median(diff(tim));%in days 11 | if isnan(dt); dt=1; end;%assume annual mean 12 | dt=dt*86400;%in seconds 13 | cont=dt*cumsum(budg(1,:)); 14 | hdiv=dt*cumsum(budg(2,:)); 15 | zdiv=dt*cumsum(budg(3,:)); 16 | 17 | %do the plotting: 18 | plot(tim,cont,'b','LineWidth',1); hold on; 19 | plot(tim,zdiv,'r','LineWidth',1); 20 | plot(tim,hdiv,'g','LineWidth',1); 21 | plot(tim,cont-zdiv-hdiv,'k','LineWidth',1); 22 | %finish the plot: 23 | tmp1=max(abs(cont)); tmp2=max(abs(zdiv)); tmp3=max(tmp1,tmp2)*1.5; 24 | if tmp3~=0&std(tim)~=0; axis([min(tim) max(tim) -tmp3 tmp3]); end; 25 | grid on; legend('content','vert. div.','hor. div.','residual','Orientation','horizontal'); 26 | res=sqrt(mean((cont-zdiv-hdiv).^2)); 27 | title(sprintf('Budget %s; in %s; residual : %0.1e',tit,uni,res)); 28 | 29 | %set the axis range : symmetric about 0 and rounded up 30 | aa=axis; 31 | tmp1=max(abs(cont)); 32 | tmp2=ceil(log10(tmp1)); 33 | tmp2=10^tmp2; 34 | tmp3=2*tmp2*round(tmp1/tmp2*10)/10; 35 | if ~isnan(tmp3); aa(3:4)=tmp3*[-1 1]; end; 36 | axis(aa); 37 | 38 | %print to screen: 39 | if ~isempty(strfind(tit,'Mass')); tmp0='Mass'; 40 | elseif ~isempty(strfind(tit,'Heat')); tmp0='Heat'; 41 | elseif ~isempty(strfind(tit,'Salt')); tmp0='Salt'; 42 | else; tmp0='????'; 43 | end; 44 | tmp1=round(log10(sqrt(mean((cont).^2)))); 45 | tmp2=round(log10(sqrt(mean((cont-zdiv-hdiv).^2)))); 46 | fprintf('%5s budget [log10(cont) | log10(res)] %3i | %3i\n',tmp0,tmp1,tmp2); 47 | 48 | 49 | -------------------------------------------------------------------------------- /gcmfaces_misc/disp_budget_mean_zonal.m: -------------------------------------------------------------------------------- 1 | function []=disp_budget_mean_zonal(lat,budg,uni,tit); 2 | %object : plot a budget from budget_integr 3 | %inputs: lat is the latitude vector 4 | % budg is the result of budget_integr (in e.g. m^3/s) 5 | % uni is the unit to be displayed 6 | % tit is the variable description to be displayed 7 | %display: cumulative sum of budg*median(dt) 8 | 9 | gcmfaces_global; global myparms; 10 | 11 | %scaled the budget terms, and integrate in time: 12 | nyears=[myparms.yearInAve(2)-myparms.yearInAve(1)]; 13 | dt=365*86400*nyears; 14 | cont=sum(dt*budg(1,:,:),3); 15 | hdiv=sum(dt*budg(2,:,:),3); 16 | zdiv=sum(dt*budg(3,:,:),3); 17 | 18 | %do the plotting: 19 | plot(lat,cont,'b','LineWidth',1); hold on; 20 | plot(lat,zdiv,'r','LineWidth',1); 21 | plot(lat,hdiv,'g','LineWidth',1); 22 | plot(lat,cont-zdiv-hdiv,'k','LineWidth',1); 23 | %finish the plot: 24 | tmp1=max(abs(cont)); tmp2=max(abs(zdiv)); tmp3=max(tmp1,tmp2)*1.5; 25 | if tmp3~=0&std(lat)~=0; axis([min(lat) max(lat) -tmp3 tmp3]); end; 26 | grid on; legend('content','vert. div.','hor. div.','residual','Orientation','horizontal'); 27 | res=sqrt(mean((cont-zdiv-hdiv).^2)); 28 | title(sprintf('Budget %s scaled by %d years; in %s; residual : %0.1e',tit,nyears,uni,res)); 29 | 30 | %set the axis range : symmetric about 0 and rounded up 31 | aa=axis; 32 | tmp1=max(abs(hdiv)); 33 | tmp2=ceil(log10(tmp1)); 34 | tmp2=10^tmp2; 35 | tmp3=2*tmp2*round(tmp1/tmp2*10)/10; 36 | if ~isnan(tmp3); aa(3:4)=tmp3*[-1 1]; end; 37 | axis(aa); 38 | 39 | %print to screen: 40 | if ~isempty(strfind(tit,'Mass')); tmp0='Mass'; 41 | elseif ~isempty(strfind(tit,'Heat')); tmp0='Heat'; 42 | elseif ~isempty(strfind(tit,'Salt')); tmp0='Salt'; 43 | else; tmp0='????'; 44 | end; 45 | tmp1=round(log10(sqrt(mean((cont).^2)))); 46 | tmp2=round(log10(sqrt(mean((cont-zdiv-hdiv).^2)))); 47 | fprintf('%5s budget [log10(cont) | log10(res)] %3i | %3i\n',tmp0,tmp1,tmp2); 48 | 49 | 50 | -------------------------------------------------------------------------------- /gcmfaces_misc/figureL.m: -------------------------------------------------------------------------------- 1 | 2 | % figure; set(gcf,'Units','Normalized','Position',[0.1 0.2 0.8 0.8]); 3 | % figure; set(gcf,'Units','Normalized','Position',[0. 0.2 0.4 0.8]); 4 | % figure; set(gcf,'Units','Normalized','Position',[-1.7 0.2 0.8 0.8]); 5 | figure; 6 | -------------------------------------------------------------------------------- /gcmfaces_misc/gcmfaces_polygonangle.m: -------------------------------------------------------------------------------- 1 | function [angsum]=gcmfaces_polygonangle(px,py,x,y); 2 | %[angsum]=gcmfaces_polygonangle(px,py,x,y); 3 | %object: compute sum of interior angles for polygons (when input 4 | % is px,py) or points vs polygons (when input is px,py,x,y) 5 | %inputs: px,py are MxN matrices where each line specifies one polygon 6 | %(optional) x,y are position vectors 7 | %outputs: ang are the corresponding sums of interior angles 8 | 9 | M=size(px,1); N=size(px,2); 10 | doPointsInPolygon=0; P=1; 11 | if nargin>2; 12 | doPointsInPolygon=1; 13 | sizxy=size(x); 14 | x=reshape(x,[1 prod(sizxy)]); 15 | y=reshape(y,[1 prod(sizxy)]); 16 | P=length(x); 17 | end; 18 | 19 | angsum=zeros(M,P); 20 | for ii=0:N-1; 21 | ppx=circshift(px,[0 -ii]); 22 | ppy=circshift(py,[0 -ii]); 23 | 24 | if ~doPointsInPolygon; 25 | %compute sum of corner angles 26 | v1x=ppx(:,2)-ppx(:,1); 27 | v1y=ppy(:,2)-ppy(:,1); 28 | v2x=ppx(:,4)-ppx(:,1); 29 | v2y=ppy(:,4)-ppy(:,1); 30 | else; 31 | %compute sum of sector angles 32 | v1x=ppx(:,1)*ones(1,P)-ones(M,1)*x; 33 | v1y=ppy(:,1)*ones(1,P)-ones(M,1)*y; 34 | v2x=ppx(:,2)*ones(1,P)-ones(M,1)*x; 35 | v2y=ppy(:,2)*ones(1,P)-ones(M,1)*y; 36 | end; 37 | g_acos=acos( ( v1x.*v2x+v1y.*v2y )./sqrt( v1x.*v1x+v1y.*v1y )./sqrt( v2x.*v2x+v2y.*v2y ) ); 38 | g_sin= ( v1x.*v2y-v1y.*v2x )./sqrt( v1x.*v1x+v1y.*v1y )./sqrt( v2x.*v2x+v2y.*v2y ) ; 39 | angsum=angsum+radtodeg(g_acos.*sign(g_sin)); 40 | end; 41 | 42 | -------------------------------------------------------------------------------- /gcmfaces_misc/input_list_check.m: -------------------------------------------------------------------------------- 1 | function []=input_list_check(myFunction,myNargin); 2 | %object: print warning/error messages related to 3 | % changes in arguments lists (June 2011). 4 | %inputs: myFunction: name of the calling routine 5 | % myNargin: number of arguments passed to the calling routine 6 | 7 | if strcmp(myFunction,'convert2gcmfaces')&myNargin~=1; 8 | warning('inputCheck:convert2gcmfaces',... 9 | ['As of june 2011, convert2gcmfaces.m expects only \n' ... 10 | ' one input argument. The others were dismissed.\n' ... 11 | ' Type ''help convert2gcmfaces'' for details.']); 12 | end; 13 | 14 | if strcmp(myFunction,'convert2array')&myNargin~=1; 15 | warning('inputCheck:convert2array',... 16 | ['As of june 2011, convert2array.m expects only \n' ... 17 | ' one input argument. The other ones are dismissed.\n' ... 18 | ' Type ''help convert2array'' for details.']); 19 | end; 20 | 21 | if strcmp(myFunction,'convert2pcol')&myNargin~=3; 22 | warning('inputCheck:convert2pcol',... 23 | ['As of june 2011, convert2pcol.m expects only \n' ... 24 | ' three input arguments. The other ones are dismissed.\n' ... 25 | ' Type ''help convert2pcol'' for details.']); 26 | end; 27 | 28 | if strcmp(myFunction,'plot_one_field')&myNargin>1; 29 | error('inputCheck:plot_one_field',... 30 | ['As of March 2015, plot_one_field.m is a \n' ... 31 | 'function with 0 or 1 input argument. \n'... 32 | 'Type ''help plot_one_field'' for details.\n']); 33 | end; 34 | 35 | if strcmp(myFunction,'plot_std_field')&myNargin>0; 36 | error('inputCheck:plot_std_field',... 37 | ['As of March 2015, plot_std_field.m is a \n' ... 38 | 'function without input argument. \n'... 39 | 'Type ''help plot_std_field'' for details.\n']); 40 | end; 41 | 42 | -------------------------------------------------------------------------------- /gcmfaces_misc/sym_g.m: -------------------------------------------------------------------------------- 1 | function [field_out]=sym_g(field_in,sym_in,op_in); 2 | %apply symmetry in the complex plane to field_in(z) 3 | % where field_in and z are in the complex arrays. 4 | %then, depending on op_in, we apply a compensating operation 5 | % 6 | %format of field_in: 7 | % z(1,:) is z=-1+?i, z(end,:) is z=1+?i 8 | % z(:,1) is z=?-i, z(:,end) is z=?+i 9 | % 10 | %sym_in: 1,2,3,4 are reflexions about x=0,y=0,x=y,x=-y 11 | % 4+nRot is rotation by nRot*pi/2 12 | % 0 just returns the input field as output 13 | %op_in: 1 apply the opposite complex operation 14 | 15 | field_out=field_in; 16 | if isempty(whos('op_in')); op_in=0; end; 17 | 18 | if sym_in==0; 19 | %do nothing 20 | elseif sym_in==1; 21 | field_out=flipdim(field_in,1); 22 | if op_in==1; field_out=-real(field_out)+i*imag(field_out); end; 23 | elseif sym_in==2; 24 | field_out=flipdim(field_in,2); 25 | if op_in==1; field_out=real(field_out)-i*imag(field_out); end; 26 | elseif sym_in==3; 27 | field_out=permute(field_in,[2,1,3,4]); 28 | if op_in==1; field_out=imag(field_out)+i*real(field_out); end; 29 | elseif sym_in==4; 30 | field_out=flipdim(permute(flipdim(field_in,1),[2,1,3,4]),1); 31 | if op_in==1; field_out=-imag(field_out)-i*real(field_out); end; 32 | elseif sym_in>=5&sym_in<=7; 33 | for icur=1:sym_in-4; 34 | field_out=flipdim(permute(field_out,[2,1,3,4]),1); 35 | if op_in==1; field_out=i*field_out; end; 36 | end 37 | else; 38 | fprintf('error in sym_g2\n'); return; 39 | end; 40 | 41 | %for test case: 42 | %-------------- 43 | %xx=[1:10]'*ones(1,10); yy=xx'; 44 | %zz=zeros(10,10); zz(1:2,1:3)=1; zz(8,9)=2; zz(2,6:8)=-1; zz(7,3)=-2; 45 | %sym_g(zz,1); %etc 46 | %with the following uncommented: 47 | %------------------------------- 48 | %figure; 49 | %subplot(2,2,1); imagesc(field_in); 50 | %subplot(2,2,4); imagesc(field_out); 51 | %xlabel('y'); xlabel('x'); 52 | 53 | 54 | -------------------------------------------------------------------------------- /gcmfaces_smooth/diffsmooth2D.m: -------------------------------------------------------------------------------- 1 | function [FLD]=diffsmooth2D(fld,dxCsm,dyCsm); 2 | %object: diffusive smoother (after Weaver and Courtier 2001) 3 | % 4 | %input: fld field to be smoothed (masked with NaN) 5 | % dxCsm,dyCsm scale in first/second grid direction 6 | %output:FLD smoothed field 7 | % 8 | %asumption: dxCsm/dyCsm are given at U/V points (as DXC/DYC are) 9 | 10 | global mygrid; 11 | 12 | %scale the diffusive operator: 13 | dxC=mygrid.DXC; dyC=mygrid.DYC; 14 | 15 | tmp0=dxCsm./dxC; tmp0(isnan(fld))=NaN; tmp00=nanmax(tmp0); 16 | tmp0=dyCsm./dyC; tmp0(isnan(fld))=NaN; tmp00=max([tmp00 nanmax(tmp0)]); 17 | nbt=tmp00; 18 | nbt=ceil(1.1*2*nbt^2); 19 | 20 | dt=1; 21 | T=nbt*dt; 22 | 23 | %diffusion operator: 24 | Kux=dxCsm.*dxCsm/T/2; 25 | Kvy=dyCsm.*dyCsm/T/2; 26 | 27 | %setup problem: 28 | myOp.dt=1; 29 | myOp.nbt=nbt; 30 | myOp.Kux=Kux; 31 | myOp.Kvy=Kvy; 32 | 33 | %time step problem: 34 | FLD=gcmfaces_timestep(myOp,fld); 35 | -------------------------------------------------------------------------------- /gcmfaces_smooth/diffsmooth2D_extrap_fwd.m: -------------------------------------------------------------------------------- 1 | function [FLD]=diffsmooth2D_extrap_fwd(fld,mskOut,eps); 2 | %object: extrapolate an incomplete field to create a full field, by 3 | % time-stepping a diffusion equation to near-equilibrium. 4 | %inputs: fld incomplete field of interest (masked with NaN) 5 | % mskOut land mask (1s and NaNs) for the full field (output) 6 | % eps convergence criterium 7 | %output: FLD full field 8 | 9 | global mygrid; 10 | 11 | dxC=mygrid.DXC; dyC=mygrid.DYC; 12 | rA=mygrid.RAC; 13 | 14 | dxCsm=dxC; dyCsm=dyC; 15 | 16 | %mask of points which values will evolve 17 | doStep=1*(isnan(fld)); 18 | 19 | %put first guess: 20 | x=convert2array(mygrid.XC); 21 | y=convert2array(mygrid.YC); 22 | z=convert2array(fld); 23 | m=convert2array(mskOut); 24 | tmp1=find(~isnan(z)); 25 | tmp2=find(~isnan(m)); 26 | zz=z; 27 | zz(tmp2) = griddata(x(tmp1),y(tmp1),z(tmp1),x(tmp2),y(tmp2),'nearest'); 28 | fld=convert2array(zz); 29 | 30 | %put 0 first guess if needed and switch land mask: 31 | fld(find(isnan(fld)))=0; fld=fld.*mskOut; 32 | 33 | %scale the diffusive operator: 34 | tmp0=dxCsm./dxC; tmp0(isnan(mskOut))=NaN; tmp00=nanmax(tmp0); 35 | tmp0=dyCsm./dyC; tmp0(isnan(mskOut))=NaN; tmp00=max([tmp00 nanmax(tmp0)]); 36 | smooth2D_nbt=tmp00; 37 | smooth2D_nbt=ceil(1.1*2*smooth2D_nbt^2); 38 | 39 | smooth2D_dt=1; 40 | smooth2D_T=smooth2D_nbt*smooth2D_dt; 41 | smooth2D_Kux=dxCsm.*dxCsm/smooth2D_T/2; 42 | smooth2D_Kvy=dyCsm.*dyCsm/smooth2D_T/2; 43 | 44 | %setup problem: 45 | myOp.dt=1; 46 | myOp.eps=eps; 47 | myOp.Kux=smooth2D_Kux; 48 | myOp.Kvy=smooth2D_Kvy; 49 | myOp.doStep=doStep; 50 | 51 | %time step problem: 52 | FLD=gcmfaces_timestep(myOp,fld); 53 | 54 | 55 | -------------------------------------------------------------------------------- /gcmfaces_smooth/diffsmooth2Drotated.m: -------------------------------------------------------------------------------- 1 | function [FLD]=diffsmooth2Drotated(fld,dxLarge,dxSmall,fldRef); 2 | % 3 | %object: slanted diffusive smoother (after Weaver and Courtier 2001) 4 | % 5 | %input: fld field to be smoothed (masked with NaN) 6 | % dxLarge,dySmall smoothing scale in direction of 7 | % weak,strong fldRef gradient 8 | % fldRef tracer field which gradient defines 9 | % directions of strong,weak smoothing 10 | %output:FLD smoothed field 11 | % 12 | %asumption: dxLarge/dxSmall are given at tracer points (not U/V points) 13 | 14 | global mygrid; 15 | 16 | dxC=mygrid.DXC; dyC=mygrid.DYC; 17 | dxG=mygrid.DXG; dyG=mygrid.DYG; 18 | rA=mygrid.RAC; 19 | 20 | %scale the diffusive operator: 21 | tmp0=dxLarge./dxC; tmp0(isnan(fld))=NaN; tmp00=nanmax(tmp0); 22 | tmp0=dxLarge./dyC; tmp0(isnan(fld))=NaN; tmp00=max([tmp00 nanmax(tmp0)]); 23 | nbt=tmp00; 24 | nbt=ceil(1.1*2*nbt^2); 25 | 26 | dt=1; 27 | T=nbt*dt; 28 | 29 | %diffusion operator: 30 | kLarge=dxLarge.*dxLarge/T/2; 31 | kSmall=dxSmall.*dxSmall/T/2; 32 | [Kux,Kuy,Kvx,Kvy]=diffrotated(kLarge,kSmall,fldRef); 33 | 34 | %setup problem: 35 | myOp.dt=1; 36 | myOp.nbt=nbt; 37 | myOp.Kux=Kux; 38 | myOp.Kuy=Kuy; 39 | myOp.Kvx=Kvx; 40 | myOp.Kvy=Kvy; 41 | 42 | %time step problem: 43 | FLD=gcmfaces_timestep(myOp,fld); 44 | 45 | -------------------------------------------------------------------------------- /sample_analysis/example_IO.m: -------------------------------------------------------------------------------- 1 | function []=example_IO(); 2 | % 3 | % EXAMPLE_IO computes and displays a standard deviation field 4 | % 5 | % stand-alone call: 6 | % addpath gcmfaces/sample_analysis/; example_IO; 7 | % 8 | % needed input files: 9 | % mkdir release2 10 | % wget --recursive ftp://mit.ecco-group.org/ecco_for_las/version_4/release2/nctiles_climatology/ETAN 11 | % mv mit.ecco-group.org/ecco_for_las/version_4/release2/nctiles_climatology release2_climatology/. 12 | 13 | gcmfaces_global; 14 | 15 | input_list_check('example_IO',nargin); 16 | 17 | %expected location: 18 | myenv.nctilesdir=fullfile(pwd,'/release2_climatology/nctiles_climatology/ETAN/'); 19 | %if ETAN is not found then try old locations: 20 | if ~isdir(myenv.nctilesdir); 21 | %if not found then try old location: 22 | tmpdir=fullfile(pwd,'/release2_climatology/nctiles_climatology/ETAN/'); 23 | if isdir(tmpdir); myenv.nctilesdir=tmpdir; end; 24 | end; 25 | %if ETAN is still not found then issue warning and skip example_IO 26 | if ~isdir(myenv.nctilesdir); 27 | help example_IO; 28 | warning('example_IO requires release2_climatology/nctiles_climatology/ETAN that was not found ---> abort!'); 29 | return; 30 | end; 31 | 32 | %%%%%%%%%%%%%%%%% 33 | %load grid: 34 | %%%%%%%%%%%%%%%%% 35 | 36 | if isempty(mygrid); 37 | grid_load; 38 | end; 39 | 40 | %%%%%%%%%%% 41 | %get field: 42 | %%%%%%%%%%% 43 | fld=read_nctiles([myenv.nctilesdir 'ETAN'],'ETAN'); 44 | fld=std(fld,[],3); fld(find(fld==0))=NaN; 45 | cc=[0:0.1:1]*0.10; 46 | 47 | %%%%%%%%%%%% 48 | %plot field: 49 | %%%%%%%%%%%% 50 | if ~myenv.lessplot; 51 | figureL; gcmfaces_sphere(fld,cc,[],[],1); 52 | end; 53 | 54 | 55 | -------------------------------------------------------------------------------- /sample_analysis/line_greatC_TUV_MASKS_core2_antarctic.m: -------------------------------------------------------------------------------- 1 | function [lonPairs,latPairs,names]=line_greatC_TUV_MASKS_core2_antarctic(); 2 | 3 | gcmfaces_global; 4 | 5 | for iy=1:5; 6 | 7 | switch iy; 8 | case 1; lonPair=[20. 20.]; latPair=[-80. -50.]; name='Weddell-Indian (20E)'; 9 | case 2; lonPair=[90. 90.]; latPair=[-80. -50.]; name='Indian-West Pacific (90E)'; 10 | case 3; lonPair=[160. 160.]; latPair=[-80. -50.]; name='West Pacific-Ross Sea (160E)'; 11 | case 4; lonPair=[-130 -130]; latPair=[-80 -50.]; name='Ross Sea-Amundson Sea (130W)'; 12 | case 5; lonPair=[-62. -62.]; latPair=[-80 -50]; name='Amundsen Sea-Peninsula (62W)'; 13 | end; 14 | 15 | if iy==1; lonPairs=lonPair; latPairs=latPair; names={name}; 16 | else; lonPairs(iy,:)=lonPair; latPairs(iy,:)=latPair; names{iy}=name; 17 | end; 18 | 19 | end; 20 | 21 | -------------------------------------------------------------------------------- /sample_analysis/line_greatC_TUV_MASKS_core2_arctic.m: -------------------------------------------------------------------------------- 1 | function [lonPairs,latPairs,names]=line_greatC_TUV_MASKS_core2_arctic(); 2 | 3 | gcmfaces_global; 4 | 5 | for iy=1:10; 6 | 7 | switch iy; 8 | case 1; lonPair=[-21. 17.]; latPair=[79 79]; name='Fram Strait'; 9 | case 2; lonPair=[17. 100.]; latPair=[79 79]; name='Barents/Kara Sea North'; 10 | case 3; lonPair=[-170. -167.]; latPair=[66 66]; name='Bering Strait (66N)'; 11 | case 4; lonPair=[-62. -53.]; latPair=[66 66]; name='Davis Strait (66N)'; 12 | case 5; lonPair=[-37. -23.]; latPair=[66 66]; name='Greenland-Iceland (66N)'; 13 | case 6; lonPair=[-16 13]; latPair=[66 66]; name='Iceland-Norway (66N)'; 14 | case 7; lonPair=[-64 -44]; latPair=[60 60]; name='Newfoundland-Greenland (60N)'; 15 | case 8; lonPair=[-44 5]; latPair=[60 60]; name='Greenland-Norway (60N)'; 16 | % 17 | case 9; lonPair=[17. 17.]; latPair=[68 79]; name='Barents Sea Opening'; 18 | case 10; lonPair=[56. 56.]; latPair=[68 79]; name='Kara Sea Opening'; 19 | end; 20 | 21 | if iy==1; lonPairs=lonPair; latPairs=latPair; names={name}; 22 | else; lonPairs(iy,:)=lonPair; latPairs(iy,:)=latPair; names{iy}=name; 23 | end; 24 | 25 | end; 26 | 27 | -------------------------------------------------------------------------------- /sample_analysis/line_greatC_TUV_MASKS_v3.m: -------------------------------------------------------------------------------- 1 | function [lonPairs,latPairs,names]=line_greatC_TUV_MASKS_v3(); 2 | 3 | gcmfaces_global; 4 | 5 | for iy=1:21; 6 | 7 | switch iy; 8 | case 1; lonPair=[-173 -164]; latPair=[65.5 65.5]; name='Bering Strait'; 9 | case 2; lonPair=[-5 -5]; latPair=[34 40]; name='Gibraltar'; 10 | case 3; lonPair=[-81 -75]; latPair=[28 26]; name='Florida Strait'; 11 | case 4; lonPair=[-81 -79]; latPair=[28 22]; name='Florida Strait W1'; 12 | case 5; lonPair=[-76 -76]; latPair=[21 8]; name='Florida Strait S1'; 13 | case 6; lonPair=[-75 -75]; latPair=[26 24]; name='Florida Strait E1'; 14 | case 7; lonPair=[-75 -75]; latPair=[24 21]; name='Florida Strait E2'; 15 | case 8; lonPair=[-65 -50]; latPair=[66 66]; name='Davis Strait'; 16 | case 9; lonPair=[-35 -20]; latPair=[67 65]; name='Denmark Strait'; 17 | case 10; lonPair=[-16 -7]; latPair=[65 62.5]; name='Iceland Feroe'; 18 | case 11; lonPair=[-6.5 -4]; latPair=[62.5 57]; name='Feroe England'; 19 | case 12; lonPair=[-4 8]; latPair=[57 62]; name='England Norway'; 20 | case 13; lonPair=[-68 -63]; latPair=[-54 -66]; name='Drake Passage'; 21 | case 14; lonPair=[103 103]; latPair=[4 -1]; name='Indonesia W1'; 22 | case 15; lonPair=[104 109]; latPair=[-3 -7]; name='Indonesia W2'; 23 | case 16; lonPair=[113 118]; latPair=[-7.5 -7.5]; name='Indonesia W3'; 24 | case 17; lonPair=[118 127 ]; latPair=[-7.5 -15]; name='Indonesia W4'; 25 | case 18; lonPair=[127 127]; latPair=[-25 -68]; name='Australia Antarctica'; 26 | case 19; lonPair=[38 46]; latPair=[-10 -22]; name='Madagascar Channel'; 27 | case 20; lonPair=[46 46]; latPair=[-22 -69]; name='Madagascar Antarctica'; 28 | case 21; lonPair=[20 20]; latPair=[-30 -72]; name='South Africa Antarctica'; 29 | end; 30 | 31 | lonPair(lonPair<0)=lonPair(lonPair<0)+360; 32 | 33 | if iy==1; lonPairs=lonPair; latPairs=latPair; names={name}; 34 | else; lonPairs(iy,:)=lonPair; latPairs(iy,:)=latPair; names{iy}=name; 35 | end; 36 | 37 | end; 38 | -------------------------------------------------------------------------------- /sample_analysis/line_greatC_TUV_MASKS_v4.m: -------------------------------------------------------------------------------- 1 | function [lonPairs,latPairs,names]=line_greatC_TUV_MASKS_v4(); 2 | 3 | gcmfaces_global; 4 | 5 | for iy=1:23; 6 | 7 | switch iy; 8 | case 1; lonPair=[-173 -164]; latPair=[65.5 65.5]; name='Bering Strait'; 9 | case 2; lonPair=[-5 -5]; latPair=[34 40]; name='Gibraltar'; 10 | case 3; lonPair=[-81 -77]; latPair=[28 26]; name='Florida Strait'; 11 | case 4; lonPair=[-81 -79]; latPair=[28 22]; name='Florida Strait W1'; 12 | case 5; lonPair=[-76 -76]; latPair=[21 8]; name='Florida Strait S1'; 13 | case 6; lonPair=[-77 -77]; latPair=[26 24]; name='Florida Strait E1'; 14 | case 7; lonPair=[-77 -77]; latPair=[24 22]; name='Florida Strait E2'; 15 | case 8; lonPair=[-65 -50]; latPair=[66 66]; name='Davis Strait'; 16 | case 9; lonPair=[-35 -20]; latPair=[67 65]; name='Denmark Strait'; 17 | case 10; lonPair=[-16 -7]; latPair=[65 62.5]; name='Iceland Faroe'; 18 | case 11; lonPair=[-6.5 -4]; latPair=[62.5 57]; name='Faroe Scotland'; 19 | case 12; lonPair=[-4 8]; latPair=[57 62]; name='Scotland Norway'; 20 | case 13; lonPair=[-68 -63]; latPair=[-54 -66]; name='Drake Passage'; 21 | case 14; lonPair=[103 103]; latPair=[4 -1]; name='Indonesia W1'; 22 | case 15; lonPair=[104 109]; latPair=[-3 -8]; name='Indonesia W2'; 23 | case 16; lonPair=[113 118]; latPair=[-8.5 -8.5]; name='Indonesia W3'; 24 | case 17; lonPair=[118 127 ]; latPair=[-8.5 -15]; name='Indonesia W4'; 25 | case 18; lonPair=[127 127]; latPair=[-25 -68]; name='Australia Antarctica'; 26 | case 19; lonPair=[38 46]; latPair=[-10 -22]; name='Madagascar Channel'; 27 | case 20; lonPair=[46 46]; latPair=[-22 -69]; name='Madagascar Antarctica'; 28 | case 21; lonPair=[20 20]; latPair=[-30 -69.5]; name='South Africa Antarctica'; 29 | case 22; lonPair=[-76 -72]; latPair=[21 18.5]; name='Florida Strait E3'; 30 | case 23; lonPair=[-72 -72]; latPair=[18.5 10]; name='Florida Strait E4'; 31 | end; 32 | 33 | if iy==1; lonPairs=lonPair; latPairs=latPair; names={name}; 34 | else; lonPairs(iy,:)=lonPair; latPairs(iy,:)=latPair; names{iy}=name; 35 | end; 36 | 37 | end; 38 | 39 | -------------------------------------------------------------------------------- /sample_processing/example_bin_average.m: -------------------------------------------------------------------------------- 1 | function [fld]=example_bin_average(); 2 | % EXAMPLE_BIN_AVERAGE generates a sample of random 3 | % numbers distributed over the globe and 4 | % bin averages to the default grid. 5 | 6 | %%%%%%%%%%%%%%%%% 7 | %load grid: 8 | %%%%%%%%%%%%%%%%% 9 | 10 | gcmfaces_global; 11 | 12 | if isempty(mygrid); 13 | grid_load; 14 | end; 15 | 16 | if myenv.verbose>0; 17 | gcmfaces_msg('==============================================='); 18 | gcmfaces_msg(['*** entering example_bin_average: generate ' ... 19 | 'randomly distributed data samples (position and value), ' ... 20 | 'and bin average this data set to a gcmfaces grid'],''); 21 | end; 22 | 23 | warning('off','MATLAB:dsearch:DeprecatedFunction'); 24 | warning('off','MATLAB:delaunay:DuplicateDataPoints'); 25 | 26 | %%%%%%%%%%%%%%%%%%%%%%% 27 | %generate random data 28 | 29 | if myenv.verbose>0; 30 | gcmfaces_msg('* generate random data'); 31 | end; 32 | nn=1e6; 33 | lat=(rand(nn,1)-0.5)*2*90; 34 | lon=(rand(nn,1)-0.5)*2*180; 35 | %needed for 0-360 longitude convention 36 | if mygrid.nFaces==1; 37 | xx=find(lon<0);lon(xx)=lon(xx)+360; 38 | end; 39 | sample=(rand(nn,1)-0.5)*2; 40 | 41 | %%%%%%%%%%%%%%%%%%%%%%% 42 | %generate delaunay triangulation 43 | 44 | if myenv.verbose>0; 45 | gcmfaces_msg('* call gcmfaces_bindata : generate delaunay triangulation'); 46 | end; 47 | gcmfaces_bindata; 48 | 49 | %%%%%%%%%%%%%%%%%%%%%%%% 50 | %bin average random data 51 | 52 | if myenv.verbose>0; 53 | gcmfaces_msg('* call gcmfaces_bindata : bin average data'); 54 | end; 55 | fld=gcmfaces_bindata(lon,lat,sample); 56 | 57 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 58 | %quick display 59 | if myenv.verbose>0; 60 | gcmfaces_msg('* display results on sphere'); 61 | end; 62 | figureL; set(gca,'FontSize',16); 63 | gcmfaces_sphere(fld); axis xy; caxis([-1 1]*0.4); colorbar; 64 | title('bin averaged random data'); 65 | 66 | if myenv.verbose>0; 67 | gcmfaces_msg('*** leaving example_bin_average'); 68 | gcmfaces_msg('==============================================='); 69 | end; 70 | 71 | 72 | 73 | 74 | --------------------------------------------------------------------------------