/[MITgcm]/MITgcm_contrib/gael/matlab_class/gcmfaces_calc/gcmfaces_close_basin.m
ViewVC logotype

Contents of /MITgcm_contrib/gael/matlab_class/gcmfaces_calc/gcmfaces_close_basin.m

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Fri Jan 18 18:52:22 2013 UTC (12 years, 6 months ago) by gforget
Branch: MAIN
CVS Tags: checkpoint65x, checkpoint65r, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, HEAD
- compute closed basin mask from a specificed edge and a "land" mask.

1 function [msk]=gcmfaces_close_basin(basinEdge,landMsk,doLargerBasin);
2 %object : compute closed basin mask from a specificed edge and a "land" mask
3 % By design basinEdge is required to split the global ocean into two and
4 % only two basins. Successive calls allow for numerous basin definitions.
5 %
6 %input : - basinEdge is an index (standard cases; defined by great circle arcs
7 % between pairs of locations; see below) or a 2D map (interactive case)
8 % - test cases : basinEdge = 0 to -3 (included hereafter)
9 % - user cases : basinEdge > 0 (for user to add hereafter)
10 % - interactive case : basinEdge is a 2D map of 1s and NaNs
11 % where NaNs delineate the "wet" egde of the basin.
12 % - landMsk is the "land" mask (1s & NaNs; mygrid.mskC(:,:,1) default)
13 % basinEdge values where landMsk is NaN are of no consequence.
14 % - doLargerBasin is 0 (default) or 1. If set to 1 then output
15 % larger basin mask, otherwise output smaller basin mask. The ocean
16 % edge points are always counted as part of the output basin mask.
17 %
18 %output : msk is the closed basin mask, with 1s over the basin of interest,
19 % 0s over the rest of the ocean, and NaNs consistent with landMsk.
20 %
21 %notes : - unless used in interactive mode the ocean basin edge is based on
22 % great circle arcs. That is usually perfectly adequate. The most
23 % notable exception is when one wants to delimit a basin by latitude lines,
24 % but those are easy to do in interactive mode. The NOT implemented general
25 % approach would use small circle arcs rather than great circle arcs.
26 % - the test cases below demonstrate the algorithm using great circles (0),
27 % the algorithm error cases (-1, -2) and the limitation of great circles (-3)
28
29 gcmfaces_global;
30
31 if isempty(whos('basinEdge')); basinEdge=0; end;
32 if isempty(whos('landMsk')); landMsk=mygrid.mskC(:,:,1); end;
33 if isempty(whos('doLargerBasin')); doLargerBasin=0; end;
34
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%BEGINING OF EDGE DEFINITION%%%%%%%%%%%%%%%%%%%%%%%%%%%
36
37 if isnumeric(basinEdge)&length(basinEdge(:))==1;
38 %standard cases: to be extended by user
39
40 if basinEdge==0;
41 lonPairs=[[ 10 19];[ 19 60];[ 60 100];[ 100 110]];
42 latPairs=[[ 60 80];[ 80 81];[ 81 80];[ 80 60]];
43 %a case that matches v4_basin_one
44 elseif basinEdge==-1;
45 lonPairs=[[ -70 20];[ 20 110];[ 110 200];[ 200 -70]];
46 latPairs=[[ -30 -30];[ -30 -30];[ -30 -30];[ -30 -30]];
47 %a case that fails because it delimits three basins
48 elseif basinEdge==-2;
49 lonPairs=[[ -70 20];[ 20 145]];
50 latPairs=[[ -35 -35];[ -35 -35]];
51 %a case that fails because it does not close basins
52 elseif basinEdge==-3;
53 lonPairs=[[ -70 20];[ 20 145];[ 145 -70]];
54 latPairs=[[ -35 -35];[ -35 -35];[ -35 -35]];
55 %a case that does not fail, but illustrates that long great
56 %circle arcs are not always the most appopriate basin edges
57 %(a line of constant latitude would be better in this case)
58 else;
59 error('unknown basin');
60 end;
61
62 %close basin:
63 msk=landMsk;
64 msk0=msk;
65 for iy=1:size(lonPairs,1);
66 %define great circle line by end points:
67 lonPair=lonPairs(iy,:);
68 latPair=latPairs(iy,:);
69 %get line:
70 line_cur=gcmfaces_lines_transp(lonPair,latPair,{'tmp'});
71 %close line:
72 msk(line_cur.mskCedge==1)=NaN;
73 end;
74
75
76 else;
77 %interactive cases: based on field provided by user
78
79 msk=landMsk;
80 msk0=msk;
81 msk(isnan(basinEdge))=NaN;
82 end;
83
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%END OF EDGE DEFINITION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85
86 %compute the closed basin labels for each grid face:
87 msk1=msk;
88 msk=1*~isnan(msk);
89 for iF=1:msk.nFaces;
90 msk{iF}=bwlabel(msk{iF},4);
91 end;
92
93 %remove potential aliases / account for domain periodicity:
94 msk2=msk;
95 test0=1;%do at least one faces sweep
96 while test0;
97 test0=0;%unless something changes in the upcoming sweep we will stop
98 tmpmsk=exch_T_N(msk);
99 %list aliases
100 list0=[];
101 for iF=1:msk.nFaces;
102 for iS=1:4;
103 tmp1=msk{iF};
104 if iS==1; tmp2=tmpmsk{iF}(1:end-2,2:end-1);
105 elseif iS==2; tmp2=tmpmsk{iF}(3:end,2:end-1);
106 elseif iS==3; tmp2=tmpmsk{iF}(2:end-1,1:end-2);
107 elseif iS==4; tmp2=tmpmsk{iF}(2:end-1,3:end);
108 end;
109 tmp3=find( (tmp1~=tmp2)&(tmp1>0)&(tmp2~=0));
110 %note : tmp1~=tmp2 is an alias if the two other conditions apply
111 %note : "land" (label 0) is not an alias (tmp1>0&tmp2~=0 test)
112 %note : basins cannot be relabeld multiple times (tmp1>0 test) but
113 % relabeld basins can be tested against (tmp2~=0 rather than tmp2>0)
114 list0=[list0;[tmp1(tmp3) tmp2(tmp3) iF+0*tmp3]];
115 end;
116 end;
117 %not needed : list0=unique(list0,'rows');
118 if ~isempty(list0);
119 %start with previously relabeld basin if any (needed to avoid conflicts)
120 ii=find(list0(:,2)==min(list0(:,2))); ii=ii(1);
121 iF=list0(ii,3);
122 list1=list0(ii,1:2);
123 tmp1=msk{iF};
124 %since we will have relabeld at least one basin in this
125 %faces sweep, then another faces sweep will be needed :
126 test0=1;
127 %apply unique negative label
128 if list1(2)<0;
129 %carry over unique label from previously relabeld basin
130 tmp4=list1(2);
131 else;
132 %define new unique negative label
133 tmp4=min(min(msk)-1,-1);
134 end;
135 tmp1(tmp1==list1(1))=tmp4;
136 msk{iF}=tmp1;
137 end;
138 end;
139
140 %final list should have 2 elements (1 per basin)
141 list2=convert2array(msk);
142 list2=unique(list2(:));
143 list2=list2(find(~isnan(list2)&list2~=0));
144 if length(list2)<2; msk=msk1; fprintf('failure : basin was not closed properly\n'); return; end;
145 if length(list2)>2; fprintf('failure : more than two basins\n'); return; end;
146
147 %attribute edge and prepare output:
148 tmp1=sum(mygrid.RAC.*(msk==list2(1)));
149 tmp2=sum(mygrid.RAC.*(msk==list2(2)));
150 if doLargerBasin&tmp1>=tmp2; excl=list2(2);
151 elseif doLargerBasin ; excl=list2(1);
152 elseif tmp1<=tmp2; excl=list2(2);
153 else ; excl=list2(1);
154 end;
155 msk3=msk;
156 msk=(msk~=excl).*mygrid.mskC(:,:,1);
157
158

  ViewVC Help
Powered by ViewVC 1.1.22