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

Last change on this file since 495 was 495, checked in by pinsard, 10 years ago

fix thanks to coding rules; typo; dupe empty lines; trailing blanks

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