source: trunk/UTIL/PYTHON/mymath.py @ 398

Last change on this file since 398 was 398, checked in by acolaitis, 13 years ago

PYTHON:

  • Improved handling of missing values NaN by min() and max() functions
  • Added the possibility to change the viewing angle of "ortho" projections by using --blat. Default is meanlat. (remember than in spstere and npstere projections, blat already controls the boundling latitude)
  • Changed colorbar of "operation" plots to RdBu_r, whatever the colorbar of other plots are. The thinking behind this is that this is a symmetrical colorbar, which is very usefull for difference plots. (could be changed for other operations.)
File size: 6.2 KB
Line 
1def min (field,axis=None): 
2        import numpy as np
3        if field is None: return None
4        if type(field).__name__=='MaskedArray':
5              field.set_fill_value(np.NaN)
6              return np.ma.array(field).min(axis=axis)
7        elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
8              return np.ma.masked_invalid(field).min(axis=axis)
9        else: return np.array(field).min(axis=axis)
10
11def max (field,axis=None):
12        import numpy as np
13        if field is None: return None
14        if type(field).__name__=='MaskedArray':
15              field.set_fill_value(np.NaN)
16              return np.ma.array(field).max(axis=axis)
17        elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
18              return np.ma.masked_invalid(field).max(axis=axis) 
19        else: return np.array(field).max(axis=axis)
20
21def mean (field,axis=None):
22        import numpy as np
23        if field is None: return None
24        else: 
25           if type(field).__name__=='MaskedArray':
26              field.set_fill_value(np.NaN)
27              zout=np.ma.array(field).mean(axis=axis)
28              zout.set_fill_value(np.NaN)
29              return zout.filled()
30           elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
31              zout=np.ma.masked_invalid(field).mean(axis=axis)
32              zout.set_fill_value([np.NaN])
33              return zout.filled()
34           else: 
35              return np.array(field).mean(axis=axis)
36
37def deg ():
38        return u'\u00b0'
39
40def writeascii ( tab, filename ):
41    mydata = tab
42    myfile = open(filename, 'w')
43    for line in mydata:
44        myfile.write(str(line) + '\n')
45    myfile.close()
46    return
47
48
49# A.C. routine to compute saturation temperature
50# Be Carefull, when asking for tsat-t, this routine outputs a masked array.
51# To be correctly handled, this call to tsat must be done before the call to
52# reduce_field, which handles correctly masked array with the new mean() function.
53def get_tsat(pressure,temp=None,zlon=None,zlat=None,zalt=None,ztime=None):
54    import math as mt
55    import numpy as np
56    acond=3.2403751E-04
57    bcond=7.3383721E-03
58    # if temp is not in input, the routine simply outputs the vertical profile
59    # of Tsat
60    if temp is None:
61      # Identify dimensions in temperature field
62      output=np.zeros(np.array(pressure).shape)
63      if len(np.array(pressure).shape) is 1:
64         #pressure field is a 1d column, (i.e. the altitude coordinate)
65         #temperature has to have a z-axis
66         i=0
67         for pp in pressure:
68            output[i]=1./(bcond-acond*mt.log(.0095*pp))         
69            i=i+1
70      else:
71         #pressure field is a field present in the file. Unhandled
72         #by this routine for now, which only loads unique variables.
73         print "3D pressure field not handled for now, exiting in tsat"
74         print "Use a vertical pressure coordinate if you want to compute Tsat"
75         exit()
76    # if temp is in input, the routine computes Tsat-T by detecting where the
77    # vertical axis is in temp
78    else:
79      output=np.zeros(np.array(temp).shape)
80      vardim=get_dim(zlon,zlat,zalt,ztime,temp)
81      if 'altitude' not in vardim.keys():
82         print 'no altitude coordinate in temperature field for Tsat computation'
83         exit()
84      zdim=vardim['altitude']
85      ndim=len(np.array(temp).shape)
86      print '--- in tsat(). vardim,zdim,ndim: ',vardim,zdim,ndim
87      i=0
88      for pp in pressure:
89        if ndim is 1:
90           output[i]=1./(bcond-acond*mt.log(.0095*pp))-temp[i]
91        elif ndim is 2:
92           if zdim is 0:
93              output[i,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[i,:]
94           elif zdim is 1:
95              output[:,i]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,i]
96           else:
97              print "stop in get_tsat: zdim: ",zdim
98              exit()
99        elif ndim is 3:
100           if zdim is 0:
101              output[i,:,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[i,:,:]
102           elif zdim is 1:
103              output[:,i,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,i,:]
104           elif zdim is 2:
105              output[:,:,i]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,:,i]
106           else:
107              print "stop in get_tsat: zdim: ",zdim
108              exit()
109        elif ndim is 4:
110           if zdim is 0:
111              output[i,:,:,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[i,:,:,:]
112           elif zdim is 1:
113              output[:,i,:,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,i,:,:]
114           elif zdim is 2:
115              output[:,:,i,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,:,i,:]
116           elif zdim is 3:
117              output[:,:,:,i]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,:,:,i]
118           else:
119              print "stop in get_tsat: zdim: ", zdim
120              exit()
121        else:
122           print "stop in get_tsat: ndim: ",ndim
123           exit()
124        i=i+1
125    m=np.ma.masked_invalid(temp,copy=False)
126    zoutput=np.ma.array(output,mask=m.mask,fill_value=np.NaN)
127    return zoutput
128
129# A.C. Dirty routine to determine where are the axis of a variable
130def get_dim(zlon,zlat,zalt,ztime,zvar):
131   import numpy as np
132   nx,ny,nz,nt=0,0,0,0
133   if zlon is not None:
134      nx=len(zlon)
135   if zlat is not None:
136      ny=len(zlat)
137   if zalt is not None:
138      nz=len(zalt)
139   if ztime is not None:
140      nt=len(ztime)
141   zdims={}
142   zdims['longitude']=nx
143   zdims['latitude']=ny
144   zdims['altitude']=nz
145   zdims['Time']=nt
146   zvardim=np.array(zvar).shape
147   ndim=len(zvardim)
148   zzvardim=[[]]*ndim
149   j=0
150   output={}
151   for dim in zvardim:
152       if dim not in zdims.values():
153          print "WARNING -----------------------------"
154          print "Dimensions given to subroutine do not match variables dimensions :"
155          exit()
156       else:
157          a=get_key(zdims,dim)
158          if len(a) is not 1:
159             if j is 0:                ##this should solve most conflicts with Time
160                zzvardim[j]=a[1]
161             else:
162                zzvardim[j]=a[0]
163          else:
164              zzvardim[j]=a[0]
165          output[zzvardim[j]]=j
166          j=j+1
167   return output
168
169# A.C. routine that gets keys from a dictionnary value
170def get_key(self, value):
171    """find the key(s) as a list given a value"""
172    return [item[0] for item in self.items() if item[1] == value]
173
Note: See TracBrowser for help on using the repository browser.