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

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

MCD web interface. forgot to include a file in the previous commit.

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