source: trunk/SRC/ToBeReviewed/CALCULS/grossemoyenne.pro @ 367

Last change on this file since 367 was 367, checked in by pinsard, 16 years ago

typo and translation

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 27.4 KB
Line 
1;+
2;
3; @file_comments
4; averages a 3- or 4-d time series field over a selected
5; geographical area or along the time axis. For one or more
6; selected axes (x, y, z, t)
7;
8; @categories
9;
10; @param TAB {in}{required}
11; 3 or 4d field
12;
13; @param DIREC {in}{required}
14; 'x' 'y' 'z' 't' 'xy' 'xz' 'yz' 'xyz' 'xt' 'yt' 'zt'
15; 'xyt' 'xzt' 'yzt' or 'xyzt'
16;
17; @keyword BOXZOOM
18; [xmin,xmax,ymin,ymax (,(zmin,)zmax)] to more details, see <pro>domdef</pro>
19; boxzoom can have 5 forms :
20; [vert2], [vert1, vert2],[lon1, lon2, lat1, lat2],
21; [lon1, lon2, lat1, lat2, vert2],[lon1, lon2, lat1, lat2, vert1,vert2]
22;
23; @keyword NAN
24; not a number, we activate it if we want to average without considerate some
25; masked values of TAB.
26; If masked values of TAB are values consecrated by IDL(!values.f_nan), we
27; just have to put NAN.
28; If masked values of TAB are valued a (a must be different of 1,
29; corresponding to nan = !values.f_nan and of 0, which desactivate nan).
30; We have to put NAN=a.
31; Comment: In output, result points which are NAN will be valued a or
32; !values.f_nan.
33;
34; @keyword NODOMDEF
35; We activate it if we do not want to pass in <pro>domdef</pro> even if the
36; keyword boxzoom is present (like when <pro>grossemoyenne</pro> is called via
37; <pro>checkfield</pro>)
38;
39; @keyword INTEGRATION
40; To make an integral rather than an average
41;
42; @keyword SPATIALFIRST
43; when performing at the same time
44; spatial and temporal mean, grossemoyenne is assuming
45; that the mask is not changing with the time. In
46; consequence, grossemoyenne performs temporal mean
47; first and then call moyenne. Activate /SPATIALFIRST if
48; you want to perform the spatial mean before the
49; temporal mean. Note that if NAN is activated, then
50; SPATIALFIRST is activated automatically.
51;
52; @keyword TEMPORALFIRST
53; to force to perform first temporal
54; mean even if NAN is activated (see SPATIALFIRST explanations...)
55;
56; @keyword WDEPTH
57; to specify that the field is at W depth instead of T
58; depth (automatically activated if vargrid eq 'W')
59;
60; @uses
61; result:un tableau
62; common
63; <pro>domdef</pro>
64;
65; @restrictions
66; Put values corresponding to land at 1.e20
67;
68; @history
69; Jerome Vialard (jv\@lodyc.jussieu.fr)
70;                       2/7/98
71;                       Sebastien Masson (smasson\@lodyc.jussieu.fr)
72; adaptation array containing a temporal dimension
73;                       14/8/98
74;                       15/1/98
75;                       12/3/99 adaptation for NAN and utilization of TEMPORARY
76;
77; @version
78; $Id$
79;
80;-
81FUNCTION grossemoyenne, tab, direc, BOXZOOM=boxzoom, INTEGRATION=integration $
82                      , NAN=nan, NODOMDEF=nodomdef, WDEPTH=wdepth $
83                      , SPATIALFIRST=spatialfirst, TEMPORALFIRST=temporalfirst $
84                      , _EXTRA=ex
85;
86  compile_opt idl2, strictarrsubs
87;
88@cm_4mesh
89@cm_4data
90@cm_4cal
91  IF NOT keyword_set(key_forgetold) THEN BEGIN
92@updatenew
93@updatekwd
94  ENDIF
95;---------------------------------------------------------
96  tempsun = systime(1)          ; For key_performance
97;------------------------------------------------------------
98;I) preliminaries
99;------------------------------------------------------------
100  dirt = 0
101  dirx = 0
102  diry = 0
103  dirz = 0
104  dim  = 'aa'
105;------------------------------------------------------------
106; I.1) Directions(s) we follow to integrate
107;------------------------------------------------------------
108  if ( strpos(direc, 't') ge 0 ) then dirt = 1
109  if ( strpos(direc, 'x') ge 0 ) then dirx = 1
110  if ( strpos(direc, 'y') ge 0 ) then diry = 1
111  if ( strpos(direc, 'z') ge 0 ) then dirz = 1
112  IF keyword_set(NAN) AND (dirx EQ 1 OR diry EQ 1 OR dirz EQ 1) $
113    THEN spatialfirst = 1
114  IF keyword_set(temporalfirst) THEN spatialfirst = 0
115;------------------------------------------------------------
116; I.2) verification of the input array's size
117;------------------------------------------------------------
118  taille = size(tab)
119  case 1 of
120    taille[0] eq 1 :return,  report('array has only one dimension, not implemented!')
121    taille[0] eq 2 :return,  report('array has only two dimensions, not implemented!')
122    taille[0] eq 3 :BEGIN
123      dim = '3d'
124      if dirx eq 0 and diry eq 0 and dirt eq 0 then return, tab
125    END
126    taille[0] eq 4 :BEGIN
127      dim = '4d'
128      if dirx eq 0 and diry eq 0 and dirz eq 0 and dirt eq 0 then return, tab
129    END
130    else : return, report('array must have 3 or 4 dimensions if there is not time dimension use moyenne')
131  endcase
132;------------------------------------------------------------
133;   I.3) Obtainment of scale's factors and of the mask on the subdomain concernedby the average.
134; Redefinition of the domain ajusted at boxzoom (at 6 elements)
135; This will allowed us to calculate only in the domain concerned by the average.
136; Domdef, followed by grid give us all arrays of the grid on the subdomain
137;------------------------------------------------------------
138  if keyword_set(boxzoom) then BEGIN
139    Case 1 Of
140      N_Elements(Boxzoom) Eq 1: bte = [lon1, lon2, lat1, lat2, 0., boxzoom[0]]
141      N_Elements(Boxzoom) Eq 2: bte = [lon1, lon2, lat1, lat2, boxzoom[0], boxzoom[1]]
142      N_Elements(Boxzoom) Eq 4: bte = [Boxzoom, vert1, vert2]
143      N_Elements(Boxzoom) Eq 5: bte = [Boxzoom[0:3], 0, Boxzoom[4]]
144      N_Elements(Boxzoom) Eq 6: bte = Boxzoom
145      Else: return, report('Wrong Definition of Boxzoom')
146    endcase
147    if NOT keyword_set(nodomdef) then BEGIN
148      savedbox = 1b
149      saveboxparam, 'boxparam4grmoyenne.dat'
150      domdef, bte, GRIDTYPE = vargrid, _extra = ex
151    ENDIF
152  ENDIF
153;---------------------------------------------------------------
154; attribution of the mask and of longitude and latitude arrays...
155;---------------------------------------------------------------
156  grille, mask, glam, gphi, gdep, nx, ny, nz, firstx, firsty, firstz, lastx, lasty, lastz, e1, e2, e3, WDEPTH = wdepth
157;------------------------------------------------------------
158; I.4) if dirt equal 1, we make the temporal average and we send it in moyenne
159;------------------------------------------------------------
160  if dirt EQ 1 AND NOT keyword_set(spatialfirst) then begin
161    if dim EQ 3d then BEGIN
162      case 1 of
163        taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpt: $
164          res = tab[firstx:firstx+nx-1 $
165                    , firsty:firsty+ny-1, *]
166        taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpt:res = tab
167        else:BEGIN
168          if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
169          return, report('Probleme d''adequation entre les tailles du domaine nx*ny*jpt '+strtrim(nx, 1)+'*'+strtrim(ny, 1)+'*'+strtrim(jpt, 1)+' et du tableau '+strtrim(taille[1], 1)+'*'+strtrim(taille[2], 1)+'*'+strtrim(taille[3], 1))
170        END
171      ENDCASE
172      if keyword_set(integration) then begin
173        res = total(res, 3, nan = nan)
174      ENDIF ELSE BEGIN
175        if keyword_set(nan) then BEGIN
176          divi = finite(res)
177          divi = total(temporary(divi), 3)
178          notanum = where(divi EQ 0)
179          res = total(res, 3, nan = keyword_set(nan))/ (1 > divi)
180          if notanum[0] NE -1 then res[temporary(notanum)] = !values.f_nan
181        ENDIF ELSE res = total(res, 3)/(1.*taille[3])
182      ENDELSE
183    ENDIF ELSE BEGIN
184      case 1 of
185        taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpk and taille[4] eq jpt: $
186          res = tab[firstx:lastx, firsty:lasty, firstz:lastz, *]
187        taille[1] eq jpi and taille[2] eq jpj and taille[3] eq nz and taille[4] eq jpt: $
188          res = tab[firstx:lastx, firsty:lasty, *, *]
189        taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq nz and taille[4] eq jpt:res = tab
190        taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpk and taille[4] eq jpt: $
191          res = tab[*, *, firstz:lastz, *]
192        else:BEGIN
193           if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
194          return, report('Probleme d''adequation entre les tailles du domaine nx*ny*nz*jpt ' $
195                         +strtrim(nx, 1)+'*'+strtrim(ny, 1)+'*'+strtrim(nz, 1)+'*' $
196                         +strtrim(jpt, 1)+' et du tableau '+strtrim(taille[1], 1)+'*' $
197                         +strtrim(taille[2], 1)+'*'+strtrim(taille[3], 1)+'*' $
198                         +strtrim(taille[4], 1))
199        END
200        endcase
201      if keyword_set(integration) then begin
202        res = total(res, 4, nan = nan)
203      ENDIF ELSE BEGIN
204        if keyword_set(nan) then begin
205          divi = finite(res)
206          divi = total(temporary(divi), 4)
207          notanum = where(divi EQ 0)
208          res = total(res, 4, /nan)/(1 > divi)
209          if notanum[0] NE -1 then res[temporary(notanum)] = !values.f_nan
210        ENDIF ELSE res = total(res, 4)/(1.*taille[4])
211      ENDELSE
212    ENDELSE
213    if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
214    return,  moyenne(temporary(res), direc, BOXZOOM = boxzoom, NAN = nan, INTEGRATION = integration, NODOMDEF = nodomdef, WDEPTH = wdepth, _extra = ex)
215  ENDIF ELSE res = tab
216  IF jpt EQ 1 THEN BEGIN
217    if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
218    return, moyenne(reform(res, /over), direc, BOXZOOM = boxzoom, NAN = nan, INTEGRATION = integration, NODOMDEF = nodomdef, WDEPTH = wdepth, _extra = ex)
219  END
220;------------------------------------------------------------
221;------------------------------------------------------------
222; II) Case 2d arrays series (tab3d)
223;------------------------------------------------------------
224;------------------------------------------------------------
225  if (dim eq '3d') then begin
226;---------------------------------------------------------------
227;   II.1) verification of the coherence of the array's size to average
228; Verification of the coherence between the array's size and the domain defined by domdef
229; The input array must have either the total domain's size (jpi,jpj,jpt) or
230; this one of the reduced domain (nx,ny,jpt)
231;---------------------------------------------------------------
232    case 1 of
233      taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpt: $
234        res = tab[firstx:firstx+nx-1 $
235                  , firsty:firsty+ny-1, *]
236      taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpt:res = tab
237      else:BEGIN
238        if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
239        return, report('Probleme d''adequation entre les tailles du domaine nx*ny*jpt '+strtrim(nx, 1)+'*'+strtrim(ny, 1)+'*'+strtrim(jpt, 1)+' et du tableau '+strtrim(taille[1], 1)+'*'+strtrim(taille[2], 1)+'*'+strtrim(taille[3], 1))
240      enD
241    endcase
242    if keyword_set(nan) NE 0 then BEGIN
243      if nan NE 1 then BEGIN    ; If nan is not !values.f_nan
244; we put it at !values.f_nan
245        if abs(nan) LT 1e6 then notanumber = where(res EQ nan) $
246        ELSE notanumber = where(abs(res) GT abs(nan)/10.)
247        if notanumber[0] NE -1 then res[temporary(notanumber)] = !values.f_nan
248      ENDIF
249    ENDIF
250;---------------------------------------------------------------
251; Comment : WE HAVE TO BE CAREFUL ABOUT CASES WHERE THE DIMENSION TO
252; AVERAGE = 1, AND MAKE SURE THAT IT EXIST. THAT IS WHY WE USE
253; reform(...,nx,ny,...) WHICH CAN LOOK USELESS AT THE BEGINNING
254;---------------------------------------------------------------
255    if nx EQ 1 OR ny EQ 1 then BEGIN
256      res = reform(res, nx, ny, jpt, /over)
257      e1 =  reform(e1, nx, ny, /over)
258      e2 =  reform(e2, nx, ny, /over)
259    endif
260    if nx EQ 1 OR ny EQ 1 OR nz EQ 1 THEN $
261      mask =  reform(mask, nx, ny, nz, /over)
262;---------------------------------------------------------------
263; II.3) Different types of average
264;---------------------------------------------------------------
265    if keyword_set(nan) NE 0 then msknan = finite(res) ELSE msknan = -1
266    mask = mask[*, *, 0]
267    case 1 of
268      (dirx eq 1) and (diry eq 0) : begin
269        e = temporary(e1)*temporary(mask)
270        echelle = (temporary(e))[*]#replicate(1, jpt)
271        echelle = reform(echelle, nx, ny, jpt, /over)
272        if keyword_set(integration) then divi = 1 ELSE BEGIN
273          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 1) $
274          ELSE divi = total(echelle, 1)
275        ENDELSE
276        res = total(temporary(res)*echelle, 1, nan = nan)/(divi > 1.)
277        if msknan[0] NE -1 then BEGIN
278          echelle = temporary(echelle) NE 0
279          testnan = temporary(msknan)*echelle
280          testnan = total(temporary(testnan), 1) $
281            +(total(temporary(echelle), 1) EQ 0)
282        endif
283      end
284      (dirx eq 0) and (diry eq 1) : begin
285        e = temporary(e2)*temporary(mask)
286        if nx EQ 1 OR ny EQ 1 then e = reform(e, nx, ny, /over)
287        echelle = (temporary(e))[*]#replicate(1, jpt)
288        echelle = reform(echelle, nx, ny, jpt, /over)
289        if keyword_set(integration) then divi = 1 ELSE BEGIN
290          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 2) $
291          ELSE divi = total(echelle, 2)
292        ENDELSE
293        res = total(temporary(res)*echelle, 2, nan = nan)/(divi > 1.)
294        if msknan[0] NE -1 then begin
295          echelle = temporary(echelle) NE 0
296          testnan = temporary(msknan)*echelle
297          testnan = total(temporary(testnan), 2) $
298            +(total(temporary(echelle), 2) EQ 0)
299        endif
300      end
301      (dirx eq 1) and (diry eq 1) : begin
302        echelle = (temporary(e1)*temporary(e2)*temporary(mask))[*]#replicate(1, jpt)
303        echelle = reform(echelle, nx, ny, jpt, /over)
304        if keyword_set(integration) then divi = 1 ELSE BEGIN
305          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 1), 1) $
306          ELSE divi = total(total(echelle, 1), 1)
307        ENDELSE
308        res = total(temporary(total(temporary(res)*echelle, 1, nan = nan)), 1, nan = nan)/(divi > 1.)
309        if msknan[0] NE -1 then begin
310          echelle = temporary(echelle) NE 0
311          testnan = temporary(msknan)*echelle
312          testnan = total(total(temporary(testnan), 1), 1) $
313            +(total(total(temporary(echelle), 1), 1) EQ 0)
314        endif
315      end
316    endcase
317  endif
318;------------------------------------------------------------
319;------------------------------------------------------------
320; III) Case 3d arrays series (tab4d)
321;------------------------------------------------------------
322  if (dim eq '4d') then begin
323;---------------------------------------------------------------
324; III.1) Verification of the coherence of the array to average size
325; Verification of the coherence between the array's size and the domain
326; defind by domdef
327; The input array must have either the total domain size (jpi,jpj,jpk,jpt)
328; or this one of the reduced domain (nx,ny,ny,jpt)
329;---------------------------------------------------------------
330    case 1 of
331      taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpk and taille[4] eq jpt: $
332        res = tab[firstx:lastx, firsty:lasty, firstz:lastz, *]
333      taille[1] eq jpi and taille[2] eq jpj and taille[3] eq nz and taille[4] eq jpt: $
334        res = tab[firstx:lastx, firsty:lasty, *, *]
335      taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq nz and taille[4] eq jpt:res = tab
336      taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpk and taille[4] eq jpt: $
337        res = tab[*, *, firstz:lastz, *]
338      else:BEGIN
339        if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
340        return, report('Probleme d''adequation entre les tailles du domaine nx*ny*nz*jpt ' $
341                       +strtrim(nx, 1)+'*'+strtrim(ny, 1)+'*'+strtrim(nz, 1)+'*' $
342                       +strtrim(jpt, 1)+' et du tableau '+strtrim(taille[1], 1)+'*' $
343                       +strtrim(taille[2], 1)+'*'+strtrim(taille[3], 1)+'*' $
344                       +strtrim(taille[4], 1))
345      END
346    endcase
347    if nx EQ 1 OR ny EQ 1 OR nz EQ 1 OR jpt EQ 1 then res = reform(res, nx, ny, nz, jpt, /over)
348    if keyword_set(nan) NE 0 then BEGIN
349      if nan NE 1 then BEGIN    ; if nan is not !values.f_nan
350; we put it at !values.f_nan
351        if abs(nan) LT 1e6 then notanumber = where(res EQ nan) $
352        ELSE notanumber = where(abs(res) GT abs(nan)/10.)
353        if notanumber[0] NE -1 then res[temporary(notanumber)] = !values.f_nan
354      ENDIF
355    ENDIF
356;---------------------------------------------------------------
357; Comment : WE HAVE TO BE CAREFUL ABOUT CASES WHERE THE DIMENSION TO
358; AVERAGE = 1, AND MAKE SURE THAT IT EXIST. THAT IS WHY WE USE
359; reform(...,nx,ny,...) WHICH CAN LOOK USELESS AT THE BEGINNING
360;---------------------------------------------------------------
361    if nx EQ 1 OR ny EQ 1 OR nz EQ 1 then BEGIN
362      res = reform(res, nx, ny, nz, jpt, /over)
363      mask =  reform(mask, nx, ny, nz, /over)
364    ENDIF
365    IF keyword_set(key_partialstep) THEN BEGIN
366; the top of the ocean floor is
367      IF vargrid EQ 'T' OR vargrid EQ 'W' THEN bottom = total(mask, 3) $
368      ELSE bottom = total(tmask[firstx:lastx, firsty:lasty, firstz:lastz], 3)
369; we suppress columns with only ocean or land
370      good = where(bottom NE 0 AND bottom NE nz)
371; the bottom of the ocean in 3D index is:
372      bottom = lindgen(nx*ny)+(temporary(bottom)-1L)*nx*ny
373      IF good[0] NE -1 THEN bottom = bottom[good] $
374      ELSE bottom = -1
375    ENDIF ELSE bottom = -1
376;---------------------------------------------------------------
377; III.2) different average types
378;---------------------------------------------------------------
379    IF keyword_set(nan) NE 0 THEN msknan = finite(res) ELSE msknan = -1
380    case 1 of
381      (dirx eq 1) and (diry eq 0) and (dirz eq 0) : BEGIN
382        e13 = (temporary(e1))[*]#replicate(1., nz)
383        e13 = reform(e13, nx, ny, nz, /over)
384        echelle = (temporary(e13)*temporary(mask))[*]#replicate(1, jpt)
385        echelle = reform(echelle, nx, ny, nz, jpt, /over)
386        IF keyword_set(key_partialstep) AND bottom[0] NE -1 $
387          AND nx NE 1 THEN BEGIN
388          IF msknan[0] EQ -1 THEN BEGIN
389            msknan = replicate(1b, nx, ny, nz, jpt)
390            nan = 1
391          ENDIF
392          bottom = bottom#replicate(1, jpt) $ ; 4D bottom!
393            + replicate(1, n_elements(bottom))#(nx*ny*nz*lindgen(jpt))
394          msknan[bottom] = 0
395          res[temporary(bottom)] = !values.f_nan
396        ENDIF
397        if keyword_set(integration) then divi = 1 ELSE begin
398          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 1) $
399          ELSE divi = total(echelle, 1)
400        endelse
401        res = temporary(res)*echelle
402        res = total(temporary(res), 1, nan = nan)/(divi > 1)
403        if msknan[0] NE -1 then begin
404          echelle = temporary(echelle) NE 0
405          testnan = temporary(msknan)*echelle
406          testnan = total(temporary(testnan), 1) $
407            +(total(temporary(echelle), 1) EQ 0)
408        endif
409      end
410      (dirx eq 0) and (diry eq 1) and (dirz eq 0) : begin
411        e23 = temporary(e2[*])#replicate(1., nz)
412        e23 = reform(e23, nx, ny, nz, /over)
413        echelle = (temporary(e23)*temporary(mask))[*]#replicate(1, jpt)
414        echelle = reform(echelle, nx, ny, nz, jpt, /over)
415        IF keyword_set(key_partialstep) AND bottom[0] NE -1 $
416          AND ny NE 1 THEN BEGIN
417          IF msknan[0] EQ -1 THEN BEGIN
418            msknan = replicate(1b, nx, ny, nz, jpt)
419            nan = 1
420          endif
421          bottom = bottom#replicate(1, jpt) $ ; 4D bottom!
422            + replicate(1, n_elements(bottom))#(nx*ny*nz*lindgen(jpt))
423          msknan[bottom] = 0
424          res[temporary(bottom)] = !values.f_nan
425        ENDIF
426        if keyword_set(integration) then divi = 1 ELSE begin
427          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 2) $
428          ELSE divi = total(echelle, 2)
429        endelse
430        res = total(temporary(res)*echelle, 2, nan = nan)/(divi > 1)
431        if msknan[0] NE -1 then begin
432          echelle = temporary(echelle) NE 0
433          testnan = temporary(msknan)*echelle
434          testnan = total(temporary(testnan), 2) $
435            +(total(temporary(echelle), 2) EQ 0)
436        endif
437      end
438      (dirx eq 0) and (diry eq 0) and (dirz eq 1) : begin
439        e33 = replicate(1, 1.*nx*ny)#e3
440        e33 = reform(e33, nx, ny, nz, /over)
441        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
442          IF keyword_set(wdepth) THEN $
443            e33[bottom] = (e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
444          ELSE e33[bottom] = (e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
445        ENDIF
446        echelle = (temporary(e33)*temporary(mask))[*]#replicate(1, jpt)
447        echelle = reform(echelle, nx, ny, nz, jpt, /over)
448        if keyword_set(integration) then divi = 1 ELSE begin
449          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 3) $
450          ELSE divi = total(echelle, 3)
451        endelse
452        res = total(temporary(res)*echelle, 3, nan = nan)/(divi > 1)
453        if msknan[0] NE -1 then begin
454          echelle = temporary(echelle) NE 0
455          testnan = temporary(msknan)*echelle
456          testnan = total(temporary(testnan), 3) $
457            +(total(temporary(echelle), 3) EQ 0)
458        endif
459      end
460      (dirx eq 1) and (diry eq 1) and (dirz eq 0) : begin
461        e13 = e1[*]#replicate(1., nz)
462        e13 = reform(e13, nx, ny, nz, /over)
463        e23 = e2[*]#replicate(1., nz)
464        e23 = reform(e23, nx, ny, nz, /over)
465        echelle = (temporary(e13)*temporary(e23)*temporary(mask))[*]#replicate(1, jpt)
466        echelle = reform(echelle, nx, ny, nz, jpt, /over)
467        IF keyword_set(key_partialstep) AND bottom[0] NE -1 $
468          AND nx*ny NE 1 THEN BEGIN
469          IF msknan[0] EQ -1 THEN BEGIN
470            msknan = replicate(1b, nx, ny, nz, jpt)
471            nan = 1
472          endif
473          bottom = bottom#replicate(1, jpt) $ ; 4D bottom!
474            + replicate(1, n_elements(bottom))#(nx*ny*nz*lindgen(jpt))
475          msknan[bottom] = 0
476          res[temporary(bottom)] = !values.f_nan
477        ENDIF
478        if keyword_set(integration) then divi = 1 ELSE begin
479          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 1), 1) $
480          ELSE divi = total(total(echelle, 1), 1)
481        endelse
482        res = total(total(temporary(res)*echelle, 1, nan = nan), 1, nan = nan)/(divi > 1)
483        if msknan[0] NE -1 then begin
484          echelle = temporary(echelle) NE 0
485          testnan = temporary(msknan)*echelle
486          testnan = total(total(temporary(testnan), 1), 1) $
487            +(total(total(temporary(echelle), 1), 1) EQ 0)
488        endif
489      end
490      (dirx eq 1) and (diry eq 0) and (dirz eq 1) : begin
491        e133 = e1[*]#e3
492        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
493          IF keyword_set(wdepth) THEN $
494            e133[bottom] = (e1*e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
495          ELSE e133[bottom] = (e1*e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
496        ENDIF
497        echelle = (temporary(e133[*])*temporary(mask[*]))#replicate(1, jpt)
498        echelle = reform(echelle, nx, ny, nz, jpt, /over)
499        if keyword_set(integration) then divi = 1 ELSE begin
500          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 1), 2) $
501          ELSE divi = total(total(echelle, 1), 2)
502        endelse
503        res = total(total(temporary(res)*echelle, 1, nan = nan), 2, nan = nan)/(divi > 1)
504        if msknan[0] NE -1 then begin
505          echelle = temporary(echelle) NE 0
506          testnan = temporary(msknan)*echelle
507          testnan = total(total(temporary(testnan), 1), 2) $
508            +(total(total(temporary(echelle), 1), 2) EQ 0)
509        endif
510      end
511      (dirx eq 0) and (diry eq 1) and (dirz eq 1) : begin
512        e233 = e2[*]#e3
513        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
514          IF keyword_set(wdepth) THEN $
515            e233[bottom] = (e2*e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
516          ELSE e233[bottom] = (e2*e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
517        ENDIF
518        echelle = (temporary(e233[*])*temporary(mask[*]))#replicate(1, jpt)
519        echelle = reform(echelle, nx, ny, nz, jpt, /over)
520        if keyword_set(integration) then divi = 1 ELSE begin
521          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 2), 2) $
522          ELSE divi = total(total(echelle, 2), 2)
523        endelse
524        res = total(total(temporary(res)*echelle, 2, nan = nan), 2, nan = nan)/(divi > 1)
525        if msknan[0] NE -1 then begin
526          echelle = temporary(echelle) NE 0
527          testnan = temporary(msknan)*echelle
528          testnan = total(total(temporary(testnan), 2), 2) $
529            +(total(total(temporary(echelle), 2), 2) EQ 0)
530        endif
531      end
532      (dirx eq 1) and (diry eq 1) and (dirz eq 1) : begin
533        e1233 = (e1[*]*e2[*])#e3
534        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
535          IF keyword_set(wdepth) THEN $
536            e1233[bottom] = (e1*e2*e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
537          ELSE e1233[bottom] = (e1*e2*e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
538        ENDIF
539        echelle = (temporary(e1233[*])*temporary(mask[*]))#replicate(1, jpt)
540        echelle = reform(echelle, nx, ny, nz, jpt, /over)
541        if keyword_set(integration) then divi = 1 ELSE begin
542          IF msknan[0] NE -1 THEN divi = total(total(total(echelle*msknan, 1), 1), 1) $
543          ELSE divi = total(total(total(echelle, 1), 1), 1)
544        endelse
545        res = total(total(total(temporary(res)*echelle, 1, nan = nan), 1, nan = nan), 1, nan = nan)/(divi > 1)
546        if msknan[0] NE -1 then begin
547          echelle = temporary(echelle) NE 0
548          testnan = temporary(msknan)*echelle
549          testnan = total(total(total(temporary(testnan), 1), 1), 1) $
550            +(total(total(total(temporary(echelle), 1), 1), 1) EQ 0)
551        endif
552      end
553    endcase
554  endif
555;------------------------------------------------------------
556  if dirt EQ 1 AND keyword_set(spatialfirst) then BEGIN
557    IF (reverse(size(res, /dimension)))[0] NE jpt THEN BEGIN
558      ras = report('the last dimension of res is not equal to jpt: '+strtrim(jpt, 2))
559      if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
560      return, -1
561    ENDIF
562    tdim = size(res, /n_dimensions)
563    if keyword_set(integration) then res = total(res, tdim, nan = nan) $
564    ELSE BEGIN
565      if keyword_set(nan) then BEGIN
566        testnan = testnan < 1
567        testnan = total(temporary(testnan), tdim)
568        divi = testnan
569      ENDIF ELSE divi = jpt
570      res = total(res, tdim, nan = nan)/(1 > divi)
571    ENDELSE
572  ENDIF
573;------------------------------------------------------------
574;------------------------------------------------------------
575;IV ) finishing
576;------------------------------------------------------------
577;------------------------------------------------------------
578; IV.1) We mask land by a value equal to 1.e+20
579;------------------------------------------------------------
580  valmask = 1e+20
581  terre = where(divi EQ 0)
582  IF terre[0] NE -1 THEN BEGIN
583    res[temporary(terre)] = 1e+20
584  ENDIF
585;------------------------------------------------------------
586; IV.2) We replace, when nan equal 1, !values.f_nan by nan
587;------------------------------------------------------------
588  if keyword_set(nan) NE 0 then BEGIN
589    puttonan = where(temporary(testnan) EQ 0)
590    if puttonan[0] NE -1 then res[temporary(puttonan)] = !values.f_nan
591    if nan NE 1 then BEGIN
592      notanumber = where(finite(res) eq 0)
593      if notanumber[0] NE -1 then res[temporary(notanumber)] = nan
594    ENDIF
595  ENDIF
596;------------------------------------------------------------
597; IV.3) We replace in the domain whch was defined at the entry of average
598;------------------------------------------------------------
599  if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
600;------------------------------------------------------------
601  if keyword_set(key_performance) THEN print, 'temps grossemoyenne', systime(1)-tempsun
602  return, res
603;------------------------------------------------------------
604;------------------------------------------------------------
605end
Note: See TracBrowser for help on using the repository browser.