source: trunk/UTIL/PYTHON/mcd/proto/cgi-bin/mcdcgi.py @ 1078

Last change on this file since 1078 was 1078, checked in by aslmd, 11 years ago

UTIL PYTHON MCD online. Forgot error message about dust storm scenario.

  • Property svn:executable set to *
File size: 12.3 KB
Line 
1#!/usr/bin/python
2###!/usr/bin/env python
3###!/home/aymeric/Software/epd-7.0-2-rh5-x86/bin/python
4####!/home/marshttp/EPD/epd-7.0-2-rh5-x86_64/bin/python
5### here the version used to f2py the MCD Fortran routines
6
7##################################################
8### A Python CGI for the Mars Climate Database ###
9### ------------------------------------------ ###
10### Aymeric SPIGA 18-19/04/2012 ~ 11/08/2012   ###
11### ------------------------------------------ ###
12### (see mcdtest.py for examples of use)       ###
13##################################################
14### ajouts et corrections par Franck Guyon 09/2012
15### ajouts suite a brainstorm equipe AS 10/2012
16
17import cgi, cgitb 
18import numpy as np
19from modules import *
20from modules import mcd
21
22import cStringIO
23import os as daos
24import matplotlib.pyplot as mpl
25
26### a function to read HTML arguments for coordinates
27def gethtmlcoord(userinput,defmin,defmax):
28   import string
29   # accepted separators. the symbol - should always be last.
30   separators = [":",";",",","/","_"] 
31   # initial values
32   val = -9999. ; vals = None ; vale = None ; foundinterv = False
33   if userinput == None:   userinput = "1"
34   # the main work. either all, or an interval, or a single value.
35   # ... all
36   if userinput == "all":  isfree = 1 ; vals = defmin ; vale = defmax ; foundinterv = True
37   # ... an interval
38   else:
39       for sep in separators:
40         if not foundinterv:
41           isfree = 1 ; ind = userinput.find(sep)
42           if ind != -1: vals = float(userinput[:ind]) ; vale = float(userinput[ind+1:]) ; foundinterv = True
43   # ... a single value (or an error)
44   if not foundinterv: 
45       # treat the difficult case of possible - separator
46       test = userinput[1:].find("-") # at this stage:
47                                      # * if - is found in the first position, it could not be a separator
48                                      # * if - found at positions > 0, it must be considered as a separator
49       if test != -1: 
50         isfree = 1 ; ind=test+1 
51         vals = float(userinput[:ind]) ; vale = float(userinput[ind+1:]) ; foundinterv = True
52       else:
53         # check if input is valid (each character is numeric or -)
54         for char in userinput: 
55            if char not in string.digits: 
56               if char not in ["-","."]: userinput="yorgl"
57         # either we are OK. if we are not we set isfree to -1.
58         if userinput != "yorgl":  isfree = 0 ; val = float(userinput)
59         else:                     isfree = -1
60   # return values
61   return isfree, val, vals, vale
62
63# set an errormess variable which must stay to None for interface to proceed
64errormess = ""
65
66# for debugging in web browser
67cgitb.enable()
68
69# Create instance of FieldStorage
70form = cgi.FieldStorage() 
71
72# create a MCD object
73query=mcd.mcd() 
74
75# set MCD version changes if needed
76try:     betatest = form.getvalue("betatest")
77except:  betatest = "off"
78if betatest == "on": query.toversion5()
79
80# Get the kind of vertical coordinates and choose default behavior for "all"
81try: query.zkey = int(form.getvalue("zkey"))
82except: query.zkey = int(3)
83if query.zkey == 2:    minxz = -5000.   ; maxxz = 150000.
84elif query.zkey == 3:  minxz = 0.       ; maxxz = 250000.
85elif query.zkey == 5:  minxz = -5000.   ; maxxz = 150000.
86elif query.zkey == 4:  minxz = 1.e3     ; maxxz = 1.e-6
87elif query.zkey == 1:  minxz = 3396000. ; maxxz = 3596000.
88
89# Get data from user-defined fields and define free dimensions
90islatfree,  query.lat,  query.lats,  query.late  = gethtmlcoord( form.getvalue("latitude"),   -90.,  90. )
91islonfree,  query.lon,  query.lons,  query.lone  = gethtmlcoord( form.getvalue("longitude"), -180., 180. )
92isloctfree, query.loct, query.locts, query.locte = gethtmlcoord( form.getvalue("localtime"),    0.,  24. )
93isaltfree,  query.xz,   query.xzs,   query.xze   = gethtmlcoord( form.getvalue("altitude"),  minxz, maxxz)
94if minxz < 0.1: minxz=0.1 # otherwise bug with values smaller than 0.1m
95
96try: query.datekey = int(form.getvalue("datekeyhtml"))
97except: query.datekey = float(1)
98badlschar = False
99if query.datekey == 1:
100    try: query.xdate = float(form.getvalue("ls"))
101    except: query.xdate = float(1) ; badlschar = True # comment the second part if in debug command line mode
102else:
103    try: query.xdate = float(form.getvalue("julian"))
104    except: query.xdate = float(1)
105    query.loct = 0.
106try: query.dust = int(form.getvalue("dust"))
107except: query.dust  = int(1)
108
109# Prevent the user from doing bad
110badinterv = (islatfree == -1) or (islonfree == -1) or (isloctfree == -1) or (isaltfree == -1)
111if badinterv: 
112    errormess = errormess+"<li>Bad syntax. Write a value (or) a range val1;val2 (or) 'all'. Separator shall be either ; : , / _ "
113badls = (query.datekey == 1 and (query.xdate < 0. or query.xdate > 360.))
114if badls: 
115    errormess = errormess+"<li>Solar longitude must be between 0 and 360."
116if badlschar:
117    errormess = errormess+"<li>Solar longitude is in the wrong format. It should be a positive number between 0 and 360. Intervals of solar longitude are not allowed."
118badloct = (isloctfree == 0 and query.loct > 24.) \
119       or (isloctfree == 1 and (query.locts > 24. or query.locte > 24.)) \
120       or (isloctfree == 0 and query.loct < 0.) \
121       or (isloctfree == 1 and (query.locts < 0. or query.locte < 0.))
122if badloct: 
123    errormess = errormess+"<li>Local time must be less than 24 martian hours (and not a negative number)."
124badlat = (islatfree == 0 and abs(query.lat) > 90.) \
125      or (islatfree == 1 and (abs(query.lats) > 90. or abs(query.late) > 90.))
126if badlat: 
127    errormess = errormess+"<li>Latitude coordinates must be between -90 and 90."
128badlon = (islonfree == 0 and abs(query.lon) > 360.) \
129      or (islonfree == 1 and (abs(query.lons) > 360. or abs(query.lone) > 360.))
130if badlon: 
131    errormess = errormess+"<li>Longitude coordinates must be between -360 and 360."
132badalt = (isaltfree == 0 and (query.zkey in [3]) and query.xz < 0.) \
133      or (isaltfree == 1 and (query.zkey in [3]) and (query.xzs < 0. or query.xze < 0.))
134if badalt: 
135    errormess = errormess+"<li>Vertical coordinates must be positive when requesting altitude above surface."
136badalt2 = (isaltfree == 0 and (query.zkey in [1,4]) and query.xz <= 0.) \
137      or (isaltfree == 1 and (query.zkey in [1,4]) and (query.xzs <= 0. or query.xze <= 0.))
138if badalt2: 
139    errormess = errormess+"<li>Vertical coordinates must be <b>strictly</b> positive when requesting pressure levels or altitude above Mars center."
140badalt3 = (isaltfree == 0 and query.zkey == 4 and query.xz > 1500.) \
141       or (isaltfree == 1 and query.zkey == 4 and min(query.xzs,query.xze) > 1500.)
142if badalt3: 
143    errormess = errormess+"<li>Pressure values larger than 1500 Pa are unlikely to be encountered in the Martian atmosphere."
144badrange = (isloctfree == 1 and query.locts == query.locte) \
145        or (islatfree == 1 and query.lats == query.late) \
146        or (islonfree == 1 and query.lons == query.lone) \
147        or (isaltfree == 1 and query.xzs == query.xze)
148if badrange: 
149    errormess = errormess+"<li>One or several coordinate intervals are not... intervals. Set either a real range or an unique value."
150stormls = ( (query.dust in [4,5,6]) and (query.datekey == 1 and query.xdate < 180.))
151if stormls:
152    errormess = errormess+"<li>When a dust storm scenario is selected, available dates must be within the dust storm season (180 < Ls < 360)."
153if query.xdate == 666.:
154    errormess = "<li>CONGRATULATIONS! <br><img src='../surprise.jpg'><br> You reached secret mode.<br> You can <a href='http://www.youtube.com/watch?v=fTpQOZcNASw'>watch a nice video</a>."
155
156# Get how many free dimensions we have
157sumfree = islatfree + islonfree + isloctfree + isaltfree
158if sumfree >= 3: errormess = errormess + "<li>3 or more free dimensions are set... but only 1D and 2D plots are supported!"
159
160# Get additional parameters
161try: query.hrkey = int(form.getvalue("hrkey"))
162except: query.hrkey = int(1)
163#        self.perturkey = 0  #integer perturkey ! perturbation type (0: none)
164#        self.seedin    = 1  #random number generator seed (unused if perturkey=0)
165#        self.gwlength  = 0. #gravity Wave wavelength (unused if perturkey=0)
166try: query.colorm = form.getvalue("colorm")
167except: query.colorm = "jet"
168
169try: query.min2d = float(form.getvalue("minval"))
170except: query.min2d = None
171try: query.max2d = float(form.getvalue("maxval"))
172except: query.max2d = None
173
174try: 
175  query.dpi = form.getvalue("dpi")
176  if query.dpi == "eps":  yeaheps = True  ; query.dpi = 300.
177  else:                   yeaheps = False ; query.dpi = float(query.dpi)
178except: 
179  query.dpi = 80
180  yeaheps = False
181
182# Get variables to plot
183var1 = form.getvalue("var1")
184var2 = form.getvalue("var2")
185var3 = form.getvalue("var3")
186var4 = form.getvalue("var4")
187
188# fg: init var as with form values
189if var1 == None: var1="t"
190
191vartoplot = []
192if var1 != "none": vartoplot = np.append(vartoplot,var1)
193if var2 != "none" and var2 != None: vartoplot = np.append(vartoplot,var2)
194if var3 != "none" and var3 != None: vartoplot = np.append(vartoplot,var3)
195if var4 != "none" and var4 != None: vartoplot = np.append(vartoplot,var4)
196
197iswind = form.getvalue("iswind")
198if iswind == "on": iswindlog = True
199else:              iswindlog = False
200isfixedlt = form.getvalue("isfixedlt")
201if isfixedlt == "on": query.fixedlt=True
202else:                 query.fixedlt=False 
203iszonmean = form.getvalue("zonmean")
204if iszonmean  == "on": query.zonmean=True
205else:                  query.zonmean=False
206
207islog = form.getvalue("islog")
208if islog  == "on": query.islog=True
209else:              query.islog=False
210
211### now, proceed...
212if errormess == "":
213
214 # reference name (to test which figures are already in the database)
215 try: reference = query.getnameset()+str(var1)+str(var2)+str(var3)+str(var4)+str(iswind)+str(isfixedlt)+str(iszonmean)+query.colorm+str(query.min2d)+str(query.max2d)+str(query.dpi)+str(islog)
216 except: reference = "test"
217 if yeaheps:  figname = '../img/'+reference+'.eps'
218 else:        figname = '../img/'+reference+'.png'
219 txtname = '../txt/'+reference+'.txt'
220 testexist = daos.path.isfile(figname)
221
222 # extract data from MCD if needed
223 if not testexist:
224
225  ### 1D plots
226  if sumfree == 1:
227
228    ### getting data
229    if isloctfree == 1:         query.diurnal(nd=25) 
230    elif islonfree == 1:        query.zonal(nd=64)
231    elif islatfree == 1:        query.meridional(nd=48)
232    elif isaltfree == 1:        query.profile(nd=35)   
233    else:                       exit() 
234
235    ### generic building of figure
236    query.getascii(vartoplot,filename=txtname)
237    query.htmlplot1d(vartoplot,figname=figname)
238
239  ### 2D plots
240  elif sumfree == 2:
241
242    ### getting data
243    if islatfree == 1 and islonfree == 1:     query.htmlmap2d(vartoplot,incwind=iswindlog,figname=figname) 
244    else:                                     query.htmlplot2d(vartoplot,figname=figname)
245
246#### NOW WRITE THE HTML PAGE TO USER
247
248## This is quite common
249print "Content-type:text/html\n"
250print "  "  #Apache needs a space after content-type
251
252#entete="""<?xml version="1.0" encoding="UTF-8"?>
253#<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd">
254#<html xmlns="http://www.w3.org/1999/xhtml"> """
255
256header="""<html><head><title>Mars Climate Database: The Web Interface</title></head><body>"""
257#if betatest == "on":
258#    print "<b>!!! THIS IS A BETA VERSION. RESULTS ARE NOT VALIDATED !!!</b>"
259#    if sumfree == 2:     print "<br>"
260
261print header
262#print query.printset()
263#print "<br />"
264
265## Now the part which differs
266if errormess != "":
267                       print "<h1>Ooops!</h1>"
268                       print "Please correct the following problems before submitting again."
269                       print "<ul>"
270                       print errormess
271                       print "</ul>"
272else:
273  if sumfree == 0:      query.update() ; query.htmlprinttabextvar(vartoplot)
274  elif sumfree == 2:   
275                        if yeaheps:  print "<hr><a href='"+figname+"'>!!!! Click here to download the EPS figure file !!!!</a><br /><hr>"
276                        else:        print "<img src='"+figname+"'><br />"
277  elif sumfree == 1:     
278                        print "<a href='"+txtname+"'>Click here to download an ASCII file containing data</a><br />"
279                        print "<hr>"
280                        if yeaheps:  print "<hr><a href='"+figname+"'>!!!! Click here to download the EPS figure file !!!!</a><br /><hr>"
281                        else:        print "<img src='"+figname+"'><br />"
282
283## This is quite common
284bottom = "</body></html>"
285print bottom
Note: See TracBrowser for help on using the repository browser.