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

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

replace some print by some report in some .pro (continuation) + improvements/corrections of some *.pro headers

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