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

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

modification of some headers (+some corrections) to prepare usage of the new idldoc

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