Back to home page

MITgcm

 
 

    


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