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

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

header improvements + xxx doc

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