source: trunk/SRC/Interpolation/extrapolate.pro @ 202

Last change on this file since 202 was 202, checked in by smasson, 17 years ago

add extrapsmooth + light bugfix in compute_fromirr_bilinear_weigaddr + improve some headers

  • Property svn:keywords set to Id
File size: 6.2 KB
Line 
1;+
2; @file_comments
3; extrapolate data (zinput) where maskinput eq 0 by filling step by
4; step the coastline points with the mean value of the 8 neighbourgs
5; (weighted by their mask value).
6;
7; @categories
8; Interpolation
9;
10; @param zinput {in}{required}{type=2d array}
11; data to be extrapolate
12;
13; @param maskinput {in}{required}{type=2d array or -1}
14; a 2D array, the land-sea mask of the output data (1 on ocean, 0 on land)
15; put -1 if input data are not masked
16;
17; @param nb_iteration {in}{optional}{type=integer scalar}{default=10.E20}
18; Maximum number if iterations done in the extrapolation process. If there
19; is no more masked values we exit extrapolate before reaching nb_iteration
20; (to be sure to fill everything, you can use a very large value)
21;
22; @keyword x_periodic {type=scalar, 0 or 1}{default=0}
23; put 1 to specify that the data are periodic along x axis
24;
25; @keyword MINVAL {type=scalar}{default=not used}
26; to specify a minimum value to the extrapolated values
27;
28; @keyword MAXVAL {type=scalar}{default=not used}
29; to specify a maximum value to the extrapolated values
30;
31; @keyword GE0 {type=scalar 0 or 1}{default=0}
32; put 1 to force the extrapolated values to be larger than 0, same as using minval=0.
33;
34; @returns {type=2d array}
35; the extrapolated array
36;
37; @examples
38; IDL> a=extrapolate(dist(jpi,jpj),tmask[*,*,0],/x_periodic)
39; IDL> tvplus, a
40; IDL> tvplus, a*(1-tmask[*,*,0])
41; get the coastline:
42; IDL> a=extrapolate(tmask[*,*,0],tmask[*,*,0],1,/x_periodic)
43; IDL> tvplus, a-tmask[*,*,0]
44;
45; @history
46;  Originaly written by G. Roulet
47;  Sebastien Masson (smasson\@lodyc.jussieu.fr)
48;
49; @version $Id$
50;
51;-
52FUNCTION extrapolate, zinput, maskinput, nb_iteration, x_periodic = x_periodic $
53                      , MINVAL = minval, MAXVAL = maxval, GE0 = ge0
54;
55  compile_opt idl2, strictarrsubs
56;
57; check the number of iteration used in the extrapolation.
58  IF n_elements(nb_iteration) EQ 0 THEN nb_iteration = 10.E20
59  IF nb_iteration EQ 0 THEN return, zinput
60  nx = (size(zinput))[1]
61  ny = (size(zinput))[2]
62; take care of the boundary conditions...
63;
64; for the x direction, we put 2 additional columns at the left and
65; right side of the array.
66; for the y direction, we put 2 additional lines at the bottom and
67; top side of the array.
68; These changes allow us to use shift function without taking care of
69; the x and y periodicity.
70;
71  ztmp = bytarr(nx+2, ny+2)
72  IF n_elements(maskinput) EQ 1 AND maskinput[0] EQ -1 THEN maskinput = replicate(1b, nx, ny)
73  IF n_elements(maskinput) NE nx*ny THEN BEGIN
74    print, 'input grid mask do not have the good size'
75    return, -1
76  ENDIF
77  ztmp[1:nx, 1:ny] = byte(maskinput)
78  msk = temporary(ztmp)
79;
80  ztmp = replicate(1.e20, nx+2, ny+2)
81  ztmp[1:nx, 1:ny] = zinput
82  if keyword_set(x_periodic) then begin
83    ztmp[0, 1:ny] = zinput[nx-1, *]
84    ztmp[nx+1, 1:ny] = zinput[0, *]
85  ENDIF
86; remove NaN points if there is some...
87  nan = where(finite(ztmp) EQ 0, cnt_nan)
88  IF cnt_nan NE 0 THEN ztmp[temporary(nan)] = 1.e20
89  z = temporary(ztmp)
90  nx2 = nx+2
91  ny2 = ny+2
92;---------------------------------------------------------------
93;---------------------------------------------------------------
94; extrapolation
95;---------------------------------------------------------------
96  sqrtinv = 1./sqrt(2)
97;
98  cnt = 1
99; When we look for the coast line, we don't want to select the
100; borderlines of the array. -> we force the value of the mask for
101; those lines.
102  msk[0, *] = 1b
103  msk[nx+1, *] = 1b
104  msk[*, 0] = 1b
105  msk[*, ny+1] = 1b
106; find the land points
107  land = where(msk EQ 0, cnt_land)
108;---------------------------------------------------------------
109  WHILE cnt LE nb_iteration AND cnt_land NE 0 DO BEGIN
110;---------------------------------------------------------------
111; find the coast line points...
112;---------------------------------------------------------------
113; Once the land points list has been found, we change back the the
114; mask values for the boundary conditions.
115    msk[0, *] = 0b
116    msk[nx+1, *] = 0b
117    msk[*, 0] = 0b
118    msk[*, ny+1] = 0b
119    if keyword_set(x_periodic) then begin
120      msk[0, *] = msk[nx, *]
121      msk[nx+1, *] = msk[1, *]
122    endif
123;
124; we compute the weighted number of sea neighbourgs.
125; those 4 neighbours have a weight of 1:
126;    *
127;   *+*
128;    *
129;
130; those 4 neighbours have a weight of 1/sqrt(2):
131;
132;    * *
133;     +
134;    * *
135;
136; As we make sure that none of the land points are located on the
137; border of the array, we can compute the weight without shift
138; (faster).
139;
140    weight = msk[land+1]+msk[land-1]+msk[land+nx2]+msk[land-nx2] $
141             +sqrtinv*(msk[land+nx2+1]+msk[land+nx2-1] $
142                       +msk[land-nx2+1]+msk[land-nx2-1])
143; list all the points that have sea neighbourgs
144    ok = where(weight GT 0)
145; the coastline points
146    coast = land[ok]
147; their weighted number of sea neighbourgs.
148    weight = weight[temporary(ok)]
149;---------------------------------------------------------------
150; fill the coastine points
151;---------------------------------------------------------------
152    z = temporary(z)*msk
153;
154    zcoast = z[1+coast]+z[-1+coast]+z[nx2+coast]+z[-nx2+coast] $
155             +1./sqrt(2)*(z[nx2+1+coast]+z[nx2-1+coast] $
156                          +z[-nx2+1+coast]+z[-nx2-1+coast])
157;
158    IF keyword_set(ge0) THEN zcoast = 0. > temporary(zcoast)
159    IF n_elements(minval) NE 0 THEN zcoast = minval > temporary(zcoast)
160    IF n_elements(maxval) NE 0 THEN zcoast = temporary(zcoast) < maxval
161    z[coast] = temporary(zcoast)/temporary(weight)
162; we update the the boundary conditions of z
163    if keyword_set(x_periodic) then begin
164      z[0, *] = z[nx, *]
165      z[nx+1, *] = z[1, *]
166    endif
167;---------------------------------------------------------------
168; we update the mask
169;---------------------------------------------------------------
170    msk[temporary(coast)] = 1
171;
172    cnt = cnt + 1
173; When we look for the coast line, we don't want to select the
174; borderlines of the array. -> we force the value of the mask for
175; those lines.
176    msk[0, *] = 1b
177    msk[nx+1, *] = 1b
178    msk[*, 0] = 1b
179    msk[*, ny+1] = 1b
180; find the land points
181    land = where(msk EQ 0, cnt_land)
182;
183  ENDWHILE
184;---------------------------------------------------------------
185; we return the original size of the array
186;---------------------------------------------------------------
187;
188  return, z[1:nx, 1:ny]
189END
190
Note: See TracBrowser for help on using the repository browser.