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

Last change on this file since 72 was 25, checked in by pinsard, 18 years ago

upgrade of CALCULS according to cerbere.lodyc.jussieu.fr: /usr/home/smasson/SAXO_RD/ : files

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 29.6 KB
Line 
1;------------------------------------------------------------
2;------------------------------------------------------------
3;------------------------------------------------------------
4;+
5; NAME: grossemoyenne
6;
7; PURPOSE:  averages a 3- or 4-d time serie field over a selected
8;           geographical area or along the time axis. For one ore more
9;           selected axes (x, y, z, t)
10;
11; CATEGORY:
12;
13; CALLING SEQUENCE: result = grossemoyenne(tab,'direc',BOXZOOM=boxzoom)
14;
15; INPUTS:       tab = 3 or 4d field
16;               direc ='x' 'y' 'z' 't' 'xy' 'xz' 'yz' 'xyz' 'xt' 'yt' 'zt'
17;               'xyt' 'xzt' 'yzt' or 'xyzt'
18;
19; KEYWORD PARAMETERS:
20;
21;               boxzoom = [xmin,xmax,ymin,ymax (,(zmin,)zmax)] pour plus
22;               de detail cf domdef
23;               boxzoom peut prendre 5 formes:
24;               [vert2], [vert1, vert2],[lon1, lon2, lat1, lat2], 
25;               [lon1, lon2, lat1, lat2, vert2],[lon1, lon2, lat1, lat2, vert1,vert2]
26;             
27;               NAN: not a number, a activer si l''on peut faire veut
28;               faire une moyenne sans tenir compte de certaines
29;               valeurs masques de tab.
30;               si les valeurs masques de tab sont la valeur consacree
31;               par IDL (!values.f_nan), il suffit de mettre /NAN.
32;               si les valeurs masques de tab on pour valeur a (a doit
33;               etre differente de 1 (correspond a nan =
34;               !values.f_nan) et de 0 (qui desactive nan).
35;               Il faut mettre NAN=a.
36;               Rq: en sorties les points de result qui sont NAN
37;               auront pour valeur a ou !values.f_nan.
38;           
39;               NODOMDEF: activer si l''on ne veut pas passer ds
40;               domdef bien que le mot cle boxzoom soit present (comme
41;               c''est le cas qd grossemoyenne est appelee via
42;               checkfield)
43;
44;               INTEGRATION: pour faire une integrale plutot qu''une
45;               moyenne
46;
47;               /SPATIALFIRST, when performing at the same time
48;               spatial and temporal mean, grossemoyenne is assuming
49;               that the mask is not changing with the time. In
50;               consequence, grossemoyenne performs temporal mean
51;               first and then call moyenne. Activate /SPATIALFIRST if
52;               you want to perform the spatial mean before the
53;               temporal mean. Note that if NAN is activated, then
54;               SPATIALFIRST is activated automatically.
55;
56;               /TEMPORALFIRST: to force to perform first temporal
57;               mean even if nan is activated (see SPATIALFIRST
58;               explanations...)
59;
60;
61;         /WDEPTH: to specify that the field is at W depth instad of T
62;         depth (automatically activated if vargrid eq 'W')
63;           
64; OUTPUTS:
65;
66; COMMON BLOCKS:   result:un tableau
67;       common    domdef
68;
69; SIDE EFFECTS: met les valeurs correspondants a la terre a 1e20
70;
71; RESTRICTIONS:
72;
73; EXAMPLE:
74;
75; MODIFICATION HISTORY: Jerome Vialard (jv@lodyc.jussieu.fr)
76;                       2/7/98
77;                       Sebastien Masson (smasson@lodyc.jussieu.fr)
78; adaptation pour les tableaux comportants une dimension temporelle
79;                       14/8/98
80;                       15/1/98
81;                       12/3/99 adaptation pour NAN et utilisation de TEMPORARY
82;-
83;------------------------------------------------------------
84;------------------------------------------------------------
85;------------------------------------------------------------
86; PLAN DU PROGRAMME:
87;------------------------------------------------------------
88;------------------------------------------------------------
89;I) preliminaires
90;   I.1) determination des directions de moyennes d''apres direc
91;   I.2) verification de la taille du tableau d''entree
92;   I.3) obtention des facteurs d''echelles et du masque sur le sous
93;   domaine concerne par la moyenne
94;II) moyennes pour les tableaux 3d (x,y,t)
95;   II.1) verification de la coherence de la taille du tableau a
96;   moyenner
97;   II.2) renvoie sur moyenne qd une moyenne sur t est demandee
98;   II.3) differents types de moyennes possibles
99;III) moyennes pour les tableaux 4d (x,y,z,t)
100;   III.1) verification de la coherence de la taille du tableau a
101;   moyenner
102;   III.2) differents types de moyennes possibles
103;IV ) finitions
104;   IV.1) on masque les terres par une valeur a 1e+20
105;   IV.2) on remplace, quand nan ne 1, !values.f_nan par nan
106;   IV.3) on revient au sous domaine initial.
107;------------------------------------------------------------
108;------------------------------------------------------------
109;------------------------------------------------------------
110function grossemoyenne, tab, direc, BOXZOOM = boxzoom, INTEGRATION = integration $
111                        , NAN = nan, NODOMDEF = nodomdef, WDEPTH = wdepth $
112                        , SPATIALFIRST = spatialfirst, TEMPORALFIRST = temporalfirst $
113                        , _extra = ex
114;---------------------------------------------------------
115@cm_4mesh
116@cm_4data
117@cm_4cal
118  IF NOT keyword_set(key_forgetold) THEN BEGIN
119@updatenew
120@updatekwd
121  ENDIF
122;---------------------------------------------------------
123  tempsun = systime(1)          ; pour key_performance
124;------------------------------------------------------------
125;I) preliminaires
126;------------------------------------------------------------
127  dirt = 0
128  dirx = 0
129  diry = 0
130  dirz = 0
131  dim  = 'aa'
132;------------------------------------------------------------
133; I.1) direction(s) suivants lesquelles on integre
134;------------------------------------------------------------
135  if ( strpos(direc, 't') ge 0 ) then dirt = 1
136  if ( strpos(direc, 'x') ge 0 ) then dirx = 1
137  if ( strpos(direc, 'y') ge 0 ) then diry = 1
138  if ( strpos(direc, 'z') ge 0 ) then dirz = 1
139  IF keyword_set(NAN) AND (dirx EQ 1 OR diry EQ 1 OR dirz EQ 1) $
140    THEN spatialfirst = 1
141  IF keyword_set(temporalfirst) THEN spatialfirst = 0
142;------------------------------------------------------------
143; I.2) verification de la taille du tableau d'entree
144;------------------------------------------------------------
145  taille = size(tab)
146  case 1 of
147    taille[0] eq 1 :return,  report('Le tableau n''a qu''une dimension, cas non traite!')
148    taille[0] eq 2 :return,  report('Le tableau n''a qu''deux dimension, cas non traite!')
149    taille[0] eq 3 :BEGIN
150      dim = '3d'
151      if dirx eq 0 and diry eq 0 and dirt eq 0 then return, tab
152    END
153    taille[0] eq 4 :BEGIN
154      dim = '4d'
155      if dirx eq 0 and diry eq 0 and dirz eq 0 and dirt eq 0 then return, tab
156    END
157    else : return, report('Le tableau d entree doit etre a 3 ou 4 dimensions s''il ne contient pas de dim temporelle utiliser moyenne')
158  endcase
159;------------------------------------------------------------
160;   I.4) obtention des facteurs d''echelles et du masque sur le sous
161;   domaine concerne par la moyenne
162; redefinition du domaine ajuste a boxzoom (a 6 elements)
163; ceci va nous permetre de faire les calcules que sur le sous domaine
164; comcerne par la moyenne. domdef, suivit de grille nous donne tous
165; les tableaux de la grille sur le sous domaine
166;------------------------------------------------------------
167  if keyword_set(boxzoom) then BEGIN
168    Case 1 Of
169      N_Elements(Boxzoom) Eq 1: bte = [lon1, lon2, lat1, lat2, 0., boxzoom[0]]
170      N_Elements(Boxzoom) Eq 2: bte = [lon1, lon2, lat1, lat2, boxzoom[0], boxzoom[1]]
171      N_Elements(Boxzoom) Eq 4: bte = [Boxzoom, vert1, vert2]
172      N_Elements(Boxzoom) Eq 5: bte = [Boxzoom[0:3], 0, Boxzoom[4]]
173      N_Elements(Boxzoom) Eq 6: bte = Boxzoom
174      Else: return, report('Wrong Definition of Boxzoom')
175    endcase
176    if NOT keyword_set(nodomdef) then BEGIN
177      savedbox = 1b
178      saveboxparam, 'boxparam4grmoyenne.dat'
179      domdef, bte, GRIDTYPE = vargrid, _extra = ex
180    ENDIF
181  ENDIF
182;---------------------------------------------------------------
183; attribution du mask et des tableaux de longitude et latitude...
184;---------------------------------------------------------------
185  grille, mask, glam, gphi, gdep, nx, ny, nz, firstx, firsty, firstz, lastx, lasty, lastz, e1, e2, e3, WDEPTH = wdepth
186;------------------------------------------------------------
187; I.3) si dirt eq 1 on fait la moyenne temporelle et on envoie ds moyenne
188;------------------------------------------------------------
189  if dirt EQ 1 AND NOT keyword_set(spatialfirst) then begin
190    if dim EQ 3d then BEGIN
191      case 1 of
192        taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpt: $
193          res = tab[firstx:firstx+nx-1 $
194                    , firsty:firsty+ny-1, *]
195        taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpt:res = tab
196        else:BEGIN
197          if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
198          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))
199        END
200      ENDCASE
201      if keyword_set(integration) then begin
202        res = total(res, 3, nan = nan)
203      ENDIF ELSE BEGIN
204        if keyword_set(nan) then BEGIN
205          divi = finite(res)
206          divi = total(temporary(divi), 3)
207          notanum = where(divi EQ 0)
208          res = total(res, 3, nan = keyword_set(nan))/ (1 > divi)
209          if notanum[0] NE -1 then res[temporary(notanum)] = !values.f_nan
210        ENDIF ELSE res = total(res, 3)/(1.*taille[3])
211      ENDELSE
212    ENDIF ELSE BEGIN
213      case 1 of
214        taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpk and taille[4] eq jpt: $
215          res = tab[firstx:lastx, firsty:lasty, firstz:lastz, *]
216        taille[1] eq jpi and taille[2] eq jpj and taille[3] eq nz and taille[4] eq jpt: $
217          res = tab[firstx:lastx, firsty:lasty, *, *]
218        taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq nz and taille[4] eq jpt:res = tab
219        taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpk and taille[4] eq jpt: $
220          res = tab[*, *, firstz:lastz, *]
221        else:BEGIN
222           if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
223          return, report('Probleme d''adequation entre les tailles du domaine nx*ny*nz*jpt ' $
224                         +strtrim(nx, 1)+'*'+strtrim(ny, 1)+'*'+strtrim(nz, 1)+'*' $
225                         +strtrim(jpt, 1)+' et du tableau '+strtrim(taille[1], 1)+'*' $
226                         +strtrim(taille[2], 1)+'*'+strtrim(taille[3], 1)+'*' $
227                         +strtrim(taille[4], 1))
228        END
229        endcase
230      if keyword_set(integration) then begin
231        res = total(res, 4, nan = nan)
232      ENDIF ELSE BEGIN
233        if keyword_set(nan) then begin
234          divi = finite(res)
235          divi = total(temporary(divi), 4)
236          notanum = where(divi EQ 0)
237          res = total(res, 4, /nan)/(1 > divi)
238          if notanum[0] NE -1 then res[temporary(notanum)] = !values.f_nan
239        ENDIF ELSE res = total(res, 4)/(1.*taille[4])
240      ENDELSE
241    ENDELSE
242    if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'   
243    return,  moyenne(temporary(res), direc, BOXZOOM = boxzoom, NAN = nan, INTEGRATION = integration, NODOMDEF = nodomdef, WDEPTH = wdepth, _extra = ex)
244  ENDIF ELSE res = tab
245  IF jpt EQ 1 THEN BEGIN
246    if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'   
247    return, moyenne(reform(res, /over), direc, BOXZOOM = boxzoom, NAN = nan, INTEGRATION = integration, NODOMDEF = nodomdef, WDEPTH = wdepth, _extra = ex)
248  END
249;------------------------------------------------------------
250;------------------------------------------------------------
251; II) Cas serie tableaux 2d (tab3d)
252;------------------------------------------------------------
253;------------------------------------------------------------
254  if (dim eq '3d') then begin
255;---------------------------------------------------------------
256;   II.1) verification de la coherence de la taille du tableau a
257;   moyenner
258; verification de la coherence entre la taille du tableau et le
259; domaine definit par domdef
260; le tableau en entree doit avoir soit la taille du domaine total
261; (jpi,jpj,jpt) soit celle du domaine reduit (nx,ny,jpt)
262;---------------------------------------------------------------
263    case 1 of
264      taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpt: $
265        res = tab[firstx:firstx+nx-1 $
266                  , firsty:firsty+ny-1, *]
267      taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpt:res = tab
268      else:BEGIN
269        if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
270        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))
271      enD
272    endcase
273    if keyword_set(nan) NE 0 then BEGIN
274      if nan NE 1 then BEGIN    ; si nan n''est pas !values.f_nan
275; on le met a !values.f_nan
276        if abs(nan) LT 1e6 then notanumber = where(res EQ nan) $
277        ELSE notanumber = where(abs(res) GT abs(nan)/10.)
278        if notanumber[0] NE -1 then res[temporary(notanumber)] = !values.f_nan
279      ENDIF
280    ENDIF
281;---------------------------------------------------------------
282; rq IL FAUT FAIRE ATTENTION AUX CAS OU LA DIM A MOYENNER = 1, ET
283; S'ASSURER QU'ELLE EXISTE BIEN. D'OU LES reform(...,nx,ny,...) QUI
284; PEUVENT SEMBLER INUTILE AU DEPART
285;---------------------------------------------------------------
286    if nx EQ 1 OR ny EQ 1 then BEGIN
287      res = reform(res, nx, ny, jpt, /over)
288      e1 =  reform(e1, nx, ny, /over)
289      e2 =  reform(e2, nx, ny, /over)
290    endif
291    if nx EQ 1 OR ny EQ 1 OR nz EQ 1 THEN $
292      mask =  reform(mask, nx, ny, nz, /over)
293;---------------------------------------------------------------
294; II.3) differents types de moyennes
295;---------------------------------------------------------------
296    if keyword_set(nan) NE 0 then msknan = finite(res) ELSE msknan = -1
297    mask = mask[*, *, 0]
298    case 1 of
299      (dirx eq 1) and (diry eq 0) : begin
300        e = temporary(e1)*temporary(mask)
301        echelle = (temporary(e))[*]#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(echelle*msknan, 1) $
305          ELSE divi = total(echelle, 1)
306        ENDELSE
307        res = total(temporary(res)*echelle, 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(temporary(testnan), 1) $
312            +(total(temporary(echelle), 1) EQ 0)
313        endif
314      end
315      (dirx eq 0) and (diry eq 1) : begin
316        e = temporary(e2)*temporary(mask)
317        if nx EQ 1 OR ny EQ 1 then e = reform(e, nx, ny, /over)
318        echelle = (temporary(e))[*]#replicate(1, jpt)
319        echelle = reform(echelle, nx, ny, jpt, /over)
320        if keyword_set(integration) then divi = 1 ELSE BEGIN
321          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 2) $
322          ELSE divi = total(echelle, 2)
323        ENDELSE
324        res = total(temporary(res)*echelle, 2, nan = nan)/(divi > 1.)
325        if msknan[0] NE -1 then begin
326          echelle = temporary(echelle) NE 0
327          testnan = temporary(msknan)*echelle
328          testnan = total(temporary(testnan), 2) $
329            +(total(temporary(echelle), 2) EQ 0)
330        endif
331      end
332      (dirx eq 1) and (diry eq 1) : begin
333        echelle = (temporary(e1)*temporary(e2)*temporary(mask))[*]#replicate(1, jpt)
334        echelle = reform(echelle, nx, ny, jpt, /over)
335        if keyword_set(integration) then divi = 1 ELSE BEGIN
336          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 1), 1) $
337          ELSE divi = total(total(echelle, 1), 1)
338        ENDELSE
339        res = total(temporary(total(temporary(res)*echelle, 1, nan = nan)), 1, nan = nan)/(divi > 1.)
340        if msknan[0] NE -1 then begin
341          echelle = temporary(echelle) NE 0
342          testnan = temporary(msknan)*echelle
343          testnan = total(total(temporary(testnan), 1), 1) $
344            +(total(total(temporary(echelle), 1), 1) EQ 0)
345        endif
346      end
347    endcase
348  endif
349;------------------------------------------------------------
350;------------------------------------------------------------
351; III) Cas serie tableaux 3d (tab4d)
352;------------------------------------------------------------
353  if (dim eq '4d') then begin
354;---------------------------------------------------------------
355; III.1) verification de la coherence de la taille du tableau a
356; moyenner
357; verification de la coherence entre la taille du tableau et le
358; domaine definit par domdef
359; le tableau en entree doit avoir soit la taille du domaine total
360; (jpi,jpj,jpk,jpt) soit celle du domaine reduit (nx,ny,ny,jpt)
361;---------------------------------------------------------------
362    case 1 of
363      taille[1] eq jpi and taille[2] eq jpj and taille[3] eq jpk and taille[4] eq jpt: $
364        res = tab[firstx:lastx, firsty:lasty, firstz:lastz, *]
365      taille[1] eq jpi and taille[2] eq jpj and taille[3] eq nz and taille[4] eq jpt: $
366        res = tab[firstx:lastx, firsty:lasty, *, *]
367      taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq nz and taille[4] eq jpt:res = tab
368      taille[1] EQ  nx and taille[2] eq  ny and taille[3] eq jpk and taille[4] eq jpt: $
369        res = tab[*, *, firstz:lastz, *]
370      else:BEGIN
371        if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
372        return, report('Probleme d''adequation entre les tailles du domaine nx*ny*nz*jpt ' $
373                       +strtrim(nx, 1)+'*'+strtrim(ny, 1)+'*'+strtrim(nz, 1)+'*' $
374                       +strtrim(jpt, 1)+' et du tableau '+strtrim(taille[1], 1)+'*' $
375                       +strtrim(taille[2], 1)+'*'+strtrim(taille[3], 1)+'*' $
376                       +strtrim(taille[4], 1))
377      END
378    endcase
379    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)
380    if keyword_set(nan) NE 0 then BEGIN
381      if nan NE 1 then BEGIN    ; si nan n''est pas !values.f_nan
382; on le met a !values.f_nan
383        if abs(nan) LT 1e6 then notanumber = where(res EQ nan) $
384        ELSE notanumber = where(abs(res) GT abs(nan)/10.)
385        if notanumber[0] NE -1 then res[temporary(notanumber)] = !values.f_nan
386      ENDIF
387    ENDIF
388;---------------------------------------------------------------
389; rq IL FAUT FAIRE ATTENTION AUX CAS OU LA DIM A MOYENNER = 1, ET
390; S'ASSURER QU'ELLE EXISTE BIEN. D'OU LES reform(...,nx,ny,...) QUI
391; PEUVENT SEMBLER INUTILE AU DEPART
392;---------------------------------------------------------------
393    if nx EQ 1 OR ny EQ 1 OR nz EQ 1 then BEGIN
394      res = reform(res, nx, ny, nz, jpt, /over)
395      mask =  reform(mask, nx, ny, nz, /over)
396    ENDIF
397    IF keyword_set(key_partialstep) THEN BEGIN
398; the top of the ocean floor is
399      IF vargrid EQ 'T' OR vargrid EQ 'W' THEN bottom = total(mask, 3) $
400      ELSE bottom = total(tmask[firstx:lastx, firsty:lasty, firstz:lastz], 3)
401; we suppress columns with only ocean or land
402      good = where(bottom NE 0 AND bottom NE nz)
403; the bottom of the ocean in 3D index is:
404      bottom = lindgen(nx*ny)+(temporary(bottom)-1L)*nx*ny
405      IF good[0] NE -1 THEN bottom = bottom[good] $
406      ELSE bottom = -1
407    ENDIF ELSE bottom = -1
408;---------------------------------------------------------------
409; III.2) differents types de moyennes
410;---------------------------------------------------------------
411    IF keyword_set(nan) NE 0 THEN msknan = finite(res) ELSE msknan = -1
412    case 1 of
413      (dirx eq 1) and (diry eq 0) and (dirz eq 0) : BEGIN
414        e13 = (temporary(e1))[*]#replicate(1., nz)
415        e13 = reform(e13, nx, ny, nz, /over)
416        echelle = (temporary(e13)*temporary(mask))[*]#replicate(1, jpt)
417        echelle = reform(echelle, nx, ny, nz, jpt, /over)
418        IF keyword_set(key_partialstep) AND bottom[0] NE -1 $
419          AND nx NE 1 THEN BEGIN
420          IF msknan[0] EQ -1 THEN BEGIN
421            msknan = replicate(1b, nx, ny, nz, jpt)
422            nan = 1
423          ENDIF
424          bottom = bottom#replicate(1, jpt) $ ; 4D bottom!
425            + replicate(1, n_elements(bottom))#(nx*ny*nz*lindgen(jpt))
426          msknan[bottom] = 0
427          res[temporary(bottom)] = !values.f_nan
428        ENDIF
429        if keyword_set(integration) then divi = 1 ELSE begin
430          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 1) $
431          ELSE divi = total(echelle, 1)
432        endelse
433        res = temporary(res)*echelle
434        res = total(temporary(res), 1, nan = nan)/(divi > 1)
435        if msknan[0] NE -1 then begin
436          echelle = temporary(echelle) NE 0
437          testnan = temporary(msknan)*echelle
438          testnan = total(temporary(testnan), 1) $
439            +(total(temporary(echelle), 1) EQ 0)
440        endif
441      end
442      (dirx eq 0) and (diry eq 1) and (dirz eq 0) : begin
443        e23 = temporary(e2[*])#replicate(1., nz)
444        e23 = reform(e23, nx, ny, nz, /over)
445        echelle = (temporary(e23)*temporary(mask))[*]#replicate(1, jpt)
446        echelle = reform(echelle, nx, ny, nz, jpt, /over)
447        IF keyword_set(key_partialstep) AND bottom[0] NE -1 $
448          AND ny NE 1 THEN BEGIN
449          IF msknan[0] EQ -1 THEN BEGIN
450            msknan = replicate(1b, nx, ny, nz)
451            nan = 1
452          endif
453          bottom = bottom#replicate(1, jpt) $ ; 4D bottom!
454            + replicate(1, n_elements(bottom))#(nx*ny*nz*lindgen(jpt))
455          msknan[bottom] = 0
456          res[temporary(bottom)] = !values.f_nan
457        ENDIF
458        if keyword_set(integration) then divi = 1 ELSE begin
459          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 2) $
460          ELSE divi = total(echelle, 2)
461        endelse
462        res = total(temporary(res)*echelle, 2, nan = nan)/(divi > 1)
463        if msknan[0] NE -1 then begin
464          echelle = temporary(echelle) NE 0
465          testnan = temporary(msknan)*echelle
466          testnan = total(temporary(testnan), 2) $
467            +(total(temporary(echelle), 2) EQ 0)
468        endif
469      end
470      (dirx eq 0) and (diry eq 0) and (dirz eq 1) : begin
471        e33 = replicate(1, 1.*nx*ny)#e3
472        e33 = reform(e33, nx, ny, nz, /over)
473        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
474          IF keyword_set(wdepth) THEN $
475            e33[bottom] = (e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
476          ELSE e33[bottom] = (e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
477        ENDIF
478        echelle = (temporary(e33)*temporary(mask))[*]#replicate(1, jpt)
479        echelle = reform(echelle, nx, ny, nz, jpt, /over)
480        if keyword_set(integration) then divi = 1 ELSE begin
481          IF msknan[0] NE -1 THEN divi = total(echelle*msknan, 3) $
482          ELSE divi = total(echelle, 3)
483        endelse
484        res = total(temporary(res)*echelle, 3, nan = nan)/(divi > 1)
485        if msknan[0] NE -1 then begin
486          echelle = temporary(echelle) NE 0
487          testnan = temporary(msknan)*echelle
488          testnan = total(temporary(testnan), 3) $
489            +(total(temporary(echelle), 3) EQ 0)
490        endif
491      end
492      (dirx eq 1) and (diry eq 1) and (dirz eq 0) : begin
493        e13 = e1[*]#replicate(1., nz)
494        e13 = reform(e13, nx, ny, nz, /over)
495        e23 = e2[*]#replicate(1., nz)
496        e23 = reform(e23, nx, ny, nz, /over)
497        echelle = (temporary(e13)*temporary(e23)*temporary(mask))[*]#replicate(1, jpt)
498        echelle = reform(echelle, nx, ny, nz, jpt, /over)
499        IF keyword_set(key_partialstep) AND bottom[0] NE -1 $
500          AND nx*ny NE 1 THEN BEGIN
501          IF msknan[0] EQ -1 THEN BEGIN
502            msknan = replicate(1b, nx, ny, nz)
503            nan = 1
504          endif
505          bottom = bottom#replicate(1, jpt) $ ; 4D bottom!
506            + replicate(1, n_elements(bottom))#(nx*ny*nz*lindgen(jpt))
507          msknan[bottom] = 0
508          res[temporary(bottom)] = !values.f_nan
509        ENDIF
510        if keyword_set(integration) then divi = 1 ELSE begin
511          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 1), 1) $
512          ELSE divi = total(total(echelle, 1), 1)
513        endelse
514        res = total(total(temporary(res)*echelle, 1, nan = nan), 1, nan = nan)/(divi > 1)
515        if msknan[0] NE -1 then begin
516          echelle = temporary(echelle) NE 0
517          testnan = temporary(msknan)*echelle
518          testnan = total(total(temporary(testnan), 1), 1) $
519            +(total(total(temporary(echelle), 1), 1) EQ 0)
520        endif
521      end
522      (dirx eq 1) and (diry eq 0) and (dirz eq 1) : begin
523        e133 = e1[*]#e3
524        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
525          IF keyword_set(wdepth) THEN $
526            e133[bottom] = (e1*e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
527          ELSE e133[bottom] = (e1*e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
528        ENDIF
529        echelle = (temporary(e133[*])*temporary(mask[*]))#replicate(1, jpt)
530        echelle = reform(echelle, nx, ny, nz, jpt, /over)
531        if keyword_set(integration) then divi = 1 ELSE begin
532          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 1), 2) $
533          ELSE divi = total(total(echelle, 1), 2)
534        endelse
535        res = total(total(temporary(res)*echelle, 1, nan = nan), 2, nan = nan)/(divi > 1)
536        if msknan[0] NE -1 then begin
537          echelle = temporary(echelle) NE 0
538          testnan = temporary(msknan)*echelle
539          testnan = total(total(temporary(testnan), 1), 2) $
540            +(total(total(temporary(echelle), 1), 2) EQ 0)
541        endif
542      end
543      (dirx eq 0) and (diry eq 1) and (dirz eq 1) : begin
544        e233 = e2[*]#e3
545        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
546          IF keyword_set(wdepth) THEN $
547            e233[bottom] = (e2*e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
548          ELSE e233[bottom] = (e2*e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
549        ENDIF
550        echelle = (temporary(e233[*])*temporary(mask[*]))#replicate(1, jpt)
551        echelle = reform(echelle, nx, ny, nz, jpt, /over)
552        if keyword_set(integration) then divi = 1 ELSE begin
553          IF msknan[0] NE -1 THEN divi = total(total(echelle*msknan, 2), 2) $
554          ELSE divi = total(total(echelle, 2), 2)
555        endelse
556        res = total(total(temporary(res)*echelle, 2, nan = nan), 2, nan = nan)/(divi > 1)
557        if msknan[0] NE -1 then begin
558          echelle = temporary(echelle) NE 0
559          testnan = temporary(msknan)*echelle
560          testnan = total(total(temporary(testnan), 2), 2) $
561            +(total(total(temporary(echelle), 2), 2) EQ 0)
562        endif
563      end
564      (dirx eq 1) and (diry eq 1) and (dirz eq 1) : begin
565        e1233 = (e1[*]*e2[*])#e3
566        IF keyword_set(key_partialstep) AND bottom[0] NE -1 THEN BEGIN
567          IF keyword_set(wdepth) THEN $
568            e1233[bottom] = (e1*e2*e3w_ps[firstx:lastx, firsty:lasty])[temporary(good)] $
569          ELSE e1233[bottom] = (e1*e2*e3t_ps[firstx:lastx, firsty:lasty])[temporary(good)]
570        ENDIF
571        echelle = (temporary(e1233[*])*temporary(mask[*]))#replicate(1, jpt)
572        echelle = reform(echelle, nx, ny, nz, jpt, /over)
573        if keyword_set(integration) then divi = 1 ELSE begin
574          IF msknan[0] NE -1 THEN divi = total(total(total(echelle*msknan, 1), 1), 1) $
575          ELSE divi = total(total(total(echelle, 1), 1), 1)
576        endelse
577        res = total(total(total(temporary(res)*echelle, 1, nan = nan), 1, nan = nan), 1, nan = nan)/(divi > 1)
578        if msknan[0] NE -1 then begin
579          echelle = temporary(echelle) NE 0
580          testnan = temporary(msknan)*echelle
581          testnan = total(total(total(temporary(testnan), 1), 1), 1) $
582            +(total(total(total(temporary(echelle), 1), 1), 1) EQ 0)
583        endif
584      end
585    endcase
586  endif
587;------------------------------------------------------------
588  if dirt EQ 1 AND keyword_set(spatialfirst) then BEGIN
589    IF (reverse(size(res, /dimension)))[0] NE jpt THEN BEGIN
590      print, 'the last dimension of res is not equal to jpt: '+strtrim(jpt, 2)
591      if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
592      return, -1
593    ENDIF
594    tdim = size(res, /n_dimensions)
595    if keyword_set(integration) then res = total(res, tdim, nan = nan) $
596    ELSE BEGIN
597      if keyword_set(nan) then BEGIN
598        testnan = testnan < 1
599        testnan = total(temporary(testnan), tdim)
600        divi = testnan
601      ENDIF ELSE divi = jpt
602      res = total(res, tdim, nan = nan)/(1 > divi)
603    ENDELSE
604  ENDIF
605;------------------------------------------------------------
606;------------------------------------------------------------
607;IV ) finitions
608;------------------------------------------------------------
609;------------------------------------------------------------
610; IV.1) on masque les terres par une valeur a 1e+20
611;------------------------------------------------------------
612  valmask = 1e+20
613  terre = where(divi EQ 0)
614  IF terre[0] NE -1 THEN BEGIN
615    res(temporary(terre)) = 1e+20
616  ENDIF
617;------------------------------------------------------------
618; IV.2) on remplace, quand nan ne 1, !values.f_nan par nan
619;------------------------------------------------------------
620  if keyword_set(nan) NE 0 then BEGIN
621    puttonan = where(temporary(testnan) EQ 0)
622    if puttonan[0] NE -1 then res[temporary(puttonan)] = !values.f_nan
623    if nan NE 1 then BEGIN
624      notanumber = where(finite(res) eq 0)
625      if notanumber[0] NE -1 then res[temporary(notanumber)] = nan
626    ENDIF
627  ENDIF
628;------------------------------------------------------------
629; IV.3) on se remplace ds le sous domaine qui etait definit a l''entree de
630; moyenne
631;------------------------------------------------------------
632  if keyword_set(savedbox) THEN restoreboxparam, 'boxparam4grmoyenne.dat'
633;------------------------------------------------------------
634  if keyword_set(key_performance) THEN print, 'temps grossemoyenne', systime(1)-tempsun
635  return, res
636;------------------------------------------------------------
637;------------------------------------------------------------
638end
Note: See TracBrowser for help on using the repository browser.