source: trunk/UTIL/PYTHON/mcd/mcd.py @ 807

Last change on this file since 807 was 807, checked in by aslmd, 12 years ago

UTIL PYTHON. mcd. background topo from surfacenc. title on colorbar on 2D maps. correct aspect ratio for 2D maps.

  • Property svn:executable set to *
File size: 31.4 KB
Line 
1####################################################
2### A Python Class for the Mars Climate Database ###
3### ---------------------------------------------###
4### Aymeric SPIGA 17-21/04/2012                  ###
5### ---------------------------------------------###
6### (see mcdtest.py for examples of use)         ###
7####################################################
8
9import numpy as np
10import fmcd
11import matplotlib.pyplot as mpl
12import myplot
13
14
15class mcd():
16 
17    def __repr__(self):
18    # print out a help string when help is invoked on the object
19        whatprint = 'MCD object. \"help(mcd)\" for more information\n'
20        return whatprint
21
22########################
23### Default settings ###
24########################
25
26    def __init__(self):
27    # default settings
28        ## 0. general stuff
29        self.name      = "MCD v4.3"
30        self.ack       = "Mars Climate Database (c) LMD/OU/IAA/ESA/CNES"
31        #self.dset      = '/home/aymeric/Science/MCD_v4.3/data/'
32        self.dset      = '/home/marshttp/MCD_v4.3/data/'
33        ## 1. spatio-temporal coordinates
34        self.lat       = 0.
35        self.lats      = None
36        self.late      = None
37        self.lon       = 0.
38        self.lons      = None
39        self.lone      = None
40        self.loct      = 0.
41        self.locts     = None
42        self.locte     = None
43        self.xdate     = 0.  # see datekey
44        self.xdates    = None
45        self.xdatee    = None
46        self.xz        = 10. # see zkey
47        self.xzs       = None
48        self.xze       = None
49        ## 1bis. related settings
50        self.zkey      = 3  # specify that xz is the altitude above surface (m)
51                            # zkey  : <integer>   type of vertical coordinate xz
52                            # 1 = radius from centre of planet (m)
53                            # 2 = height above areoid (m) (MOLA zero datum)
54                            # 3 = height above surface (m)
55                            # 4 = pressure level (Pa)
56                            # 5 = altitude above mean Mars Radius(=3396000m) (m)
57        self.datekey   = 1  # 0 = "Earth time": xdate is given in Julian days (localtime must be set to zero)
58                            # 1 = "Mars date": xdate is the value of Ls
59        ## 2. climatological options
60        self.dust      = 2  #our best guess MY24 scenario, with solar average conditions
61        self.hrkey     = 1  #set high resolution mode on (hrkey=0 to set high resolution off)
62        ## 3. additional settings for advanced use
63        self.extvarkey = 1  #extra output variables (1: yes, 0: no)
64        self.perturkey = 0  #integer perturkey ! perturbation type (0: none)
65        self.seedin    = 1  #random number generator seed (unused if perturkey=0)
66        self.gwlength  = 0. #gravity Wave wavelength (unused if perturkey=0)
67        ## outputs. just to define attributes.
68        ## --> in update
69        self.pres = None ; self.dens = None ; self.temp = None ; self.zonwind = None ; self.merwind = None ; self.meanvar = None ; self.extvar = None
70        self.seedout = None ; self.ierr = None
71        ## --> in prepare
72        self.xcoord = None ; self.ycoord = None
73        self.prestab = None ; self.denstab = None ; self.temptab = None 
74        self.zonwindtab = None ; self.merwindtab = None ; self.meanvartab = None ; self.extvartab = None
75        ## plot stuff
76        self.xlabel = None ; self.ylabel = None
77        self.vertplot = False
78
79    def viking1(self): self.name = "Viking 1 site. MCD v4.3 output" ; self.lat = 22.48 ; self.lon = -49.97 ; self.xdate = 97.
80    def viking2(self): self.name = "Viking 2 site. MCD v4.3 output" ; self.lat = 47.97 ; self.lon = -225.74 ; self.xdate = 117.6
81
82    def getdustlabel(self):
83        if self.dust == 1: self.dustlabel = "MY24 minimum solar scenario"
84        elif self.dust == 2: self.dustlabel = "MY24 average solar scenario"
85        elif self.dust == 3: self.dustlabel = "MY24 maximum solar scenario"
86        elif self.dust == 4: self.dustlabel = "dust storm minimum solar scenario"
87        elif self.dust == 5: self.dustlabel = "dust storm average solar scenario"
88        elif self.dust == 6: self.dustlabel = "dust storm maximum solar scenario"
89        elif self.dust == 7: self.dustlabel = "warm scenario (dusty, maximum solar)"
90        elif self.dust == 8: self.dustlabel = "cold scenario (low dust, minimum solar)"
91
92    def gettitle(self):
93        self.getdustlabel()
94        self.title = self.name + " with " + self.dustlabel + "."
95        if self.lats is None:  self.title = self.title + " Latitude " + str(self.lat) + "E"
96        if self.lons is None:  self.title = self.title + " Longitude " + str(self.lon) + "N"
97        if self.xzs is None:   
98            self.vertunits()
99            self.title = self.title + " Altitude " + str(self.xz) + " " + self.vunits
100        if self.locts is None: self.title = self.title + " Local time " + str(self.loct) + "h"
101
102    def getextvarlab(self,num):
103        whichfield = { \
104        91: "Pressure (Pa)", \
105        92: "Density (kg/m3)", \
106        93: "Temperature (K)", \
107        94: "W-E wind component (m/s)", \
108        95: "S-N wind component (m/s)", \
109        1: "Radial distance from planet center (m)",\
110        2: "Altitude above areoid (Mars geoid) (m)",\
111        3: "Altitude above local surface (m)",\
112        4: "orographic height (m) (surf alt above areoid)",\
113        5: "Ls, solar longitude of Mars (deg)",\
114        6: "LST local true solar time (hrs)",\
115        7: "Universal solar time (LST at lon=0) (hrs)",\
116        8: "Air heat capacity Cp (J kg-1 K-1)",\
117        9: "gamma=Cp/Cv Ratio of specific heats",\
118        10: "density RMS day to day variations (kg/m^3)",\
119        11: "[not defined]",\
120        12: "[not defined]",\
121        13: "scale height H(p) (m)",\
122        14: "GCM orography (m)",\
123        15: "surface temperature (K)",\
124        16: "daily max mean surface temperature (K)",\
125        17: "daily min mean surface temperature (K)",\
126        18: "surf. temperature RMS day to day variations (K)",\
127        19: "surface pressure (high resolution if hireskey=1)",\
128        20: "GCM surface pressure (Pa)",\
129        21: "atmospheric pressure RMS day to day variations (Pa)",\
130        22: "surface pressure RMS day to day variations (Pa)",\
131        23: "temperature RMS day to day variations (K)",\
132        24: "zonal wind RMS day to day variations (m/s)",\
133        25: "meridional wind RMS day to day variations (m/s)",\
134        26: "vertical wind component (m/s) >0 when downwards!",\
135        27: "vertical wind RMS day to day variations (m/s)",\
136        28: "small scale perturbation (gravity wave) (kg/m^3)",\
137        29: "q2: turbulent kinetic energy (m2/s2)",\
138        30: "[not defined]",\
139        31: "thermal IR flux to surface (W/m2)",\
140        32: "solar flux to surface (W/m2)",\
141        33: "thermal IR flux to space (W/m2)",\
142        34: "solar flux reflected to space (W/m2)",\
143        35: "surface CO2 ice layer (kg/m2)",\
144        36: "DOD: Dust column visible optical depth",\
145        37: "Dust mass mixing ratio (kg/kg)",\
146        38: "DOD RMS day to day variations",\
147        39: "DOD total standard deviation over season",\
148        40: "Water vapor column (kg/m2)",\
149        41: "Water vapor vol. mixing ratio (mol/mol)",\
150        42: "Water ice column (kg/m2)",\
151        43: "Water ice mixing ratio (mol/mol)",\
152        44: "O3 ozone vol. mixing ratio (mol/mol)",\
153        45: "[CO2] vol. mixing ratio (mol/mol)",\
154        46: "[O] vol. mixing ratio (mol/mol)",\
155        47: "[N2] vol. mixing ratio (mol/mol)",\
156        48: "[CO] vol. mixing ratio (mol/mol)",\
157        49: "R: Molecular gas constant (J K-1 kg-1)",\
158        50: "Air viscosity estimation (N s m-2)"
159        }
160        if num not in whichfield: myplot.errormess("Incorrect subscript in extvar.")
161        return whichfield[num]
162
163    def convertlab(self,num):       
164        ## a conversion from text inquiries to extvar numbers. to be completed.
165        if num == "p": num = 91
166        elif num == "rho": num = 92
167        elif num == "t": num = 93
168        elif num == "u": num = 94
169        elif num == "v": num = 95
170        elif num == "tsurf": num = 15
171        elif num == "topo": num = 4
172        elif num == "h": num = 13
173        elif num == "ps": num = 19
174        elif num == "tau": num = 36
175        elif num == "mtot": num = 40
176        elif num == "icetot": num = 42
177        elif num == "ps_ddv": num = 22
178        elif num == "h2ovap": num = 41
179        elif num == "h2oice": num = 43
180        elif num == "cp": num = 8
181        elif num == "rho_ddv": num = 10
182        elif num == "tsurfmx": num = 16
183        elif num == "tsurfmn": num = 17
184        elif num == "lwdown": num = 31
185        elif num == "swdown": num = 32
186        elif num == "lwup": num = 33
187        elif num == "swup": num = 34
188        elif num == "o3": num = 44
189        elif num == "o": num = 46
190        elif num == "co": num = 48
191        elif num == "visc": num = 50
192        elif num == "co2ice": num = 35
193        elif not isinstance(num, np.int): myplot.errormess("field reference not found.")
194        return num
195
196###################
197### One request ###
198###################
199
200    def update(self):
201    # retrieve fields from MCD (call_mcd). more info in fmcd.call_mcd.__doc__
202        (self.pres, self.dens, self.temp, self.zonwind, self.merwind, \
203         self.meanvar, self.extvar, self.seedout, self.ierr) \
204         = \
205         fmcd.call_mcd(self.zkey,self.xz,self.lon,self.lat,self.hrkey, \
206             self.datekey,self.xdate,self.loct,self.dset,self.dust, \
207             self.perturkey,self.seedin,self.gwlength,self.extvarkey )
208        ## we use the end of extvar (unused) to store meanvar. this is convenient for getextvar(lab)
209        self.extvar[90] = self.pres ; self.extvar[91] = self.dens
210        self.extvar[92] = self.temp ; self.extvar[93] = self.zonwind ; self.extvar[94] = self.merwind
211        ## treat missing values
212        if self.temp == -999: self.extvar[:] = np.NaN ; self.meanvar[:] = np.NaN
213
214    def printset(self):
215    # print main settings
216        print "zkey",self.zkey,"xz",self.xz,"lon",self.lon,"lat",self.lat,"hrkey",self.hrkey, \
217              "xdate",self.xdate,"loct",self.loct,"dust",self.dust
218
219    def getnameset(self):
220    # set a name referring to settings [convenient for databases]
221        strlat = str(self.lat)+str(self.lats)+str(self.late)
222        strlon = str(self.lon)+str(self.lons)+str(self.lone)
223        strxz = str(self.xz)+str(self.xzs)+str(self.xze)
224        strloct = str(self.loct)+str(self.locts)+str(self.locte)
225        name = str(self.zkey)+strxz+strlon+strlat+str(self.hrkey)+str(self.datekey)+str(self.xdate)+strloct+str(self.dust)
226        return name
227
228    def printcoord(self):
229    # print requested space-time coordinates
230        print "LAT",self.lat,"LON",self.lon,"LOCT",self.loct,"XDATE",self.xdate
231
232    def printmeanvar(self):
233    # print mean MCD variables
234        print "Pressure = %5.3f pascals. " % (self.pres)
235        print "Density = %5.3f kilograms per cubic meter. " % (self.dens)
236        print "Temperature = %3.0f kelvins (%4.0f degrees celsius)." % (self.temp,self.temp-273.15)
237        print "Zonal wind = %5.3f meters per second." % (self.zonwind)
238        print "Meridional wind = %5.3f meters per second." % (self.merwind)
239        print "Total horizontal wind = %5.3f meters per second." % ( np.sqrt(self.zonwind**2 + self.merwind**2) )
240
241    def printextvar(self,num):
242    # print extra MCD variables
243        num = self.convertlab(num)
244        print self.getextvarlab(num) + " ..... " + str(self.extvar[num-1])
245
246    def printallextvar(self):
247    # print all extra MCD variables   
248        for i in range(50): self.printextvar(i+1)
249
250    def htmlprinttabextvar(self,tabtodo):
251        print "Results from the Mars Climate Database"
252        print "<ul>"
253        for i in range(len(tabtodo)): print "<li>" ; self.printextvar(tabtodo[i]) ; print "</li>"
254        print "</ul>"
255        print "<hr>"
256        print "SETTINGS<br />"
257        self.printcoord()
258        self.printset()
259
260    def printmcd(self):
261    # 1. call MCD 2. print settings 3. print mean vars
262        self.update()
263        self.printcoord()
264        print "-------------------------------------------"
265        self.printmeanvar()
266
267########################
268### Several requests ###
269########################
270
271    def prepare(self,ndx=None,ndy=None):
272    ### prepare I/O arrays for 1d slices
273      if ndx is None:  print "No dimension in prepare. Exit. Set at least ndx." ; exit()
274      else:            self.xcoord = np.ones(ndx)
275      if ndy is None:  dashape = (ndx)     ; dashapemean = (ndx,6)     ; dashapeext = (ndx,101)     ; self.ycoord = None
276      else:            dashape = (ndx,ndy) ; dashapemean = (ndx,ndy,6) ; dashapeext = (ndx,ndy,101) ; self.ycoord = np.ones(ndy)
277      self.prestab = np.ones(dashape) ; self.denstab = np.ones(dashape) ; self.temptab = np.ones(dashape)
278      self.zonwindtab = np.ones(dashape) ; self.merwindtab = np.ones(dashape) 
279      self.meanvartab = np.ones(dashapemean) ; self.extvartab = np.ones(dashapeext)
280
281    def getextvar(self,num):
282    ### get a given var in extvartab
283      try: field=self.extvartab[:,:,num] 
284      except: field=self.extvartab[:,num]
285      return field
286
287    def definefield(self,choice):
288    ### for analysis or plot purposes, set field and field label from user-defined choice
289      choice = self.convertlab(choice)
290      field = self.getextvar(choice); fieldlab = self.getextvarlab(choice)
291      return field,fieldlab
292
293    def ininterv(self,dstart,dend,nd,start=None,end=None,yaxis=False,vertcoord=False):
294    ### user-defined start and end are used to create xcoord (or ycoord) vector
295      if start is not None and end is not None:  first, second = self.correctbounds(start,end,vertcoord)
296      else:                                      first, second = self.correctbounds(dstart,dend,vertcoord) 
297      if self.zkey != 4 or not vertcoord:   tabtab = np.linspace(first,second,nd)
298      else:                                 tabtab = np.logspace(first,second,nd)
299      if not yaxis:      self.xcoord = tabtab
300      else:              self.ycoord = tabtab
301
302    def correctbounds(self,start,end,vertcoord):
303      if self.zkey != 4 or not vertcoord:
304        # regular altitudes
305        if start > end: first = end ; second = start
306        else:           first = start ; second = end
307      else:
308        # pressure: reversed avis
309        if start < end: first = np.log10(end) ; second = np.log10(start)
310        else:           first = np.log10(start) ; second = np.log10(end)
311      return first, second
312
313    def vertlabel(self):
314      if self.zkey == 1:   self.xlabel = "radius from centre of planet (m)"
315      elif self.zkey == 2: self.xlabel = "height above areoid (m) (MOLA zero datum)"
316      elif self.zkey == 3: self.xlabel = "height above surface (m)"
317      elif self.zkey == 4: self.xlabel = "pressure level (Pa)"
318      elif self.zkey == 5: self.xlabel = "altitude above mean Mars Radius(=3396000m) (m)"
319
320    def vertunits(self):
321      if self.zkey == 1:   self.vunits = "m CP"
322      elif self.zkey == 2: self.vunits = "m AMR"
323      elif self.zkey == 3: self.vunits = "m ALS"
324      elif self.zkey == 4: self.vunits = "Pa"
325      elif self.zkey == 5: self.vunits = "m AMMRad"
326
327    def vertaxis(self,number,yaxis=False):
328      if self.zkey == 2:   self.ininterv(-5000.,100000.,number,start=self.xzs,end=self.xze,yaxis=yaxis,vertcoord=True)
329      elif self.zkey == 3: self.ininterv(0.,120000.,number,start=self.xzs,end=self.xze,yaxis=yaxis,vertcoord=True)
330      elif self.zkey == 5: self.ininterv(-5000.,100000.,number,start=self.xzs,end=self.xze,yaxis=yaxis,vertcoord=True)
331      elif self.zkey == 4: self.ininterv(1000.,0.001,number,start=self.xzs,end=self.xze,yaxis=yaxis,vertcoord=True)
332      elif self.zkey == 1: self.ininterv(3396000,3596000,number,start=self.xzs,end=self.xze,yaxis=yaxis,vertcoord=True)
333
334###################
335### 1D analysis ###
336###################
337
338    def put1d(self,i):
339    ## fill in subscript i in output arrays
340    ## (arrays must have been correctly defined through prepare)
341      if self.prestab is None:  myplot.errormess("arrays must be prepared first through self.prepare")
342      self.prestab[i] = self.pres ; self.denstab[i] = self.dens ; self.temptab[i] = self.temp
343      self.zonwindtab[i] = self.zonwind ; self.merwindtab[i] = self.merwind
344      self.meanvartab[i,1:5] = self.meanvar[0:4]  ## note: var numbering according to MCD manual is kept
345      self.extvartab[i,1:100] = self.extvar[0:99] ## note: var numbering according to MCD manual is kept
346
347    def diurnal(self,nd=13):
348    ### retrieve a local time slice
349      save = self.loct
350      self.xlabel = "Local time (Martian hour)"
351      self.prepare(ndx=nd) ; self.ininterv(0.,24.,nd,start=self.locts,end=self.locte) 
352      for i in range(nd): self.loct = self.xcoord[i] ; self.update() ; self.put1d(i)
353      self.loct = save
354
355    def zonal(self,nd=37):
356    ### retrieve a longitude slice
357      save = self.lon
358      self.xlabel = "East longitude (degrees)"
359      self.prepare(ndx=nd) ; self.ininterv(-180.,180.,nd,start=self.lons,end=self.lone)
360      for i in range(nd): self.lon = self.xcoord[i] ; self.update() ; self.put1d(i)
361      self.lon = save
362
363    def meridional(self,nd=19):
364    ### retrieve a latitude slice
365      save = self.lat
366      self.xlabel = "North latitude (degrees)"
367      self.prepare(ndx=nd) ; self.ininterv(-90.,90.,nd,start=self.lats,end=self.late)
368      for i in range(nd): self.lat = self.xcoord[i] ; self.update() ; self.put1d(i)
369      self.lat = save
370
371    def profile(self,nd=20,tabperso=None):
372    ### retrieve an altitude slice (profile)
373      save = self.xz
374      self.vertlabel()
375      self.vertplot = True
376      if tabperso is not None: nd = len(tabperso)
377      correct = False
378      self.prepare(ndx=nd) ; self.vertaxis(nd)
379      if tabperso is not None: self.xcoord = tabperso
380      for i in range(nd): self.xz = self.xcoord[i] ; self.update() ; self.put1d(i)
381      self.xz = save
382
383    def seasonal(self,nd=12):
384    ### retrieve a seasonal slice
385      save = self.xdate
386      self.xlabel = "Areocentric longitude (degrees)"
387      self.prepare(ndx=nd) ; self.ininterv(0.,360.,nd,start=self.xdates,end=self.xdatee)
388      for i in range(nd): self.xdate = self.xcoord[i] ; self.update() ; self.put1d(i)
389      self.xdate = save
390
391    def makeplot1d(self,choice):
392    ### one 1D plot is created for the user-defined variable in choice.
393      (field, fieldlab) = self.definefield(choice)
394      if not self.vertplot:  absc = self.xcoord ; ordo = field ; ordolab = fieldlab ; absclab = self.xlabel
395      else:                  ordo = self.xcoord ; absc = field ; absclab = fieldlab ; ordolab = self.xlabel
396      mpl.plot(absc,ordo,'-bo') ; mpl.ylabel(ordolab) ; mpl.xlabel(absclab) #; mpl.xticks(query.xcoord)
397      if self.zkey == 4: mpl.semilogy() ; ax = mpl.gca() ; ax.set_ylim(ax.get_ylim()[::-1])
398      mpl.figtext(0.5, 0.01, self.ack, ha='center')
399
400    def plot1d(self,tabtodo):
401    ### complete 1D figure with possible multiplots
402      if isinstance(tabtodo,np.str): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
403      if isinstance(tabtodo,np.int): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
404      fig = mpl.figure() ; subv,subh = myplot.definesubplot( len(tabtodo) , fig ) 
405      for i in range(len(tabtodo)): mpl.subplot(subv,subh,i+1).grid(True, linestyle=':', color='grey') ; self.makeplot1d(tabtodo[i])
406
407    def htmlplot1d(self,tabtodo,figname="temp.png",title=""):
408    ### complete 1D figure with possible multiplots
409    ### added in 09/2012 for online MCD
410    ### see http://www.dalkescientific.com/writings/diary/archive/2005/04/23/matplotlib_without_gui.html
411      from matplotlib.figure import Figure
412      from matplotlib.backends.backend_agg import FigureCanvasAgg
413      if isinstance(tabtodo,np.str): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
414      if isinstance(tabtodo,np.int): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
415      fig = Figure(figsize=(8,8)) ; subv,subh = myplot.definesubplot( len(tabtodo) , fig )
416      for i in range(len(tabtodo)):
417        yeah = fig.add_subplot(subv,subh,i+1) #.grid(True, linestyle=':', color='grey')
418        choice = tabtodo[i]
419        (field, fieldlab) = self.definefield(choice)
420        if not self.vertplot:  absc = self.xcoord ; ordo = field ; ordolab = fieldlab ; absclab = self.xlabel
421        else:                  ordo = self.xcoord ; absc = field ; absclab = fieldlab ; ordolab = self.xlabel
422        yeah.plot(absc,ordo,'-bo') #; mpl.xticks(query.xcoord)
423        ax = fig.gca() ; ax.set_ylabel(ordolab) ; ax.set_xlabel(absclab)
424        if self.zkey == 4: ax.set_yscale('log') ; ax.set_ylim(ax.get_ylim()[::-1])
425      self.gettitle()
426      fig.text(0.5, 0.95, self.title, ha='center')
427      fig.text(0.5, 0.01, self.ack, ha='center')
428      canvas = FigureCanvasAgg(fig)
429      # The size * the dpi gives the final image size
430      #   a4"x4" image * 80 dpi ==> 320x320 pixel image
431      canvas.print_figure(figname, dpi=80)
432
433###################
434### 2D analysis ###
435###################
436
437    def latlon(self,ndx=37,ndy=19,fixedlt=False):
438    ### retrieve a latitude/longitude slice
439    ### default is: local time is not fixed. user-defined local time is at longitude 0.
440      save1 = self.lon ; save2 = self.lat ; save3 = self.loct
441      self.xlabel = "East longitude (degrees)" ; self.ylabel = "North latitude (degrees)"
442      self.prepare(ndx=ndx,ndy=ndy)
443      self.ininterv(-180.,180.,ndx,start=self.lons,end=self.lone)
444      self.ininterv(-90.,  90.,ndy,start=self.lats,end=self.late,yaxis=True)
445      if not fixedlt: umst = self.loct
446      for i in range(ndx):
447       for j in range(ndy):
448         self.lon = self.xcoord[i] ; self.lat = self.ycoord[j]
449         if not fixedlt: 
450           if self.lons is not None and self.lone is not None: self.loct = (umst + (self.lons+self.lone)/30.) % 24
451           else:                                               self.loct = (umst + self.lon/15.) % 24
452         self.update() ; self.put2d(i,j)
453      if not fixedlt: self.loct = umst
454      self.lon = save1 ; self.lat = save2 ; self.loct = save3
455
456    def lonalt(self,ndx=37,ndy=20,fixedlt=False):
457    ### retrieve a longitude/altitude slice
458      save1 = self.lon ; save2 = self.xz ; save3 = self.loct
459      self.vertlabel() ; self.ylabel = self.xlabel
460      self.xlabel = "East longitude (degrees)"
461      self.prepare(ndx=ndx,ndy=ndy)
462      self.ininterv(-180.,180.,ndx,start=self.lons,end=self.lone)
463      self.vertaxis(ndy,yaxis=True)
464      if not fixedlt: umst = self.loct
465      for i in range(ndx):
466       for j in range(ndy):
467         self.lon = self.xcoord[i] ; self.xz = self.ycoord[j] 
468         if not fixedlt: 
469           if self.lons is not None and self.lone is not None: self.loct = (umst + (self.lons+self.lone)/30.) % 24
470           else:                                               self.loct = (umst + self.lon/15.) % 24
471         self.update() ; self.put2d(i,j)
472      if not fixedlt: self.loct = umst
473      self.lon = save1 ; self.xz = save2 ; self.loct = save3
474
475    def latalt(self,ndx=19,ndy=20,fixedlt=False):
476    ### retrieve a latitude/altitude slice
477      save1 = self.lat ; save2 = self.xz ; save3 = self.loct
478      self.vertlabel() ; self.ylabel = self.xlabel
479      self.xlabel = "North latitude (degrees)"
480      self.prepare(ndx=ndx,ndy=ndy)
481      self.ininterv(-90.,90.,ndx,start=self.lats,end=self.late)
482      self.vertaxis(ndy,yaxis=True)
483      if not fixedlt: umst = self.loct
484      for i in range(ndx):
485       for j in range(ndy):
486         self.lat = self.xcoord[i] ; self.xz = self.ycoord[j] 
487         if not fixedlt: self.loct = (umst + self.lon/15.) % 24
488         self.update() ; self.put2d(i,j)
489      if not fixedlt: self.loct = umst
490      self.lat = save1 ; self.xz = save2 ; self.loct = save3
491
492    def put2d(self,i,j):
493    ## fill in subscript i,j in output arrays
494    ## (arrays must have been correctly defined through prepare)
495      if self.prestab is None:  myplot.errormess("arrays must be prepared first through self.prepare")
496      self.prestab[i,j] = self.pres ; self.denstab[i,j] = self.dens ; self.temptab[i,j] = self.temp
497      self.zonwindtab[i,j] = self.zonwind ; self.merwindtab[i,j] = self.merwind
498      self.meanvartab[i,j,1:5] = self.meanvar[0:4]  ## note: var numbering according to MCD manual is kept
499      self.extvartab[i,j,1:100] = self.extvar[0:99] ## note: var numbering according to MCD manual is kept
500
501    def makemap2d(self,choice,incwind=False,fixedlt=False,proj="cyl"):
502    ### one 2D map is created for the user-defined variable in choice.
503      self.latlon(fixedlt=fixedlt) ## a map is implicitely a lat-lon plot. otherwise it is a plot (cf. makeplot2d)
504      if choice == "wind" or incwind:
505          (windx, fieldlabwx) = self.definefield("u")
506          (windy, fieldlabwy) = self.definefield("v")
507      if choice == "wind":
508          field = np.sqrt(windx*windx + windy*windy)
509          fieldlab = "Horizontal wind speed (m/s)"
510      else:   
511          (field, fieldlab) = self.definefield(choice)
512      if incwind:   myplot.maplatlon(self.xcoord,self.ycoord,field,title=fieldlab,proj=proj,vecx=windx,vecy=windy) #,stride=1)
513      else:         myplot.maplatlon(self.xcoord,self.ycoord,field,title=fieldlab,proj=proj)
514      mpl.figtext(0.5, 0.0, self.ack, ha='center')
515
516    def map2d(self,tabtodo,incwind=False,fixedlt=False,proj="cyl"):
517    ### complete 2D figure with possible multiplots
518      if isinstance(tabtodo,np.str): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
519      if isinstance(tabtodo,np.int): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
520      fig = mpl.figure()
521      subv,subh = myplot.definesubplot( len(tabtodo) , fig ) 
522      for i in range(len(tabtodo)): mpl.subplot(subv,subh,i+1) ; self.makemap2d(tabtodo[i],incwind=incwind,fixedlt=fixedlt,proj=proj)
523
524    def htmlmap2d(self,tabtodo,incwind=False,fixedlt=False,figname="temp.png",title="",back="zMOL"):
525    ### complete 2D figure with possible multiplots
526    ### added in 09/2012 for online MCD
527    ### see http://www.dalkescientific.com/writings/diary/archive/2005/04/23/matplotlib_without_gui.html
528      from matplotlib.figure import Figure
529      from matplotlib.backends.backend_agg import FigureCanvasAgg
530      from matplotlib.cm import get_cmap
531
532      #from mpl_toolkits.basemap import Basemap
533
534      from Scientific.IO import NetCDF
535      filename = "/home/marshttp/surface.nc"
536      zefile = NetCDF.NetCDFFile(filename, 'r') 
537      fieldc = zefile.variables[back]
538      yc = zefile.variables['latitude']
539      xc = zefile.variables['longitude']
540      ## plutot que fieldc = self.getextvar(self.convertlab("topo"))
541
542      if isinstance(tabtodo,np.str): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
543      if isinstance(tabtodo,np.int): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
544
545      howmanyplots = len(tabtodo)
546      if howmanyplots == 1: fig = Figure(figsize=(16,8)) 
547      elif howmanyplots == 2: fig = Figure(figsize=(8,8)) 
548      elif howmanyplots == 3: fig = Figure(figsize=(8,16)) 
549      elif howmanyplots == 4: fig = Figure(figsize=(16,8)) 
550
551      subv,subh = myplot.definesubplot( len(tabtodo) , fig )
552
553      for i in range(len(tabtodo)):
554        yeah = fig.add_subplot(subv,subh,i+1)
555        choice = tabtodo[i]
556        self.latlon(fixedlt=fixedlt) 
557        ## a map is implicitely a lat-lon plot. otherwise it is a plot (cf. makeplot2d)
558        (field, fieldlab) = self.definefield(choice)
559        if incwind: (windx, fieldlabwx) = self.definefield("u") ; (windy, fieldlabwy) = self.definefield("v")
560
561        proj="moll" ; colorb="jet" ; ndiv=20 ; zeback="molabw" ; trans=1.0 #0.6
562        title="" ; vecx=None ; vecy=None ; stride=2
563        lon = self.xcoord
564        lat = self.ycoord
565       
566        #[lon2d,lat2d] = np.meshgrid(lon,lat)
567        ##### define projection and background. define x and y given the projection
568        ##[wlon,wlat] = myplot.latinterv()
569        ##yeahm = myplot.define_proj(proj,wlon,wlat,back=zeback,blat=None,blon=None)
570        ##x, y = yeahm(lon2d, lat2d)
571        #map = Basemap(projection='ortho',lat_0=45,lon_0=-100)
572        #x, y = map(lon2d, lat2d)
573
574        #### TEMP
575        x = lon ; y = lat
576
577        ## define field. bound field.
578        what_I_plot = np.transpose(field)
579        zevmin, zevmax = myplot.calculate_bounds(what_I_plot)  ## vmin=min(what_I_plot_frame), vmax=max(what_I_plot_frame))
580        what_I_plot = myplot.bounds(what_I_plot,zevmin,zevmax)
581        ## define contour field levels. define color palette
582        ticks = ndiv + 1
583        zelevels = np.linspace(zevmin,zevmax,ticks)
584        palette = get_cmap(name=colorb)
585
586        ## contours topo
587        zelevc = np.linspace(-9.,20.,11)
588        yeah.contour( xc, yc, fieldc, zelevc, colors='black',linewidths = 0.4)
589        # contour field
590        c = yeah.contourf( x, y, what_I_plot, zelevels, cmap = palette, alpha = trans )
591        clb = Figure.colorbar(fig,c,orientation='vertical',format="%.2e",ticks=np.linspace(zevmin,zevmax,num=min([ticks/2+1,21])))
592        clb.set_label(fieldlab)
593        ax = fig.gca() ; ax.set_ylabel("Latitude") ; ax.set_xlabel("Longitude")
594        ax.set_xticks(np.arange(-180,181,45)) ; ax.set_xbound(lower=self.lons, upper=self.lone)
595        ax.set_yticks(np.arange(-90,91,30)) ; ax.set_ybound(lower=self.lats, upper=self.late)
596        if incwind:
597          [x2d,y2d] = np.meshgrid(x,y)
598          yeah.quiver(x2d,y2d,np.transpose(windx),np.transpose(windy))
599      self.gettitle()
600      fig.text(0.5, 0.95, self.title, ha='center')
601      fig.text(0.5, 0.01, self.ack, ha='center')
602      canvas = FigureCanvasAgg(fig)
603      # The size * the dpi gives the final image size
604      #   a4"x4" image * 80 dpi ==> 320x320 pixel image
605      canvas.print_figure(figname, dpi=80)
606
607    def htmlplot2d(self,tabtodo,fixedlt=False,figname="temp.png",title=""):
608    ### complete 2D figure with possible multiplots
609    ### added in 10/2012 for online MCD
610    ### see http://www.dalkescientific.com/writings/diary/archive/2005/04/23/matplotlib_without_gui.html
611      from matplotlib.figure import Figure
612      from matplotlib.backends.backend_agg import FigureCanvasAgg
613      from matplotlib.cm import get_cmap
614      if isinstance(tabtodo,np.str): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
615      if isinstance(tabtodo,np.int): tabtodo=[tabtodo] ## so that asking one element without [] is possible.
616      fig = Figure(figsize=(8,8)) ; subv,subh = myplot.definesubplot( len(tabtodo) , fig )
617
618      for i in range(len(tabtodo)):
619        yeah = fig.add_subplot(subv,subh,i+1)
620        choice = tabtodo[i]
621
622        if self.lons is not None:    self.lonalt(fixedlt=fixedlt)
623        elif self.lats is not None:  self.latalt(fixedlt=fixedlt)
624
625        (field, fieldlab) = self.definefield(choice)
626
627        colorb="jet" ; ndiv=20 ; title=""
628
629        ## define field. bound field.
630        what_I_plot = np.transpose(field)
631        zevmin, zevmax = myplot.calculate_bounds(what_I_plot)  ## vmin=min(what_I_plot_frame), vmax=max(what_I_plot_frame))
632        what_I_plot = myplot.bounds(what_I_plot,zevmin,zevmax)
633        ## define contour field levels. define color palette
634        ticks = ndiv + 1
635        zelevels = np.linspace(zevmin,zevmax,ticks)
636        palette = get_cmap(name=colorb)
637        # contour field
638        c = yeah.contourf( self.xcoord, self.ycoord, what_I_plot, zelevels, cmap = palette )
639        clb = Figure.colorbar(fig,c,orientation='vertical',format="%.2e",ticks=np.linspace(zevmin,zevmax,num=min([ticks/2+1,21])))
640        clb.set_label(fieldlab)
641        ax = fig.gca() ; ax.set_ylabel(self.ylabel) ; ax.set_xlabel(self.xlabel)
642        if self.zkey == 4: ax.set_yscale('log') ; ax.set_ylim(ax.get_ylim()[::-1])
643
644        #ax.set_xticks(np.arange(-180,181,45)) ; ax.set_xbound(lower=self.lons, upper=self.lone)
645        #ax.set_yticks(np.arange(-90,91,30)) ; ax.set_ybound(lower=self.lats, upper=self.late)
646
647      self.gettitle()
648      fig.text(0.5, 0.95, self.title, ha='center')
649      fig.text(0.5, 0.01, self.ack, ha='center')
650      canvas = FigureCanvasAgg(fig)
651      # The size * the dpi gives the final image size
652      #   a4"x4" image * 80 dpi ==> 320x320 pixel image
653      canvas.print_figure(figname, dpi=80)
654
655
656    ### TODO: makeplot2d, plot2d, passer plot settings
657
Note: See TracBrowser for help on using the repository browser.