You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@climate.apache.org by jo...@apache.org on 2014/05/09 04:03:55 UTC
[46/51] [abbrv] [partial] Adding Jinwon's custom RCMET
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/cli/rcmet_ui.py
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/cli/rcmet_ui.py b/src/main/python/rcmes/cli/rcmet_ui.py
new file mode 100755
index 0000000..ddc11f6
--- /dev/null
+++ b/src/main/python/rcmes/cli/rcmet_ui.py
@@ -0,0 +1,91 @@
+#!/usr/local/bin/python
+"""
+ Step by Step Wizard that demonstrates how the underlying RCMES code can
+ be used to generate climate dataset intercomparisons
+"""
+# Imports
+# Native Python Module Imports
+import sys
+
+# RCMES Imports
+from classes import Model, JobProperties, GridBox
+import storage.rcmed as rcmed
+import toolkit.metrics
+import toolkit.do_data_prep
+from utils import misc
+
+def rcmetUI():
+ """"
+ Command Line User interface for RCMET.
+ Collects user OPTIONS then runs RCMET to perform processing.
+
+ Duplicates job of GUI.
+ """
+ print 'Regional Climate Model Evaluation System BETA'
+ print "Querying RCMED for available parameters..."
+
+ try:
+ parameters = rcmed.getParams()
+ except Exception:
+ raise
+ sys.exit()
+
+ # Section 0: Collect directories to store RCMET working files.
+ workDir, cacheDir = misc.getDirSettings()
+ temporalGrid = misc.getTemporalGrid()
+ spatialGrid = misc.getSpatialGrid()
+ jobProperties = JobProperties(workDir, cacheDir, spatialGrid, temporalGrid)
+
+ # Section 1a: Enter model file/s
+ modelFiles = misc.getModelFiles()
+ # Create a list of model objects for use later
+ models = [Model(modelFile) for modelFile in modelFiles]
+
+ # Section 3b: Select 1 Parameter from list
+ for parameter in parameters:
+ """( 38 ) - CRU3.1 Daily-Mean Temperature : monthly"""
+ print "({:^2}) - {:<54} :: {:<10}".format(parameter['parameter_id'], parameter['longname'], parameter['timestep'])
+
+ obsDatasetList = []
+ validParamIds = [int(p['parameter_id']) for p in parameters]
+ while obsDatasetList == []:
+ print("Please select the available observation you would like to use from the list above:")
+ userChoice = int(raw_input(">>>"))
+ if userChoice in validParamIds:
+ for param in parameters:
+ if param['parameter_id'] == userChoice:
+ obsDatasetList.append(param)
+ else:
+ pass
+ else:
+ print("Your selection '%s' is invalid. Please make another selection." % userChoice)
+
+
+ # User must provide startTime and endTime if not defined
+ if jobProperties.startDate == None or jobProperties.endDate == None:
+ jobProperties.startDate, jobProperties.endDate = misc.userDefinedStartEndTimes(obsDatasetList, models)
+
+ try:
+ gridBox = GridBox(jobProperties.latMin, jobProperties.lonMin, jobProperties.latMax,
+ jobProperties.lonMax, jobProperties.gridLonStep, jobProperties.gridLatStep)
+ except:
+ gridBox = None
+
+ numOBS, numMDL, nT, ngrdY, ngrdX, Times, lons, lats, obsData, mdlData, obsList, mdlName = toolkit.do_data_prep.prep_data(jobProperties, obsDatasetList, gridBox, models)
+
+ counts = {'observations': numOBS,
+ 'models' : numMDL,
+ 'times' : nT}
+ subRegions = misc.getSubRegionsInteractively(counts, jobProperties.workDir)
+
+ # TODO: New function Call
+ fileOutputOption = jobProperties.writeOutFile
+ modelVarName = models[0].varName
+ toolkit.metrics.metrics_plots(modelVarName, numOBS, numMDL, nT, ngrdY, ngrdX, Times, lons, lats, obsData, mdlData, obsList, mdlName, workDir, subRegions, fileOutputOption)
+
+
+
+# Actually call the UI function.
+if __name__ == "__main__":
+ rcmetUI()
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/cli/rcmet_ui.pyc
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/cli/rcmet_ui.pyc b/src/main/python/rcmes/cli/rcmet_ui.pyc
new file mode 100644
index 0000000..bc5ed9f
Binary files /dev/null and b/src/main/python/rcmes/cli/rcmet_ui.pyc differ
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/rcmet.py
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/rcmet.py b/src/main/python/rcmes/rcmet.py
new file mode 100755
index 0000000..01799f9
--- /dev/null
+++ b/src/main/python/rcmes/rcmet.py
@@ -0,0 +1,305 @@
+#!/usr/local/python27
+""" DOCSTRING"""
+
+# Python Standard Lib Imports
+import argparse
+import ConfigParser
+import datetime
+import glob
+import os
+import sys
+import numpy as np
+import numpy.ma as ma
+
+
+# RCMES Imports
+import storage.rcmed as db
+from toolkit import do_data_prep, process, metrics
+from utils import misc
+from classes import JobProperties, Model, GridBox
+from cli import rcmet_ui as ui
+
+parser = argparse.ArgumentParser(description='Regional Climate Model Evaluation Toolkit. Use -h for help and options')
+parser.add_argument('-c', '--config', dest='CONFIG', help='Path to an evaluation configuration file')
+args = parser.parse_args()
+
+def checkConfigSettings(config):
+ """ This function will check the SETTINGS block of the user supplied config file.
+ This will only check if the working and cache dirs are writable from this program.
+ Additional configuration parameters can be checked here later on.
+
+ Input::
+ config - ConfigParser configuration object
+
+ Output::
+ none - An exception will be raised if something goes wrong
+ """
+ settings = config.items('SETTINGS')
+ for key_val in settings:
+ # Check the user provided directories are valid
+ if key_val[0] == 'workDir' or key_val[0] == 'cacheDir':
+ _ = misc.isDirGood(os.path.abspath(key_val[1]))
+
+ else:
+ pass
+
+def setSettings(settings, config):
+ """
+ This function is used to set the values within the 'SETTINGS' dictionary when a user provides an external
+ configuration file.
+
+ Input::
+ settings - Python Dictionary object that will collect the key : value pairs
+ config - A configparse object that contains the external config values
+
+ Output::
+ None - The settings dictionary will be updated in place.
+ """
+ pass
+
+def generateModels(modelConfig):
+ """
+ This function will return a list of Model objects that can easily be used for
+ metric computation and other processing tasks.
+
+ Input::
+ modelConfig - list of ('key', 'value') tuples. Below is a list of valid keys
+ filenamepattern - string i.e. '/nas/run/model/output/MOD*precip*.nc'
+ latvariable - string i.e. 'latitude'
+ lonvariable - string i.e. 'longitude'
+ timevariable - string i.e. 't'
+ timestep - string 'monthly' | 'daily' | 'annual'
+ varname - string i.e. 'pr'
+
+ Output::
+ modelList - List of Model objects
+ """
+ # Setup the config Data Dictionary to make parsing easier later
+ configData = {}
+ for entry in modelConfig:
+ configData[entry[0]] = entry[1]
+
+ modelFileList = None
+ for keyValTuple in modelConfig:
+ if keyValTuple[0] == 'filenamePattern':
+ modelFileList = glob.glob(keyValTuple[1])
+ modelFileList.sort()
+
+ # Remove the filenamePattern from the dict since it is no longer used
+ configData.pop('filenamePattern')
+
+ models = []
+ for modelFile in modelFileList:
+ # use getModelTimes(modelFile,timeVarName) to generate the modelTimeStep and time list
+ _ , configData['timeStep'] = process.getModelTimes(modelFile, configData['timeVariable'])
+ configData['filename'] = modelFile
+ model = Model(**configData)
+ models.append(model)
+
+ return models
+
+def generateSettings(config):
+ """
+ Helper function to decouple the argument parsing from the Settings object creation
+
+ Input::
+ config - list of ('key', 'value') tuples.
+ workdir - string i.e. '/nas/run/rcmet/work/'
+ cachedir - string i.e. '/tmp/rcmet/cache/'
+ Output::
+ JobProperties - JobProperties Object
+ """
+ # Setup the config Data Dictionary to make parsing easier later
+ configData = {}
+ for entry in config:
+ configData[entry[0]] = entry[1]
+
+ return JobProperties(**configData)
+
+def makeDatasetsDictionary(rcmedConfig):
+ """
+ Helper function to decouple the argument parsing from the RCMEDDataset object creation
+
+ Input::
+ rcmedConfig - list of ('key', 'value') tuples.
+ obsDatasetId=3,10
+ obsParamId=36,32
+ obsTimeStep=monthly,monthly
+
+ Output::
+ datasetDict - Dictionary with dataset metadata
+ # Setup the config Data Dictionary to make parsing easier later
+ """
+ delimiter = ','
+ configData = {}
+ for entry in rcmedConfig:
+ if delimiter in entry[1]:
+ # print 'delim found - %s' % entry[1]
+ valueList = entry[1].split(delimiter)
+ configData[entry[0]] = valueList
+ else:
+ configData[entry[0]] = entry[1:]
+
+ return configData
+
+def tempGetYears():
+ startYear = int(raw_input('Enter start year YYYY \n'))
+ endYear = int(raw_input('Enter end year YYYY \n'))
+ # CGOODALE - Updating the Static endTime to be 31-DEC
+ startTime = datetime.datetime(startYear, 1, 1, 0, 0)
+ endTime = datetime.datetime(endYear, 12, 31, 0, 0)
+ return (startTime, endTime)
+
+
+def runUsingConfig(argsConfig):
+ """
+ This function is called when a user provides a configuration file to specify an evaluation job.
+
+ Input::
+ argsConfig - Path to a ConfigParser compliant file
+
+ Output::
+ Plots that visualize the evaluation job. These will be output to SETTINGS.workDir from the config file
+ """
+
+ print 'Running using config file: %s' % argsConfig
+ # Parse the Config file
+ userConfig = ConfigParser.SafeConfigParser()
+ userConfig.optionxform = str # This is so the case is preserved on the items in the config file
+ userConfig.read(argsConfig)
+
+ try:
+ checkConfigSettings(userConfig)
+ except:
+ raise
+
+ jobProperties = generateSettings(userConfig.items('SETTINGS'))
+ workdir = jobProperties.workDir
+
+ try:
+ gridBox = GridBox(jobProperties.latMin, jobProperties.lonMin, jobProperties.latMax,
+ jobProperties.lonMax, jobProperties.gridLonStep, jobProperties.gridLatStep)
+ except:
+ gridBox = None
+
+ models = generateModels(userConfig.items('MODEL'))
+
+ # 5/28/2013, JK: The RCMED block has been modified to accommodate ref data input from users' local disk
+
+ datasetDict = makeDatasetsDictionary(userConfig.items('RCMED'))
+
+
+ # Go get the parameter listing from the database
+ try:
+ params = db.get_parameters_metadata()
+ except:
+ raise
+
+ obsDatasetList = []
+ obsList = []
+ obsVarName = datasetDict['obsVarName'][0]
+ obsTimeName = datasetDict['obsTimeVar'][0]
+ obsLonName = datasetDict['obsLonVar'][0]
+ obsLatName = datasetDict['obsLatVar'][0]
+ obsTimestep = []
+ obsSource = int(datasetDict['obsSource'][0])
+ #print 'Obs datasetDict'
+ #print datasetDict
+
+ if obsSource < 0: # no obs data to be processed
+ obsVarName = []
+ obsTimeName = []
+ obsLonName = []
+ obsLatName = []
+ elif obsSource == 0: # input from RCMED
+ for param_id in datasetDict['obsParamId']:
+ for param in params:
+ if int(param['parameter_id']) == int(param_id):
+ obsDatasetList.append(param)
+ else:
+ pass
+ elif obsSource == 1: # input from local disk
+ for param in datasetDict['obsInputFile']:
+ obsDatasetList.append(param)
+ for param in datasetDict['obsFileName']:
+ obsList.append(param)
+ for param in datasetDict['obsDltaTime']:
+ obsTimestep.append(param)
+ #print obsSource,obsDatasetList,obsList,obsTimeName,obsTimestep
+
+ #TODO: Unhardcode this when we decided where this belongs in the Config File
+ jobProperties.maskOption = True
+ # User must provide startTime and endTime if not defined
+ if jobProperties.startDate == None or jobProperties.endDate == None:
+ jobProperties.startDate,jobProperties.endDate = misc.userDefinedStartEndTimes(obsSource,obsList,obsTimeName,obsDatasetList,models)
+
+ numOBS,numMDL,nT,ngrdY,ngrdX,Times,lons,lats,obsData,mdlData,obsName,mdlName,varType = do_data_prep.prep_data \
+ (jobProperties,obsSource,obsDatasetList,obsList,obsVarName,obsLonName,obsLatName,obsTimeName,obsTimestep,gridBox,models)
+
+ # 6/3/2013: Combine the regridded reference and model datasets. The packing order is:
+ # First pack all ref (obs) data with the ref enseble in the end (if exists).
+ # Then pack all model data with the model ensemble in the end (if exists)
+ # Release 'obsData' and 'mdlData' after their values are transferred to 'allData'
+ print 'Input and regridding of both obs and model data are completed. Combine the obs and model data'
+ numDatasets = numOBS + numMDL
+ allData = ma.zeros((numDatasets, nT, ngrdY, ngrdX))
+ if (numOBS>0) & (numMDL>0):
+ dataName = obsName + mdlName
+ allData[0:numOBS, :, :, :] = obsData[0:numOBS, :, :, :]
+ allData[numOBS:numDatasets, :, :, :] = mdlData[0:numMDL, :, :, :]
+ obsData = 0.
+ mdlData = 0.
+ elif numOBS==0:
+ dataName = mdlName
+ allData = mdlData
+ mdlData = 0.
+ else:
+ dataName = obsName
+ allData = obsData
+ obsData = 0
+ print ''
+ print 'dataName: ',dataName,' shape of all data= ',allData.shape
+
+ ##################################################################################
+ # calculate metrics and make plots using the regridded reference and model data. #
+ ##################################################################################
+ print 'Data preparation is completed; now move to metrics calculations'
+
+ try:
+ subRegionConfig = misc.configToDict(userConfig.items('SUB_REGION'))
+ subRegions = misc.parseSubRegions(subRegionConfig)
+ # REORDER SUBREGION OBJECTS until we standardize on Python 2.7
+ # TODO Remove once Python 2.7 support is finalized
+ if subRegions:
+ subRegions.sort(key=lambda x:x.name)
+
+ except ConfigParser.NoSectionError:
+
+ counts = {'observations': numOBS,
+ 'models' : numMDL,
+ 'times' : nT}
+ subRegions = misc.getSubRegionsInteractively(counts, workdir)
+
+ if len(subRegions) == 0:
+ print 'Processing without SubRegion support'
+
+
+ # TODO: New function Call
+ timeRegridOption = jobProperties.temporalGrid
+ fileOutputOption = jobProperties.writeOutFile
+ modelVarName = models[0].varName
+ metrics.metrics_plots(modelVarName, numOBS, numMDL, nT, ngrdY, ngrdX, Times, lons, lats, allData, dataName, workdir, subRegions, \
+ timeRegridOption, fileOutputOption, varType)
+
+
+if __name__ == "__main__":
+
+ if args.CONFIG:
+
+ runUsingConfig(args.CONFIG)
+
+ else:
+ print 'Interactive mode has been enabled'
+ ui.rcmetUI()
+
+ #rcmet_cordexAF()
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/.svn/all-wcprops b/src/main/python/rcmes/resources/.svn/all-wcprops
new file mode 100755
index 0000000..b1b775d
--- /dev/null
+++ b/src/main/python/rcmes/resources/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 89
+/repos/asf/!svn/ver/1479720/incubator/climate/trunk/rcmet/src/main/python/rcmes/resources
+END
+cordexSubRegions.txt
+K 25
+svn:wc:ra_dav:version-url
+V 110
+/repos/asf/!svn/ver/1476460/incubator/climate/trunk/rcmet/src/main/python/rcmes/resources/cordexSubRegions.txt
+END
+cordexAF.cfg
+K 25
+svn:wc:ra_dav:version-url
+V 102
+/repos/asf/!svn/ver/1479720/incubator/climate/trunk/rcmet/src/main/python/rcmes/resources/cordexAF.cfg
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/.svn/entries
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/.svn/entries b/src/main/python/rcmes/resources/.svn/entries
new file mode 100755
index 0000000..71a5233
--- /dev/null
+++ b/src/main/python/rcmes/resources/.svn/entries
@@ -0,0 +1,99 @@
+10
+
+dir
+1485921
+https://svn.apache.org/repos/asf/incubator/climate/trunk/rcmet/src/main/python/rcmes/resources
+https://svn.apache.org/repos/asf
+
+
+
+2013-05-06T23:24:37.933090Z
+1479720
+huikyole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13f79535-47bb-0310-9956-ffa450edef68
+
+cordexSubRegions.txt
+file
+
+
+
+
+2013-05-24T10:13:50.000000Z
+b2e732c6fd18365a4a2ffdff8cde539c
+2013-01-25T19:56:01.681818Z
+1474794
+mjjoyce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+928
+
+watersheds
+dir
+
+cordexAF.cfg
+file
+
+
+
+
+2013-05-24T10:13:50.000000Z
+914367b5c8e85cb405f1c5c548110445
+2013-05-06T23:24:37.933090Z
+1479720
+huikyole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+956
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/.svn/text-base/cordexAF.cfg.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/.svn/text-base/cordexAF.cfg.svn-base b/src/main/python/rcmes/resources/.svn/text-base/cordexAF.cfg.svn-base
new file mode 100755
index 0000000..77ee0d5
--- /dev/null
+++ b/src/main/python/rcmes/resources/.svn/text-base/cordexAF.cfg.svn-base
@@ -0,0 +1,30 @@
+[SETTINGS]
+workDir=/home/huikyole/work/RCMES/cases/cordex-af
+cacheDir=/nas/share4-cf/huikyole/RCMES_cache
+# Choices: full, annual, monthly, daily
+temporalGrid=monthly
+# Choices, obs, model, user
+spatialGrid=model
+gridLonStep=0.44 ; only use with user spatialGrid
+gridLatStep=0.44 ; only use with user spatialGrid
+latMin=-45.76 ; only use with user spatialGrid
+latMax=42.24 ; only use with user spatialGrid
+lonMin=-24.64 ; only use with user spatialGrid
+lonMax=60.28 ; only use with user spatialGrid
+# Choices: False, NetCDF
+outputFile=NetCDF
+[MODEL]
+filenamePattern=/nas/share4-cf/jinwonki/data/cordex-af/*pr.nc
+latVariable=lat
+lonVariable=lon
+timeVariable=time
+varName=pr
+precipFlag=True ; This is just used to support an unknown UNITS in precip data
+
+[RCMED]
+obsParamId=36 ; pcp and pr
+obsTimeStep=monthly ; WITH THE PARAMETER SERVICE THIS WILL GO AWAY
+
+[SUB_REGION]
+# Sub Region(s) Full File Path
+subRegionFile=../rcmes/resources/cordexSubRegions.txt
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/.svn/text-base/cordexSubRegions.txt.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/.svn/text-base/cordexSubRegions.txt.svn-base b/src/main/python/rcmes/resources/.svn/text-base/cordexSubRegions.txt.svn-base
new file mode 100755
index 0000000..c4dc220
--- /dev/null
+++ b/src/main/python/rcmes/resources/.svn/text-base/cordexSubRegions.txt.svn-base
@@ -0,0 +1,25 @@
+[REGIONS]
+# RegionXX:["region Label", north, south, east, west] >>> Region00:["Region Zero", 30.1, 10.54, 92.1332, -10.7 ]
+#TestRegion:["TEST", 27, 25, 15, 12]
+Region01:["R01", 36.5, 29, 0.0, -10]
+Region02:["R02", 37.5, 29, 10, 0]
+Region03:["R03", 32.5, 25, 20, 10]
+Region04:["R04", 32.5, 25, 33, 20]
+Region05:["R05", 20.0, 12, -10.2, -19.3]
+Region06:["R06", 25.0, 15.0, 30, 15]
+Region07:["R07", 15, 7.3, 10, -10]
+Region08:["R08", 7.3, 5.0, 10, -10]
+Region09:["R09", 15, 6.9, 40, 33.9]
+Region10:["R10", 11.8, 2.2, 51.8, 44.2]
+Region11:["R11", 10, 0, 25, 10]
+Region12:["R12", 0, -10, 25, 10]
+Region13:["R13", 0, -15, 40, 30]
+Region14:["R14", -21.4, -27.9, 20, 13.6]
+Region15:["R15", -27.9, -35, 20, 13.6]
+Region16:["R16", -21.4, -35, 35.7, 20]
+Region17:["R17", -11.7, -25.8, 50.3, 43.2]
+Region18:["R18", 35.0, 25, 40, 33]
+Region19:["R19", 35, 28, 50, 45]
+Region20:["R20", 20.0, 13, 50, 43]
+Region21:["R21", 27.5, 20, 58, 50]
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/cordexAF.cfg
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/cordexAF.cfg b/src/main/python/rcmes/resources/cordexAF.cfg
new file mode 100755
index 0000000..b26d279
--- /dev/null
+++ b/src/main/python/rcmes/resources/cordexAF.cfg
@@ -0,0 +1,55 @@
+# The configure file for the Indian subdomain of the CORDEX-Asia domain
+[SETTINGS]
+workDir=/Volumes/rcmes2t/rcmet/cases/cordex-af/work
+cacheDir=/Volumes/rcmes2t/rcmet/cases/cordex-af/cache
+# temporalGrid assigns the data time step to be temporally regridded: Choices = full (entire period), annual, monthly, daily
+temporalGrid=monthly
+# Choices, obs, model, user
+# gridLonStep, gridLatStep, latMin, latMax, lonMin, lonMax are used only with 'user' spatial grid option
+spatialGrid=user
+gridLonStep=0.44
+gridLatStep=0.44
+latMin=-45.76
+latMax=42.24
+lonMin=-24.64
+lonMax=60.28
+# Choices: False, NetCDF
+outputFile=False
+# variableType (reference units): 'precipitation' (mm/day); 'temperature' (K); 'cloudiness' (%), 'radiation' (W/m^2);
+# 'evaporation' (mm/day); 'runoff' (mm/day); 'SMC' (fraction)'; 'SWE' (mm); 'heatFlux' (W/m2)
+variableType=precipitation
+
+[MODEL]
+# The model data file(s) to be evaluated is(are) assinged here. Note that the current convention is for easy handling of
+# multiple model datasets from coordinated experiments such as CORDEX that tend to assign a data file with a name that
+# follows pre-determined convention (a combination of model name, institution, variable name, experiment name, etc.).
+# In case only one model is evaluated, a user can specify the full file name for 'filenamePattern'
+#filenamePattern = none # option currently not working; 2b added for obs-only processing
+filenamePattern=/Volumes/rcmes2t/rcmet/cases/cordex-af/mdlData/mon/*pr.nc
+latVariable=lat
+lonVariable=lon
+timeVariable=time
+varName=pr
+
+[RCMED]
+# obsParamId designates the reference data file. see http://rcmes.jpl.nasa.gov/rcmed/parameters
+# for multiple ref datasets, provide the id separated by ',' (e.g., 36,37 for TRMM and CRU3.1).
+# obsSource specifies the source of the reference data: 0 = RCMED, 1 = user's local disk, -9 = no obs data
+# For obsSource == 1, obsInputFile, the file that provides the list of users' own reference data
+# also a user have to provide obsVarName, obsTimeVar, obsLonVar, and obsLatVar as specified in the data files
+obsSource = 0
+obsInputFile = /nas/share1-hp/jinwonki/data/rean/narr/day_narccap_domain/NARR_prec.nc,/nas/share1-hp/jinwonki/data/obs/cpc/netcdf/cpc_1979_present.nc
+obsVarName = pr,pr
+obsFileName = NARR,CPC
+obsDltaTime = daily,daily
+obsTimeVar = time,time
+obsLonVar = lon,longitude
+obsLatVar = lat,latitude
+# if obsSource = 0, the lines from 'obsSource' to 'obsLatVar' above are inactive
+# 36= TRMM monthly, 37= CRU3.1 monthly, 72= UDEL monthly; 74= GPCP2.2 monthly; 81=GPCC
+obsParamId=37,72,81,36,74
+obsTimeStep=monthly,monthly,monthly,monthly,monthly ; WITH THE PARAMETER SERVICE THIS WILL GO AWAY
+
+[SUB_REGION]
+# Sub Region(s) Full File Path
+subRegionFile=/Volumes/rcmes2t/rcmet/cases/cordex-af/work/inputs/subRgns.AF
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/cordexIndia.cfg
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/cordexIndia.cfg b/src/main/python/rcmes/resources/cordexIndia.cfg
new file mode 100755
index 0000000..d63beaf
--- /dev/null
+++ b/src/main/python/rcmes/resources/cordexIndia.cfg
@@ -0,0 +1,56 @@
+# The configure file for the Indian subdomain of the CORDEX-Asia domain
+[SETTINGS]
+workDir=/Volumes/rcmes2t/rcmet/cases/cordex-sa/work
+cacheDir=/Volumes/rcmes2t/rcmet/cases/cordex-sa/cache
+# temporalGrid assigns the data time step to be temporally regridded: Choices = full (entire period), annual, monthly, daily
+temporalGrid=monthly
+# Choices, obs, model, user
+# gridLonStep, gridLatStep, latMin, latMax, lonMin, lonMax are used only with 'user' spatial grid option
+spatialGrid=user
+gridLonStep=0.5
+gridLatStep=0.5
+latMin=5.
+latMax=40.
+lonMin=60.
+lonMax=100.
+# Choices: False, NetCDF
+outputFile=False
+# variableType (reference units): 'precipitation' (mm/day); 'temperature' (K); 'cloudiness' (%), 'radiation' (W/m^2);
+# 'evaporation' (mm/day); 'runoff' (mm/day); 'SMC' (fraction)'; 'SWE' (mm); 'heatFlux' (W/m2)
+variableType=precipitation
+
+[MODEL]
+# The model data file(s) to be evaluated is(are) assinged here. Note that the current convention is for easy handling of
+# multiple model datasets from coordinated experiments such as CORDEX that tend to assign a data file with a name that
+# follows pre-determined convention (a combination of model name, institution, variable name, experiment name, etc.).
+# In case only one model is evaluated, a user can specify the full file name for 'filenamePattern'
+#filenamePattern = none # option currently not working; 2b added for obs-only processing
+filenamePattern=/Volumes/rcmes2t/rcmet/cases/cordex-sa/mdlData/mon/pr*.nc
+latVariable=lat
+lonVariable=lon
+timeVariable=time
+varName=pr
+
+[RCMED]
+# obsParamId designates the reference data file. see http://rcmes.jpl.nasa.gov/rcmed/parameters
+# for multiple ref datasets, provide the id separated by ',' (e.g., 36,37 for TRMM and CRU3.1).
+# obsSource specifies the source of the reference data: 0 = RCMED, 1 = user's local disk, -9 = no obs data
+# For obsSource == 1, obsInputFile, the file that provides the list of users' own reference data
+# also a user have to provide obsVarName, obsTimeVar, obsLonVar, and obsLatVar as specified in the data files
+obsSource = 0
+obsInputFile = /nas/share1-hp/jinwonki/data/rean/narr/day_narccap_domain/NARR_prec.nc,/nas/share1-hp/jinwonki/data/obs/cpc/netcdf/cpc_1979_present.nc
+obsVarName = pr,pr
+obsFileName = NARR,CPC
+obsDltaTime = daily,daily
+obsTimeVar = time,time
+obsLonVar = lon,longitude
+obsLatVar = lat,latitude
+# if obsSource = 0, the lines from 'obsSource' to 'obsLatVar' above are inactive
+# 36= TRMM monthly, 37= CRU3.1 monthly, 72= UDEL monthly; 74= GPCP2.2 monthly; 80= aphr1101
+obsParamId=37,80,81,36,74
+obsTimeStep=monthly,monthly,monthly,monthly ; WITH THE PARAMETER SERVICE THIS WILL GO AWAY
+
+[SUB_REGION]
+# Sub Region(s) Full File Path
+#subRegionFile=/nas/share3-wf/jinwonki/rcmet/cases/cordex-sa/work/inputs/subRgnsSA.India
+subRegionFile=/Volumes/rcmes2t/rcmet/cases/cordex-sa/work/inputs/subRgnsSA.India
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/resources/narccap.cfg
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/resources/narccap.cfg b/src/main/python/rcmes/resources/narccap.cfg
new file mode 100755
index 0000000..f0f3b50
--- /dev/null
+++ b/src/main/python/rcmes/resources/narccap.cfg
@@ -0,0 +1,55 @@
+[SETTINGS]
+workDir=/Volumes/rcmes2t/rcmet/cases/narccap/work
+cacheDir=/Volumes/rcmes2t/rcmet/cases/narccap/cache
+# temporalGrid assigns the data time step to be temporally regridded: Choices = full (entire period), annual, monthly, daily
+temporalGrid=monthly
+# Choices, obs, model, user
+# gridLonStep, gridLatStep, latMin, latMax, lonMin, lonMax are used only with 'user' spatial grid option
+spatialGrid=user
+gridLonStep=0.5
+gridLatStep=0.5
+latMin=23.75 ; for NARCCAP-ConterminousUS / WUS
+latMax=49.75 ; for NARCCAP-ConterminousUS / WUS
+lonMin=-125.75 ; for NARCCAP-ConterminousUS / WUS
+lonMax=-66.75 ; for NARCCAP-Conterminous US
+#lonMax=-100.75 ; for NARCCAP-WUS.
+# Choices: False, NetCDF
+outputFile=NetCDF
+# variableType (reference units): 'precipitation' (mm/day); 'temperature' (K); 'cloudiness' (%), 'radiation' (W/m^2);
+# 'evaporation' (mm/day); 'runoff' (mm/day); 'SMC' (fraction)'; 'SWE' (mm); 'heatFlux' (W/m2)
+variableType=precipitation
+
+[MODEL]
+# The model data file(s) to be evaluated is(are) assinged here. Note that the current convention is for easy handling of
+# multiple model datasets from coordinated experiments such as CORDEX that tend to assign a data file with a name that
+# follows pre-determined convention (a combination of model name, institution, variable name, experiment name, etc.).
+# In case only one model is evaluated, a user can specify the full file name for 'filenamePattern'
+#filenamePattern = none # option currently not working; 2b added for obs-only processing
+filenamePattern=/Volumes/rcmes2t/rcmet/cases/narccap/mdlData/mon/prec*.nc
+latVariable=lat
+lonVariable=lon
+timeVariable=time
+varName=prec
+#variableType=precipitation
+
+[RCMED]
+# obsParamId designates the reference data file. see http://rcmes.jpl.nasa.gov/rcmed/parameters
+# for multiple ref datasets, provide the id separated by ',' (e.g., 36,37 for TRMM and CRU3.1).
+# obsSource specifies the source of the reference data: 0 = RCMED, 1 = user's local disk, -9 = no obs data
+# For obsSource == 1, obsInputFile, the file that provides the list of users' own reference data
+obsSource = 0
+obsInputFile = /nas/share1-hp/jinwonki/data/rean/narr/day_narccap_domain/NARR_prec.nc,/nas/share1-hp/jinwonki/data/obs/cpc/netcdf/cpc_1979_present.nc
+obsVarName = pr,pr
+obsFileName = NARR,CPC
+obsDltaTime = daily,daily
+obsTimeVar = time,time
+obsLonVar = lon,longitude
+obsLatVar = lat,latitude
+# if obsSource = 0, the lines from 'obsSource' to 'obsLatVar' above are inactive
+#obsParamId=37,72,81,36,74
+obsParamId=37,36
+obsTimeStep=monthly,monthly,monthly,monthly,monthly ; WITH THE PARAMETER SERVICE THIS WILL GO AWAY
+
+[SUB_REGION]
+# Sub Region(s) Full File Path
+subRegionFile=/Volumes/rcmes2t/rcmet/cases/narccap/work/inputs/subRgnsNARCCAP.US
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/all-wcprops b/src/main/python/rcmes/services/.svn/all-wcprops
new file mode 100755
index 0000000..3cd9eb6
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/all-wcprops
@@ -0,0 +1,71 @@
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/repos/asf/!svn/ver/1482547/incubator/climate/trunk/rcmet/src/main/python/rcmes/services
+END
+run_rcmes_processing.py
+K 25
+svn:wc:ra_dav:version-url
+V 112
+/repos/asf/!svn/ver/1480068/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/run_rcmes_processing.py
+END
+list_vars_in_file.py
+K 25
+svn:wc:ra_dav:version-url
+V 109
+/repos/asf/!svn/ver/1480068/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/list_vars_in_file.py
+END
+main_ws.py
+K 25
+svn:wc:ra_dav:version-url
+V 99
+/repos/asf/!svn/ver/1480068/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/main_ws.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 100
+/repos/asf/!svn/ver/1476460/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/__init__.py
+END
+bottlemet.py
+K 25
+svn:wc:ra_dav:version-url
+V 101
+/repos/asf/!svn/ver/1476460/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/bottlemet.py
+END
+find_latlon_var.py
+K 25
+svn:wc:ra_dav:version-url
+V 107
+/repos/asf/!svn/ver/1480068/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/find_latlon_var.py
+END
+README.txt
+K 25
+svn:wc:ra_dav:version-url
+V 99
+/repos/asf/!svn/ver/1476460/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/README.txt
+END
+decode_model_times.py
+K 25
+svn:wc:ra_dav:version-url
+V 110
+/repos/asf/!svn/ver/1476460/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/decode_model_times.py
+END
+directory_helpers.py
+K 25
+svn:wc:ra_dav:version-url
+V 109
+/repos/asf/!svn/ver/1482547/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/directory_helpers.py
+END
+find_time_var.py
+K 25
+svn:wc:ra_dav:version-url
+V 105
+/repos/asf/!svn/ver/1480068/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/find_time_var.py
+END
+dataset_helpers.py
+K 25
+svn:wc:ra_dav:version-url
+V 107
+/repos/asf/!svn/ver/1480068/incubator/climate/trunk/rcmet/src/main/python/rcmes/services/dataset_helpers.py
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/entries
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/entries b/src/main/python/rcmes/services/.svn/entries
new file mode 100755
index 0000000..b34041c
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/entries
@@ -0,0 +1,402 @@
+10
+
+dir
+1485921
+https://svn.apache.org/repos/asf/incubator/climate/trunk/rcmet/src/main/python/rcmes/services
+https://svn.apache.org/repos/asf
+
+
+
+2013-05-14T20:07:57.184268Z
+1482547
+joyce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13f79535-47bb-0310-9956-ffa450edef68
+
+run_rcmes_processing.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+b72b173d9a8423c2ecc3ff915009717f
+2013-05-07T20:50:17.582309Z
+1480068
+joyce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4914
+
+list_vars_in_file.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+2a2cd6269710cf6136c3b026713a63fb
+2013-05-07T20:50:17.582309Z
+1480068
+joyce
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1548
+
+main_ws.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+f6aaf93ae28329a6a6c75d074ce69bf5
+2013-05-07T20:50:17.582309Z
+1480068
+joyce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+889
+
+__init__.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+5c7b875cde03a6b682cc84a7858fd5dc
+2012-08-16T14:19:38.500472Z
+1473885
+cgoodale
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+132
+
+bottlemet.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+6f5737a819d82d8c0cd574d6195acdbf
+2013-02-20T17:07:53.256865Z
+1474978
+cgoodale
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21280
+
+find_latlon_var.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+aa30bfb54cacbfb99ac263ae42ab32da
+2013-05-07T20:50:17.582309Z
+1480068
+joyce
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4154
+
+README.txt
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+dcf5694caba89c7989ff1e86fd9ea14b
+2012-08-14T20:33:03.986567Z
+1473860
+pramirez
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1854
+
+decode_model_times.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+52b776bfd8845a4830659cb09779af9b
+2013-03-05T16:19:20.432667Z
+1475039
+mjjoyce
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4817
+
+directory_helpers.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+22a41a483c4a806e3ef7dd8c17364e2e
+2013-05-14T20:07:57.184268Z
+1482547
+joyce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1260
+
+find_time_var.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+addf1ca2427854ece4e5cbdaf1920e3b
+2013-05-07T20:50:17.582309Z
+1480068
+joyce
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2882
+
+dataset_helpers.py
+file
+
+
+
+
+2013-05-24T10:13:49.000000Z
+69f9dd2f04b3b8e171e9b5593c076203
+2013-05-07T20:50:17.582309Z
+1480068
+joyce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+834
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/prop-base/__init__.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/prop-base/__init__.py.svn-base b/src/main/python/rcmes/services/.svn/prop-base/__init__.py.svn-base
new file mode 100755
index 0000000..614166f
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/prop-base/__init__.py.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 11
+Id Revision
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/prop-base/decode_model_times.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/prop-base/decode_model_times.py.svn-base b/src/main/python/rcmes/services/.svn/prop-base/decode_model_times.py.svn-base
new file mode 100755
index 0000000..869ac71
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/prop-base/decode_model_times.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/prop-base/find_latlon_var.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/prop-base/find_latlon_var.py.svn-base b/src/main/python/rcmes/services/.svn/prop-base/find_latlon_var.py.svn-base
new file mode 100755
index 0000000..869ac71
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/prop-base/find_latlon_var.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/prop-base/find_time_var.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/prop-base/find_time_var.py.svn-base b/src/main/python/rcmes/services/.svn/prop-base/find_time_var.py.svn-base
new file mode 100755
index 0000000..869ac71
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/prop-base/find_time_var.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/prop-base/list_vars_in_file.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/prop-base/list_vars_in_file.py.svn-base b/src/main/python/rcmes/services/.svn/prop-base/list_vars_in_file.py.svn-base
new file mode 100755
index 0000000..869ac71
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/prop-base/list_vars_in_file.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/README.txt.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/README.txt.svn-base b/src/main/python/rcmes/services/.svn/text-base/README.txt.svn-base
new file mode 100755
index 0000000..27622ab
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/README.txt.svn-base
@@ -0,0 +1,68 @@
+RCMET Client API Web Service README
+===========================================================
+
+Prerequisites:
+
+ * Python 2.6+ with easy_install
+ * Bottle (http://bottlepy.org) Web Framework
+
+Usage:
+
+ ./python main_ws.py
+
+
+Hints:
+
+ Changing the port Bottle runs on
+ --------------------------------
+ The port Bottle starts up on can be changed by editing
+ the last line in the ./main_ws.py file as follows:
+
+ if __name__ == "__main__":
+ run(host='localhost', port=*NEWPORT*)
+
+
+API Documentation:
+=================================================================
+
+Extract Model File Variables
+--------------------------------
+http://<webserviceUrl>/list/vars/"<PATH>"
+
+ INPUTS:
+ PATH: the fully qualified path to the model file to use. Note
+ that the path must be enclosed in double quotes.
+
+ RETURN:
+ SUCCESS: {"variables": ["tas", "level", "lon", "time", "lat"]}
+ FAILURE: [] <-- should probably be {}
+
+
+Extract Model Latitude and Longitude Variables and Bounds
+---------------------------------------------------------
+http://<webserviceUrl>/list/latlon/"<PATH>"
+
+ INPUTS:
+ PATH: the fully qualified path to the model file to use. Note
+ that the path must be enclosed in double quotes.
+
+ RETURN:
+ SUCCESS: {"latMax": "42.24", "success": 1, "latname": "lat",
+ "lonMax": "60.28", "lonMin": "-24.64",
+ "lonname": "lon", "latMin": "-45.76"}
+ FAILURE: ?
+
+
+Extract Model Time Variable and Bounds
+--------------------------------------
+http://<webserviceUrl>/list/time/"<PATH>"
+
+ INPUTS:
+ PATH: the fully qualified path to the model file to use. Note
+ that the path must be enclosed in double quotes.
+
+ RETURN:
+ SUCCESS: {"start_time": "1989-01-15 00:00:00",
+ "timename": "time", "success": 1,
+ "end_time": "2008-12-15 00:00:00"}
+ FAILURE: ?
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/__init__.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/__init__.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/__init__.py.svn-base
new file mode 100755
index 0000000..9a00597
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/__init__.py.svn-base
@@ -0,0 +1,2 @@
+"""The Services Package is a collection of RESTful Web Service modules that can
+be used to create custom User Interfaces to RCMES"""
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/bottlemet.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/bottlemet.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/bottlemet.py.svn-base
new file mode 100755
index 0000000..0bcefb8
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/bottlemet.py.svn-base
@@ -0,0 +1,599 @@
+'''
+ 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)
+
+
+
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/dataset_helpers.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/dataset_helpers.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/dataset_helpers.py.svn-base
new file mode 100755
index 0000000..2031caf
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/dataset_helpers.py.svn-base
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+"""
+ Provides Bottle services for interacting with RCMED
+"""
+
+from bottle import request, route
+
+import requests
+import Nio
+
+@route('/getObsDatasets')
+def getObservationDatasetData():
+ r = requests.get('http://rcmes.jpl.nasa.gov/query-api/datasets.php')
+
+ # Handle JSONP requests
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, r.text)
+ # Otherwise, just return JSON
+ else:
+ return r.text
+
+@route('/getDatasetParam')
+def getDatasetParameters():
+ url = 'http://rcmes.jpl.nasa.gov/query-api/parameters.php?dataset=' + request.query.dataset
+ r = requests.get(url)
+
+ # Handle JSONP requests
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, r.text)
+ # Otherwise, just return JSON
+ else:
+ return r.text
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/decode_model_times.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/decode_model_times.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/decode_model_times.py.svn-base
new file mode 100755
index 0000000..ae7974d
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/decode_model_times.py.svn-base
@@ -0,0 +1,185 @@
+#!/usr/local/bin/python
+"""Module to simplify handling of model times """
+def decodeTimeFromString(time_string):
+ '''
+ # Decodes string into a python datetime object
+ # Method: tries a bunch of different time format possibilities and hopefully one of them will hit.
+ #
+ # Input: time_string - a string that represents a date/time
+ # Output: mytime - a python datetime object
+ #
+ # Peter Lean February 2011
+ '''
+ import time
+ import datetime
+
+ try:
+ mytime = time.strptime(time_string, '%Y-%m-%d %H:%M:%S')
+ mytime = datetime.datetime(*mytime[0:6])
+ return mytime
+
+ except ValueError:
+ pass
+
+ try:
+ mytime = time.strptime(time_string, '%Y/%m/%d %H:%M:%S')
+ mytime = datetime.datetime(*mytime[0:6])
+ return mytime
+
+ except ValueError:
+ pass
+
+ try:
+ mytime = time.strptime(time_string, '%Y%m%d %H:%M:%S')
+ mytime = datetime.datetime(*mytime[0:6])
+ return mytime
+
+ except ValueError:
+ pass
+
+ try:
+ mytime = time.strptime(time_string, '%Y:%m:%d %H:%M:%S')
+ mytime = datetime.datetime(*mytime[0:6])
+ return mytime
+
+ except ValueError:
+ pass
+
+ try:
+ mytime = time.strptime(time_string, '%Y%m%d%H%M%S')
+ mytime = datetime.datetime(*mytime[0:6])
+ return mytime
+
+ except ValueError:
+ pass
+
+ try:
+ mytime = time.strptime(time_string, '%Y-%m-%d %H:%M')
+ mytime = datetime.datetime(*mytime[0:6])
+ return mytime
+
+ except ValueError:
+ pass
+
+
+ print 'Error decoding time string: string does not match a predefined time format'
+ return 0
+
+
+
+def decode_model_times(filelist,timeVarName):
+ '''
+ # Routine to convert from model times ('hours since 1900...', 'days since ...')
+ # into a python datetime structure
+ #
+ # Input:
+ # filelist - list of model files
+ # timeVarName - name of the time variable in the model files
+ #
+ # Output:
+ # times - list of python datetime objects describing model data times
+ #
+ #
+ # Peter Lean February 2011
+ #
+ '''
+ import datetime
+ import re
+ import string
+ import math
+ import numpy
+ import Nio
+
+ f = Nio.open_file(filelist[0])
+ xtimes = f.variables[timeVarName]
+ timeFormat = xtimes.units
+
+ # search to check if 'since' appears in units
+ try:
+ sinceLoc = re.search('since',timeFormat).end()
+
+ except:
+ print 'Error decoding model times: time variable attributes do not contain "since"'
+ return 0
+
+ # search for 'seconds','minutes','hours', 'days', 'months', 'years' so know units
+ units = ''
+ try:
+ mysearch = re.search('minutes',timeFormat).end()
+ units = 'minutes'
+ except:
+ pass
+ try:
+ mysearch = re.search('hours',timeFormat).end()
+ units = 'hours'
+ except:
+ pass
+ try:
+ mysearch = re.search('days',timeFormat).end()
+ units = 'days'
+ except:
+ pass
+ try:
+ mysearch = re.search('months',timeFormat).end()
+ units = 'months'
+ except:
+ pass
+ try:
+ mysearch = re.search('years',timeFormat).end()
+ units = 'years'
+ except:
+ pass
+
+ # cut out base time (the bit following 'since')
+ base_time_string = string.lstrip(timeFormat[sinceLoc:])
+
+ # decode base time
+ base_time = decodeTimeFromString(base_time_string)
+
+
+ times=[]
+ for xtime in xtimes[:]:
+ if(units=='minutes'):
+ dt = datetime.timedelta(minutes=xtime)
+ new_time = base_time + dt
+
+ if(units=='hours'):
+ dt = datetime.timedelta(hours=xtime)
+ new_time = base_time + dt
+
+ if(units=='days'):
+ dt = datetime.timedelta(days=xtime)
+ new_time = base_time + dt
+
+ if(units=='months'): # NB. adding months in python is complicated as month length varies and hence ambigous.
+ # Perform date arithmatic manually
+ # Assumption: the base_date will usually be the first of the month
+ # NB. this method will fail if the base time is on the 29th or higher day of month
+ # -as can't have, e.g. Feb 31st.
+ new_month = int(base_time.month + xtime % 12)
+ new_year = int(math.floor(base_time.year + xtime / 12.))
+ new_time = datetime.datetime(new_year,new_month,base_time.day,base_time.hour,base_time.second,0)
+
+ if(units=='years'):
+ dt = datetime.timedelta(years=xtime)
+ new_time = base_time + dt
+
+ times.append(new_time)
+
+ return times
+
+
+''' NOT USED BY BOTTLE WS CALLS
+import sys
+import datetime
+filename = [sys.argv[1]]
+time_var_name = sys.argv[2]
+
+print filename, type(filename)
+print time_var_name
+
+times = decode_model_times(filename,time_var_name)
+
+for time in times:
+ print time.strftime('%Y-%m-%d %H:%M:%S')
+'''
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/directory_helpers.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/directory_helpers.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/directory_helpers.py.svn-base
new file mode 100755
index 0000000..70147c4
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/directory_helpers.py.svn-base
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+"""
+ Provides helpers for listing retrieving directory information from the server.
+"""
+
+from bottle import request, route
+import os
+import json
+
+PATH_LEADER = "/usr/local/rcmes"
+
+@route('/getDirInfo/<dirPath:path>')
+def getDirectoryInfo(dirPath):
+ dirPath = PATH_LEADER + dirPath
+ dirPath = dirPath.replace('/../', '/')
+ dirPath = dirPath.replace('/./', '/')
+
+ if os.path.isdir(dirPath):
+ listing = os.listdir(dirPath)
+ listingNoHidden = [f for f in listing if f[0] != '.']
+ joinedPaths = [os.path.join(dirPath, f) for f in listingNoHidden]
+ joinedPaths = [f + "/" if os.path.isdir(f) else f for f in joinedPaths]
+ finalPaths = [p.replace(PATH_LEADER, '') for p in joinedPaths]
+ sorted(finalPaths, key=lambda s: s.lower())
+ returnJSON = finalPaths
+ else:
+ returnJSON = []
+
+ returnJSON = json.dumps(returnJSON)
+ if request.query.callback:
+ return "%s(%s)" % (request.query.callback, returnJSON)
+ else:
+ return returnJSON
+
+@route('/getPathLeader/')
+def getPathLeader():
+ returnJSON = {"leader": PATH_LEADER}
+
+ if request.query.callback:
+ return "%s(%s)" % (request.query.callback, returnJSON)
+ else:
+ return returnJSON
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/find_latlon_var.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/find_latlon_var.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/find_latlon_var.py.svn-base
new file mode 100755
index 0000000..f46e8d4
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/find_latlon_var.py.svn-base
@@ -0,0 +1,136 @@
+#!/usr/local/bin/python
+"""
+ Small command line utility to find what the latitude and longitude variables are called in a model file.
+
+ Background::
+ Model output files tend not to follow any defined standard in terms of
+ variable naming conventions. One model may call the latitude "lat",
+ another one may call it "Latitudes". This script looks for the
+ existence of any of a predefined list of synonyms for lat and long.
+
+ This script should be run from the command line (i.e. not called from
+ within python)
+
+ Input::
+ -filename
+
+ Output::
+ -success flag (1 or 0): were both latitude and longitude variable names found in the file?
+
+ if successful::
+ -name of latitude variable
+ -name of longitude variable
+ -latMin -descriptions of lat/lon ranges in data files
+ -latMax
+ -lonMin
+ -lonMax
+
+ if unsuccessful:
+ -list of variable names in file
+
+ (NB. all printed to standar output)
+
+"""
+
+import sys
+import Nio
+import bottle
+from bottle import request
+import json
+
+#filename = sys.argv[1]
+
+@bottle.route('/list/latlon/:filename#".*"#')
+def find_latlon(filename):
+ success = 0
+ filename = filename.strip('"')
+ f = Nio.open_file(filename)
+ var_name_list = f.variables.keys()
+
+ # convert all variable names into lower case
+ var_name_list_lower = [x.lower() for x in var_name_list]
+
+ # create a "set" from this list of names
+ varset = set(var_name_list_lower)
+
+ # Use "set" types for finding common variable name from in the file and from the list of possibilities
+ lat_possible_names = set(['latitude','lat','lats','latitudes'])
+ lon_possible_names = set(['longitude','lon','lons','longitudes'])
+
+ # Search for common latitude name variants:
+ # Find the intersection of two sets, i.e. find what latitude is called in this file.
+
+ try:
+ print 'hello from inside try block'
+ lat_var_name = list(varset & lat_possible_names)[0]
+ successlat = 1
+ index = 0
+ for i in var_name_list_lower:
+ if i==lat_var_name:
+ whlat = index
+ index += 1
+ latname = var_name_list[whlat]
+
+ lats = f.variables[latname][:]
+ latMin = lats.min()
+ latMax = lats.max()
+
+ except:
+ print 'exception happens'
+ latname = 'not_found'
+ successlat = 0
+
+ # Search for common longitude name variants:
+ # Find the intersection of two sets, i.e. find what longitude
+ # is called in this file.
+ try:
+ lon_var_name = list(varset & lon_possible_names)[0]
+ successlon = 1
+ index = 0
+ for i in var_name_list_lower:
+ if i==lon_var_name:
+ whlon = index
+ index += 1
+ lonname = var_name_list[whlon]
+
+ lons = f.variables[lonname][:]
+ #this will correct all lons to -180 , 180
+ lons[lons>180]=lons[lons>180]-360
+
+ lonMin = lons.min()
+ lonMax = lons.max()
+
+ except:
+ lonname = 'not_found'
+ successlon = 0
+
+
+ if(successlat & successlon):
+ success = 1
+
+
+ if success:
+ print success, latname, lonname, latMin, latMax, lonMin, lonMax
+ val_types= [int,str,str,str,str,str,str]
+ success_values = [success, latname, lonname, latMin, latMax, lonMin, lonMax]
+ value_names = ['success','latname','lonname','latMin','latMax','lonMin','lonMax']
+ values = [vtypes(svalues) for vtypes,svalues in zip(val_types,success_values)]
+ print values
+ output = dict(zip(value_names,values))
+ #json_output = json.dumps({'success':success,'latname':latname, \
+ # 'lonname':lonname,'latMin':latMin, \
+ # 'latMax':latMax,'lonMin':lonMin, \
+ # 'lonMax':lonMax }, sort_keys=True, indent=4)
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, output)
+ return output
+
+ if success==0:
+ json_output = json.dumps({'success':success,
+ 'variables':var_name_list }, \
+ sort_keys=True, indent=4)
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, json_output)
+ return json_output
+ #print success, var_name_list
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/find_time_var.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/find_time_var.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/find_time_var.py.svn-base
new file mode 100755
index 0000000..b099553
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/find_time_var.py.svn-base
@@ -0,0 +1,87 @@
+#!/usr/local/bin/python
+"""
+ Small command line utility to find what the time variable is called in a model file.
+
+ Background::
+ Model output files tend not to follow any defined standard in terms of
+ variable naming conventions. One model may call the time "time",
+ another one may call it "t". This script looks for the existence of
+ any of a predefined list of synonyms for time.
+
+ This script should be run from the command line (i.e. not called from within python)
+
+ Input::
+ -filename
+
+ Output::
+ -success flag (1 or 0): were both latitude and longitude variable names found in the file?
+
+ if successful:
+ -name of time variable
+ -(TODO) modelStartTime -descriptions of time ranges in data files
+ -(TODO) modelEndTime
+ if unsuccessful:
+ -list of variable names in file
+
+ (NB. all printed to standar output)
+"""
+
+import sys
+import bottle
+from bottle import request
+import Nio
+import json
+import decode_model_times as dmt
+
+
+#filename = sys.argv[1]
+
+
+@bottle.route('/list/time/:filename#".*"#')
+def list_time(filename):
+ filename = filename.strip('"')
+ success = 0
+ f = Nio.open_file(filename)
+ var_name_list = f.variables.keys()
+ # convert all variable names into lower case
+ var_name_list_lower = [x.lower() for x in var_name_list]
+ # create a "set" from this list of names
+ varset = set(var_name_list_lower)
+ # Use "set" types for finding common variable name from in the file and from the list of possibilities
+ time_possible_names = set(['time','t','times','date','dates','julian'])
+ # Search for common latitude name variants:
+ # Find the intersection of two sets, i.e. find what latitude is called in this file.
+ try:
+ time_var_name = list(varset & time_possible_names)[0]
+ success = 1
+ index = 0
+ for i in var_name_list_lower:
+ if i==time_var_name:
+ wh = index
+ index += 1
+ timename = var_name_list[wh]
+
+ except:
+ timename = 'not_found'
+ success = 0
+
+ if success:
+ print 'timename is '+timename
+ times = dmt.decode_model_times([filename],timename)
+ start_time = str(min(times))
+ end_time = str(max(times))
+ time_var = json.dumps({'success':success,'timename':timename,
+ 'start_time':start_time,'end_time':end_time})
+ #return time_var
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, time_var)
+ return time_var
+
+ if success==0:
+ json_output = json.dumps({'success':success,'variables':var_name_list })
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, json_output)
+ return json_output
+
+ #print success, var_name_list
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/list_vars_in_file.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/list_vars_in_file.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/list_vars_in_file.py.svn-base
new file mode 100755
index 0000000..43da7e6
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/list_vars_in_file.py.svn-base
@@ -0,0 +1,59 @@
+#!/usr/local/bin/python
+"""
+ Small command line utility to list the variables contained within a model file.
+
+ This script should be run from the command line (i.e. not called from within python)
+
+ Input:
+ -filename
+
+ Output:
+ -list of variable names in file
+
+ (NB. all printed to standar output)
+
+ Peter Lean February 2011
+
+ WEBSERVICE PLAN
+
+ URL: localhost:9999/list_vars/:filename (full file path plus file name)
+ Example: localhost:9999/list/vars/"/usr/local/wrm/modeldata/wrf.nc"
+
+ Return: JSON Array of Variable Names
+ Example: { "variables": [ "time_bnds", "tas", "level", "lon", "time", "lat" ] }
+"""
+
+import sys
+import Nio
+import bottle
+from bottle import request
+import json
+#filename = sys.argv[1]
+
+
+@bottle.route('/list/vars/:filename#".*"#')
+def list_vars(filename):
+ success = 0
+ filename = filename.strip('"')
+ print filename + ' is filename variable'
+ try:
+ f = Nio.open_file(filename)
+ success = 1
+ except:
+ print 'Error_reading_file '+filename
+
+ if success: #make some json
+ var_name_list = json.dumps({'variables':f.variables.keys() }, \
+ sort_keys=True, indent=2)
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, var_name_list)
+ return var_name_list
+
+ else:
+ failRet = "{\"FAIL\": \""+filename+"\"}"
+ if (request.query.callback):
+ return "%s(%s)" % (request.query.callback, failRet)
+ return failRet
+
+
+
http://git-wip-us.apache.org/repos/asf/climate/blob/a6aa1cd2/src/main/python/rcmes/services/.svn/text-base/main_ws.py.svn-base
----------------------------------------------------------------------
diff --git a/src/main/python/rcmes/services/.svn/text-base/main_ws.py.svn-base b/src/main/python/rcmes/services/.svn/text-base/main_ws.py.svn-base
new file mode 100755
index 0000000..4d78f4d
--- /dev/null
+++ b/src/main/python/rcmes/services/.svn/text-base/main_ws.py.svn-base
@@ -0,0 +1,36 @@
+"""Module that demonstrates how to initialize the RESTful web services that
+power the RCMET GUI"""
+
+from bottle import route, response, run, static_file, hook
+import list_vars_in_file
+import find_latlon_var
+import find_time_var
+import decode_model_times as dmt
+import run_rcmes_processing
+import dataset_helpers
+import directory_helpers
+
+@route('/')
+@route('/index.html')
+def index():
+ return "<a href='/hello'>Go to Hello World page</a>"
+
+@route('/hello')
+def hello():
+ return "Hello World!"
+
+@route('/api/status')
+def api_status():
+ return {'status':'online', 'key':'value'}
+
+@route('/static/evalResults/<filename>')
+def get_eval_result_image(filename):
+ return static_file(filename, root="/tmp/rcmet")
+
+@hook('after_request')
+def enable_cors():
+ response.headers['Access-Control-Allow-Origin'] = '*'
+
+if __name__ == "__main__":
+ run(host='localhost', port=8082)
+