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

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

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


Revision 1.3 - (hide annotations) (download)
Fri Jan 15 15:31:07 2016 UTC (9 years, 6 months ago) by gforget
Branch: MAIN
CVS Tags: checkpoint65x, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, HEAD
Changes since 1.2: +3 -0 lines
- fix potential truncation errors

1 gforget 1.1 function [fld]=gcmfaces_remap_2d(lon,lat,fld,nDblRes,varargin);
2     %object: use bin average to remap ONE lat-lon grid FIELD to a gcmfaces grid
3     %input: lon,lat,fld are the gridded product arrays
4     % nDblRes is the number of times the input field
5     % resolution should be doubled before bin average.
6     %optional: mskExtrap is the mask to which to extrapolate after bin average
7     % If it is not specified we do no extrapolation
8     %note: nDblRes>0 is useful if the starting resolution is coarse
9     % enough that the bin average would leave many empty points.
10     %assumption:fld should show NaN for missing values
11    
12     global mygrid;
13     if nargin>4; mskExtrap=varargin{1}; else; mskExtrap=[]; end;
14 gforget 1.2
15     %apply meshgrid if not already the case
16    
17     %switch longitude range to 0-360 if not already the case
18     if ~isempty(find(lon(:,1)<0));
19     ii=max(find(lon(:,1)<0));
20     lon=circshift(lon,[-ii 0]);
21     lon(end-ii+1:end,:)=lon(end-ii+1:end,:)+360;
22     fld=circshift(fld,[-ii 0]);
23     end;
24    
25 gforget 1.1 %refine grid before bin average:
26     for ii=1:nDblRes;
27     [lon,lat,fld]=dbl_res(lon,lat,fld,ii);
28     end;
29     %put in vector form:
30     tmp1=find(~isnan(fld));
31     lon=lon(tmp1); lat=lat(tmp1); fld=fld(tmp1);
32     %switch longitude range to -180+180
33     lon(find(lon>180))=lon(find(lon>180))-360;
34     %compute bin average:
35     fld=gcmfaces_bindata(lon,lat,fld);
36     %potential extrapolation:
37     if ~isempty(mskExtrap); fld=diffsmooth2D_extrap_inv(fld,mskExtrap); end;
38     %apply surface land mask:
39     fld=fld.*mygrid.mskC(:,:,1);
40    
41     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42    
43     function [lonOut,latOut,obsOut]=dbl_res(lon,lat,obs,extendNaN);
44     %object: use neighbor average to double the fields resolution
45     %inputs: lon,lat,fld are the gridded product arrays, with
46     % NaN for missing values in fld.
47     % extendNaN states whether between a real and a NaN
48     % we add a NaN (extendNaN==1) or a real (extendNaN~=1)
49     %outputs: lonOut,latOut,fldOut are the x2 resolution arrays
50     %
51     %assumptions: 0-360 longitudes and a consistent ordering of arrays
52    
53     %check longitude range:
54     if ~isempty(find(lon(:)<0))|~isempty(find(lon(:)>360)); fprintf('problem in longitude specs\n'); return; end;
55     %check simple ordering:
56     tmp1=diff(lon(:,1)); if ~isempty(find(tmp1<=0)); fprintf('problem in longitude specs\n'); return; end;
57    
58     %make sure that we are >=0 and <360:
59     if lon(1,1)>0&lon(end,1)==360; lon=[lon(end,:)-360;lon(1:end-1,:)];
60     lat=[lat(end,:);lat(1:end-1,:)]; obs=[obs(end,:);obs(1:end-1,:)]; end;
61     %make sure that the last point is not duplicated:
62     if lon(1,1)==0&lon(end,1)==360; lon=lon(1:end-1,:);
63     lat=lat(1:end-1,:); obs=obs(1:end-1,:); end;
64    
65     %what do we do with last longitude points:
66     if lon(1,1)>0&lon(end,1)<360;
67     addOnePt=1; %add point at the beginning
68     else;
69     addOnePt=2; %add point at the end
70     end;
71    
72     for ii=1:3;
73     %0) get field
74     if ii==1; tmpA=lon;
75     elseif ii==2; tmpA=lat;
76     elseif ii==3; tmpA=obs;
77     end;
78    
79     %1) zonal direction:
80     tmpB=nanmean2flds(tmpA(1:end-1,:),tmpA(2:end,:),extendNaN);
81     tmpC=ones(size(tmpA,1)*2-1,size(tmpA,2));
82     tmpC(1:2:end,:)=tmpA;
83     tmpC(2:2:end-1,:)=tmpB;
84     %treat zonal edge of the domain
85     if addOnePt==1; %add one point at the beginning
86     if ii==1; offset=-360; else; offset=0; end;
87     tmpB=nanmean2flds(tmpA(1,:),offset+tmpA(end,:),extendNaN); tmpC=[tmpB;tmpC];
88     end;
89     if addOnePt==2; %add one point at the end
90     if ii==1; offset=360; else; offset=0; end;
91     tmpB=nanmean2flds(offset+tmpA(1,:),tmpA(end,:),extendNaN); tmpC=[tmpC;tmpB];
92     end;
93     %check that we did not go too far (should not happen)
94     if ii==1; tmp1=~isempty(find(lon(:)<0))|~isempty(find(lon(:)>360));
95     if tmp1; fprintf('problem in longitude interp\n'); return; end;
96     end;
97    
98     %2) meridional direction:
99     tmpB=nanmean2flds(tmpC(:,1:end-1),tmpC(:,2:end),extendNaN);
100     tmpA=ones(size(tmpC,1),size(tmpC,2)*2-1);
101     tmpA(:,1:2:end)=tmpC;
102     tmpA(:,2:2:end-1)=tmpB;
103    
104     %3) store field:
105     if ii==1; lonOut=tmpA;
106     elseif ii==2; latOut=tmpA;
107     elseif ii==3; obsOut=tmpA;
108     end;
109     end;
110    
111 gforget 1.3 %fix potential truncation errors:
112     lonOut(lonOut<0)=0; lonOut(lonOut>360)=360;
113    
114 gforget 1.1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115    
116     function [fld]=nanmean2flds(fld1,fld2,extendNaN);
117     %object: compute the average of two fields, accounting for NaNs
118     %inputs: fld1 and fld2 are the two fields
119     % if extendNaN==1 the result is NaN if either fld1 or fld2 is NaN.
120     % Otherwise the result is real if either fld1 or fld2 is real.
121    
122     if extendNaN==1;
123     fld=(fld1+fld2)/2;
124     else;
125     msk1=~isnan(fld1); fld1(isnan(fld1))=0;
126     msk2=~isnan(fld2); fld2(isnan(fld2))=0;
127     fld=fld1+fld2;
128     msk=msk1+msk2;
129     msk(msk==0)=NaN;
130     fld=fld./msk;
131     end;
132    

  ViewVC Help
Powered by ViewVC 1.1.22