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

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

UTIL PYTHON. MCD online interface. addressed the TODO list of rev 812, plus other small improvements. this version was sent to beta-testers in the euromars list.

  • Property svn:executable set to *
File size: 10.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# Get the kind of vertical coordinates and choose default behavior for "all"
76try: query.zkey = int(form.getvalue("zkey"))
77except: query.zkey = int(3)
78if query.zkey == 2:    minxz = -5000.   ; maxxz = 150000.
79elif query.zkey == 3:  minxz = 0.       ; maxxz = 250000.
80elif query.zkey == 5:  minxz = -5000.   ; maxxz = 150000.
81elif query.zkey == 4:  minxz = 1.e3     ; maxxz = 1.e-6
82elif query.zkey == 1:  minxz = 3396000. ; maxxz = 3596000.
83
84# Get data from user-defined fields and define free dimensions
85islatfree,  query.lat,  query.lats,  query.late  = gethtmlcoord( form.getvalue("latitude"),   -90.,  90. )
86islonfree,  query.lon,  query.lons,  query.lone  = gethtmlcoord( form.getvalue("longitude"), -180., 180. )
87isloctfree, query.loct, query.locts, query.locte = gethtmlcoord( form.getvalue("localtime"),    0.,  24. )
88isaltfree,  query.xz,   query.xzs,   query.xze   = gethtmlcoord( form.getvalue("altitude"),  minxz, maxxz)
89
90try: query.datekey = int(form.getvalue("datekeyhtml"))
91except: query.datekey = float(1)
92if query.datekey == 1:
93    try: query.xdate = float(form.getvalue("ls"))
94    except: query.xdate = float(1)
95else:
96    try: query.xdate = float(form.getvalue("julian"))
97    except: query.xdate = float(1)
98    query.loct = 0.
99
100# Prevent the user from doing bad
101badinterv = (islatfree == -1) or (islonfree == -1) or (isloctfree == -1) or (isaltfree == -1)
102if badinterv: 
103    errormess = errormess+"<li>Bad syntax. Write a value (or) a range val1;val2 (or) 'all'. Separator shall be either ; : , / _ "
104badls = (query.datekey == 1 and (query.xdate < 0. or query.xdate > 360.))
105if badls: 
106    errormess = errormess+"<li>Solar longitude must be between 0 and 360."
107badloct = (isloctfree == 0 and query.loct > 24.) \
108       or (isloctfree == 1 and (query.locts > 24. or query.locte > 24.)) \
109       or (isloctfree == 0 and query.loct < 0.) \
110       or (isloctfree == 1 and (query.locts < 0. or query.locte < 0.))
111if badloct: 
112    errormess = errormess+"<li>Local time must be less than 24 martian hours (and not a negative number)."
113badlat = (islatfree == 0 and abs(query.lat) > 90.) \
114      or (islatfree == 1 and (abs(query.lats) > 90. or abs(query.late) > 90.))
115if badlat: 
116    errormess = errormess+"<li>Latitude coordinates must be between -90 and 90."
117badlon = (islonfree == 0 and abs(query.lon) > 360.) \
118      or (islonfree == 1 and (abs(query.lons) > 360. or abs(query.lone) > 360.))
119if badlon: 
120    errormess = errormess+"<li>Longitude coordinates must be between -360 and 360."
121badalt = (isaltfree == 0 and (query.zkey in [3]) and query.xz < 0.) \
122      or (isaltfree == 1 and (query.zkey in [3]) and (query.xzs < 0. or query.xze < 0.))
123if badalt: 
124    errormess = errormess+"<li>Vertical coordinates must be positive when requesting altitude above surface."
125badalt2 = (isaltfree == 0 and (query.zkey in [1,4]) and query.xz <= 0.) \
126      or (isaltfree == 1 and (query.zkey in [1,4]) and (query.xzs <= 0. or query.xze <= 0.))
127if badalt2: 
128    errormess = errormess+"<li>Vertical coordinates must be <b>strictly</b> positive when requesting pressure levels or altitude above Mars center."
129badalt3 = (isaltfree == 0 and query.zkey == 4 and query.xz > 1500.) \
130       or (isaltfree == 1 and query.zkey == 4 and min(query.xzs,query.xze) > 1500.)
131if badalt3: 
132    errormess = errormess+"<li>Pressure values larger than 1500 Pa are unlikely to be encountered in the Martian atmosphere."
133badrange = (isloctfree == 1 and query.locts == query.locte) \
134        or (islatfree == 1 and query.lats == query.late) \
135        or (islonfree == 1 and query.lons == query.lone) \
136        or (isaltfree == 1 and query.xzs == query.xze)
137if badrange: 
138    errormess = errormess+"<li>One or several coordinate intervals are not... intervals. Set either a real range or an unique value."
139
140# Get how many free dimensions we have
141sumfree = islatfree + islonfree + isloctfree + isaltfree
142if sumfree >= 3: errormess = errormess + "<li>3 or more free dimensions are set... but only 1D and 2D plots are supported!"
143
144# Get additional parameters
145try: query.hrkey = int(form.getvalue("hrkey"))
146except: query.hrkey = int(1)
147try: query.dust = int(form.getvalue("dust"))
148except: query.dust  = int(1)
149#        self.perturkey = 0  #integer perturkey ! perturbation type (0: none)
150#        self.seedin    = 1  #random number generator seed (unused if perturkey=0)
151#        self.gwlength  = 0. #gravity Wave wavelength (unused if perturkey=0)
152try: query.colorm = form.getvalue("colorm")
153except: query.colorm = "jet"
154
155# Get variables to plot
156var1 = form.getvalue("var1")
157var2 = form.getvalue("var2")
158var3 = form.getvalue("var3")
159var4 = form.getvalue("var4")
160
161# fg: init var as with form values
162if var1 == None: var1="t"
163
164vartoplot = []
165if var1 != "none": vartoplot = np.append(vartoplot,var1)
166if var2 != "none" and var2 != None: vartoplot = np.append(vartoplot,var2)
167if var3 != "none" and var3 != None: vartoplot = np.append(vartoplot,var3)
168if var4 != "none" and var4 != None: vartoplot = np.append(vartoplot,var4)
169
170iswind = form.getvalue("iswind")
171if iswind == "on": iswindlog = True
172else:              iswindlog = False
173isfixedlt = form.getvalue("isfixedlt")
174if isfixedlt == "on": query.fixedlt=True
175else:                 query.fixedlt=False 
176iszonmean = form.getvalue("zonmean")
177if iszonmean  == "on": query.zonmean=True
178else:                  query.zonmean=False
179
180### now, proceed...
181if errormess == "":
182
183 # reference name (to test which figures are already in the database)
184 reference = query.getnameset()+str(var1)+str(var2)+str(var3)+str(var4)+str(iswind)+str(isfixedlt)+str(iszonmean)+query.colorm
185 figname = '../img/'+reference+'.png'
186 txtname = '../txt/'+reference+'.txt'
187 testexist = daos.path.isfile(figname)
188
189 # extract data from MCD if needed
190 if not testexist:
191
192  ### 1D plots
193  if sumfree == 1:
194
195    ### getting data
196    if isloctfree == 1:         query.diurnal(nd=25) 
197    elif islonfree == 1:        query.zonal(nd=64)
198    elif islatfree == 1:        query.meridional(nd=48)
199    elif isaltfree == 1:        query.profile(nd=35)   
200    else:                       exit() 
201
202    ### generic building of figure
203    query.getascii(vartoplot,filename=txtname)
204    query.htmlplot1d(vartoplot,figname=figname)
205
206  ### 2D plots
207  elif sumfree == 2:
208
209    ### getting data
210    if islatfree == 1 and islonfree == 1:     query.htmlmap2d(vartoplot,incwind=iswindlog,figname=figname) 
211    else:                                     query.htmlplot2d(vartoplot,figname=figname)
212
213#### NOW WRITE THE HTML PAGE TO USER
214
215## This is quite common
216print "Content-type:text/html\n"
217print "  "  #Apache needs a space after content-type
218
219#entete="""<?xml version="1.0" encoding="UTF-8"?>
220#<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd">
221#<html xmlns="http://www.w3.org/1999/xhtml"> """
222
223header="""<html><head><title>Mars Climate Database: The Web Interface</title></head><body>"""
224
225print header
226#print query.printset()
227#print "<br />"
228
229## Now the part which differs
230if errormess != "":
231                       print "<h1>Ooops!</h1>"
232                       print "Please correct the following problems before submitting again."
233                       print "<ul>"
234                       print errormess
235                       print "</ul>"
236else:
237  if sumfree == 0:      query.update() ; query.htmlprinttabextvar(vartoplot)
238  elif sumfree == 2:    print "<img src='"+figname+"'><br />"
239  elif sumfree == 1:     
240                        print "<a href='"+txtname+"'>Click here to download an ASCII file containing data</a><br />"
241                        print "<hr>"
242                        print "<img src='"+figname+"'><br />"
243
244## This is quite common
245bottom = "</body></html>"
246print bottom
Note: See TracBrowser for help on using the repository browser.