source: trunk/SRC/ToBeReviewed/TRIANGULATION/section.pro @ 386

Last change on this file since 386 was 386, checked in by smasson, 15 years ago

3 small bugfix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.4 KB
Line 
1;+
2; @file_comments
3;
4;
5; @categories
6;
7; @param FIELD
8;
9; @param RES
10;
11; @param GLAMAXE
12;
13; @param GPHIAXE
14;
15; @keyword ENDPOINTS
16;
17; @keyword BOXZOOM
18;
19; @keyword TYPE
20;
21; @keyword WDEPTH
22;
23; @keyword DIREC
24;
25; @keyword SHOWBUILD
26;
27; @keyword ONLYBOX
28;
29; @keyword _EXTRA
30; Used to pass keywords
31;
32; @returns
33;
34; @uses
35; <pro>common</pro>
36;
37; @restrictions
38;
39; @examples
40;
41; @history
42; Sebastien Masson (smasson\@lodyc.jussieu.fr)
43;
44; @version
45; $Id$
46;
47;-
48PRO section, field, res, glamaxe, gphiaxe, ENDPOINTS=endpoints $
49             , BOXZOOM=boxzoom, TYPE=type, WDEPTH=wdepth $
50             , DIREC=direc, SHOWBUILD=showbuild, ONLYBOX=onlybox $
51             , _EXTRA=ex
52;
53  compile_opt idl2, strictarrsubs
54;
55@cm_4mesh
56@cm_4data
57@cm_4cal
58  IF NOT keyword_set(key_forgetold) THEN BEGIN
59@updatenew
60@updatekwd
61  ENDIF
62;--------------------------------------------------------------
63;---------------------
64;---------------------
65; definition of boxzoom in function of endpoints, then redefinition of the domain
66  boxzoom2d = [min([endpoints[0], endpoints[2]], max = ma02), ma02 $
67               , min([endpoints[1], endpoints[3]], max = ma13), ma13]
68;
69  minprof = 0.
70  profdefault = 200.
71  if n_elements(type) EQ 0 then type = 'nothing'
72  Case N_Elements(Boxzoom) OF
73    0:localbox = [boxzoom2d, minprof, profdefault]
74    1:localbox = [boxzoom2d, minprof, boxzoom[0]]
75    2:localbox = [boxzoom2d, boxzoom]
76    4:if strpos(type, 'z') NE -1 THEN $
77      localbox = [boxzoom2d, minprof, profdefault] ELSE localbox = boxzoom2d
78    5:localbox = [boxzoom2d, minprof, boxzoom[4]]
79    6:localbox = [boxzoom2d, boxzoom[4:5]]
80    Else:BEGIN
81      ras = report('Bad definition of the box')
82      stop
83    END
84  ENDCASE
85  nelbox = n_elements(localbox)
86;
87  if keyword_set(wdepth) then grillechoice = [vargrid, 'W'] $
88  ELSE grillechoice = vargrid
89  domdef, localbox, GRIDTYPE = grillechoice, /findalways, _extra = ex
90  grille, -1, -1, -1, -1, nx, ny
91; if less than 10 points where found, we apply domdef over the whole domain
92; -> problem... why 10 points as a test value???
93; how can we find a good test value?
94  IF nx * ny LE 10 THEN domdef, GRIDTYPE = grillechoice, _extra = ex
95; We redefine lon1, ... in case findalways has been used in domdef
96  lon1 = min([endpoints[0], endpoints[2]], max = lon2)
97  lat1 = min([endpoints[1], endpoints[3]], max = lat2)
98; we extend the box along the z axis -> i that way the plot will be drawn
99; until its bottom part.
100  if strpos(type, 'z') NE -1 THEN BEGIN
101; We keep yranges (axis z) before changing the boxzoom.
102    !y.range = [localbox[nelbox-1], localbox[nelbox-2]]
103    if vargrid EQ 'W' OR keyword_set(wdepth) then BEGIN
104      firstzw = 0 > (firstzw-1)
105      lastzw = (lastzw+1) < (jpk-1)
106      nzw = lastzw - firstzw + 1
107    ENDIF ELSE BEGIN
108      firstzt = 0 > (firstzt-1)
109      lastzt = (lastzt+1) < (jpk-1)
110      nzt = lastzt - firstzt + 1
111    ENDELSE
112    IF NOT keyword_set(key_forgetold) THEN BEGIN
113     @updateold
114   ENDIF
115  ENDIF
116  !y.range = [localbox[nelbox-1], localbox[nelbox-2]]
117; We recuperate the grid on the boxzoom.
118;
119  IF NOT keyword_set(onlybox) THEN saveboxparam, 'boxparam4section.dat'
120  grille, -1, -1, -1, -1, nx, ny, nz $
121          , firstx, firsty, firstz, lastx, lasty, lastz
122; the extend the box in the x and y direction in order to maximise
123; the number of triangles used to build the section
124  firstx = 0 > (firstx - 1)
125  lastx = (lastx + 1) < (jpi -1)
126  firsty = 0 > (firsty - 1)
127  lasty = (lasty + 1) < (jpj -1)
128
129  domdef, firstx, lastx, firsty, lasty, firstz, lastz $
130          , /index, gridtype = vargrid
131
132  IF keyword_set(onlybox) THEN return
133;
134  grille, mask, glam, gphi, gdep, nx, ny, nz $
135          , firstx, firsty, firstz, lastx, lasty, lastz
136
137;---------------------
138; We define the triangulation which will allows us to determinate the section.
139; We recalculate it because it must be defined on the Earth and on oceans.
140; Following the direction of the section -rather longitude or rather latitude-
141; we define the way to triangulate.
142  if strpos(type, 'x') NE -1 then BEGIN
143    downward = (lindgen(nx, ny))[0:nx-2, 0:ny-2]
144    tri = definetri(nx, ny, (downward)[*])
145  ENDIF ELSE tri = definetri(nx, ny)
146; If we have an irregular grid that is periodic, then it is possible that
147; some of the triangle have a very large size (neighborg points on the
148; sphere but far away when doing the projection) and should not be
149; taken into account..
150  IF keyword_set(key_irregular) AND keyword_set(key_periodic) THEN BEGIN
151    glamtri = glam[tri]
152    glamtri = abs(glamtri - shift(glamtri, 1, 0))
153    good = temporary(glamtri) LT (10.*max(glam)/nx)
154    good = where(total(temporary(good), 1) EQ 3)
155    tri = (temporary(tri))[*, temporary(good)]
156  ENDIF
157;---------------------
158; Equation of the line on which we do the section.
159;---------------------
160  abc = linearequation(endpoints[0:1], endpoints[2:3])
161  glamtri = glam[tri]
162  gphitri = gphi[tri]
163; Which points of the triangulation are above and below the line?
164  if abc[1] NE 0 THEN $
165    test = temporary(gphitri) GE (-abc[0]/abc[1]*temporary(glamtri)-abc[2]/abc[1]) $
166  ELSE test = temporary(glamtri) GE (-abc[1]/abc[0]*temporary(gphitri)-abc[2]/abc[0])
167
168  zero123 = total(test, 1)
169; to keep: triangles of the triangulation which are over the line.
170  tokeep1 = where(zero123 EQ 1)
171  tokeep2 = where(temporary(zero123) EQ 2)
172  tokeep = [tokeep1, tokeep2]
173
174  test = test[*, tokeep]
175  tri = tri[*, tokeep]
176; Which summit of the triangle is alone in a side of the line?
177  single1 = where(test[*, 0:n_elements(tokeep1)-1] EQ 1)
178  single1 = single1-(single1/3)*3
179  single2 = where(test[*, n_elements(tokeep1):n_elements(tokeep)-1] EQ 0)
180  single2 = single2-(single2/3)*3
181
182  undefine, tokeep
183  undefine, tokeep1
184  undefine, tokeep2
185  undefine, test
186
187  single = [temporary(single1), temporary(single2)]
188; points1 the point (of the triangle) alone in a side of the line.
189; point2 the other point of the triangle in the other side of the line.
190  point1 = [single, single]
191  point2 = [single EQ 0, 1 + (single LE 1)]
192
193  undefine,  single
194
195  ntri = (size(tri))[2]
196  index = [lindgen(ntri), lindgen(ntri)]
197
198  points1 = tri[point1, index]
199  points2 = tri[point2, temporary(index)]
200; points : complex containing couples of points in a side and the other
201; side of the line. We have to delete duplicates.
202  points = dcomplex(points1, points2)
203  points = points[uniq(points, sort(points))]
204  symetrique = dcomplex(imaginary(points), double(points))
205  points = points[where(points-shift(temporary(symetrique), 1) NE 0)]
206; points1 coordinates of the point of the triangle which is alone in a side of the line.
207; point2 coordinates of the other point of the triangle in the other side of the line.
208  points1 = complex(glam[   double(points)], gphi[   double(points)])
209  points2 = complex(glam[imaginary(points)], gphi[imaginary(points)])
210; droites equations of line whose we look for the intersection wit the section.
211  droites = linearequation(points1, points2)
212  inter = lineintersection(droites, abc#replicate(1, n_elements(points1) ) )
213
214; Geographic coordinates of points we look for on the section.
215  glamaxe = float(inter)
216  gphiaxe = imaginary(inter)
217; We arrange them in the growing order between boundaries of the section.
218  if strpos(type, 'x') NE -1 then BEGIN
219    sort = sort(glamaxe)
220    glamaxe = glamaxe[sort]
221    inbox = where(glamaxe GE lon1 AND glamaxe LE lon2)
222    glamaxe = glamaxe[inbox]
223    sort = sort[inbox]
224    gphiaxe = gphiaxe[sort]
225  ENDIF ELSE BEGIN
226    sort = sort(gphiaxe)
227    gphiaxe = gphiaxe[sort]
228    inbox = where(gphiaxe GE lat1 AND gphiaxe LE lat2)
229    gphiaxe = gphiaxe[inbox]
230    sort = sort[inbox]
231    glamaxe = glamaxe[sort]
232  ENDELSE
233  points = points[sort]
234  points1 = points1[sort]
235  points2 = points2[sort]
236  inter = inter[sort]
237  poids = abs(points2-inter)/abs(points2-points1)
238
239;---------------------
240  array = litchamp(field)
241  array = fitintobox(array)
242  if array[0] EQ -1 THEN BEGIN
243    res = -1
244    return
245  ENDIF
246  if n_elements(valmask) EQ 0 THEN valmask = 1e20
247  taille = size(array)
248  if jpt GT 1 AND taille[0] GE 3 AND strpos(type, 't') EQ -1 then BEGIN
249    direc = 't'
250    array = grossemoyenne(array, 't')
251    taille = size(array)
252    jpt = 1
253  ENDIF
254  case 1 of
255;----------------------------------------------------------------------------
256;xy
257;----------------------------------------------------------------------------
258    taille[0] EQ 2:BEGIN
259      value1 = array[double(points)]
260      terre = where(value1 GT valmask/10)
261      if terre[0] NE -1 then value1[terre] = !values.f_nan
262      value2 = array[imaginary(points)]
263      terre = where(value2 GT valmask/10)
264      if terre[0] NE -1 then value2[terre] = !values.f_nan
265      res = poids*value1+(1-poids)*value2
266    END
267;----------------------------------------------------------------------------
268;xyz
269;----------------------------------------------------------------------------
270    taille[0] EQ 3 AND jpt EQ 1:BEGIN
271      npoints = n_elements(points)
272      index = double(points)#replicate(1, nz)+replicate(nx*ny, npoints)#lindgen(nz)
273      value1 = array[index]
274      terre = where(value1 GT valmask/10)
275      if terre[0] NE -1 then value1[terre] = !values.f_nan
276      index = imaginary(points)#replicate(1, nz)+replicate(nx*ny, npoints)#lindgen(nz)
277      value2 = array[index]
278      terre = where(value2 GT valmask/10)
279      if terre[0] NE -1 then value2[terre] = !values.f_nan
280      poids = poids#replicate(1, nz)
281      res = poids*value1+(1-poids)*value2
282; average following z ?
283      if strpos(type, 'z') EQ -1 then begin
284        nan = where(finite(res) EQ 0)
285        if vargrid EQ 'W' then e3 = e3w[firstzw:lastzw] ELSE e3 = e3t[firstzt:lastzt]
286        weight = replicate(1, npoints)#e3
287        if nan[0] NE -1 then weight[nan] = !values.f_nan
288        totalweight = total(weight, 2, /nan)
289        zero = where(totalweight EQ 0)
290        if zero[0] NE -1 then totalweight[zero] = !values.f_nan
291        res = total(res*weight, 2, /nan)/totalweight
292        direc = 'z'+string(byte(testvar(var = toto)))
293      endif
294    END
295;----------------------------------------------------------------------------
296;xyt
297;----------------------------------------------------------------------------
298    taille[0] EQ 3 AND jpt NE 1:BEGIN
299      npoints = n_elements(points)
300      index = double(points)#replicate(1, jpt)+replicate(nx*ny, npoints)#lindgen(jpt)
301      value1 = array[index]
302      terre = where(value1 GT valmask/10)
303      if terre[0] NE -1 then value1[terre] = !values.f_nan
304      index = imaginary(points)#replicate(1, jpt)+replicate(nx*ny, npoints)#lindgen(jpt)
305      value2 = array[index]
306      terre = where(value2 GT valmask/10)
307      if terre[0] NE -1 then value2[terre] = !values.f_nan
308      poids = poids#replicate(1, jpt)
309      res = poids*value1+(1-poids)*value2
310    END
311;----------------------------------------------------------------------------
312;xyzt
313;----------------------------------------------------------------------------
314    taille[0] EQ 4:BEGIN
315      npoints = n_elements(points)
316      index = double(points)#replicate(1, nz*jpt)+replicate(nx*ny, npoints)#lindgen(nz*jpt)
317      index = reform(index, npoints, nz, jpt, /over)
318      value1 = array[index]
319      terre = where(value1 GT valmask/10)
320      if terre[0] NE -1 then value1[terre] = !values.f_nan
321      index = imaginary(points)#replicate(1, nz*jpt)+replicate(nx*ny, npoints)#lindgen(nz*jpt)
322      index = reform(index, npoints, nz, jpt, /over)
323      value2 = array[index]
324      terre = where(value2 GT valmask/10)
325      if terre[0] NE -1 then value2[terre] = !values.f_nan
326      poids = poids#replicate(1, nz*jpt)
327      poids = reform(poids, npoints, nz, jpt, /over)
328      res = poids*value1+(1-poids)*value2
329; average following z ?
330      if strpos(type, 'z') EQ -1 then begin
331        nan = where(finite(res) EQ 0)
332        if vargrid EQ 'W' then e3 = e3w[firstzw:lastzw] ELSE e3 = e3t[firstzt:lastzt]
333        weight = replicate(1, npoints)#e3
334        weight = weight[*]#replicate(1, jpt)
335        weight = reform(weight, npoints, nz, jpt, /over)
336        if nan[0] NE -1 then weight[nan] = !values.f_nan
337        totalweight = total(weight, 2, /nan)
338        zero = where(totalweight EQ 0)
339        if zero[0] NE -1 then totalweight[zero] = !values.f_nan
340        res = total(res*weight, 2, /nan)/totalweight
341        direc = 'z'+string(byte(testvar(var = toto)))
342      endif
343    END
344  endcase
345;---------------------
346
347  terre = where(finite(res) EQ 0)
348  if terre[0] NE -1 then res[terre] = valmask
349
350  if n_elements(showbuild) then BEGIN
351    winsave = !window
352    psave = !p
353    xsave = !x
354    ysave = !y
355    plt, findgen(nx, ny), /nodata, /nofill, /rempli, title = '', subtitle = '' $
356         , coast_thick = 2, window = showbuild
357    !p.title = ''
358    !p.subtitle = ''
359
360    plots, [endpoints[0], endpoints[2]], [endpoints[1], endpoints[3]], color = 50
361    plots, [endpoints[0], endpoints[2]], [endpoints[1], endpoints[3]], color = 50, psym = 2, thick = 2
362
363    FOR i = 0, n_elements(points1)-1 DO $
364      plots, [float(points1[i]), float(points2[i])] $
365             , [imaginary(points1[i]), imaginary(points2[i])], color = 150
366
367    plots, float(points1), imaginary(points1), color = 150, psym = 1
368    plots, float(points2), imaginary(points2), color = 150, psym = 1
369    plots, float(inter), imaginary(inter), color = 250, psym = 1
370
371;  ?? bug ??    IF terre[0] NE -1 THEN plots, float(terre[inter]), imaginary(terre[inter]), color = 0, psym = 1
372
373;      dummy = ''
374;      read, dummy,  prompt = 'press return to continue'
375    IF !d.name EQ 'PS' THEN erase ELSE wset, winsave
376    !p = psave
377    !x = xsave
378    !y = ysave
379  ENDIF
380
381  restoreboxparam, 'boxparam4section.dat'
382
383;---------------------
384  return
385end
Note: See TracBrowser for help on using the repository browser.