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
RevLine 
[2]1;+
[150]2; @file_comments
[2]3;
[150]4; @categories
[2]5;
[150]6; @param FIELD
[2]7;
[150]8; @param RES
[2]9;
[150]10; @param GLAMAXE
[2]11;
[150]12; @param GPHIAXE
[2]13;
[231]14; @keyword ENDPOINTS
15;
[150]16; @keyword BOXZOOM
[2]17;
[231]18; @keyword TYPE
[2]19;
[150]20; @keyword WDEPTH
[2]21;
[150]22; @keyword DIREC
23;
24; @keyword SHOWBUILD
25;
26; @keyword ONLYBOX
27;
[231]28; @keyword _EXTRA
29; Used to pass keywords
[150]30;
31; @returns
[231]32;
[150]33; @uses
[370]34; <pro>common</pro>
[231]35;
[150]36; @restrictions
[231]37;
[150]38; @examples
[231]39;
[150]40; @history
[157]41; Sebastien Masson (smasson\@lodyc.jussieu.fr)
[231]42;
43; @version
[186]44; $Id$
[231]45;
[2]46;-
[327]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
[29]51;
[114]52  compile_opt idl2, strictarrsubs
53;
[29]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;--------------------------------------------------------------
[2]62;---------------------
63;---------------------
[150]64; definition of boxzoom in function of endpoints, then redefinition of the domain
[29]65  boxzoom2d = [min([endpoints[0], endpoints[2]], max = ma02), ma02 $
66               , min([endpoints[1], endpoints[3]], max = ma13), ma13]
[2]67;
[29]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]]
[386]74    2:localbox = [boxzoom2d, boxzoom]
[29]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
[237]80      ras = report('Bad definition of the box')
[29]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
[231]90; if less than 10 points where found, we apply domdef over the whole domain
[29]91; -> problem... why 10 points as a test value???
92; how can we find a good test value?
[393]93  IF nx * ny LE 10 THEN domdef, [0, jpi-1, 0, jpj-1, localbox[4:5]], /xindex, /yindex, GRIDTYPE = grillechoice, _extra = ex
[150]94; We redefine lon1, ... in case findalways has been used in domdef
[29]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
[150]100; We keep yranges (axis z) before changing the boxzoom.
[231]101    !y.range = [localbox[nelbox-1], localbox[nelbox-2]]
[29]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
[231]113   ENDIF
[29]114  ENDIF
[231]115  !y.range = [localbox[nelbox-1], localbox[nelbox-2]]
[150]116; We recuperate the grid on the boxzoom.
[29]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)
[231]127
[29]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
[2]136;---------------------
[231]137; We define the triangulation which will allows us to determinate the section.
[150]138; We recalculate it because it must be defined on the Earth and on oceans.
[231]139; Following the direction of the section -rather longitude or rather latitude-
[150]140; we define the way to triangulate.
[231]141  if strpos(type, 'x') NE -1 then BEGIN
[29]142    downward = (lindgen(nx, ny))[0:nx-2, 0:ny-2]
[231]143    tri = definetri(nx, ny, (downward)[*])
[29]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
[231]148; taken into account..
[29]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
[2]156;---------------------
[150]157; Equation of the line on which we do the section.
[2]158;---------------------
[29]159  abc = linearequation(endpoints[0:1], endpoints[2:3])
160  glamtri = glam[tri]
161  gphitri = gphi[tri]
[150]162; Which points of the triangulation are above and below the line?
[29]163  if abc[1] NE 0 THEN $
[2]164    test = temporary(gphitri) GE (-abc[0]/abc[1]*temporary(glamtri)-abc[2]/abc[1]) $
[29]165  ELSE test = temporary(glamtri) GE (-abc[1]/abc[0]*temporary(gphitri)-abc[2]/abc[0])
[2]166
[29]167  zero123 = total(test, 1)
[150]168; to keep: triangles of the triangulation which are over the line.
[29]169  tokeep1 = where(zero123 EQ 1)
170  tokeep2 = where(temporary(zero123) EQ 2)
171  tokeep = [tokeep1, tokeep2]
[2]172
[29]173  test = test[*, tokeep]
174  tri = tri[*, tokeep]
[150]175; Which summit of the triangle is alone in a side of the line?
[29]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
[2]180
[29]181  undefine, tokeep
182  undefine, tokeep1
183  undefine, tokeep2
184  undefine, test
[2]185
[29]186  single = [temporary(single1), temporary(single2)]
[150]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.
[29]189  point1 = [single, single]
190  point2 = [single EQ 0, 1 + (single LE 1)]
[2]191
[29]192  undefine,  single
[2]193
[29]194  ntri = (size(tri))[2]
195  index = [lindgen(ntri), lindgen(ntri)]
[2]196
[29]197  points1 = tri[point1, index]
198  points2 = tri[point2, temporary(index)]
[231]199; points : complex containing couples of points in a side and the other
[150]200; side of the line. We have to delete duplicates.
[29]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)]
[150]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.
[29]207  points1 = complex(glam[   double(points)], gphi[   double(points)])
208  points2 = complex(glam[imaginary(points)], gphi[imaginary(points)])
[150]209; droites equations of line whose we look for the intersection wit the section.
[29]210  droites = linearequation(points1, points2)
211  inter = lineintersection(droites, abc#replicate(1, n_elements(points1) ) )
[2]212
[150]213; Geographic coordinates of points we look for on the section.
[29]214  glamaxe = float(inter)
215  gphiaxe = imaginary(inter)
[150]216; We arrange them in the growing order between boundaries of the section.
[231]217  if strpos(type, 'x') NE -1 then BEGIN
[29]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)
[2]237
238;---------------------
[29]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
[2]254;----------------------------------------------------------------------------
255;xy
256;----------------------------------------------------------------------------
[29]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
[2]266;----------------------------------------------------------------------------
267;xyz
268;----------------------------------------------------------------------------
[29]269    taille[0] EQ 3 AND jpt EQ 1:BEGIN
[231]270      npoints = n_elements(points)
[29]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
[150]281; average following z ?
[29]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
[2]294;----------------------------------------------------------------------------
295;xyt
296;----------------------------------------------------------------------------
[29]297    taille[0] EQ 3 AND jpt NE 1:BEGIN
[231]298      npoints = n_elements(points)
[29]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
[2]310;----------------------------------------------------------------------------
311;xyzt
312;----------------------------------------------------------------------------
[29]313    taille[0] EQ 4:BEGIN
[231]314      npoints = n_elements(points)
[29]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
[150]328; average following z ?
[29]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
[2]344;---------------------
345
[29]346  terre = where(finite(res) EQ 0)
347  if terre[0] NE -1 then res[terre] = valmask
[2]348
[231]349  if n_elements(showbuild) then BEGIN
[29]350    winsave = !window
351    psave = !p
352    xsave = !x
353    ysave = !y
[114]354    plt, findgen(nx, ny), /nodata, /nofill, /rempli, title = '', subtitle = '' $
355         , coast_thick = 2, window = showbuild
[29]356    !p.title = ''
357    !p.subtitle = ''
[2]358
[29]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
[2]361
[29]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
[2]365
[29]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
[114]369
370;  ?? bug ??    IF terre[0] NE -1 THEN plots, float(terre[inter]), imaginary(terre[inter]), color = 0, psym = 1
[231]371
[29]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
[231]378  ENDIF
[2]379
[29]380  restoreboxparam, 'boxparam4section.dat'
[2]381
382;---------------------
[29]383  return
[2]384end
Note: See TracBrowser for help on using the repository browser.