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

Last change on this file since 138 was 136, checked in by pinsard, 18 years ago

some improvements and corrections in some .pro file according to
aspell and idldoc log file

  • Property svn:keywords set to Id
File size: 4.7 KB
Line 
1;+
2; @file_comments
3; extrapolate data (zinput) where maskinput eq 0 by filling
4; step by step the coastline points with the mean value of the 8 neighbourgs.
5;
6; @param zinput {in}{required}
7; data to be extrapolate
8;
9; @param maskinput {in}{required}
10;
11; @param nb_iteration {in}{optional}
12; number of iteration
13;
14; @keyword x_periodic
15; @keyword MINVAL
16; @keyword MAXVAL
17;
18; @version $Id$
19;
20;-
21FUNCTION extrapolate, zinput, maskinput, nb_iteration, x_periodic = x_periodic, MINVAL = minval, MAXVAL = maxval
22;
23  compile_opt idl2, strictarrsubs
24;
25; check the number of iteration used in the extrapolation.
26  IF n_elements(nb_iteration) EQ 0 THEN nb_iteration = 10.E20
27  IF nb_iteration EQ 0 THEN return, zinput
28  nx = (size(zinput))[1]
29  ny = (size(zinput))[2]
30; take care of the boundary conditions...
31;
32; for the x direction, we put 2 additional columns at the left and
33; right side of the array.
34; for the y direction, we put 2 additional lines at the bottom and
35; top side of the array.
36; These changes allow us to use shift function without taking care of
37; the x and y periodicity.
38;
39  ztmp = bytarr(nx+2, ny+2)
40  ztmp[1:nx, 1:ny] = byte(maskinput)
41  msk = temporary(ztmp)
42;
43  ztmp = replicate(1.e20, nx+2, ny+2)
44  ztmp[1:nx, 1:ny] = zinput
45  if keyword_set(x_periodic) then begin
46    ztmp[0, 1:ny] = zinput[nx-1, *]
47    ztmp[nx+1, 1:ny] = zinput[0, *]
48  ENDIF
49; remove NaN points if there is some...
50  nan = where(finite(ztmp) EQ 0, cnt_nan)
51  IF cnt_nan NE 0 THEN ztmp[temporary(nan)] = 1.e20
52  z = temporary(ztmp)
53  nx2 = nx+2
54  ny2 = ny+2
55;---------------------------------------------------------------
56;---------------------------------------------------------------
57; extrapolation
58;---------------------------------------------------------------
59  sqrtinv = 1./sqrt(2)
60;
61  cnt = 1
62; When we look for the coast line, we don't want to select the
63; borderlines of the array. -> we force the value of the mask for
64; those lines.
65  msk[0, *] = 1b
66  msk[nx+1, *] = 1b
67  msk[*, 0] = 1b
68  msk[*, ny+1] = 1b
69; find the land points
70  land = where(msk EQ 0, cnt_land)
71;---------------------------------------------------------------
72  WHILE cnt LE nb_iteration AND cnt_land NE 0 DO BEGIN
73;---------------------------------------------------------------
74; find the coast line points...
75;---------------------------------------------------------------
76; Once the land points list has been found, we change back the the
77; mask values for the boundary conditions.
78    msk[0, *] = 0b
79    msk[nx+1, *] = 0b
80    msk[*, 0] = 0b
81    msk[*, ny+1] = 0b
82    if keyword_set(x_periodic) then begin
83      msk[0, *] = msk[nx, *]
84      msk[nx+1, *] = msk[1, *]
85    endif
86;
87; we compute the weighted number of sea neighbourgs.
88; those 4 neighbours have a weight of 1:
89;    *
90;   *+*
91;    *
92;
93; those 4 neighbours have a weight of 1/sqrt(2):
94;
95;    * *
96;     +
97;    * *
98;
99; As we make sure that none of the land points are located on the
100; border of the array, we can compute the weight without shift
101; (faster).
102;
103    weight = msk[land+1]+msk[land-1]+msk[land+nx2]+msk[land-nx2] $
104             +sqrtinv*(msk[land+nx2+1]+msk[land+nx2-1] $
105                       +msk[land-nx2+1]+msk[land-nx2-1])
106; list all the points that have sea neighbourgs
107    ok = where(weight GT 0)
108; the coastline points
109    coast = land[ok]
110; their weighted number of sea neighbourgs.
111    weight = weight[temporary(ok)]
112;---------------------------------------------------------------
113; fill the coastine points
114;---------------------------------------------------------------
115    z = temporary(z)*msk
116;
117    zcoast = z[1+coast]+z[-1+coast]+z[nx2+coast]+z[-nx2+coast] $
118             +1./sqrt(2)*(z[nx2+1+coast]+z[nx2-1+coast] $
119                          +z[-nx2+1+coast]+z[-nx2-1+coast])
120;
121    IF n_elements(minval) NE 0 THEN zcoast = minval > temporary(zcoast)
122    IF n_elements(maxval) NE 0 THEN zcoast = temporary(zcoast) < maxval
123    z[coast] = temporary(zcoast)/temporary(weight)
124; we update the the boundary conditions of z
125    if keyword_set(x_periodic) then begin
126      z[0, *] = z[nx, *]
127      z[nx+1, *] = z[1, *]
128    endif
129;---------------------------------------------------------------
130; we update the mask
131;---------------------------------------------------------------
132    msk[temporary(coast)] = 1
133;
134    cnt = cnt + 1
135; When we look for the coast line, we don't want to select the
136; borderlines of the array. -> we force the value of the mask for
137; those lines.
138    msk[0, *] = 1b
139    msk[nx+1, *] = 1b
140    msk[*, 0] = 1b
141    msk[*, ny+1] = 1b
142; find the land points
143    land = where(msk EQ 0, cnt_land)
144;
145  ENDWHILE
146;---------------------------------------------------------------
147; we return the original size of the array
148;---------------------------------------------------------------
149;
150  return, z[1:nx, 1:ny]
151END
152
Note: See TracBrowser for help on using the repository browser.