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

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

keywords in uppercase in headers of pro files

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