Repository: climate Updated Branches: refs/heads/master 8d3ab4eae -> 0b74c82d9
CLIMATE-550 - Drop bottlemet module from ocw-ui backend code Project: http://git-wip-us.apache.org/repos/asf/climate/repo Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/ebf52328 Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/ebf52328 Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/ebf52328 Branch: refs/heads/master Commit: ebf523289703bc0bddaf99e75426786f161b9e97 Parents: cff5b54 Author: Michael Joyce <[email protected]> Authored: Fri Nov 7 09:21:09 2014 -0800 Committer: Michael Joyce <[email protected]> Committed: Fri Nov 7 09:21:09 2014 -0800 ---------------------------------------------------------------------- ocw-ui/backend/bottlemet.py | 615 --------------------------------------- 1 file changed, 615 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/climate/blob/ebf52328/ocw-ui/backend/bottlemet.py ---------------------------------------------------------------------- diff --git a/ocw-ui/backend/bottlemet.py b/ocw-ui/backend/bottlemet.py deleted file mode 100644 index b67382c..0000000 --- a/ocw-ui/backend/bottlemet.py +++ /dev/null @@ -1,615 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -''' - Module to create a web service for RCMET statistical metrics -''' - - - - -########################################################################################## -#setting up bottle and importing metrics -########################################################################################## - -#sets up bottle and necessary methods. -from bottle import route, run, post, request, redirect, debug - -#temporary quick-fix to track errors, not for publication -debug(True) - -#imports pickle -import pickle - -#imports metrics from RCMET -import rcmes.metrics as mtx - - - - -########################################################################################## -#error-catching dictionaries -########################################################################################## - -#dictionary of MetricNames and their number of variables. Useful later on -HowManyVariables={ - "calc_stdev" :1, - "calc_annual_cycle_means" : 2, - "calc_annual_cycle_std" : 2, - "calc_annual_cycle_domain_means" : 2, - "calc_annual_cycle_domain_std" : 2, - "calc_bias" : 2, - "calc_bias_dom" : 2, - "calc_difference" : 2, - "calc_mae" : 2, - "calc_mae_dom" :2, - "calc_rms" : 2, - "calc_rms_dom" : 2, - "calc_temporal_pat_cor" : 2, - "calc_pat_cor" : 2, - "calc_nash_sutcliff" : 2, - "calc_pdf" : 2, - "calc_anom_corn" : 3 -} - -#dictionary of metric names and the names of their variables. -NameOfVariables={ - "calc_stdev":['t1'], - "calc_annual_cycle_means" :['data','time'], - "calc_annual_cycle_std" :['data','time'], - "calc_annual_cycle_domain_means" :['data','time'], - "calc_annual_cycle_domain_std" :['data','time'], - "calc_bias" :['t1','t2'], - "calc_bias_dom" :['t1','t2'], - "calc_difference" :['t1','t2'], - "calc_mae" :['t1','t2'], - "calc_mae_dom" : ['t1','t2'], - "calc_rms" :['t1','t2'], - "calc_rms_dom" :['t1','t2'], - "calc_temporal_pat_cor" :['t1','t2'], - "calc_pat_cor" :['t1','t2'], - "calc_nash_sutcliff" :['t1','t2'], - "calc_pdf" :['t1','t2'], - "calc_anom_corn" :['t1','t2','t4'] -} - -#two lists that will help with user explanation later - -ArrayNames=[] - -ListOfArrays=[] - - - -########################################################################################## - -#Running the metrics through interactive web pages - -########################################################################################## - - - -########################################################################################## -#First parts: introduction and identification of user's needs -########################################################################################## - -#basic first page. Explanation could be more comprehensive -@route('/rcmet/metrics/online') -def ShowPossibleMetrics(): - ''' - Returns a page in html that allows the user to select a metric through links - ''' - return '''<html> - <head> RCMET Metrics through Bottle </head> - <body> - <p>Please select the metric you will use.</p> - - <p> Metrics with one variable: - <a href='/rcmet/metrics/online/calc_stdev'>"calc_stdev" to return standard deviation</a> - </p> - - <p> Metrics with two variables: - <a href='/rcmet/metrics/online/calc_annual_cycle_means'>"calc_annual_cycle_means" to return monthly means</a> - <a href='/rcmet/metrics/online/calc_annual_cycle_std'>""calc_annual_cycle_std" to return monthly standard deviation</a> - <a href='/rcmet/metrics/online/calc_annual_cycle_domain_means'>"calc_annual_cycle_domain_ means" to return monthly - domain means</a> - <a href='/rcmet/metrics/online/calc_annual_cycle_domain_std'>"calc_annual_cycle_domain_std" to return monthly standard - deviation</a> - <a href='/rcmet/metrics/online/calc_bias'>"calc_bias" to return mean difference</a> - <a href='/rcmet/metrics/online/calc_bias_dom'>"calc_bias_dom" to return domain mean difference</a> - <a href='/rcmet/metrics/online/calc_difference'>"calc_difference" to return difference</a> - <a href='/rcmet/metrics/online/calc_mae'>"calc_mae" to return mean absolute error</a> - <a href='/rcmet/metrics/online/calc_mae_dom'>"calc_mae_dom" to return domain mean difference over time</a> - <a href='/rcmet/metrics/online/calc_rms'>"calc_rms" to return root mean square error - </a> - <a href='/rcmet/metrics/online/calc_rms_dom'>"calc_rms_dom" to return domain root mean square error</a> - <a href='/rcmet/metrics/online/calc_temporal_pat_cor'>"calc_temporal_pat_cor" to return temporal pattern correlation</a> - <a href='/rcmet/metrics/online/calc_pat_cor'>"calc_pat_cor" to return pattern correlation</a> - <a href='/rcmet/metrics/online/calc_nash_sutcliff'>"calc_nash_sutcliff" to return Nash-Sutcliff coefficient of - efficiency</a> - <a href='/rcmet/metrics/online/calc_pdf'>"calc_pdf" to return probability distribution function</a> - - <p> Metrics with three variables: - <a href='/rcmet/metrics/online/calc_anom_corn'>"calc_anom_corn" to return anomaly correlation</a> </p> - </body> - <html>''' - -#creates introductory page to explain how to use bottle -@route('/rcmet/metrics/online/<MetricNameHere>') -def VariableSubmission(MetricNameHere): - ''' - Returns a page in html that allows the user to choose between submitting variables on the command line or searching - RCMED - ''' - - global MetricName - - MetricName=MetricNameHere - - if MetricName in HowManyVariables: - return "For metric %s , you need %d variable(s), which will represent: %s" %(MetricName, - HowManyVariables[MetricName], NameOfVariables[MetricName][:]), '''<html> - <body> - <p>Will you enter variables (which are arrays) through the command line or - will you search the RCMES Database?</p> - <a href="/rcmet/metrics/online/commandline">command line</a> - <a href="/rcmet/metrics/online/rcmed">RCMED</a> - </body> - </html>''', - '''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''' - - else: - return "The metric you entered doesn't exist." - - -########################################################################################## -#getting arrays through the command line -########################################################################################## - -#Tells the user how to send variables from the command line -@route('/rcmet/metrics/online/commandline') -def ArraysFromCommandLine(): - ''' - Explains to the user how to submit a variable through POST on the command line - ''' - if HowManyVariables[MetricName]-count<=0: - print "You have already submitted all the needed variables for this metric." - redirect('/rcmet/metrics/online/calculate') - else: - return "Please use your command line to POST a form with the array. Send either a pickled file or serialized ", - "string. Name the form: array. Include also, a form that describes/names the array. Call this form: name. A ", - "sample would be array=array_here and name=array_name_here. Send the form to: ", - "http://.../rcmet/metrics/<metric_name>/commandline. Once the computer receives all variables, you may ", - "move on to the metrics portion of the website. Currently, you have submitted %d variable(s) and need %d ", - "more. The next variable you submit will represent the variable %s in %s" %(count, - (HowManyVariables[MetricName]-count),NameOfVariables[MetricName][count], MetricName) - -#this function gets the array from the command line -@route('/rcmet/metrics/online/commandline', method='POST') -def ReceivingArrays(): - ''' - Uses the POST method to retrieve any arrays sent by the user, and proceed to deserialize them. Also adds each - variable to the appropriate list, and proceeds to offer the user the option to add more variables or else move - on to calculating the value of the metric; - ''' - - try: - BottleMetrics.GetVariablesFromCommandLine() - - return "Variable received as %s. Will represent %s" % (ArrayNames[count-1], - NameOfVariables[MetricName][count-1]), "Submit more variables?", - '''<a href='/rcmet/metrics/online/rcmed'>Online</a>''', - '''<a href='/rcmet/metrics/online/commandline'>Command Line</a>''', - '''<a href='/rcmet/metrics/online/calculate'>No More Variables</a>''', - '''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''' - - except pickle.UnpicklingError: - return "This object cannot be unpickled. Send only a file or serialized string.", - '''<a href='/rcmet/metrics/online/commandline'>Re-submit Variable</a>''', - '''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''' - - -########################################################################################## -#getting variables through RCMED -########################################################################################## - -#explains how to enter information into a dynamic link -@route('/rcmet/metrics/online/rcmed') -def QueryRcmed(): - ''' - Returns a page in html that explains to the user how to search RCMED for the desired arrays, and offers the - user multiple forms in which to enter search parameters - ''' - - #I was unclear what type the dataset ID and paramID were supposed to be. This may need to change - - return "Currently, you have submitted %d variable(s) and need %d more. The next"\ - " variable you submit will represent the variable %s in %s" %(count, - (HowManyVariables[MetricName]-count),NameOfVariables[MetricName][count], MetricName),'''<html> - <head> Query RCMED for Array Data </head> - <body> - <p>Enter the parameters into the appropriate boxes.</p> - <form method="POST"> - <p>Dataset ID</p> - <input name="datasetID" type="string" /> - <p>Parameter ID</p> - <input name="paramID" type="string" /> - <p>latMin, float</p> - <input name="latMin" type="float" /> - <p>latMax, float</p> - <input name="latMax" type="float" /> - <p>lonMin, float</p> - <input name="lonMin" type="float" /> - <p>lonMax, float</p> - <input name="lonMax" type="float" /> - <p>startTime, datetime object</p> - <input name="startTime" type="datetime" /> - <p>endTime, datetime object</p> - <input name="endTime" type="datetime" /> - <p>cachedir, string</p> - <input name="cachedir" type="string" /> - <p>Array Name, string</p> - <input name="ArrayName" type="string" /> - <input type="Submit" /> </form> - </body> - </html>''' - - -@route('/rcmet/metrics/online/rcmed', method='POST') -def GetVariablesFromDatabase(): - ''' - Gets data from forms, searches the database, processes the variables, and prompts the user to submit more. - ''' - BottleMetrics.GetVariablesFromRcmed() - - - return "Submit more variables?",'''<a href='/rcmet/metrics/online/rcmed'>Online</a>''', - '''<a href='/rcmet/metrics/online/commandline'>Command Line</a>''', - '''<a href='/rcmet/metrics/online/calculate'>No More Variables</a>''', - '''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''' - - -########################################################################################## -#running the metrics online -########################################################################################## - -#this function actually runs the metrics -@route('/rcmet/metrics/online/calculate') -def Calculate(MetricName): - ''' - Uses variables from the lists to return the answer for the metric. Also returns a brief description of the metric performed. - ''' - - if HowManyVariables[MetricName]<count: - return "You have too few variables to run this metric.",'''<a href='/rcmet/metrics/online/commandline'>Command Line</a>, - <a href='/rcmet/metrics/online/rcmed'>Online</a>''','''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''' - - else: - return BottleMetrics.ExplainMetric(), str(result), '''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''', - '''<a href='/rcmet/metrics/online'>Start Over</a>''' - - - '''<a href='/rcmet/metrics/online/methods'>Run Methods</a>''' - -@route('/rcmet/metrics/online/methods') -def ChooseMethodOnline(): - ''' - Allows an online user to access any method in the class - ''' - - return "Which method?", '''<html> - <a href='/rcmet/metrics/online/methods/Status'>Status</a> - <a href='/rcmet/metrics/online/methods/ExplainMetric'>ExplainMetric</a> - <a href='/rcmet/metrics/online/methods/VariableCount'>VariableCount</a> - <a href='/rcmet/metrics/online/methods/ReturnResult'>ReturnResult</a> - <a href='/rcmet/metrics/online/methods/CleanUp'>CleanUp</a>''' - -@route('/rcmet/metrics/online/methods/<MethodName>) -def RunMethodOnline(MethodName): - ''' - Runs any method in class MetricWebService() chosen by an online user - ''' - - MetricWebServiceMethod=getattr(BottleMetrics, MethodName) - - return BottleMetrics.MetricWebServiceMethod(), '''<a href='/rcmet/metrics/online'>Back to Beginning</a>''' - - -########################################################################################## -########################################################################################## - -#creating a class for the Web Service - -########################################################################################## -########################################################################################## - -class MetricWebService(object): - ''' - Class containing all of the necessary functions to find, process, and use the variables to run metrics. Also allows - the user to see the state of the metric, i.e. how many variables have been entered. - ''' - - def __init__(self): - - global count - count=0 - -########################################################################################## - - def Status(self): - ''' - Provides a standardized system for showing how many variables are submitted, allowing the user to - check their progress - ''' - print "For metric %s , you need %d variable(s): %s. Currently, you have submitted "\ - "%d variable(s) and need %d more. The values you have submitted, %s, will represent %s respectively." - %(MetricName, HowManyVariables[MetricName], NameOfVariables[MetricName][:], count, - (HowManyVariables[MetricName]-count),ArrayNames[:],NameOfVariables[MetricName][:]) - - return "For metric %s , you need %d variable(s): %s. Currently, you have submitted "\ - "%d variable(s) and need %d more. The values you have submitted, %s, will represent %s respectively." - %(MetricName, HowManyVariables[MetricName], NameOfVariables[MetricName][:], count, - (HowManyVariables[MetricName]-count),ArrayNames[:],NameOfVariables[MetricName][:]) - -########################################################################################## - - def ExplainMetric(self): - ''' - Provides a standardized means of returning a metric's docstring and thus describing the metric - ''' - method=getattr(mt, MetricName) - - print method.__doc__ - - return method.__doc__ -########################################################################################## - - def VariableCount(self): - ''' - Determines how many variables have been submitted, and if the right number has, this function runs the RunMetrics() method - ''' - - if HowManyVariables[MetricName]-count>0: - - print "Please add more variables" - - return "Please add more variables" - - if HowManyVariables[MetricName]-count<0: - print "You have added too many variables" - - return "Please add more variabels" - - else: - print "You have added all necessary metrics. The program will now run your metric." - - self.RunMetrics() - - -########################################################################################## - - def ProcessVariables(self, array, ArrayName): - ''' - adds the variables posted by the user to the appropriate lists, raises count to indicate this addition, and - starts VariableCount() - ''' - ListOfArrays.append(array) - ArrayNames.append(ArrayName) - - global count - count=count+1 - - print "Variable received as %s. Will represent %s" % (ArrayName, - NameOfVariables[MetricName][count-1]) - - self.VariableCount() - -########################################################################################## - - def GetVariablesFromCommandLine(self): - ''' - Gets array and array name from forms, deserializes them with unpickle, and runs ProcessVariables() - ''' - - if HowManyVariables[MetricName]-count>0: - array=request.forms.get('array') - ArrayName=request.forms.get('name') - - if type(array)==str: - array=pickle.loads(array) - - else: - array=pickle.load(array) - - self.ProcessVariables(array, ArrayName) - - else: - self.VariableCount() - -########################################################################################## - - def GetVariablesFromRcmed(self): - ''' - Gets search parameters from forms, runs a search of RCMED, and returns the array mdata - ''' - - if HowManyVariables[MetricName]-count>0: - - import rcmes.db as db - - datasetID=request.forms.get('datasetID') - paramID=request.forms.get('paramID') - latMin=request.forms.get('latMin') - latMax=request.forms.get('latMax') - lonMin=request.forms.get('lonMin') - lonMax=request.forms.get('lonMax') - startTime=request.forms.get('startTime') - endTime=request.forms.get('endTime') - cachedir=request.forms.get('cachedir') - - ArrayName=request.forms.get('name') - - try: - - db.extract_data_from_db(datasetID, paramID, latMin, latMax, lonMin, lonMax, startTime, endTime, cachedir) - - #I don't think this will work - array=mdata - - self.ProcessVariables(array,ArrayName) - - except TypeError: - print "One of your variables was not entered in the correct format or was not entered at all" - - else: - self.VariableCount() - -########################################################################################## - - def GetVariables(self): - ''' - Runs two links that connect with functions meant to handle the variables posted to the links - ''' -#################### - - @route('/rcmet/metrics/get/variables/commandline', method='POST') - def VariablesPostedToCommandline(): - ''' - runs the method GetVariablesFromCommandLine() at the URL, allowing the user to post their forms to this url and have - them handled by GetVariablesFromCommandLine(). - ''' - - try: - self.GetVariablesFromCommandLine() - - except pickle.UnpicklingError: - print "This object cannot be unpickled. Send only a file or serialized string." - - -#################### - - @route('/rcmet/metrics/get/variables/rcmed', method='POST') - def GetVariablesFromRCMED(self): - ''' - runs the method GetVariablesFromRcmed() at the URL, allowing the user to post their forms to this url and have - them handled by GetVariablesFromRcmed(). - ''' - - self.GetVariablesFromRcmed() - -########################################################################################## - - def RunMetrics(self): - ''' - Calls to metrics.py and runs the desired metric using variables submitted by the user. Returns a string of the - value returned by the metric - ''' - - print "Running metric" - - method=getattr(mtx, MetricName) - - global result - - if HowManyVariables[MetricName]==1: - result=method(ListOfArrays[0]) - - if HowManyVariables[MetricName]==2: - result=method(ListOfArrays[0], ListOfArrays[1]) - - if HowManyVariables[MetricName]==3: - result=method(ListOfArrays[0], ListOfArrays[1], ListOfArrays[2]) - -########################################################################################## - - @route('/rcmet/metrics/commandline/return/result') - def ReturnResult(): - ''' - links the result to a uri from which the user can easily fetch it. Note, the result is returned as a string - ''' - #If the result of the metrics is an array, I would recommend including a provision in - #ReturnResult() that pickles or somehow serializes the result, and then, upon getting - #the pickled string from the URL, the user could unpickle it and use it as an array. - - return str(result) - -########################################################################################## - - def CleanUp(self, name): - ''' - resets the lists, the count, and the variable MetricName back to zero, enabling a user to in effect start over, without - re-creating the instance of the class. - ''' - - global ArrayNames - ArrayNames=[] - - global ListOfArrays - ListOfArrays=[] - - global count - count=0 - - global MetricName - name=MetricName - -########################################################################################## -#final commands to tie everything together -########################################################################################## - -#allows the command line user to remotely create an instance of the class -@route('/rcmet/metrics/commandline', method='POST') -def CreateAnInstance(): - ''' - Sets up a POST page that creates an instance of the class for a user on the command line. The user does not need - to open this page for it to function; they need only post the name of the metric they want. - ''' - - NameOfMetric=request.forms.get('NameOfMetric') - - global MetricName - - MetricName=NameOfMetric - - if name in HowManyVariables: - BottleMetrics.GetVariables() - - else: - print "The metric you entered, %s, does not exist" %name - - - -@route('/rcmet/metrics/commandline/methods', method='POST') -def RunAMethod(): - ''' - Allows a command line user to access any method in class MetricWebService() by sending a form - ''' - MethodName=request.forms.get('MethodName') - - MetricWebServiceMethod=getattr(BottleMetrics, MethodName) - - BottleMetrics.MetricWebServiceMethod() - - -BottleMetrics=MetricWebService() - -#final function starts up bottle at http://localhost:8080 -#note: localhost:8080 may need to be changed eventually -run(host='localhost', port=8080) - - - -
