1 | ;------------------------------------------------------------ |
---|
2 | ;------------------------------------------------------------ |
---|
3 | ;------------------------------------------------------------ |
---|
4 | ;+ |
---|
5 | ; NAME: interp.pro |
---|
6 | ; |
---|
7 | ; PURPOSE: Performs a bilinear or bicubic interpolation on |
---|
8 | ; data from a regular origin grid to any grid |
---|
9 | |
---|
10 | ; CATEGORY: Subroutine |
---|
11 | ; |
---|
12 | ; CALLING SEQUENCE: interp, znumdta, zdata_name, mask, t, glam, gphi, zresul |
---|
13 | ; |
---|
14 | ; INPUTS: |
---|
15 | ; |
---|
16 | ; znumdta : ID of input data file |
---|
17 | ; zdata_name : input data name |
---|
18 | ; mask : data mask |
---|
19 | ; t : timestep |
---|
20 | ; glam : longitude of target grid |
---|
21 | ; gphi : latitude " " " |
---|
22 | ; |
---|
23 | ; KEYWORD PARAMETERS: None |
---|
24 | ; |
---|
25 | ; OUTPUTS: |
---|
26 | ; zresul : interpolated field |
---|
27 | ; |
---|
28 | ; COMMON BLOCKS: |
---|
29 | ; common_interp.pro |
---|
30 | ; |
---|
31 | ; SIDE EFFECTS: |
---|
32 | ; |
---|
33 | ; RESTRICTIONS: |
---|
34 | ; |
---|
35 | ; EXAMPLE: |
---|
36 | ; |
---|
37 | ; MODIFICATION HISTORY: 11/99 A. Jouzeau |
---|
38 | ; 04/00 A. Jouzeau, M. Imbard |
---|
39 | ; 08/00 A. Jouzeau |
---|
40 | ; 10/01 R. Hordoir : Added boundary conditions, |
---|
41 | ; Bug correction, North Pole Problem |
---|
42 | ; 02/02 R. Hordoir : Added North Pole Treatment |
---|
43 | ; for non coherent winds. |
---|
44 | ; 03/2003 R.Hordoir & Christian Ethe, Irregular |
---|
45 | ; grid on meridian axis |
---|
46 | ; |
---|
47 | ; |
---|
48 | ;- |
---|
49 | ;------------------------------------------------------------ |
---|
50 | ;------------------------------------------------------------ |
---|
51 | ;------------------------------------------------------------ |
---|
52 | PRO interp, znumdta, zdata_name,zsign, mask, t, glam, gphi, phi_field, zresul |
---|
53 | @common_interp |
---|
54 | tempsun = systime(1) ; pour key_performance |
---|
55 | ; |
---|
56 | ;------------------------------------------------- |
---|
57 | ; BILINEAR OR BICUBIC INTERPOLATION OF A FIELD * |
---|
58 | ;------------------------------------------------- |
---|
59 | ; |
---|
60 | ; |
---|
61 | ; 0. Extracting data at timestep t |
---|
62 | ; ================================ |
---|
63 | ; |
---|
64 | zzresul = fltarr(jpioce, jpjoce, jpkatm) |
---|
65 | zzresul2 = fltarr(jpioce, jpjoce, jpkoce) |
---|
66 | |
---|
67 | FOR jk = 0, jpkatm-1 DO BEGIN |
---|
68 | |
---|
69 | |
---|
70 | IF keyword_set(ndim) THEN $ |
---|
71 | ncdf_varget, znumdta, zdata_name, zdata, count = [jpiatm, jpjatm, 1, 1], offset = [0, 0, jk, t] ELSE BEGIN |
---|
72 | IF keyword_set(key_2d) THEN $ |
---|
73 | ncdf_varget, znumdta, zdata_name, zdata, count = [jpiatm, jpjatm, 1], offset = [0, 0, t] ELSE $ |
---|
74 | ncdf_varget, znumdta, zdata_name, zdata, count = [jpiatm, jpjatm,1, 1], offset = [0, 0, 0, t] |
---|
75 | ENDELSE |
---|
76 | |
---|
77 | zmask = fltarr(jpiatm, jpjatm) |
---|
78 | zmask = mask(*, *, jk) |
---|
79 | printf, 40, '' |
---|
80 | printf, 40, 'Data reading OK' |
---|
81 | IF keyword_set(key_vari) THEN BEGIN |
---|
82 | varid = ncdf_varid(znumdta, zdata_name) |
---|
83 | ncdf_attget, znumdta, varid, "scale_factor", scale_factor |
---|
84 | ncdf_attget, znumdta, varid, "add_offset", add_offset |
---|
85 | |
---|
86 | printf, 40, '' |
---|
87 | printf, 40, 'Scale factor and add_offset reading OK' |
---|
88 | ENDIF |
---|
89 | ; Scale Factor + Add_offset |
---|
90 | ; Modif Fred |
---|
91 | ; zdata=ncdf_lec('/usr/work/sur/fvi/OPA/geomag/condmag.nc',var='cond_sed') |
---|
92 | zdata=ncdf_lec('/usr/work/sur/fvi/OPA/geomag/condmag.nc',var='Br') |
---|
93 | |
---|
94 | ; Fin modif fred |
---|
95 | zdata = zdata*scale_factor + add_offset |
---|
96 | |
---|
97 | ; The data array and its mask are shifted zonally as defined in |
---|
98 | ; namelist by lon_shift |
---|
99 | |
---|
100 | zdata = shift(zdata, lon_shift, 0) |
---|
101 | zmask = shift(zmask, lon_shift, 0) |
---|
102 | |
---|
103 | ; zdata = double(zdata) |
---|
104 | IF keyword_set(nreverse) THEN BEGIN |
---|
105 | zdata = reverse(zdata, 2) |
---|
106 | printf, 40, 'Re-arranging data in latitudes : North-South --> South-North' |
---|
107 | ENDIF |
---|
108 | |
---|
109 | |
---|
110 | ; |
---|
111 | ; 0.5 Checking Coherence of winds on North Pole |
---|
112 | ; ============================================= |
---|
113 | ; |
---|
114 | |
---|
115 | |
---|
116 | |
---|
117 | IF keyword_set(nscal) AND keyword_set(north_pole) THEN BEGIN |
---|
118 | |
---|
119 | IF zdata_name EQ data_u_name then BEGIN |
---|
120 | |
---|
121 | |
---|
122 | zdata_u=zdata |
---|
123 | |
---|
124 | IF keyword_set(key_2d) THEN $ |
---|
125 | ncdf_varget, numdta_v, data_v_name, zdata_v, count = [jpiatm, jpjatm, 1], offset = [0, 0, t] ELSE $ |
---|
126 | ncdf_varget, numdta_v, data_v_name, zdata_v, count = [jpiatm, jpjatm,1, 1], offset = [0, 0, 0, t] |
---|
127 | |
---|
128 | |
---|
129 | ENDIF |
---|
130 | |
---|
131 | IF zdata_name EQ data_v_name then BEGIN |
---|
132 | |
---|
133 | |
---|
134 | zdata_v=zdata |
---|
135 | |
---|
136 | IF keyword_set(key_2d) THEN $ |
---|
137 | ncdf_varget, numdta_u, data_u_name, zdata_u, count = [jpiatm, jpjatm, 1], offset = [0, 0, t] ELSE $ |
---|
138 | ncdf_varget, numdta_u, data_u_name, zdata_u, count = [jpiatm, jpjatm,1, 1], offset = [0, 0, 0, t] |
---|
139 | |
---|
140 | |
---|
141 | ENDIF |
---|
142 | |
---|
143 | ; Check is made here |
---|
144 | |
---|
145 | global_vect=replicate(0.,jpiatm,jpjatm,2) |
---|
146 | |
---|
147 | global_vect(*,*,0)=zdata_u |
---|
148 | global_vect(*,*,1)=zdata_v |
---|
149 | |
---|
150 | northwind, global_vect,zdata_name,t |
---|
151 | |
---|
152 | zdata_u=global_vect(*,*,0) |
---|
153 | zdata_v=global_vect(*,*,1) |
---|
154 | |
---|
155 | ; End check and correction |
---|
156 | |
---|
157 | ; Puts back corrected value into initial variable |
---|
158 | |
---|
159 | |
---|
160 | IF zdata_name EQ data_u_name then BEGIN |
---|
161 | |
---|
162 | zdata=zdata_u |
---|
163 | |
---|
164 | ENDIF |
---|
165 | |
---|
166 | IF zdata_name EQ data_v_name then BEGIN |
---|
167 | |
---|
168 | zdata=zdata_v |
---|
169 | |
---|
170 | ENDIF |
---|
171 | |
---|
172 | ENDIF |
---|
173 | |
---|
174 | ; |
---|
175 | ; |
---|
176 | ; 1. Applying mask on data and plotting |
---|
177 | ; ===================================== |
---|
178 | ; |
---|
179 | val = 1.e20 |
---|
180 | IF keyword_set(nmiss) THEN BEGIN |
---|
181 | |
---|
182 | ind = where(abs(zdata) GE abs(missing_val)) |
---|
183 | IF ind[0] NE -1 then zmask(ind) = 0. |
---|
184 | |
---|
185 | ENDIF |
---|
186 | |
---|
187 | ind = where(zmask EQ 0.) |
---|
188 | |
---|
189 | IF ind[0] NE -1 then zdata(ind) = val |
---|
190 | |
---|
191 | ind = where(zmask NE 0.) |
---|
192 | IF ind[0] NE -1 THEN min = min(zdata(ind)) ELSE BEGIN |
---|
193 | min = missing_val |
---|
194 | ENDELSE |
---|
195 | IF ind[0] NE -1 THEN max = max(zdata(ind)) ELSE BEGIN |
---|
196 | max = missing_val |
---|
197 | zdata(*, *) = missing_val |
---|
198 | ENDELSE |
---|
199 | IF t MOD ndraw EQ 0 AND keyword_set(keydraw) AND jk MOD nlevel EQ 0 THEN BEGIN |
---|
200 | IF keyword_set(key_ps) THEN openps, string(zdata_name, '_controle_iteration_', strtrim(t+1, 2), '.ps') |
---|
201 | draw, zdata, lonatm, latatm, jpiatm, jpjatm, 1, 1, 3, $ |
---|
202 | TITLE = zdata_name+', iteration = '+strtrim(t+1,1), min, max |
---|
203 | ENDIF |
---|
204 | ; |
---|
205 | ; 2. Extrapolating coastal values on land points |
---|
206 | ; ============================================== |
---|
207 | ; |
---|
208 | eps = 0. |
---|
209 | n = 0 |
---|
210 | tempsun2 = systime(1) ; pour key_performance |
---|
211 | ; |
---|
212 | ; ... adding a border to overcome shifting problems |
---|
213 | ; |
---|
214 | zero = fltarr(jpiatm+2, jpjatm+2) |
---|
215 | zero[1:jpiatm, 1:jpjatm] = zmask |
---|
216 | zmask = zero |
---|
217 | zero = fltarr(jpiatm+2, jpjatm+2) |
---|
218 | zero[1:jpiatm, 1:jpjatm] = zdata |
---|
219 | zdata = zero |
---|
220 | |
---|
221 | |
---|
222 | ; |
---|
223 | ; ... filling |
---|
224 | ; |
---|
225 | |
---|
226 | if max(zmask) GT 0 then begin |
---|
227 | |
---|
228 | WHILE n LE nfil AND eps LE 1.e-5 DO BEGIN |
---|
229 | |
---|
230 | extrap, zdata, zmask, n, val |
---|
231 | eps = min(abs(zdata-replicate(val, jpiatm, jpjatm))) |
---|
232 | n = n+1 |
---|
233 | ENDWHILE |
---|
234 | |
---|
235 | endif |
---|
236 | ; |
---|
237 | ; ... recovering values on initial domain |
---|
238 | ; |
---|
239 | zdata = zdata[1:jpiatm, 1:jpjatm] |
---|
240 | zmask = zmask[1:jpiatm, 1:jpjatm] |
---|
241 | ; |
---|
242 | if keyword_set(key_performance) THEN print, 'temps extrap', systime(1)-tempsun2 |
---|
243 | ; .. drawing |
---|
244 | IF t MOD ndraw EQ 0 AND keyword_set(keydraw) AND jk MOD nlevel EQ 0 THEN BEGIN |
---|
245 | draw, zdata, lonatm, latatm, jpiatm, jpjatm, 1, 2, 3, $ |
---|
246 | TITLE = 'extrapolated '+zdata_name+', iteration = '+strtrim(t+1,1), min, max |
---|
247 | ENDIF |
---|
248 | |
---|
249 | ind = where(zmask NE 0. AND zdata GE val) |
---|
250 | IF n_elements(ind) GT 1 THEN BEGIN |
---|
251 | print, 'We stop because of insufficient extrapolation on missing values' |
---|
252 | print, n_elements(ind), ' points non extrapolated' |
---|
253 | print, 'Increase nfill in naminterp.pro' |
---|
254 | stop |
---|
255 | ENDIF |
---|
256 | |
---|
257 | |
---|
258 | ; 3. Treatment of Boundary Conditions |
---|
259 | ; ======================================================== |
---|
260 | ; Treatment of boundary conditions require extra stripes |
---|
261 | ; Size of extra stripe is calculated after a given extension |
---|
262 | ; along x and y axis on the OUTPUT grid. iplus and jplus will be |
---|
263 | ; the number of extra points required for the extra stripes of the |
---|
264 | ; INPUT grid. |
---|
265 | |
---|
266 | |
---|
267 | iplus=fix((ext_x*pres_x)/mean(dx)) |
---|
268 | jplus=fix((ext_y*pres_y)/mean(abs(phi_field(1:jpjatm/2)-shift(phi_field(1:jpjatm/2),1)))) |
---|
269 | |
---|
270 | ; Initialisation of array for the northern boundary condition |
---|
271 | |
---|
272 | zdata_north=replicate(0.,jpiatm,jpjatm+jplus) |
---|
273 | zdata_north(*,0:jpjatm-1)=zdata |
---|
274 | |
---|
275 | ; Data of the input grid is duplicated for the northern boundary condition |
---|
276 | |
---|
277 | zdata_inv=shift(zdata_north(*,jpjatm-1-jplus+1:jpjatm-1),jpiatm/2,0) |
---|
278 | |
---|
279 | zdata_inv=reverse(zdata_inv,2) |
---|
280 | |
---|
281 | zdata_north(*,jpjatm:jpjatm+jplus-1)=zdata_inv |
---|
282 | |
---|
283 | ; Transition to East/West Boundary Conditions |
---|
284 | |
---|
285 | zdata=zdata_north |
---|
286 | |
---|
287 | ; East/West Boundary Condition, zdata_extend will be the array that |
---|
288 | ; contains both northern boundary condition and E/W boundary |
---|
289 | ; condition, on the input grid |
---|
290 | |
---|
291 | |
---|
292 | zdata_extend=replicate(0.,jpiatm+2*iplus,jpjatm+jplus) |
---|
293 | |
---|
294 | zdata_extend(iplus:jpiatm-1+iplus,*)=zdata |
---|
295 | |
---|
296 | zdata_extend(0:iplus-1,*)=zdata(jpiatm-1-iplus+1:jpiatm-1,*) |
---|
297 | |
---|
298 | zdata_extend(jpiatm+iplus:jpiatm+2*iplus-1,*)=zdata(0:iplus-1,*) |
---|
299 | |
---|
300 | ; |
---|
301 | ; 3.1 Interpolating data on output grid and plotting result |
---|
302 | ; ========================================================= |
---|
303 | ; The interpolation is made bellow. We use the index of the input grid |
---|
304 | ; to interpolate which makes we need to convert the latitudes and |
---|
305 | ; longitudes of the output grid its dimensions. ext_x*pres_x/dx is added to |
---|
306 | ; take into account the extra stripe at the left handside of the input |
---|
307 | ; grid |
---|
308 | |
---|
309 | print, 'Time Step=',t |
---|
310 | print, 'Input Level=',jk |
---|
311 | |
---|
312 | |
---|
313 | glam2 = (glam - west_lon+ext_x*pres_x )/dx |
---|
314 | gphi2 = replicate(0.,jpioce,jpjoce) |
---|
315 | |
---|
316 | |
---|
317 | |
---|
318 | for ji = 0, jpioce - 1 do begin |
---|
319 | for jj = 0, jpjoce - 1 do begin |
---|
320 | |
---|
321 | |
---|
322 | |
---|
323 | diff = - gphi(ji,jj) $ |
---|
324 | + phi_field |
---|
325 | |
---|
326 | diff = where( diff GE 0. ) |
---|
327 | |
---|
328 | |
---|
329 | j_above=min( diff ) |
---|
330 | |
---|
331 | if diff(0) eq -1 then begin |
---|
332 | ; print, 'Output grid goes above input grid latitude top value !!!' |
---|
333 | ; print, 'Output grid top value has been take as input grid maximum value' |
---|
334 | ; print, 'Please check results at the vicinity of North Pole' |
---|
335 | |
---|
336 | j_fine = jpjatm-1 |
---|
337 | gphi2(ji,jj) = j_fine |
---|
338 | endif else begin |
---|
339 | |
---|
340 | j_bellow = j_above -1 |
---|
341 | |
---|
342 | if j_bellow GE 0 then begin |
---|
343 | |
---|
344 | j_fine = j_bellow |
---|
345 | |
---|
346 | if j_above LT jpjatm then begin |
---|
347 | j_fine = j_bellow+( gphi(ji,jj)-phi_field(j_bellow) )/( phi_field(j_above)-phi_field(j_bellow) ) |
---|
348 | endif |
---|
349 | |
---|
350 | gphi2(ji,jj) = j_fine |
---|
351 | if j_fine GT j_above then stop |
---|
352 | |
---|
353 | endif else begin |
---|
354 | |
---|
355 | j_fine = j_above |
---|
356 | |
---|
357 | gphi2(ji,jj) = j_fine |
---|
358 | |
---|
359 | endelse |
---|
360 | |
---|
361 | |
---|
362 | endelse |
---|
363 | |
---|
364 | endfor |
---|
365 | endfor |
---|
366 | |
---|
367 | |
---|
368 | IF keyword_set(ninterp) THEN BEGIN |
---|
369 | |
---|
370 | zresul = interpolate(zdata_extend, glam2, gphi2, cubic = -.5) |
---|
371 | |
---|
372 | ENDIF ELSE BEGIN |
---|
373 | |
---|
374 | zresul = bilinear(zdata_extend , glam2, gphi2) |
---|
375 | |
---|
376 | ENDELSE |
---|
377 | |
---|
378 | IF t MOD ndraw EQ 0 AND keyword_set(keydraw) AND jk MOD nlevel EQ 0 THEN BEGIN |
---|
379 | draw, zresul, glam, gphi, jpioce, jpjoce, 1, 3, 3, $ |
---|
380 | TITLE = 'interpolated '+zdata_name+', iteration = '+strtrim(t+1,1), min, max |
---|
381 | IF keyword_set(key_ps) THEN BEGIN |
---|
382 | closeps |
---|
383 | ENDIF ELSE BEGIN |
---|
384 | print, 'Press return to continue' |
---|
385 | zxc = strarr(1) |
---|
386 | read, zxc |
---|
387 | ENDELSE |
---|
388 | ENDIF |
---|
389 | zzresul(*, *, jk) = temporary(zresul) |
---|
390 | ENDFOR |
---|
391 | zresul = zzresul |
---|
392 | |
---|
393 | ; |
---|
394 | ; 4. Interpolating data on the vertical axis if the outdept not equal datadept |
---|
395 | ; =========================================================================== |
---|
396 | |
---|
397 | |
---|
398 | IF keyword_set(ndim) THEN BEGIN |
---|
399 | |
---|
400 | nlev_flag = WHERE ( datadept(0:jpkatm-1) ne outdept(0:jpkoce-1) ) |
---|
401 | IF nlev_flag(0) NE -1 THEN BEGIN |
---|
402 | FOR jk = 0, jpkoce-1 DO BEGIN |
---|
403 | |
---|
404 | jn = where(abs(datadept) GE abs(outdept(jk)) $ |
---|
405 | AND abs(shift(datadept, 1)) LT abs(outdept(jk))) |
---|
406 | |
---|
407 | |
---|
408 | IF min(jn) GE 0 THEN BEGIN |
---|
409 | |
---|
410 | ikt=jn-1 |
---|
411 | ikb=jn |
---|
412 | |
---|
413 | IF jn NE 0 then begin |
---|
414 | |
---|
415 | zt1=abs(outdept(jk))-abs(datadept(ikt)) |
---|
416 | zt2=abs(datadept(ikb))-abs(outdept(jk)) |
---|
417 | ztx1=abs(datadept(ikb))-abs(datadept(ikt)) |
---|
418 | za1=replicate(zt1/ztx1, jpioce, jpjoce) |
---|
419 | zb1=replicate(zt2/ztx1, jpioce, jpjoce) |
---|
420 | zzresul2(*, *, jk) = temporary(za1*zzresul(*, *, ikb)+zb1*zzresul(*, *, ikt)) |
---|
421 | |
---|
422 | ENDIF ELSE BEGIN |
---|
423 | |
---|
424 | zzresul2(*, *, jk) = zzresul(*, *, ikb) |
---|
425 | |
---|
426 | ENDELSE |
---|
427 | |
---|
428 | ENDIF ELSE BEGIN |
---|
429 | |
---|
430 | zzresul2(*, *, jk) = temporary(zzresul2(*, *, jk-1)) |
---|
431 | |
---|
432 | ENDELSE |
---|
433 | ENDFOR |
---|
434 | zresul = zzresul2 |
---|
435 | ENDIF ELSE BEGIN |
---|
436 | print, ' ' |
---|
437 | print, 'No need to perform vertical interpolation' |
---|
438 | print, ' ' |
---|
439 | ENDELSE |
---|
440 | ENDIF |
---|
441 | |
---|
442 | |
---|
443 | if keyword_set(key_performance) THEN print, 'temps interp', systime(1)-tempsun |
---|
444 | |
---|
445 | return |
---|
446 | END |
---|