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

Last change on this file since 796 was 792, checked in by acolaitis, 12 years ago

PYTHON GRAPHICS

  • Added option --finddevil which finds the steepest pressure drop in the PSFC field of the file, and add a cross in it's position.

This new function is intended to provide lon and lat of a dust devil to planetoplot. This could be used to drive a slice plot at the corresponding location.

  • Removed dumpbdy for LES files (no relaxation zone)
  • Added --mark mode to tiled plot
  • Added routines in mymath to convert back and forth between greyscale Image objects and 2D arrays
File size: 10.0 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              if axis is not None:
29                 zout.set_fill_value(np.NaN)
30                 return zout.filled()
31              else:return zout
32           elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
33              zout=np.ma.masked_invalid(field).mean(axis=axis)
34              if axis is not None:
35                 zout.set_fill_value([np.NaN])
36                 return zout.filled()
37              else:return zout
38           else: 
39              return np.array(field).mean(axis=axis)
40
41def sum (field,axis=None):
42        import numpy as np
43        if field is None: return None
44        else:
45           if type(field).__name__=='MaskedArray':
46              field.set_fill_value(np.NaN)
47              zout=np.ma.array(field).sum(axis=axis)
48              if axis is not None:
49                 zout.set_fill_value(np.NaN)
50                 return zout.filled()
51              else:return zout
52           elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
53              zout=np.ma.masked_invalid(field).sum(axis=axis)
54              if axis is not None:
55                 zout.set_fill_value([np.NaN])
56                 return zout.filled()
57              else:return zout
58           else:
59              return np.array(field).sum(axis=axis)
60             
61def getmask (field):
62        import numpy as np
63        if field is None: return None
64        if type(field).__name__=='MaskedArray':
65              return np.ma.getmask(field)
66        else:
67              return np.isnan(field)
68       
69
70def deg ():
71        return u'\u00b0'
72
73def writeascii ( tab, filename ):
74    mydata = tab
75    myfile = open(filename, 'w')
76    for line in mydata:
77        zeline = str(line)
78        zeline = zeline.replace('[','')
79        zeline = zeline.replace(']','')
80        myfile.write(zeline + '\n')
81    myfile.close()
82    return
83
84
85# A.C. routine to compute saturation temperature
86# Be Carefull, when asking for tsat-t, this routine outputs a masked array.
87# To be correctly handled, this call to tsat must be done before the call to
88# reduce_field, which handles correctly masked array with the new mean() function.
89def get_tsat(pressure,temp=None,zlon=None,zlat=None,zalt=None,ztime=None):
90    import math as mt
91    import numpy as np
92    acond=3.2403751E-04
93    bcond=7.3383721E-03
94    # if temp is not in input, the routine simply outputs the vertical profile
95    # of Tsat
96    if temp is None:
97      # Identify dimensions in temperature field
98      output=np.zeros(np.array(pressure).shape)
99      if len(np.array(pressure).shape) is 1:
100         #pressure field is a 1d column, (i.e. the altitude coordinate)
101         #temperature has to have a z-axis
102         i=0
103         for pp in pressure:
104            output[i]=1./(bcond-acond*mt.log(.0095*pp))         
105            i=i+1
106      else:
107         #pressure field is a field present in the file. Unhandled
108         #by this routine for now, which only loads unique variables.
109         print "3D pressure field not handled for now, exiting in tsat"
110         print "Use a vertical pressure coordinate if you want to compute Tsat"
111         exit()
112    # if temp is in input, the routine computes Tsat-T by detecting where the
113    # vertical axis is in temp
114    else:
115      output=np.zeros(np.array(temp).shape)
116      vardim=get_dim(zlon,zlat,zalt,ztime,temp)
117      if 'altitude' not in vardim.keys():
118         print 'no altitude coordinate in temperature field for Tsat computation'
119         exit()
120      zdim=vardim['altitude']
121      ndim=len(np.array(temp).shape)
122      print '--- in tsat(). vardim,zdim,ndim: ',vardim,zdim,ndim
123      i=0
124      for pp in pressure:
125        if ndim is 1:
126           output[i]=1./(bcond-acond*mt.log(.0095*pp))-temp[i]
127        elif ndim is 2:
128           if zdim is 0:
129              output[i,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[i,:]
130           elif zdim is 1:
131              output[:,i]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,i]
132           else:
133              print "stop in get_tsat: zdim: ",zdim
134              exit()
135        elif ndim is 3:
136           if zdim is 0:
137              output[i,:,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[i,:,:]
138           elif zdim is 1:
139              output[:,i,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,i,:]
140           elif zdim is 2:
141              output[:,:,i]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,:,i]
142           else:
143              print "stop in get_tsat: zdim: ",zdim
144              exit()
145        elif ndim is 4:
146           if zdim is 0:
147              output[i,:,:,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[i,:,:,:]
148           elif zdim is 1:
149              output[:,i,:,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,i,:,:]
150           elif zdim is 2:
151              output[:,:,i,:]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,:,i,:]
152           elif zdim is 3:
153              output[:,:,:,i]=1./(bcond-acond*mt.log(.0095*pp))-temp[:,:,:,i]
154           else:
155              print "stop in get_tsat: zdim: ", zdim
156              exit()
157        else:
158           print "stop in get_tsat: ndim: ",ndim
159           exit()
160        i=i+1
161    m=np.ma.masked_invalid(temp,copy=False)
162    zoutput=np.ma.array(output,mask=m.mask,fill_value=np.NaN)
163    return zoutput
164
165# A.C. Dirty routine to determine where are the axis of a variable
166def get_dim(zlon,zlat,zalt,ztime,zvar):
167   import numpy as np
168   nx,ny,nz,nt=0,0,0,0
169   if zlon is not None:
170      nx=len(zlon)
171   if zlat is not None:
172      ny=len(zlat)
173   if zalt is not None:
174      nz=len(zalt)
175   if ztime is not None:
176      nt=len(ztime)
177   zdims={}
178   zdims['longitude']=nx
179   zdims['latitude']=ny
180   zdims['altitude']=nz
181   zdims['Time']=nt
182   zvardim=np.array(zvar).shape
183   ndim=len(zvardim)
184   zzvardim=[[]]*ndim
185   j=0
186   output={}
187   for dim in zvardim:
188       if dim not in zdims.values():
189          print "WARNING -----------------------------"
190          print "Dimensions given to subroutine do not match variables dimensions :"
191          exit()
192       else:
193          a=get_key(zdims,dim)
194          if len(a) is not 1:
195             if j is 0:                ##this should solve most conflicts with Time
196                zzvardim[j]=a[1]
197             else:
198                zzvardim[j]=a[0]
199          else:
200              zzvardim[j]=a[0]
201          output[zzvardim[j]]=j
202          j=j+1
203   return output
204
205# A.C. routine that gets keys from a dictionnary value
206def get_key(self, value):
207    """find the key(s) as a list given a value"""
208    return [item[0] for item in self.items() if item[1] == value]
209
210# A.C. routine that gets the nearest value index of array and value
211def find_nearest(arr,value,axis=None,strict=False):
212    import numpy as np
213    # Special case when the value is nan
214    if value*0 != 0: return np.NaN
215    # Check that the value we search is inside the array for the strict mode
216    if strict:
217       min=arr.min()
218       max=arr.max()
219       if ((value > max) or (value < min)): return np.NaN
220
221    if type(arr).__name__=='MaskedArray':
222       mask=np.ma.getmask(arr)
223       idx=np.ma.argmin(np.abs(arr-value),axis=axis)
224    # Special case when there are only missing values on the axis
225       if mask[idx]:
226          idx=np.NaN
227    else:
228       idx=(np.abs(arr-value)).argmin(axis=axis)
229    return idx
230
231# Author: A.C.
232def fig2data ( fig ):
233    import numpy
234    """
235    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
236    @param fig a matplotlib figure
237    @return a numpy 3D array of RGBA values
238    """
239    # draw the renderer
240    fig.canvas.draw ( )
241 
242    # Get the RGBA buffer from the figure
243    w,h = fig.canvas.get_width_height()
244    buf = numpy.fromstring ( fig.canvas.tostring_argb(), dtype=numpy.uint8 )
245    buf.shape = ( w, h,4 )
246 
247    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
248    buf = numpy.roll ( buf, 3, axis = 2 )
249    return buf
250
251# Author: A.C.
252def fig2img ( fig ):
253    import Image
254    import numpy
255    """
256    @brief Convert a Matplotlib figure to a PIL Image in RGBA format and return it
257    @param fig a matplotlib figure
258    @return a Python Imaging Library ( PIL ) image
259    """
260    # put the figure pixmap into a numpy array
261    buf = fig2data ( fig )
262    w, h, d = buf.shape
263    return Image.fromstring( "RGBA", ( w ,h ), buf.tostring( ) )
264
265# Author: A.C.
266# Convert a single layer image object (greyscale) to an array
267def image2array(im):
268    import numpy as np
269    if im.mode not in ("L", "F"):
270        raise ValueError, ("can only convert single-layer images", im.mode)
271    if im.mode == "L":
272        a = np.fromstring(im.tostring(), np.uint8)
273    else:
274        a = np.fromstring(im.tostring(), np.float32)
275    a.shape = im.size[1], im.size[0]
276    return a
277
278# Author: A.C.
279# Convert a 2D array to a single layer image object (greyscale)
280def array2image(a):
281    import numpy as np
282    import Image
283    if a.dtype == np.uint8:
284        mode = "L"
285    elif a.dtype == np.float32:
286        mode = "F"
287    else:
288        raise ValueError, "unsupported image mode"
289    return Image.fromstring(mode, (a.shape[1], a.shape[0]), a.tostring())
290
Note: See TracBrowser for help on using the repository browser.