Warning, /utils/matlab/ocean_basin/set_mask.m is written in an unsupported language. File is not indexed.
view on githubraw file Latest commit 127047c0 on 2017-02-07 17:02:10 UTC
127047c0ca Dimi*0001 function [newmask,iMask,XV,YV]=set_mask(x,y,mask,val)
0002
0003 % [newmask,iMask,XV,YV]=set_mask(x,y,mask,val)
0004 % GUI to create mask by hand. Idea is to set masking area
0005 % by selecting polygon(s) or selecting single points.
0006 % Area enclosed by the polygon or the selected point is
0007 % set to value 'val'.
0008 % Press 'v' or 'o' to begin selecting a polygon.
0009 % If you want to mark a single point, place cursor over that point
0010 % and press 'm'.
0011 % If you pressed 'v' or 'o', click as many times as needed to
0012 % pick the vertices of a polygon.
0013 % When finished picking points, hit 'enter'.
0014 % (It is not necessary to close the polygon. This will be
0015 % done automatically.) Points with a value of '1' (ocean) are set
0016 % to a value of 'val'. Thus land points (NaN) and points
0017 % corresponding to other masks i.e., values ~= 1 (displayed in
0018 % different colors) will not be touched. HOWEVER, if you
0019 % pressed 'o', the latter points will be OVERWRITTEN.
0020 % If you pressed 'm', the selected point is set to value 'val',
0021 % but ONLY IF its original value was '1' (ocean).
0022 % So you can call this
0023 % function multiple times with a different value of 'val', and
0024 % set a different mask each time (without overwriting what was
0025 % set during a previous call).
0026 % Once the polygon has been selected and the values set, the
0027 % plot will update. You can then pick another polygon or select
0028 % another point by hitting 'v'/'o' or 'm'.
0029 % To end, press 'e'.
0030 % To undo the last step, press 'u'.
0031 % Outputs:
0032 % newmask: the modified mask
0033 % iMask: vector of indices of points that were modified
0034 % XV,YV: cell arrays containing the vertices of polygons selected.
0035 % Thus, the action of this script can be reproduced in two ways:
0036 % (1) newmask=mask;
0037 % newmask(iMask)=val;
0038 % (2) newmask=mask; [Xp,Yp]=ndgrid(x,y);
0039 % for iv=1:length(XV)
0040 % in=inpolygon(Xp,Yp,XV{iv},YV{iv});
0041 % ii=find(newmask==1 & in==1);
0042 % newmask(ii)=val;
0043 % end
0044 % (1) is most robust. (2) will not reproduce the action of
0045 % selecting single points, but it will allow you to set masks
0046 % defined on a different grid.
0047
0048 if val==0 | val==1
0049 error('Cannot set mask value to 0 or 1')
0050 end
0051
0052 newmask=mask;
0053 iNaNs=find(isnan(newmask));
0054 newmask(iNaNs)=0;
0055 [Xp,Yp]=ndgrid(x,y);
0056
0057 % pcolor(x,y,newmask');
0058 % set(gcf,'renderer','zbuffer'); % hack to deal with disappearing crosshairs
0059 refresh_plot(x,y,newmask)
0060
0061 iv=1;
0062 iMask=[];
0063 XV=[];
0064 YV=[];
0065 but='v';
0066 while (~strcmp(but,'e'))
0067 [x1,y1,but]=ginput(1);
0068 but=char(but);
0069 if (strcmp(but,'v') | strcmp(but,'o')) % select polygon
0070 xv=[];yv=[]; but1=but;
0071 while (~strcmp(but1,''))
0072 [x1,y1,but1]=ginput(1);
0073 but1=char(but1);
0074 xv=[xv;x1];yv=[yv;y1];
0075 add_point(xv,yv)
0076 end
0077 xv=[xv;xv(1)]; yv=[yv;yv(1)];
0078 XV{iv}=xv; YV{iv}=yv; iv=iv+1;
0079 in=inpolygon(Xp,Yp,xv,yv);
0080 if (strcmp(but,'v'))
0081 % Only select water points and points in polygon. Points belonging to
0082 % other masks (different colors/values~=val) are not touched.
0083 lastBut='v';
0084 ii=find(newmask==1 & in==1);
0085 else
0086 % Only select water points and points in polygon. Points belonging to
0087 % other masks (different colors/values~=val) may be overwritten.
0088 % ii=find(~isnan(newmask) & in==1);
0089 lastBut='o';
0090 ii=find(newmask~=0 & in==1);
0091 end
0092 oldmask=newmask; % in case we want to undo
0093 newmask(ii)=val;
0094 iMask=[iMask;ii];
0095 % pcolor(x,y,newmask');
0096 % set(gcf,'renderer','zbuffer'); % hack to deal with disappearing crosshairs
0097 refresh_plot(x,y,newmask,XV,YV)
0098 elseif (strcmp(but,'m'))
0099 lastBut='m';
0100 [m,im]=min(abs(x1-x));
0101 [m,jm]=min(abs(y1-y));
0102 % only mark water points
0103 if newmask(im,jm)==1
0104 ii=sub2ind(size(newmask),im,jm);
0105 oldmask=newmask; % in case we want to undo
0106 newmask(ii)=val;
0107 iMask=[iMask;ii];
0108 refresh_plot(x,y,newmask)
0109 end
0110 elseif (strcmp(but,'u')) % undo
0111 nadd=length(ii); % number of points added
0112 disp('Undoing last step ...')
0113 newmask=oldmask; % reset previous values
0114 iMask=iMask(1:end-nadd); % delete mask indices
0115 if lastBut~='m'
0116 tmpXV=XV; tmpYV=YV; % delete polygon vertices. is there an easy way to do this?
0117 clear XV YV
0118 for k=1:length(tmpXV)-1
0119 XV{k}=tmpXV{k};
0120 YV{k}=tmpYV{k};
0121 end
0122 iv=iv-1;
0123 % pcolor(x,y,newmask');
0124 % set(gcf,'renderer','zbuffer'); % hack to deal with disappearing crosshairs
0125 end
0126 refresh_plot(x,y,newmask,XV,YV)
0127 end
0128 end
0129
0130 newmask(iNaNs)=NaN;
0131
0132 function refresh_plot(x,y,mask,XV,YV)
0133
0134 % pcolor(x,y,mask');
0135 % shading interp
0136 imagesc(x,y,mask')
0137 axis xy
0138 % set(gcf,'renderer','zbuffer'); % hack to deal with disappearing crosshairs
0139
0140 if nargin>3
0141 hold on
0142 for k=1:length(XV)
0143 plot(XV{k},YV{k},'k-o')
0144 end
0145 hold off
0146 end
0147
0148 function add_point(x,y)
0149
0150 hold on
0151 plot(x,y,'k-o')
0152 hold off