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

Last change on this file since 226 was 226, checked in by pinsard, 17 years ago

corrections of some misspellings in some *.pro

  • 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
50; $Id$
51;
52;-
53FUNCTION extrapolate, zinput, maskinput, nb_iteration, x_periodic = x_periodic $
54                      , MINVAL = minval, MAXVAL = maxval, GE0 = ge0
55;
56  compile_opt idl2, strictarrsubs
57;
58; check the number of iteration used in the extrapolation.
59  IF n_elements(nb_iteration) EQ 0 THEN nb_iteration = 10.E20
60  IF nb_iteration EQ 0 THEN return, zinput
61  nx = (size(zinput))[1]
62  ny = (size(zinput))[2]
63; take care of the boundary conditions...
64;
65; for the x direction, we put 2 additional columns at the left and
66; right side of the array.
67; for the y direction, we put 2 additional lines at the bottom and
68; top side of the array.
69; These changes allow us to use shift function without taking care of
70; the x and y periodicity.
71;
72  ztmp = bytarr(nx+2, ny+2)
73  IF n_elements(maskinput) EQ 1 AND maskinput[0] EQ -1 THEN maskinput = replicate(1b, nx, ny)
74  IF n_elements(maskinput) NE nx*ny THEN BEGIN
75    print, 'input grid mask do not have the good size'
76    return, -1
77  ENDIF
78  ztmp[1:nx, 1:ny] = byte(maskinput)
79  msk = temporary(ztmp)
80;
81  ztmp = replicate(1.e20, nx+2, ny+2)
82  ztmp[1:nx, 1:ny] = zinput
83  if keyword_set(x_periodic) then begin
84    ztmp[0, 1:ny] = zinput[nx-1, *]
85    ztmp[nx+1, 1:ny] = zinput[0, *]
86  ENDIF
87; remove NaN points if there is some...
88  nan = where(finite(ztmp) EQ 0, cnt_nan)
89  IF cnt_nan NE 0 THEN ztmp[temporary(nan)] = 1.e20
90  z = temporary(ztmp)
91  nx2 = nx+2
92  ny2 = ny+2
93;---------------------------------------------------------------
94;---------------------------------------------------------------
95; extrapolation
96;---------------------------------------------------------------
97  sqrtinv = 1./sqrt(2)
98;
99  cnt = 1
100; When we look for the coastline, we don't want to select the
101; borderlines of the array. -> we force the value of the mask for
102; those lines.
103  msk[0, *] = 1b
104  msk[nx+1, *] = 1b
105  msk[*, 0] = 1b
106  msk[*, ny+1] = 1b
107; find the land points
108  land = where(msk EQ 0, cnt_land)
109;---------------------------------------------------------------
110  WHILE cnt LE nb_iteration AND cnt_land NE 0 DO BEGIN
111;---------------------------------------------------------------
112; find the coastline points...
113;---------------------------------------------------------------
114; Once the land points list has been found, we change back the the
115; mask values for the boundary conditions.
116    msk[0, *] = 0b
117    msk[nx+1, *] = 0b
118    msk[*, 0] = 0b
119    msk[*, ny+1] = 0b
120    if keyword_set(x_periodic) then begin
121      msk[0, *] = msk[nx, *]
122      msk[nx+1, *] = msk[1, *]
123    endif
124;
125; we compute the weighted number of sea neighbourgs.
126; those 4 neighbours have a weight of 1:
127;    *
128;   *+*
129;    *
130;
131; those 4 neighbours have a weight of 1/sqrt(2):
132;
133;    * *
134;     +
135;    * *
136;
137; As we make sure that none of the land points are located on the
138; border of the array, we can compute the weight without shift
139; (faster).
140;
141    weight = msk[land+1]+msk[land-1]+msk[land+nx2]+msk[land-nx2] $
142             +sqrtinv*(msk[land+nx2+1]+msk[land+nx2-1] $
143                       +msk[land-nx2+1]+msk[land-nx2-1])
144; list all the points that have sea neighbourgs
145    ok = where(weight GT 0)
146; the coastline points
147    coast = land[ok]
148; their weighted number of sea neighbourgs.
149    weight = weight[temporary(ok)]
150;---------------------------------------------------------------
151; fill the coastline points
152;---------------------------------------------------------------
153    z = temporary(z)*msk
154;
155    zcoast = z[1+coast]+z[-1+coast]+z[nx2+coast]+z[-nx2+coast] $
156             +1./sqrt(2)*(z[nx2+1+coast]+z[nx2-1+coast] $
157                          +z[-nx2+1+coast]+z[-nx2-1+coast])
158;
159    IF keyword_set(ge0) THEN zcoast = 0. > temporary(zcoast)
160    IF n_elements(minval) NE 0 THEN zcoast = minval > temporary(zcoast)
161    IF n_elements(maxval) NE 0 THEN zcoast = temporary(zcoast) < maxval
162    z[coast] = temporary(zcoast)/temporary(weight)
163; we update the the boundary conditions of z
164    if keyword_set(x_periodic) then begin
165      z[0, *] = z[nx, *]
166      z[nx+1, *] = z[1, *]
167    endif
168;---------------------------------------------------------------
169; we update the mask
170;---------------------------------------------------------------
171    msk[temporary(coast)] = 1
172;
173    cnt = cnt + 1
174; When we look for the coast line, we don't want to select the
175; borderlines of the array. -> we force the value of the mask for
176; those lines.
177    msk[0, *] = 1b
178    msk[nx+1, *] = 1b
179    msk[*, 0] = 1b
180    msk[*, ny+1] = 1b
181; find the land points
182    land = where(msk EQ 0, cnt_land)
183;
184  ENDWHILE
185;---------------------------------------------------------------
186; we return the original size of the array
187;---------------------------------------------------------------
188;
189  return, z[1:nx, 1:ny]
190END
191
Note: See TracBrowser for help on using the repository browser.