/[MITgcm]/MITgcm_contrib/gael/profilesMatlabProcessing/netcdf_ecco_GenericgridMatFirstStep_4points.m
ViewVC logotype

Contents of /MITgcm_contrib/gael/profilesMatlabProcessing/netcdf_ecco_GenericgridMatFirstStep_4points.m

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


Revision 1.3 - (show annotations) (download)
Thu May 13 19:42:34 2010 UTC (15 years, 2 months ago) by gforget
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +0 -0 lines
FILE REMOVED
moving to profiles_genericgrid directory

1 %
2 %function: netcdf_ecco_GenericgridMatFirstStep
3 %object: compute the additional information to use an "ECCO format" data set with a non latlon grid
4 %author: Gael Forget (gforget@mit.edu)
5 %date: June 12th, 2007
6 %
7 %inputs:
8 % - an "ECCO format" data set and grid files (profilesXCincl1PointOverlap* etc)
9 % that the model should generate when you first try to run pkg/profiles
10 % with a non latlon grid
11 % - directories for I/O
12 % - lat_polar (see below)
13 %output: mat files that are then fed to netcdf_ecco_GenericgridMat2Nc (step 2)
14 %
15 %lat_polar: positive value smaller than 90
16 % [in Cube Sphere/Polar Cap case]
17 % lat_polar should be set to the latitude beyond which lies the cube polar tiles (all of the tile grid points)
18 % -> there we start by project coordinates on the polar tangent plane because the lat/lon system collapes at the pole
19 % -> we refer to this operation as "polar switch" below
20 % [in other grids that do not include the poles]
21 % set it to 85
22 %
23 %rk: below you will find a parameter [choice_plot] do do some display
24 %
25 function []=netcdf_ecco_GenericgridMatFirstStep_4points(file_data,rep_data,rep_grid,rep_out,lat_polar);
26
27 warning off MATLAB:mir_warning_variable_used_as_function;
28
29 fprintf('\n WARNING from netcdf_ecco_GenericgridMatFirstStep.m : \n');
30 fprintf('please have a look at netcdf_ecco_GenericgridNOTEONOVERLAPCORNERS \n\n');
31
32
33
34 %choice to do some visual chek or not
35 choice_plot=0; if choice_plot==1; figure; end; fprintf('visualization off \n\n');
36
37
38 %longitude systems: 1 <-> degree east from Greenwich [0 360] // 2 <-> degree east and west [-180 180]
39 lonSystModel=2;
40 if lonSystModel==1; fprintf('the script below assumes [-180 +180] longitudes => please do not change \n'); return; end
41 %-> both model and observations will first be switched to this system
42
43
44
45
46 eval(['ncload ' rep_data file_data ' prof_lon prof_lat;']);
47
48 %set the longitude system for observations:
49 [prof_lon]=netcdf_ecco_GenericgridRotateLon(prof_lon,0,0,lonSystModel);
50 prof_lonM2=prof_lon; prof_latM2=prof_lat;
51
52 list_subsets=[1:4];
53
54 for subset_cur=list_subsets
55 switch subset_cur
56 case 1
57 switch_to_polar=0;
58 list_profilesM2=find((prof_lonM2>=-90&prof_lonM2<90)&abs(prof_latM2)<lat_polar);
59 suff_cur='latlon1'; fprintf('computing mid latitudes, part 1 \n');
60 case 2
61 switch_to_polar=0;
62 list_profilesM2=find((prof_lonM2<-90|prof_lonM2>=90)&abs(prof_latM2)<lat_polar);
63 suff_cur='latlon2'; fprintf('computing mid latitudes, part 2 \n');
64 case 3
65 switch_to_polar=1;
66 list_profilesM2=find(prof_latM2>=switch_to_polar*lat_polar);
67 suff_cur='northpole'; fprintf('computing high latitude, northern hemisphere \n');
68 case 4
69 switch_to_polar=-1;
70 list_profilesM2=find(prof_latM2<=switch_to_polar*lat_polar);
71 suff_cur='southpole'; fprintf('computing high latitude, southern hemisphere \n');
72 end
73 prof_lonM1=prof_lonM2(list_profilesM2); prof_latM1=prof_latM2(list_profilesM2);
74
75 %do the "polar switch" for the data
76 [prof_lonM1,prof_latM1]=netcdf_ecco_GenericgridPolarPlaneCoords(prof_lonM1,prof_latM1,switch_to_polar);
77
78
79 eval(['files_list=ls('' -1 ' rep_grid 'profilesXC*.data '');']);
80 tmp1=files_list; tmp2=strfind(files_list,rep_grid)+length(rep_grid);
81 tmp3=strfind(files_list,'.data')+4;
82 files_list='';
83 for tmp4=1:length(tmp2);
84 files_list=strvcat(files_list, tmp1(tmp2(tmp4):tmp3(tmp4)) );
85 end
86
87
88 for tcur=1:size(files_list,1)
89
90 prof_interp_XC11=NaN*zeros(length(prof_lonM2),1); prof_interp_YC11=prof_interp_XC11;
91 prof_interp_XCNINJ=prof_interp_XC11; prof_interp_YCNINJ=prof_interp_XC11;
92 prof_interp_i=NaN*zeros(length(prof_lonM2),4); prof_interp_j=prof_interp_i; prof_interp_weights=prof_interp_i;
93 prof_interp_lon=prof_interp_i; prof_interp_lat=prof_interp_i;
94
95 file_cur=deblank(files_list(tcur,:));
96 tmp3=strfind(file_cur,'.');
97 ni=str2num(file_cur(tmp3(end-2)+1:tmp3(end-1)-1));
98 nj=str2num(file_cur(tmp3(end-1)+1:tmp3(end)-1));
99 fid=fopen([rep_grid file_cur],'r','b'); XC_cur=fread(fid,[ni+2 nj+2],'float64'); fclose(fid);
100 tmp3=strfind(file_cur,'XC'); file_cur(tmp3)='Y';
101 fid=fopen([rep_grid file_cur],'r','b'); YC_cur=fread(fid,[ni+2 nj+2],'float64'); fclose(fid);
102 XC_ref=XC_cur; YC_ref=YC_cur;
103 %set the longitude system for model:
104 [XC_cur(:)]=netcdf_ecco_GenericgridRotateLon(XC_cur(:),0,0,lonSystModel);
105
106
107 %tests to avoid bug particualr cases (test1&test2) and useless loops
108 %-------------------------------------------------------------------
109
110 %test1=1; if we are to do "polar switch", only tiles that have grid points in the "polar region" can be relevant!
111 test1=1; if switch_to_polar~=0; test1=~isempty(find(( YC_cur(:)-switch_to_polar*(lat_polar-10) )*switch_to_polar > 0)); end;
112
113 %test2: if no switch_to_polar do not address the polar tiles (the ones that go though all latitudes)
114 test2=1; if switch_to_polar==0; test2=isempty(find(XC_cur(:)>175))|isempty(find(XC_cur(:)<-175))|isempty(find(abs(XC_cur(:))<5)); end;
115 %alternative:
116 % test2=1; if switch_to_polar==0; test2=isempty(find(abs(XC_cur(:)+135)<30))|isempty(find(abs(XC_cur(:)+45)<30))|...
117 % isempty(find(abs(XC_cur(:)-135)<30))|isempty(find(abs(XC_cur(:)-45)<30)); end;
118
119 %test3: if no data don't bother!
120 test3=~isempty(list_profilesM2);
121
122 %fprintf([num2str([subset_cur tcur test1 test2 test3]) '\n']);
123
124 %%%%%%%%%%%%%%%%%%%%
125 if test1&test2&test3
126 %%%%%%%%%%%%%%%%%%%%
127
128
129 if choice_plot==1; subplot(2,1,1); plot(XC_cur(:),YC_cur(:),'yx'); hold on; plot(XC_cur(1,1),YC_cur(1,1),'b.'); plot(XC_cur(end,1),YC_cur(end,1),'m.');
130 tmp_lonM1=prof_lonM2(list_profilesM2); tmp_latM1=prof_latM2(list_profilesM2); plot(tmp_lonM1,tmp_latM1,'go'); axis([-180 180 -90 90]); end;
131
132 if switch_to_polar~=0;
133 %switch to polar plane coordinates
134 tmp1=find(( YC_cur(:)-switch_to_polar*(lat_polar-10) )*switch_to_polar <= 0); XC_cur(tmp1)=NaN; YC_cur(tmp1)=NaN;
135 [XC_cur,YC_cur]=netcdf_ecco_GenericgridPolarPlaneCoords(XC_cur,YC_cur,switch_to_polar);
136 [XC_cur,YC_cur]=netcdf_ecco_GenericgridFixFieldsOverlapCorners(XC_cur,YC_cur);
137 else
138 lon0global=0;
139 if ~isempty(find(abs(XC_cur(:))>175)); lon0tile=180; else; lon0tile=0; end;
140 %alternative: lon0tile=mean(XC_cur(:));
141 prof_lonM1ref=prof_lonM1;
142 %do the "model flip" for the data ... or not
143 [prof_lonM1]=netcdf_ecco_GenericgridRotateLon(prof_lonM1,lon0global,lon0tile,lonSystModel);
144 %do the "model flip" for the model ... or not
145 [XC_cur]=netcdf_ecco_GenericgridRotateLon(XC_cur,lon0global,lon0tile,lonSystModel);
146 [XC_cur,YC_cur]=netcdf_ecco_GenericgridFixFieldsOverlapCorners(XC_cur,YC_cur);
147 end
148
149 if choice_plot==1; subplot(2,1,2); plot(XC_cur(:),YC_cur(:),'yx'); hold on; plot(XC_cur(1,1),YC_cur(1,1),'b.'); plot(XC_cur(end,1),YC_cur(end,1),'m.');
150 plot(prof_lonM1,prof_latM1,'go'); if ~switch_to_polar; axis([-180 180 -90 90]); else; axis([-90 90 -90 90]); end; end;
151
152 x0=zeros((ni+1)*(nj+1),4); y0=x0; i0=x0; j0=x0;
153
154 tmp_count=0;
155 for icur=1:ni+1; for jcur=1:nj+1;
156 tmp_count=tmp_count+1;
157
158 x0(tmp_count,:)=[XC_cur(icur,jcur) XC_cur(icur+1,jcur) XC_cur(icur+1,jcur+1) XC_cur(icur,jcur+1)];
159 y0(tmp_count,:)=[YC_cur(icur,jcur) YC_cur(icur+1,jcur) YC_cur(icur+1,jcur+1) YC_cur(icur,jcur+1)];
160 i0(tmp_count,:)=[icur icur+1 icur+1 icur]; j0(tmp_count,:)=[jcur jcur jcur+1 jcur+1];
161
162 end; end;
163
164 tmp1=find(~isnan(sum(x0,2)));
165 x0=x0(tmp1,:); y0=y0(tmp1,:); i0=i0(tmp1,:); j0=j0(tmp1,:);
166
167
168 %first step: restrict our attention to profiles that are within the area
169 %-----------
170 %will work in any case when
171 % 1) the cell is non polar, so we do not cross the longitude limit
172 % or
173 % 2) we use polar coordinates, which is well defined, for both model and data
174 %=> if this is not the case: I have put some NaNs in XC_cur
175 if isempty(find(isnan(XC_cur)))
176 x00=[XC_cur(:,1)' XC_cur(end,2:end-1) flipdim(XC_cur(:,end)',2) XC_cur(1,end-1:-1:2)];
177 y00=[YC_cur(:,1)' YC_cur(end,2:end-1) flipdim(YC_cur(:,end)',2) YC_cur(1,end-1:-1:2)];
178 list_profilesM1=zeros(size(prof_lonM1));
179 length_div=1e3;
180 num_div=ceil(length(prof_lonM1)/length_div);
181 for cur_div=1:num_div
182 list_profiles0=[(cur_div-1)*length_div+1:min(cur_div*length_div,length(prof_lonM1))];
183 [tmp1]=netcdf_ecco_GenericgridLocateCell(x00,y00,prof_lonM1(list_profiles0),prof_latM1(list_profiles0));
184 list_profilesM1(list_profiles0(find(tmp1>0)))=1;
185 end
186 list_profilesM1=find(list_profilesM1>0);
187 prof_lon=prof_lonM1(list_profilesM1); prof_lat=prof_latM1(list_profilesM1);
188 else
189 list_profilesM1=[1:length(prof_lonM1)]'; prof_lon=prof_lonM1; prof_lat=prof_latM1;
190 end
191
192 %second step: the main computation
193 %---------------------------------
194 if ~isempty(list_profilesM1)
195
196 length_div=1e2;
197 num_div=ceil(length(prof_lon)/length_div);
198 for cur_div=1:num_div
199 list_profiles0=[(cur_div-1)*length_div+1:min(cur_div*length_div,length(prof_lon))];
200
201 %if mod(cur_div,20)==1;
202 %tmp1=length(find(~isnan(prof_interp_i(:,1)))); tmp2=length(prof_lon);
203 %fprintf([num2str(tcur) ' -- ' num2str(list_profiles0(1)) ' / ' num2str(length(prof_lon)) ' -- ' num2str(tmp1) '\n']);
204 %end
205
206 [list_profiles2]=netcdf_ecco_GenericgridLocateCell(x0,y0,prof_lon(list_profiles0),prof_lat(list_profiles0));
207
208 [coeffs2]=netcdf_ecco_GenericgridCoeffs_4points(x0,y0,prof_lon(list_profiles0),prof_lat(list_profiles0));
209
210 list_profiles3=find(sum(list_profiles2,2)>0);
211
212 for kkcur=1:length(list_profiles3)
213 %index in small data vector:
214 kcur0=list_profiles3(kkcur);
215 %more than one 1 can happen when close to cell edges; we pick the first;
216 tmp1=find(list_profiles2(kcur0,:)>0); tmp1=tmp1(1);
217 tmp2=squeeze(coeffs2(kcur0,tmp1,:)); %NOT PRACTICAL tmp3=find(tmp2>0);
218 %index in the full data vector:
219 kcur=list_profilesM2(list_profilesM1(list_profiles0(kcur0)));
220 %fill arrays:
221 prof_interp_XC11(kcur)=XC_ref(2,2); prof_interp_YC11(kcur)=YC_ref(2,2);
222 prof_interp_XCNINJ(kcur)=XC_ref(end-1,end-1); prof_interp_YCNINJ(kcur)=YC_ref(end-1,end-1);
223 prof_interp_i(kcur,:)=i0(tmp1,:)-1;
224 prof_interp_j(kcur,:)=j0(tmp1,:)-1;
225 prof_interp_weights(kcur,:)=tmp2(:);
226 end
227
228 end%for cur_div=1:num_div
229
230 end%if ~isempty(list_profilesM1)
231
232 if switch_to_polar==0;
233 %undo the "model flip" for the data
234 [prof_lonM1]=netcdf_ecco_GenericgridRotateLon(prof_lonM1,lon0tile,lon0global,lonSystModel); %needed for computation
235 [XC_cur]=netcdf_ecco_GenericgridRotateLon(XC_cur,lon0tile,lon0global,lonSystModel); %needed for plot only
236 % if ~isempty(find(mod(prof_lonM1,360)~=mod(prof_lonM1ref,360)));
237 % fprintf('pb due to change in longitudes => stop \n'); return;
238 % end
239 end
240
241 if choice_plot==1; tmp1=find(~isnan(prof_interp_i(:,1)));
242 tmp_i=prof_interp_i(tmp1,1); tmp_j=prof_interp_j(tmp1,1); tmp2=(tmp_j+1-1)*(ni+2)+(tmp_i+1); plot(XC_cur(tmp2),YC_cur(tmp2),'ro');
243 % tmp_i=prof_interp_i(tmp1,2); tmp_j=prof_interp_j(tmp1,2); tmp2=(tmp_j+1-1)*(ni+2)+(tmp_i+1); plot(XC_cur(tmp2),YC_cur(tmp2),'bo');
244 if ~switch_to_polar;
245 plot(prof_lonM2(tmp1),prof_latM2(tmp1),'k.');
246 else;
247 tmp_x=prof_lonM2(tmp1); tmp_y=prof_latM2(tmp1);
248 [tmp_x,tmp_y]=netcdf_ecco_GenericgridPolarPlaneCoords(tmp_x,tmp_y,switch_to_polar); plot(tmp_x,tmp_y,'k.');
249 end;
250 pause(2); clf;
251 end;
252
253
254 %third step : we do not use overlap corner points in interpolation
255 %-----------
256 %
257 %1) rare case when algorithm has collapsed on overlap corners:
258 tmp1=find(~isnan(prof_interp_XC11)&round(sum(prof_interp_weights,2)*1e6)*1e-6~=1);
259 %1.1) rarest case: two points in overlap corner => mask profile
260 tmp2=( (prof_interp_i(tmp1,:)==0&prof_interp_j(tmp1,:)==0)|( prof_interp_i(tmp1,:)==0&prof_interp_j(tmp1,:)==nj+1 )|...
261 ( prof_interp_i(tmp1,:)==ni+1&prof_interp_j(tmp1,:)==0 )|( prof_interp_i(tmp1,:)==ni+1&prof_interp_j(tmp1,:)==nj+1 ));
262 if ~isempty(find(sum(tmp2,2)~=1));
263 %fprintf('this is unexpected!! \n'); return;
264 fprintf([num2str(length(tmp2)) ' masked due to overlap corner issue \n']);
265 tmp11=tmp1(find(sum(tmp2,2)~=1));
266 prof_interp_XC11(tmp11)=NaN; prof_interp_YC11(tmp11)=NaN;
267 prof_interp_XCNINJ(tmp11)=NaN; prof_interp_YCNINJ(tmp11)=NaN;
268 prof_interp_i(tmp11,:)=NaN; prof_interp_j(tmp11,:)=NaN;
269 prof_interp_lon(tmp11,:)=NaN; prof_interp_lat(tmp11,:)=NaN;
270 prof_interp_weights(tmp11,:)=NaN;
271 %reset tmp1 to handle the other points
272 tmp1=find(~isnan(prof_interp_XC11)&round(sum(prof_interp_weights,2)*1e6)*1e-6~=1);
273 tmp2=( (prof_interp_i(tmp1,:)==0&prof_interp_j(tmp1,:)==0)|( prof_interp_i(tmp1,:)==0&prof_interp_j(tmp1,:)==nj+1 )|...
274 ( prof_interp_i(tmp1,:)==ni+1&prof_interp_j(tmp1,:)==0 )|( prof_interp_i(tmp1,:)==ni+1&prof_interp_j(tmp1,:)==nj+1 ));
275 end
276 %1.2) one point in overlap corner => equally weighted average of the three neighbors
277 tmp3=prof_interp_weights(tmp1,:); tmp3(find(tmp2==0))=1/3; tmp3(find(tmp2==1))=0;
278 prof_interp_weights(tmp1,:)=tmp3;
279 %2) normal behaviour => distribute equally the corner weight to the three neighbors
280 tmp1=find(~isnan(prof_interp_XC11));
281 tmp2=( (prof_interp_i(tmp1,:)==0&prof_interp_j(tmp1,:)==0)|( prof_interp_i(tmp1,:)==0&prof_interp_j(tmp1,:)==nj+1 )|...
282 ( prof_interp_i(tmp1,:)==ni+1&prof_interp_j(tmp1,:)==0 )|( prof_interp_i(tmp1,:)==ni+1&prof_interp_j(tmp1,:)==nj+1 ));
283 tmp3=find(sum(tmp2,2)==1); tmp1=tmp1(tmp3); tmp2=tmp2(tmp3,:);
284 tmp3=prof_interp_weights(tmp1,:);
285 if ~isempty(find(tmp2.*tmp3~=0)); fprintf('o');
286 tmp3=tmp3+1/3*sum(tmp3.*tmp2,2)*ones(1,4); tmp3(find(tmp2==1))=0;
287 prof_interp_weights(tmp1,:)=tmp3;
288 end
289
290 %fourth step: store the lon/lat of the interpolation points for checks
291 %------------
292 tmp1=find(~isnan(prof_interp_i));
293 tmp2=(ni+2)*prof_interp_j(tmp1)+prof_interp_i(tmp1)+1;
294 %rk: the computation of the previous line accounts for the fact that i/j go from 0 to ni+1/nj+1
295 prof_interp_lon(tmp1)=XC_ref(tmp2); prof_interp_lat(tmp1)=YC_ref(tmp2);
296
297
298 %fifth step: save in .mat file
299 %------------------------------
300 tmp1=findstr(file_data,'.nc');
301 eval(['save ' rep_out file_data(1:tmp1(end)-1) '_4mygrid.' suff_cur '.' num2str(tcur) '.mat prof_interp_*;']);
302
303 %%%%%%%%%%%%%%%%%%%%%%%%
304 end%if test1&test2&test3
305 %%%%%%%%%%%%%%%%%%%%%%%%
306
307 end%for tcur=...
308
309 end%for subset_cur=1:3
310
311

  ViewVC Help
Powered by ViewVC 1.1.22