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

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

take into account the ssh in moyenne and grossemoyenne

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