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

Last change on this file since 163 was 157, checked in by navarro, 18 years ago

header improvements + xxx doc

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