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

Annotation of /MITgcm_contrib/gael/matlab_class/gcmfaces_calc/gcmfaces_interp_2d.m

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


Revision 1.6 - (hide annotations) (download)
Fri Jan 29 15:19:48 2016 UTC (9 years, 5 months ago) by gforget
Branch: MAIN
CVS Tags: checkpoint65t
Changes since 1.5: +7 -1 lines
- gcmfaces_interp_1d.m: bug fix
- gcmfaces_interp_2d.m: treat case of a single data point

1 gforget 1.3 function [val]=gcmfaces_interp_2d(fld,lon,lat,method);
2     %[val]=GCMFACES_INTERP_2D(fld,lon,lat,method);
3 gforget 1.4 % interpolates a gcmfaces field (fld) to a set of locations (lon, lat)
4 gforget 1.5 % using one of several methods: 'polygons' (default), 'natural', 'linear',
5     % 'nearest', or 'mix'.
6 gforget 1.4 %
7     % If instead fld is is an array (of the same size as lon and lat)
8     % then the field is interpolated to the gcmfaces grid (in mygrid).
9 gforget 1.1 %
10 gforget 1.5 % The 'polygons' method is a particular implementation of bilinear
11     % interpolation on the sphere. The other methods applies on DelaunayTri
12     % in longitude/latitude coordinates. In particular, the 'mix' option
13     % is `natural' extended with 'nearest' when the input field
14 gforget 1.3 % has been land-masked with NaNs.
15     %
16     %Example:
17     % lon=[-179.9:0.2:179.9]; lat=[-89.9:0.2:89.9];
18     % [lat,lon] = meshgrid(lat,lon);
19     % fld=mygrid.Depth.*mygrid.mskC(:,:,1);
20     % [val]=gcmfaces_interp_2d(fld,lon,lat);
21     % figureL; pcolor(lon,lat,val); shading flat;
22 gforget 1.1
23 gforget 1.5 % note: using gcmfaces_bindata to determine nearest neighbors on the sphere
24     % can be problematic. To illustrate the problem: uncomment the old
25     % method (using gcmfaces_bindata) in gcmfaces_loc_tile.m, set myenv.verbose
26     % to 2 and run the example as explained above. Points at the edge
27     % of tile 59 provide an example -- see display generated by
28     % gcmfaces_interp_coeffs.m
29    
30 gforget 1.3 gcmfaces_global;
31 gforget 1.1
32 gforget 1.3 %backward compatibility checks:
33 gforget 1.1 if ~isfield(myenv,'useDelaunayTri');
34     myenv.useDelaunayTri=~isempty(which('DelaunayTri'));
35     end;
36    
37 gforget 1.5 if isempty(whos('method')); method='polygons'; end;
38 gforget 1.3
39     if ~ischar(method);
40     error('fourth argument to gcmfaces_interp_2d is now ''method''');
41 gforget 1.1 end;
42    
43 gforget 1.3 if ~myenv.useDelaunayTri;;
44     warning('DelaunayTri is missing -> reverting to old tsearch method');
45 gforget 1.4 if ~isa(fld,'gcmfaces');
46     error('old tsearch method only works with a gcmfaces input (fld)');
47     end;
48 gforget 1.1 end;
49    
50 gforget 1.3 %%use TriScatteredInterp
51     if strcmp(method,'linear')|strcmp(method,'nearest')|strcmp(method,'natural')|strcmp(method,'mix');
52    
53 gforget 1.4 if isa(fld,'gcmfaces');
54     XC=convert2array(mygrid.XC);
55     YC=convert2array(mygrid.YC);
56     VEC=convert2array(fld);
57     else;
58     XC=lon;
59     YC=lat;
60     VEC=fld;
61     lon=convert2gcmfaces(mygrid.XC);
62     lat=convert2gcmfaces(mygrid.YC);
63     end;
64    
65 gforget 1.3 val=NaN*lon;
66     for ii=1:3;
67     if ii==1;
68     myXC=XC; myXC(myXC<0)=myXC(myXC<0)+360;
69     jj=find(lon>90);
70     elseif ii==2;
71     myXC=XC;
72     jj=find(lon>=-90&lon<=90);
73     else;
74     myXC=XC; myXC(myXC>0)=myXC(myXC>0)-360;
75     jj=find(lon<-90);
76     end;
77     kk=find(~isnan(myXC));
78     TRI=DelaunayTri(myXC(kk),YC(kk));
79     if strcmp(method,'mix');
80     F = TriScatteredInterp(TRI, VEC(kk),'natural');
81     tmp1=F(lon(jj),lat(jj));
82     F = TriScatteredInterp(TRI, VEC(kk),'nearest');
83     tmp2=F(lon(jj),lat(jj));
84     tmp1(isnan(tmp1))=tmp2(isnan(tmp1));
85     val(jj)=tmp1;
86     else;
87     F = TriScatteredInterp(TRI, VEC(kk),method);
88     val(jj)=F(lon(jj),lat(jj));
89     end;
90 gforget 1.1 end;
91    
92 gforget 1.4 if ~isa(fld,'gcmfaces');
93     val=convert2gcmfaces(val);
94     end;
95    
96 gforget 1.1 end;
97    
98 gforget 1.3 %%old linear interpolation method:
99     if strcmp(method,'tsearch');
100    
101     % Generate triangulation
102     global mytri;
103     gcmfaces_bindata;
104    
105     %switch longitude range to -180+180 or 0-360 according to grid
106     if max(mygrid.XC)<0;
107     lon(find(lon>180))=lon(find(lon>180))-360;
108     end;
109     if max(mygrid.XC)>180;
110     lon(find(lon<0))=lon(find(lon<0))+360;
111     end;
112 gforget 1.1
113     % Find the nearest triangle (t)
114     x=convert2array(mygrid.XC); x=x(mytri.kk);
115     y=convert2array(mygrid.YC); y=y(mytri.kk);
116     VEC=convert2array(fld); VEC=VEC(mytri.kk);
117     t = tsearch(x,y,mytri.TRI,lon',lat')';%the order of dims matters!!
118    
119     % Only keep the relevant triangles.
120     out = find(isnan(t));
121     if ~isempty(out), t(out) = ones(size(out)); end
122     tri = mytri.TRI(t(:),:);
123    
124     % Compute Barycentric coordinates (w). P. 78 in Watson.
125     del = (x(tri(:,2))-x(tri(:,1))) .* (y(tri(:,3))-y(tri(:,1))) - ...
126     (x(tri(:,3))-x(tri(:,1))) .* (y(tri(:,2))-y(tri(:,1)));
127     w(:,3) = ((x(tri(:,1))-lon(:)).*(y(tri(:,2))-lat(:)) - ...
128     (x(tri(:,2))-lon(:)).*(y(tri(:,1))-lat(:))) ./ del;
129     w(:,2) = ((x(tri(:,3))-lon(:)).*(y(tri(:,1))-lat(:)) - ...
130     (x(tri(:,1))-lon(:)).*(y(tri(:,3))-lat(:))) ./ del;
131     w(:,1) = ((x(tri(:,2))-lon(:)).*(y(tri(:,3))-lat(:)) - ...
132     (x(tri(:,3))-lon(:)).*(y(tri(:,2))-lat(:))) ./ del;
133    
134     val = sum(VEC(tri) .* w,2);
135 gforget 1.2 val(out)=NaN;
136 gforget 1.1 val=reshape(val,size(lon));
137    
138 gforget 1.3 end;%if strcmp(method,'tsearch');
139    
140    
141     %%use gcmfaces_interp_coeffs (under development):
142     if strcmp(method,'polygons');
143     siz=size(lon);
144     lon=lon(:);
145     lat=lat(:);
146    
147     ni=30; nj=30;
148     map_tile=gcmfaces_loc_tile(ni,nj);
149    
150     loc_tile=gcmfaces_loc_tile(ni,nj,lon,lat);
151     loc_tile=loc_tile.tileNo;
152     [loc_interp]=gcmfaces_interp_coeffs(lon,lat,ni,nj);
153    
154     fld=exch_T_N(fld);
155     [tmp1,tmp2,n3,n4]=size(fld{1});
156     arr=NaN*zeros(length(lon),n3,n4);
157    
158     for ii_tile=1:max(map_tile);
159     ii=find(loc_tile==ii_tile&nansum(loc_interp.w,2));
160     if ~isempty(ii);
161     %1) determine face of current tile
162     tmp1=1*(map_tile==ii_tile);
163     tmp11=sum(sum(tmp1,1),2); tmp12=[];
164     for kk=1:tmp11.nFaces; tmp12=[tmp12,tmp11{kk}]; end;
165     ii_face=find(tmp12);
166     %... and its index range within face ...
167     tmp1=tmp1{ii_face};
168     tmp11=sum(tmp1,2);
169     iiMin=min(find(tmp11)); iiMax=max(find(tmp11));
170     tmp11=sum(tmp1,1);
171     jjMin=min(find(tmp11)); jjMax=max(find(tmp11));
172    
173     %2) determine points and weights for next step
174     interp_i=1+loc_interp.i(ii,:);
175     interp_j=1+loc_interp.j(ii,:);
176     interp_k=(interp_j-1)*(ni+2)+interp_i;%index after reshape
177     interp_w=loc_interp.w(ii,:);%bininear weights
178    
179     %3) get the tile array
180     til=fld{ii_face}(iiMin:iiMax+2,jjMin:jjMax+2,:,:);
181     msk=1*(~isnan(til));
182     til(isnan(til))=0;
183    
184     %4) interpolate each month to profile locations
185 gforget 1.5 tmp0=repmat(interp_w,[1 1 n3 n4]);
186 gforget 1.3 tmp1=reshape(til,[(ni+2)*(nj+2) n3 n4]);
187     tmp2=reshape(msk,[(ni+2)*(nj+2) n3 n4]);
188     tmp11=tmp1(interp_k(:),:); tmp11=reshape(tmp11,[size(interp_k) n3 n4]);
189     tmp22=tmp2(interp_k(:),:); tmp22=reshape(tmp22,[size(interp_k) n3 n4]);
190 gforget 1.5 tmp1=squeeze(sum(tmp0.*tmp11,2));
191     tmp2=squeeze(sum(tmp0.*tmp22,2));
192 gforget 1.3 arr(ii,:,:,:)=tmp1./tmp2;
193    
194     end;%if ~isempty(ii);
195     end;%for ii_tile=1:117;
196    
197 gforget 1.6 if sum(siz~=1)<=1;
198     val=reshape(arr,[prod(siz) n3 n4]);
199     else;
200     val=reshape(arr,[siz n3 n4]);
201     end;
202     % val=squeeze(reshape(arr,[siz n3 n4]));
203     % if size(val,1)~=size(lon,1); val=val'; end;
204 gforget 1.1 end;
205    

  ViewVC Help
Powered by ViewVC 1.1.22