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

Last change on this file since 424 was 424, checked in by smasson, 14 years ago

add keepbottom keyword in moyenne and grossemoyenne

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