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

Last change on this file since 199 was 199, checked in by smasson, 18 years ago

minor bugfixs

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