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

Annotation 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 - (hide 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 gforget 1.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