#!/usr/bin/python ###!/usr/bin/env python ###!/home/aymeric/Software/epd-7.0-2-rh5-x86/bin/python ####!/home/marshttp/EPD/epd-7.0-2-rh5-x86_64/bin/python ### here the version used to f2py the MCD Fortran routines ################################################## ### A Python CGI for the Mars Climate Database ### ### ------------------------------------------ ### ### Aymeric SPIGA 18-19/04/2012 ~ 11/08/2012 ### ### ------------------------------------------ ### ### (see mcdtest.py for examples of use) ### ################################################## ### ajouts et corrections par Franck Guyon 09/2012 ### ajouts suite a brainstorm equipe AS 10/2012 import cgi, cgitb import numpy as np from modules import * from modules import mcd import cStringIO import os as daos import matplotlib.pyplot as mpl ### a function to read HTML arguments for coordinates def gethtmlcoord(userinput,defmin,defmax): import string # accepted separators. the symbol - should always be last. separators = [":",";",",","/","_"] # initial values val = -9999. ; vals = None ; vale = None ; foundinterv = False if userinput == None: userinput = "1" # the main work. either all, or an interval, or a single value. # ... all if userinput == "all": isfree = 1 ; vals = defmin ; vale = defmax ; foundinterv = True # ... an interval else: for sep in separators: if not foundinterv: isfree = 1 ; ind = userinput.find(sep) if ind != -1: vals = float(userinput[:ind]) ; vale = float(userinput[ind+1:]) ; foundinterv = True # ... a single value (or an error) if not foundinterv: # treat the difficult case of possible - separator test = userinput[1:].find("-") # at this stage: # * if - is found in the first position, it could not be a separator # * if - found at positions > 0, it must be considered as a separator if test != -1: isfree = 1 ; ind=test+1 vals = float(userinput[:ind]) ; vale = float(userinput[ind+1:]) ; foundinterv = True else: # check if input is valid (each character is numeric or -) for char in userinput: if char not in string.digits: if char not in ["-","."]: userinput="yorgl" # either we are OK. if we are not we set isfree to -1. if userinput != "yorgl": isfree = 0 ; val = float(userinput) else: isfree = -1 # return values return isfree, val, vals, vale # set an errormess variable which must stay to None for interface to proceed errormess = "" # for debugging in web browser cgitb.enable() # Create instance of FieldStorage form = cgi.FieldStorage() # create a MCD object query=mcd.mcd() # Get the kind of vertical coordinates and choose default behavior for "all" try: query.zkey = int(form.getvalue("zkey")) except: query.zkey = int(3) if query.zkey == 2: minxz = -5000. ; maxxz = 150000. elif query.zkey == 3: minxz = 0. ; maxxz = 250000. elif query.zkey == 5: minxz = -5000. ; maxxz = 150000. elif query.zkey == 4: minxz = 1.e3 ; maxxz = 1.e-6 elif query.zkey == 1: minxz = 3396000. ; maxxz = 3596000. # Get data from user-defined fields and define free dimensions islatfree, query.lat, query.lats, query.late = gethtmlcoord( form.getvalue("latitude"), -90., 90. ) islonfree, query.lon, query.lons, query.lone = gethtmlcoord( form.getvalue("longitude"), -180., 180. ) isloctfree, query.loct, query.locts, query.locte = gethtmlcoord( form.getvalue("localtime"), 0., 24. ) isaltfree, query.xz, query.xzs, query.xze = gethtmlcoord( form.getvalue("altitude"), minxz, maxxz) try: query.datekey = int(form.getvalue("datekeyhtml")) except: query.datekey = float(1) badlschar = False if query.datekey == 1: try: query.xdate = float(form.getvalue("ls")) except: query.xdate = float(1) ; badlschar = True else: try: query.xdate = float(form.getvalue("julian")) except: query.xdate = float(1) query.loct = 0. # Prevent the user from doing bad badinterv = (islatfree == -1) or (islonfree == -1) or (isloctfree == -1) or (isaltfree == -1) if badinterv: errormess = errormess+"
  • Bad syntax. Write a value (or) a range val1;val2 (or) 'all'. Separator shall be either ; : , / _ " badls = (query.datekey == 1 and (query.xdate < 0. or query.xdate > 360.)) if badls: errormess = errormess+"
  • Solar longitude must be between 0 and 360." if badlschar: errormess = errormess+"
  • Solar longitude is in the wrong format. It should be a positive number between 0 and 360. Intervals of solar longitude are not allowed." badloct = (isloctfree == 0 and query.loct > 24.) \ or (isloctfree == 1 and (query.locts > 24. or query.locte > 24.)) \ or (isloctfree == 0 and query.loct < 0.) \ or (isloctfree == 1 and (query.locts < 0. or query.locte < 0.)) if badloct: errormess = errormess+"
  • Local time must be less than 24 martian hours (and not a negative number)." badlat = (islatfree == 0 and abs(query.lat) > 90.) \ or (islatfree == 1 and (abs(query.lats) > 90. or abs(query.late) > 90.)) if badlat: errormess = errormess+"
  • Latitude coordinates must be between -90 and 90." badlon = (islonfree == 0 and abs(query.lon) > 360.) \ or (islonfree == 1 and (abs(query.lons) > 360. or abs(query.lone) > 360.)) if badlon: errormess = errormess+"
  • Longitude coordinates must be between -360 and 360." badalt = (isaltfree == 0 and (query.zkey in [3]) and query.xz < 0.) \ or (isaltfree == 1 and (query.zkey in [3]) and (query.xzs < 0. or query.xze < 0.)) if badalt: errormess = errormess+"
  • Vertical coordinates must be positive when requesting altitude above surface." badalt2 = (isaltfree == 0 and (query.zkey in [1,4]) and query.xz <= 0.) \ or (isaltfree == 1 and (query.zkey in [1,4]) and (query.xzs <= 0. or query.xze <= 0.)) if badalt2: errormess = errormess+"
  • Vertical coordinates must be strictly positive when requesting pressure levels or altitude above Mars center." badalt3 = (isaltfree == 0 and query.zkey == 4 and query.xz > 1500.) \ or (isaltfree == 1 and query.zkey == 4 and min(query.xzs,query.xze) > 1500.) if badalt3: errormess = errormess+"
  • Pressure values larger than 1500 Pa are unlikely to be encountered in the Martian atmosphere." badrange = (isloctfree == 1 and query.locts == query.locte) \ or (islatfree == 1 and query.lats == query.late) \ or (islonfree == 1 and query.lons == query.lone) \ or (isaltfree == 1 and query.xzs == query.xze) if badrange: errormess = errormess+"
  • One or several coordinate intervals are not... intervals. Set either a real range or an unique value." # Get how many free dimensions we have sumfree = islatfree + islonfree + isloctfree + isaltfree if sumfree >= 3: errormess = errormess + "
  • 3 or more free dimensions are set... but only 1D and 2D plots are supported!" # Get additional parameters try: query.hrkey = int(form.getvalue("hrkey")) except: query.hrkey = int(1) try: query.dust = int(form.getvalue("dust")) except: query.dust = int(1) # self.perturkey = 0 #integer perturkey ! perturbation type (0: none) # self.seedin = 1 #random number generator seed (unused if perturkey=0) # self.gwlength = 0. #gravity Wave wavelength (unused if perturkey=0) try: query.colorm = form.getvalue("colorm") except: query.colorm = "jet" try: query.min2d = float(form.getvalue("minval")) except: query.min2d = None try: query.max2d = float(form.getvalue("maxval")) except: query.max2d = None try: query.dpi = float(form.getvalue("dpi")) except: query.dpi = 80. # Get variables to plot var1 = form.getvalue("var1") var2 = form.getvalue("var2") var3 = form.getvalue("var3") var4 = form.getvalue("var4") # fg: init var as with form values if var1 == None: var1="t" vartoplot = [] if var1 != "none": vartoplot = np.append(vartoplot,var1) if var2 != "none" and var2 != None: vartoplot = np.append(vartoplot,var2) if var3 != "none" and var3 != None: vartoplot = np.append(vartoplot,var3) if var4 != "none" and var4 != None: vartoplot = np.append(vartoplot,var4) iswind = form.getvalue("iswind") if iswind == "on": iswindlog = True else: iswindlog = False isfixedlt = form.getvalue("isfixedlt") if isfixedlt == "on": query.fixedlt=True else: query.fixedlt=False iszonmean = form.getvalue("zonmean") if iszonmean == "on": query.zonmean=True else: query.zonmean=False ### now, proceed... if errormess == "": # reference name (to test which figures are already in the database) 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) figname = '../img/'+reference+'.png' txtname = '../txt/'+reference+'.txt' testexist = daos.path.isfile(figname) # extract data from MCD if needed if not testexist: ### 1D plots if sumfree == 1: ### getting data if isloctfree == 1: query.diurnal(nd=25) elif islonfree == 1: query.zonal(nd=64) elif islatfree == 1: query.meridional(nd=48) elif isaltfree == 1: query.profile(nd=35) else: exit() ### generic building of figure query.getascii(vartoplot,filename=txtname) query.htmlplot1d(vartoplot,figname=figname) ### 2D plots elif sumfree == 2: ### getting data if islatfree == 1 and islonfree == 1: query.htmlmap2d(vartoplot,incwind=iswindlog,figname=figname) else: query.htmlplot2d(vartoplot,figname=figname) #### NOW WRITE THE HTML PAGE TO USER ## This is quite common print "Content-type:text/html\n" print " " #Apache needs a space after content-type #entete=""" # # """ header="""Mars Climate Database: The Web Interface""" print header #print query.printset() #print "
    " ## Now the part which differs if errormess != "": print "

    Ooops!

    " print "Please correct the following problems before submitting again." print "" else: if sumfree == 0: query.update() ; query.htmlprinttabextvar(vartoplot) elif sumfree == 2: print "
    " elif sumfree == 1: print "Click here to download an ASCII file containing data
    " print "
    " print "
    " ## This is quite common bottom = "" print bottom