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/07/01 16:50:01 UTC

[37/56] [partial] gh-pages clean up

http://git-wip-us.apache.org/repos/asf/climate/blob/a53e3af5/ocw-cli/ocw_cli.py
----------------------------------------------------------------------
diff --git a/ocw-cli/ocw_cli.py b/ocw-cli/ocw_cli.py
deleted file mode 100644
index a2de5cd..0000000
--- a/ocw-cli/ocw_cli.py
+++ /dev/null
@@ -1,846 +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.
-
-import curses
-import sys
-import os
-import numpy as np
-
-from netCDF4 import Dataset
-from datetime import datetime, timedelta
-
-import ocw.metrics as metrics
-import ocw.plotter as plotter
-import ocw.dataset_processor as dsp
-import ocw.evaluation as evaluation
-import ocw.data_source.rcmed as rcmed
-from ocw.dataset import Bounds
-from ocw.data_source.local import load_file
-
-
-def ready_screen(page, note=""):
-     ''' Generates page borders, header, footer and notification center.
-
-     :param note: Notification that system returns and will be shown
-          at the bottom of page
-     :type note: string
-     :param page: Name of current page
-     :type page: string
-
-     :returns: y and x as location of text on screen
-     :rtype: integer
-     '''
-
-     screen.clear()
-     y, x = screen.getmaxyx()
-     screen.border(0)
-     screen.addstr(0, x/2-len(TITLE)/2, TITLE)
-     screen.addstr(y-1, x/2-len(ORGANIZATION)/2, ORGANIZATION)
-     screen.addstr(y-3, 1, "Notification:")
-     for each in range(1, x-1):
-          screen.addstr(y-4, each, "-")
-     if page == "main_menu":
-          screen.addstr(y-3, x-21, "(NC) = Not complete")
-          screen.addstr(y-2, x-21, "(C)  = Complete")
-     screen.addstr(y-2, 1, note)
-
-     return y,x
-
-
-##############################################################
-#         Manage Model Screen
-##############################################################
-
-def load_model_screen(header):
-     '''Generates screen to be able to load model file.
-     Path to model file (netCDF) and variable name is required.
-
-     :param header: Header of page
-     :type header: string
-
-     :returns: Notification
-     :rtype: string
-     '''
-
-     ready_screen("load_model_screen")
-     screen.addstr(1, 1, header + " > Load Model File ")
-     screen.addstr(4, 2, "Enter model path: ")
-     model_path = screen.getstr()
-     try:
-          netCDF_file = Dataset(model_path, 'r')
-          all_netcdf_variables = [variable.encode() for variable in netCDF_file.variables.keys()]
-          netCDF_file.close()
-          try:
-               screen.addstr(6, 2, "Enter model variable name {0}: ".format(all_netcdf_variables))
-               variable_name = screen.getstr()
-               model_dataset = load_file(model_path, variable_name)
-               model_datasets.append(model_dataset)
-               models_info.append({ 'directory': model_path,
-                                 'variable_name': variable_name
-                              })
-               note = "Model file successfully added."
-          except:
-               note = "WARNING: Model file cannot be added. The variable [{0}] is not accepted. Please try again.".format(variable_name)
-     except:
-          note = "WARNING: Model file cannot be read. Please check the file directory or format. Only netCDF format is accepted."
-
-     return note
-
-
-
-def unload_model_screen(header):
-     '''Generates screen to be able to unload model file.
-     It lists all loaded model with index for each.
-     Selection of model with index will remove model from list of models.
-
-     :param header: Header of page
-     :type header: string
-
-     :returns: Notification
-     :rtype: string
-     '''
-
-     ready_screen("unload_model_screen")
-     screen.addstr(1, 1, header + " > Unload Model File")
-     screen.addstr(6, 1, "List of Model:")
-     for i, model in enumerate(models_info):
-          screen.addstr(8 + i, 10,  "Model Number:[{0}] - Model path:[{1}] - Variables:[{2}]".format(str(i), model['directory'], model['variable_name']))
-     screen.addstr(3, 2, "Select the model number to remove (press enter to go back): ")
-     try:
-          model_remove_index = screen.getstr()
-          models_info.pop(int(model_remove_index))
-          model_datasets.pop(int(model_remove_index))
-          note = "Model file unloaded successfully"
-     except:
-          note = "WARNING: Model file was not unloaded successfully."
-
-     return note
-
-
-def list_model_screen(header):
-     '''Generates screen to list all model files.
-
-     :param header: Header of page
-     :type header: string
-     '''
-
-     ready_screen("list_model_screen")
-     screen.addstr(1, 1, header + " > List Model File ")
-     screen.addstr(6, 6, "List of model(s): ")
-     for i, model in enumerate(models_info):
-          screen.addstr(8 + i, 10,  "Model Number:[{0}] - Model path:[{1}] - Variables:[{2}]".format(str(i), model['directory'], model['variable_name']))
-     screen.addstr(4, 4, "Return to Manage Model (press Enter) :")
-     screen.getstr()
-
-
-def manage_model_screen(header, note = ""):
-     '''Generates Manage Model screen.
-
-     :param header: Header of page
-     :type header: string
-     :param note: Notification, defult to empty string.
-     :type note: string
-     '''
-
-     option = ''
-     while option != '0':
-          ready_screen(note, page="manage_model_screen")
-          screen.addstr(1, 1, header)
-          screen.addstr(4, 4, "1 - Load Model File     [Number of loaded model: {0}]".format(len(model_datasets)))
-          screen.addstr(6, 4, "2 - Unload Model File")
-          screen.addstr(8, 4, "3 - List Model File")
-          screen.addstr(10, 4, "0 - Return to Main Menu")
-          screen.addstr(12, 2, "Select an option: ")
-          screen.refresh()
-          option = screen.getstr()
-
-          if option == '1':
-               note = load_model_screen(header)
-          if option == '2':
-               note = unload_model_screen(header)
-          if option == '3':
-               note = list_model_screen(header)
-               note = " "
-
-
-##############################################################
-#     Manage Observation Screen
-##############################################################
-
-def select_obs_screen(header):   #TODO: if the observation is already selected, don't select again.
-     '''Generates screen to select observation.
-     It reterives list of observations from database and make a table from that.
-     User has to select observation with dataset_id, parameter_id, start_date, end_date, minimum and maximum of lat and lon.
-     If the size of terminal screen is small to show whole table, a notification with link to parameter table on website will show up instead.
-
-     :param header: Header of page
-     :type header: string
-
-     :returns: Notification
-     :rtype: string
-     '''
-
-     ready_screen("select_obs_screen")
-     screen.addstr(1, 1, header + " > Select Observation ")
-     screen.addstr(8, 1, "Observations Table: ")
-     screen.addstr(9, 2, "|Dataset ID| - |Parameter ID| - |Time Step| - |Start Date| - | End Date | - | Min Lat | - | Max Lat | - | Min Lon | - | Max Lat | - |Database name")
-     screen.addstr(10, 2, "|----------| - |------------| - |---------| - |----------| - |----------| - |---------| - |---------| - |---------| - |---------| - |-------------")
-     all_obs_info = rcmed.get_parameters_metadata()
-     try:
-          for position, obs_info in enumerate(all_obs_info):
-               dataset_id = obs_info['dataset_id']
-               parameter_id = obs_info['parameter_id']
-               timestep = obs_info ['timestep']
-               start_date = obs_info ['start_date']
-               end_date = obs_info ['end_date']
-               min_lat = eval(obs_info['bounding_box'].encode())[2][0] if obs_info['bounding_box'] else None
-               max_lat = eval(obs_info['bounding_box'].encode())[0][0] if obs_info['bounding_box'] else None
-               min_lon = eval(obs_info['bounding_box'].encode())[2][1] if obs_info['bounding_box'] else None
-               max_lon = eval(obs_info['bounding_box'].encode())[0][1] if obs_info['bounding_box'] else None
-               database = obs_info ['database']
-               line = "|{0:>10}| - |{1:>12}| - |{2:>9}| - |{3}| - |{4}| - |{5:>9}| - |{6:>9}| - |{7:>9}| - |{8:>9}| - |{9}".format(
-                    dataset_id, parameter_id, timestep, start_date, end_date,
-                    str(min_lat), str(max_lat), str(min_lon), str(max_lon), database)
-               screen.addstr(11 + position, 2, line)
-     except:
-          ready_screen("select_obs_screen")
-          screen.addstr(1, 1, header + " > Select Observation ")
-          screen.addstr(10, 1, "Observation table cannot be shown due to small screen size. ")
-          screen.addstr(11, 1, "Please enlarge your screen and try again or refer to 'http://rcmes.jpl.nasa.gov/rcmed/parameters'. ")
-     try:
-          screen.addstr(4, 2, "Enter Dataset ID: ")
-          dataset_id = screen.getstr()
-          screen.addstr(5, 2, "Enter Parameter ID: ")
-          parameter_id = screen.getstr()
-
-          for obs in all_obs_info:
-               if obs['dataset_id'] == dataset_id and obs['parameter_id'] == parameter_id:
-                    observations_info.append({
-                                        'database':obs['database'],
-                                        'dataset_id':dataset_id,
-                                        'parameter_id':parameter_id,
-                                        'start_date':obs['start_date'],
-                                        'end_date':obs['end_date'],
-                                        'bounding_box':obs['bounding_box'],
-                                        'timestep':obs['timestep'],
-                                        'min_lat':float(eval(obs['bounding_box'].encode())[2][0]) if obs['bounding_box'] else None,
-                                        'max_lat':float(eval(obs['bounding_box'].encode())[0][0]) if obs['bounding_box'] else None,
-                                        'min_lon':float(eval(obs['bounding_box'].encode())[2][1]) if obs['bounding_box'] else None,
-                                        'max_lon':float(eval(obs['bounding_box'].encode())[0][1]) if obs['bounding_box'] else None,
-                                        'timestep':obs['timestep'],
-                                        'timestep':obs['timestep'],
-                                        'timestep':obs['timestep'],
-                                        'lat_res':float(obs['lat_res'].encode()),
-                                        'lon_res':float(obs['lon_res'].encode())
-                                        })
-                    note = "Observation sucessfully selected."
-                    break
-               else:
-                    note = "WARNING: Observation cannot be selected. There is no observation with given info."
-     except:
-          note = "WARNING: Observation cannot be selected, dataset or parameter id is wrong."
-
-     return  note
-
-
-def unselect_obs_screen(header):
-     '''Generates screen to be able to unselect observations.
-     Observations can be unselected by entering index allocated to them.
-
-     :param header: Header of page
-     :type header: string
-
-     :returns: Notification
-     :rtype: string
-     '''
-
-     ready_screen("unselect_obs_screen")
-     screen.addstr(1, 1, header + " > Unselect Observation ")
-     screen.addstr(6, 1, "List Observation(s):")
-     for i, obs_info in enumerate(observations_info):
-          screen.addstr(8 + i, 10, " [" + str(i) + "] : " + " Dataset ID: " + obs_info['dataset_id'] + " - Parameter ID: "+ obs_info['parameter_id'] + " - Database: "+ obs_info['database'])
-     screen.addstr(3, 2, "Select the observation to remove (press enter to go back): ")
-     try:
-          obs_remove_index = screen.getstr()
-          observations_info.pop(int(obs_remove_index))
-          note = "Observation sucessfully unselected."
-     except:
-          note = "WARNING: Unselecting model was not successful."
-
-     return note
-
-
-def list_obs_screen(header):
-     '''Generates screen to list observations.
-
-     :param header: Header of page
-     :type header: string
-     '''
-
-     ready_screen("list_obs_screen")
-     screen.addstr(1, 1, header + " > List Observation ")
-     screen.addstr(6, 6, "List of observation(s): ")
-     for i, obs_info in enumerate(observations_info):
-          screen.addstr(8 + i, 10, " [" + str(i) + "] : " + " Dataset ID: " + obs_info['dataset_id'] + " - Parameter ID: "+ obs_info['parameter_id'] + " - Database: "+ obs_info['database'])
-     screen.addstr(4, 4, "Return to Manage Observation (press Enter) :")
-     screen.getstr()
-
-
-def manage_obs_screen(header, note = ""):
-     '''Generates Manage Observation screen.
-
-     :param header: Header of page
-     :type header: string
-     :param note: Notification, defult to empty string.
-     :type note: string
-     '''
-
-     option = ''
-     while option != '0':
-          ready_screen(note, page="manage_obs_screen")
-          screen.addstr(1, 1, header)
-          screen.addstr(4, 4, "1 - Select Observation     [Number of selected observation: {0}]".format(len(observations_info)))
-          screen.addstr(6, 4, "2 - Unselect Observation")
-          screen.addstr(8, 4, "3 - List Observation")
-          screen.addstr(10, 4, "0 - Return to Main Menu")
-          screen.addstr(12, 2, "Select an option: ")
-          screen.refresh()
-
-          option = screen.getstr()
-          if option == '1':
-               note = select_obs_screen(header)
-          if option == '2':
-               note = unselect_obs_screen(header)
-          if option == '3':
-               list_obs_screen(header)
-               note = " "
-
-
-##############################################################
-#     Run Evaluation Screen
-##############################################################
-
-def run_screen(model_datasets, models_info, observations_info,
-               overlap_start_time, overlap_end_time, overlap_min_lat,
-               overlap_max_lat, overlap_min_lon, overlap_max_lon,
-               temp_grid_setting, spatial_grid_setting, working_directory, plot_title):
-     '''Generates screen to show running evaluation process.
-
-     :param model_datasets: list of model dataset objects
-     :type model_datasets: list
-     :param models_info: list of dictionaries that contain information for each model
-     :type models_info: list
-     :param observations_info: list of dictionaries that contain information for each observation
-     :type observations_info: list
-     :param overlap_start_time: overlap start time between model and obs start time
-     :type overlap_start_time: datetime
-     :param overlap_end_time: overlap end time between model and obs end time
-     :type overlap_end_time: float
-     :param overlap_min_lat: overlap minimum lat between model and obs minimum lat
-     :type overlap_min_lat: float
-     :param overlap_max_lat: overlap maximum lat between model and obs maximum lat
-     :type overlap_max_lat: float
-     :param overlap_min_lon: overlap minimum lon between model and obs minimum lon
-     :type overlap_min_lon: float
-     :param overlap_max_lon: overlap maximum lon between model and obs maximum lon
-     :type overlap_max_lon: float
-     :param temp_grid_setting: temporal grid option such as hourly, daily, monthly and annually
-     :type temp_grid_setting: string
-     :param spatial_grid_setting:
-     :type spatial_grid_setting: string
-     :param working_directory: path to a directory for storring outputs
-     :type working_directory: string
-     :param plot_title: Title for plot
-     :type plot_title: string
-     '''
-
-     option = None
-     if option != "0":
-          ready_screen(page="manage_obs_screen")
-          y = screen.getmaxyx()[0]
-          screen.addstr(2, 2, "Evaluation started....")
-          screen.refresh()
-
-          OUTPUT_PLOT = "plot"
-
-          dataset_id = int(observations_info[0]['dataset_id'])       #just accepts one dataset at this time
-          parameter_id =  int(observations_info[0]['parameter_id'])  #just accepts one dataset at this time
-
-          new_bounds = Bounds(overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon, overlap_start_time, overlap_end_time)
-          model_dataset = dsp.subset(new_bounds, model_datasets[0])   #just accepts one model at this time
-
-          #Getting bound info of subseted model file to retrive obs data with same bound as subseted model
-          new_model_spatial_bounds = model_dataset.spatial_boundaries()
-          new_model_temp_bounds = model_dataset.time_range()
-          new_min_lat = new_model_spatial_bounds[0]
-          new_max_lat = new_model_spatial_bounds[1]
-          new_min_lon = new_model_spatial_bounds[2]
-          new_max_lon = new_model_spatial_bounds[3]
-          new_start_time = new_model_temp_bounds[0]
-          new_end_time = new_model_temp_bounds[1]
-
-          screen.addstr(4, 4, "Retrieving data...")
-          screen.refresh()
-
-          #Retrieve obs data
-          obs_dataset = rcmed.parameter_dataset(
-                                        dataset_id,
-                                        parameter_id,
-                                        new_min_lat,
-                                        new_max_lat,
-                                        new_min_lon,
-                                        new_max_lon,
-                                        new_start_time,
-                                        new_end_time)
-          screen.addstr(4, 4, "--> Data retrieved.")
-          screen.refresh()
-
-          screen.addstr(5, 4, "Temporally regridding...")
-          screen.refresh()
-          if temp_grid_setting.lower() == 'hourly':
-               days = 0.5
-          elif temp_grid_setting.lower() == 'daily':
-               days = 1
-          elif temp_grid_setting.lower() == 'monthly':
-               days = 31
-          else:
-               days = 365
-          model_dataset = dsp.temporal_rebin(model_dataset, timedelta(days))
-          obs_dataset = dsp.temporal_rebin(obs_dataset, timedelta(days))
-          screen.addstr(5, 4, "--> Temporally regridded.")
-          screen.refresh()
-
-          new_lats = np.arange(new_min_lat, new_max_lat, spatial_grid_setting)
-          new_lons = np.arange(new_min_lon, new_max_lon, spatial_grid_setting)
-
-          screen.addstr(6, 4, "Spatially regridding...")
-          screen.refresh()
-          spatial_gridded_model = dsp.spatial_regrid(model_dataset, new_lats, new_lons)
-          spatial_gridded_obs = dsp.spatial_regrid(obs_dataset, new_lats, new_lons)
-          screen.addstr(6, 4, "--> Spatially regridded.")
-          screen.refresh()
-
-          screen.addstr(7, 4, "Setting up metrics...")
-          screen.refresh()
-          bias = metrics.Bias()
-          bias_evaluation = evaluation.Evaluation(spatial_gridded_model, [spatial_gridded_obs], [bias])
-          screen.addstr(7, 4, "--> Metrics setting done.")
-          screen.refresh()
-
-          screen.addstr(8, 4, "Running evaluation.....")
-          screen.refresh()
-          bias_evaluation.run()
-          results = bias_evaluation.results[0][0]
-          screen.addstr(8, 4, "--> Evaluation Finished.")
-          screen.refresh()
-
-          screen.addstr(9, 4, "Generating plots....")
-          screen.refresh()
-          lats = new_lats
-          lons = new_lons
-
-          gridshape = (1, 1)
-          sub_titles = [""]   #No subtitle set for now
-
-          if not os.path.exists(working_directory):
-               os.makedirs(working_directory)
-
-          for i in range(len(results)):
-               fname = working_directory + OUTPUT_PLOT + str(i)
-               plotter.draw_contour_map(results[i], lats, lons, fname,
-                               gridshape=gridshape, ptitle=plot_title,
-                               subtitles=sub_titles)
-          screen.addstr(9, 4, "--> Plots generated.")
-          screen.refresh()
-          screen.addstr(y-2, 1, "Press 'enter' to Exit: ")
-          option = screen.getstr()
-
-
-##############################################################
-#     Settings Screen
-##############################################################
-
-def get_model_temp_bound():
-     '''Get model temporal bound.
-
-     :returns: model start and end time
-     :rtypes: (datatime, datetime)
-     '''
-
-     model_start_time = model_datasets[0].time_range()[0]    #just accepts one model at this time
-     model_end_time = model_datasets[0].time_range()[1]      #just accepts one model at this time
-
-     return model_start_time, model_end_time
-
-
-def get_obs_temp_bound():
-     '''Get observation temporal bound.
-
-     :returns: observation start and end time
-     :rtype: (datetime, datetime)
-     '''
-
-     obs_start_time = observations_info[0]['start_date']    #just accepts one obs at this time
-     obs_end_time = observations_info[0]['end_date']        #just accepts one obs at this time
-     obs_start_time = datetime.strptime(obs_start_time, "%Y-%m-%d")
-     obs_end_time = datetime.strptime(obs_end_time, "%Y-%m-%d")
-
-     return obs_start_time, obs_end_time
-
-
-def get_temp_overlap(model_start_time, model_end_time, obs_start_time, obs_end_time):
-     '''Calculate temporal overlap between given datasets.
-
-     :param model_start_time: model start time
-     :type model_start_time: datetime
-     :param model_end_time: model end time
-     :type model_end_time: datetime
-     :param obs_start_time: obs start time
-     :type obs_start_time: datetime
-     :param obs_end_time: obs end time
-     :type obs_end_time: datetime
-
-     :returns: overlap start and end time between model and observation
-     :rtype: (datetime, datetime)
-     '''
-
-     overlap_start_time = max(model_start_time, obs_start_time)
-     overlap_end_time = min(model_end_time, obs_end_time)
-
-     return overlap_start_time, overlap_end_time
-
-
-def get_model_spatial_bound():               #TODO: convert longitudes to -180, 180 to match with observation data
-     '''Get model spatial bound.
-
-     :returns: model spatial boundaries
-     :rtype: (float, float, float, float)
-     '''
-
-     model_bound = model_datasets[0].spatial_boundaries()    #just accepts one model at this time
-     model_min_lat = model_bound[0]
-     model_max_lat = model_bound[1]
-     model_min_lon = model_bound[2]
-     model_max_lon = model_bound[3]
-
-     return model_min_lat, model_max_lat, model_min_lon, model_max_lon
-
-
-def get_obs_spatial_bound():
-     '''Get observation spatial bound.
-
-     :returns: observation spatial boundaries
-     :rtype: (float, float, float, float)
-     '''
-
-     obs_min_lat = observations_info[0]['min_lat']     #just accepts one obs at this time
-     obs_max_lat = observations_info[0]['max_lat']     #just accepts one obs at this time
-     obs_min_lon = observations_info[0]['min_lon']     #just accepts one obs at this time
-     obs_max_lon = observations_info[0]['max_lon']     #just accepts one obs at this time
-
-     return obs_min_lat, obs_max_lat, obs_min_lon, obs_max_lon
-
-
-def get_spatial_overlap(model_min_lat, model_max_lat, model_min_lon, model_max_lon, obs_min_lat, obs_max_lat, obs_min_lon, obs_max_lon):
-     '''Calculate spatial overlap between given datasets.
-
-     :param model_min_lat: model minumum latitude
-     :type model_min_lat: float
-     :param model_max_lat: model maximum latitude
-     :type model_max_lat: float
-     :param model_min_lon: model minimum longitude
-     :type model_min_lon: float
-     :param model_max_lon: model maximum longitude
-     :type model_max_lon: float
-     :param obs_min_lat: observation minimum latitude
-     :type obs_min_lat: float
-     :param obs_max_lat: observation maximum latitude
-     :type obs_max_lat: float
-     :param obs_min_lon: observation minimum longitude
-     :type obs_min_lon: float
-     :param obs_max_lon: observation maximum longitude
-     :type obs_max_lon: float
-
-     :returns: spatial boundaries overlap between model and observation
-     :rtype: (float, float, float, float)
-     '''
-
-     overlap_min_lat = max(model_min_lat, obs_min_lat)
-     overlap_max_lat = min(model_max_lat, obs_max_lat)
-     overlap_min_lon = max(model_min_lon, obs_min_lon)
-     overlap_max_lon = min(model_max_lon, obs_max_lon)
-
-     return overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon
-
-
-def settings_screen(header):
-     '''Generates screen for settings before running evaluation.
-
-     :param header: Header of page
-     :type header: string
-     '''
-
-     note = ""
-     model_start_time, model_end_time = get_model_temp_bound()
-     obs_start_time, obs_end_time = get_obs_temp_bound()
-     overlap_start_time, overlap_end_time = get_temp_overlap(model_start_time, model_end_time, obs_start_time, obs_end_time)
-     model_min_lat, model_max_lat, model_min_lon, model_max_lon = get_model_spatial_bound()
-     obs_min_lat, obs_max_lat, obs_min_lon, obs_max_lon = get_obs_spatial_bound()
-     overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon = get_spatial_overlap(model_min_lat, model_max_lat, model_min_lon, model_max_lon, obs_min_lat, obs_max_lat, obs_min_lon, obs_max_lon)
-     model_temp_res = model_datasets[0].temporal_resolution()       #just accepts one model at this time
-     obs_temp_res = observations_info[0]['timestep']        #just accepts one obs at this time
-     model_lat_res = model_datasets[0].spatial_resolution()[0] #just accepts one model at this time
-     model_lon_res = model_datasets[0].spatial_resolution()[1]  #just accepts one model at this time
-     obs_lat_res = observations_info[0].observations_info['lat_res']     #just accepts one obs at this time
-     obs_lon_res = observations_info[0].observations_info['lon_res']    #just accepts one obs at this time
-
-     temp_grid_option = "Observation"
-     temp_grid_setting = obs_temp_res
-     spatial_grid_option = "Observation"
-     spatial_grid_setting = obs_lat_res
-     subregion_path = None
-     metrics = 'BIAS'
-     working_directory = os.getcwd() + "/plots/"  #Default value of working directory set to "plots" folder in current directory
-     plot_title = '' #TODO: ask user about plot title or figure out automatically
-
-     fix_min_time = overlap_start_time
-     fix_max_time = overlap_end_time
-     fix_min_lat = overlap_min_lat
-     fix_max_lat = overlap_max_lat
-     fix_min_lon = overlap_min_lon
-     fix_max_lon = overlap_max_lon
-
-     option = ''
-     while option != '0':
-          ready_screen(note, page="settings_screen")
-          screen.addstr(1, 1, header)
-          screen.addstr(4, 4, "Number of model file:   {0}".format(str(len(model_datasets))))
-          screen.addstr(5, 4, "Number of observation:  {0}".format(str(len(observations_info))))
-          screen.addstr(6, 4, "Temporal Boundaries:    [start time = {0} - end time = {1}]".format(overlap_start_time, overlap_end_time))
-          screen.addstr(7, 4, "Spatial Boundaries:     [min-lat={0}  max-lat={1} min-lon={2} max-lon={3}]".format(overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon))
-          screen.addstr(8, 4, "Temporal Resolution:    [Model={0} - Observation={1}]".format(model_temp_res, obs_temp_res))
-          screen.addstr(9, 4, "Spatial Resolution:     [Model: lat={0} lon={1} - Observation: lat={2} lon={3}]".format(model_lat_res, model_lon_res, obs_lat_res, obs_lon_res))
-          screen.addstr(10, 4, "Temporal Grid Option:   [{0}]".format(temp_grid_option))
-          screen.addstr(11, 4, "Spatial Grid Option:    [{0}]".format(spatial_grid_option))
-          screen.addstr(12, 4, "Working Directory:      {0}".format(working_directory))
-          screen.addstr(13, 4, "Metrics:                {0}".format(metrics))
-
-          screen.addstr(15, 5, "1 - Change Temporal Boundaries")
-          screen.addstr(16, 5, "2 - Change Spatial Boundaries")
-          screen.addstr(17, 5, "3 - Change Temporal Gridding")
-          screen.addstr(18, 5, "4 - Change Spatial Gridding")
-          screen.addstr(19, 5, "5 - Add Subregion file (txt file) [Coming Soon....]")
-          screen.addstr(20, 5, "6 - Modify Metric (add/remove) [Coming Soon....]")
-          screen.addstr(21, 5, "7 - Change Working Directory")
-          screen.addstr(22, 5, "8 - Change Plot Title [Coming Soon....]")
-          screen.addstr(23, 5, "0 - Return to Main Menu")
-          screen.addstr(26, 5, "r - Run Evaluation")
-          screen.addstr(28, 2, "Select an option: ")
-
-          screen.refresh()
-          option = screen.getstr()
-          ### TODO: It breaks when you want to pick start time after end time and same issue with lat, lon.
-
-          if option == '1':
-               screen.addstr(33, 4, "Enter Start Time [min time: {0}] (Format YYYY-MM-DD):".format(fix_min_time))
-               new_start_time = screen.getstr()
-               try:
-                    new_start_time = datetime.strptime(new_start_time, '%Y-%m-%d')
-                    if new_start_time < fix_min_time or new_start_time > fix_max_time or new_start_time > overlap_end_time:
-                         note = "Start time has not changed."
-                    else:
-                         overlap_start_time = new_start_time
-                         note = "Start time has changed successfully."
-               except:
-                    note = "Start time has not changed."
-               screen.addstr(34, 4, "Enter End Time [max time:{0}] (Format YYYY-MM-DD):".format(fix_max_time))
-               new_max_time = screen.getstr()
-               try:
-                    new_max_time = datetime.strptime(new_max_time, '%Y-%m-%d')
-                    if new_max_time > fix_max_time or new_max_time < fix_min_time or new_max_time < overlap_start_time:
-                         note = note + " End time has not changed."
-                    else:
-                         overlap_end_time = new_max_time
-                         note = note + "End time has changed successfully."
-               except:
-                    note = note + " End time has not changed."
-
-          if option == '2':
-               screen.addstr(33, 4, "Enter Minimum Latitude [{0}]:".format(fix_min_lat))
-               new_min_lat = screen.getstr()
-               try:
-                    new_min_lat = float(new_min_lat)
-                    if new_min_lat < fix_min_lat or new_min_lat > fix_max_lat or new_min_lat > overlap_max_lat:
-                         note = "Minimum latitude has not changed."
-                    else:
-                         overlap_min_lat = new_min_lat
-                         note = "Minimum latitude has changed successfully."
-               except:
-                    note = "Minimum latitude has not changed."
-               screen.addstr(34, 4, "Enter Maximum Latitude [{0}]:".format(fix_max_lat))
-               new_max_lat = screen.getstr()
-               try:
-                    new_max_lat = float(new_max_lat)
-                    if new_max_lat > fix_max_lat or new_max_lat < fix_min_lat or new_max_lat < overlap_min_lat:
-                         note = note + " Maximum latitude has not changed."
-                    else:
-                         overlap_max_lat = new_max_lat
-                         note = note + "Maximum latitude has changed successfully."
-               except:
-                    note = note + " Maximum latitude has not changed."
-               screen.addstr(35, 4, "Enter Minimum Longitude [{0}]:".format(fix_min_lon))
-               new_min_lon = screen.getstr()
-               try:
-                    new_min_lon = float(new_min_lon)
-                    if new_min_lon < fix_min_lon or new_min_lon > fix_max_lon or new_min_lon > overlap_max_lon:
-                         note = note + " Minimum longitude has not changed."
-                    else:
-                         overlap_min_lon = new_min_lon
-                         note = note + "Minimum longitude has changed successfully."
-               except:
-                    note = note + " Minimum longitude has not changed."
-               screen.addstr(36, 4, "Enter Maximum Longitude [{0}]:".format(fix_max_lon))
-               new_max_lon = screen.getstr()
-               try:
-                    new_max_lon = float(new_max_lon)
-                    if new_max_lon > fix_max_lon or new_max_lon < fix_min_lon or new_max_lon < overlap_min_lon:
-                         note = note + " Maximum longitude has not changed."
-                    else:
-                         overlap_max_lon = new_max_lon
-                         note = note + "Maximum longitude has changed successfully."
-               except:
-                    note = note + " Maximum longitude has not changed."
-
-          if option == '3':
-               screen.addstr(33, 4, "Enter Temporal Gridding Option [Model or Observation]:")
-               new_temp_grid_option = screen.getstr()
-               if new_temp_grid_option.lower() == 'model':
-                    temp_grid_option = 'Model'
-                    temp_grid_setting = model_temp_res
-                    note = "Temporal gridding option has changed successfully to {0}".format(temp_grid_option)
-               elif new_temp_grid_option.lower() == 'observation':
-                    temp_grid_option = 'Observation'
-                    temp_grid_setting = obs_temp_res
-                    note = "Temporal gridding option has changed successfully to {0}".format(temp_grid_option)
-               else:
-                    note = "Temporal gridding option has not be changed."
-
-          if option == '4':
-               screen.addstr(33, 4, "Enter Spatial Gridding Option [Model, Observation or User]:")
-               new_spatial_grid_option = screen.getstr()
-               if new_spatial_grid_option.lower() == 'model':
-                    spatial_grid_option = 'Model'
-                    spatial_grid_setting = model_lat_res
-                    note = "Spatial gridding option has changed successfully to {0}".format(spatial_grid_option)
-               elif new_spatial_grid_option.lower() == 'observation':
-                    spatial_grid_option = 'Observation'
-                    spatial_grid_setting = obs_lat_res
-                    note = "Spatial gridding option has changed successfully to {0}".format(spatial_grid_option)
-               elif new_spatial_grid_option.lower() == 'user':
-                    screen.addstr(34, 4, "Please enter spatial resolution: ")
-                    user_res = screen.getstr()
-                    try:
-                         user_res = float(user_res)
-                         spatial_grid_option = 'User: resolution {0}'.format(str(user_res))
-                         spatial_grid_setting = user_res
-                         note = "Spatial gridding option has changed successfully to {0}".format(spatial_grid_option)
-                    except:
-                         note = "Spatial gridding option has not be changed."
-               else:
-                    note = "Spatial gridding option has not be changed."
-
-          '''
-          if option == '5':
-               screen.addstr(33, 4, "Please enter one Subregion path:")
-               subregion_path = screen.getstr()
-          '''
-          if option == '7':
-               screen.addstr(33, 4, "Please enter working directory path:")
-               working_directory = screen.getstr()
-               if working_directory[-1] != '/':
-                    working_directory = working_directory + "/"
-
-          if option == '8':
-               screen.addstr(33, 4, "Please enter plot title:")
-               plot_title = screen.getstr()
-
-          if option.lower() == 'r':
-               run_screen(model_datasets, models_info, observations_info, overlap_start_time, overlap_end_time, \
-                          overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon, \
-                          temp_grid_setting, spatial_grid_setting, working_directory, plot_title)
-
-
-##############################################################
-#     Main Menu Screen
-##############################################################
-
-def main_menu(model_datasets, models_info, observation_datasets, observations_info, note = ""):
-     '''This function Generates main menu page.
-
-     :param model_datasets: list of model dataset objects
-     :type model_datasets: list
-     :param models_info: list of dictionaries that contain information for each model
-     :type models_info: list
-     :param observation_datasets: list of observation dataset objects
-     :type observation_datasets: list
-     :param observations_info: list of dictionaries that contain information for each observation
-     :type observations_info: list
-     '''
-
-     option = ''
-     while option != '0':
-          ready_screen(note, "main_menu")
-          model_status = "NC" if len(model_datasets) == 0 else "C"     #NC (Not Complete), if there is no model added, C (Complete) if model is added
-          obs_status = "NC" if len(observations_info) == 0 else "C"    #NC (Not Complete), if there is no observation added, C (Complete) if observation is added
-          screen.addstr(1, 1, "Main Menu:")
-          screen.addstr(4, 4, "1 - Manage Model ({0})".format(model_status))
-          screen.addstr(6, 4, "2 - Manage Observation ({0})".format(obs_status))
-          screen.addstr(8, 4, "3 - Run(Config File) [coming soon....]")
-          screen.addstr(10, 4, "4 - Run(Settings)")
-          screen.addstr(12, 4, "0 - EXIT")
-          screen.addstr(18, 2, "Select an option: ")
-          screen.refresh()
-          option = screen.getstr()
-
-          if option == '1':
-               header = "Main Menu > Manage Model"
-               manage_model_screen(header)
-          if option == '2':
-               header = "Main Menu > Manage Observation"
-               manage_obs_screen(header)
-          if option == '3':
-               header = "Main Menu > Run(Config File)"
-               #TODO: function to read config file and run evaluation
-          if option == '4':
-               if model_status =='NC' or obs_status == 'NC':
-                    main_menu(model_datasets, models_info, observation_datasets, observations_info, note="WARNING: Please complete step 1 and 2 before 4.")
-               else:
-                    header = "Main Menu > Run(Settings)"
-                    settings_screen(header)
-     curses.endwin()
-     sys.exit()
-
-
-if __name__ == '__main__':
-     TITLE = "Open Climate Workbench Evaluation System"
-     ORGANIZATION = "Apache Software Foundation"
-     screen = curses.initscr()
-     model_datasets = []           #list of model dataset objects
-     models_info = []              #list of dictionaries that contain information for each model
-     observation_datasets = []     #list of observation dataset objects
-     observations_info = []        #list of dictionaries that contain information for each observation
-     main_menu(model_datasets, models_info, observation_datasets, observations_info)

http://git-wip-us.apache.org/repos/asf/climate/blob/a53e3af5/ocw-ui/backend/__init__.py
----------------------------------------------------------------------
diff --git a/ocw-ui/backend/__init__.py b/ocw-ui/backend/__init__.py
deleted file mode 100644
index fab9f8c..0000000
--- a/ocw-ui/backend/__init__.py
+++ /dev/null
@@ -1,18 +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.
-#
-"""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/a53e3af5/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)
-
-
-
-

http://git-wip-us.apache.org/repos/asf/climate/blob/a53e3af5/ocw-ui/backend/config.py
----------------------------------------------------------------------
diff --git a/ocw-ui/backend/config.py b/ocw-ui/backend/config.py
deleted file mode 100644
index a92044e..0000000
--- a/ocw-ui/backend/config.py
+++ /dev/null
@@ -1,26 +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.
-#
-
-''' Configuration settings for the OCW backend webservices. '''
-
-# Directory where all results are save/cache-ing is done
-WORK_DIR = '/tmp/ocw/'
-
-# Parent directory that the frontend is allowed to load model files from.
-# Any directory under this will be visible to the frontend when loading
-# a local model file.
-PATH_LEADER = '/usr/local/ocw'

http://git-wip-us.apache.org/repos/asf/climate/blob/a53e3af5/ocw-ui/backend/directory_helpers.py
----------------------------------------------------------------------
diff --git a/ocw-ui/backend/directory_helpers.py b/ocw-ui/backend/directory_helpers.py
deleted file mode 100644
index c754cf3..0000000
--- a/ocw-ui/backend/directory_helpers.py
+++ /dev/null
@@ -1,232 +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.
-#
-
-''' Endpoints for retrieving directory information from the server. '''
-
-from bottle import Bottle, request, response
-import os
-import re
-
-from config import WORK_DIR, PATH_LEADER
-
-dir_app = Bottle()
-
-@dir_app.route('/list/')
-@dir_app.route('/list/<dir_path:path>')
-def get_directory_info(dir_path='/'):
-    ''' Return the listing of a supplied path.
-
-    :param dir_path: The directory path to list.
-    :type dir_path: String
-
-    :returns: Dictionary containing the directory listing if possible.
-
-    **Example successful JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            'listing': [
-                '/bar/',
-                '/baz.txt',
-                '/test.txt'
-            ]
-        }
-
-    **Example failure JSON return**
-
-    .. sourcecode:: javascript
-
-        {'listing': []}
-    '''
-    dir_info = []
-
-    try:
-        clean_path = _get_clean_directory_path(PATH_LEADER, dir_path)
-        dir_listing = os.listdir(clean_path)
-    except:
-        # ValueError - dir_path couldn't be 'cleaned'
-        # OSError - clean_path is not a directory
-        # Either way, we don't have anything to list for the directory!
-        pass
-    else:
-        for obj in dir_listing:
-            # Ignore hidden files
-            if obj[0] == '.': continue
-
-            # Create a path to the listed object. If it's a directory add a
-            # trailing slash as a visual clue. Then strip out the path leader.
-            obj = os.path.join(clean_path, obj)
-            if os.path.isdir(obj): obj = obj + '/'
-            dir_info.append(obj.replace(PATH_LEADER, ''))
-
-        sorted(dir_info, key=lambda s: s.lower())
-
-    if request.query.callback:
-        return "%s(%s)" % (request.query.callback, {'listing': dir_info})
-    return {'listing': dir_info}
-
-@dir_app.route('/results/')
-def get_result_dir_info():
-    ''' Retrieve results directory information.
-
-    The backend's results directory is determined by WORK_DIR. All the 
-    directories there are formatted and returned as results. If WORK_DIR does
-    not exist, an empty listing will be returned (shown as a 'failure below').
-
-    **Successful JSON Response**
-
-    .. sourcecode:: javascript
-
-        {
-            'listing': [
-                '/bar',
-                '/foo'
-            ]
-        }
-
-    **Failure JSON Response**
-
-    .. sourcecode:: javascript
-
-        {
-            'listing': []
-        }
-    '''
-    dir_info = []
-
-    try:
-        dir_listing = os.listdir(WORK_DIR)
-    except OSError:
-        # The WORK_DIR hasn't been created, so we don't have any results!
-        pass
-    else:
-        for obj in dir_listing:
-            # Ignore hidden files
-            if obj[0] == '.': continue
-
-            # Create a path to the listed object and strip the work dir leader.
-            # If the result isn't a directory, ignore it.
-            obj = os.path.join(WORK_DIR, obj)
-            if not os.path.isdir(obj): continue
-            dir_info.append(obj.replace(WORK_DIR, ''))
-
-        sorted(dir_info, key=lambda s: s.lower())
-
-    if request.query.callback:
-        return "%s(%s)" % (request.query.callback, {'listing': dir_info})
-    return {'listing': dir_info}
-
-@dir_app.route('/results/<dir_path:path>')
-def get_results(dir_path):
-    ''' Retrieve specific result files.
-
-    :param dir_path: The relative results path to list.
-    :type dir_path: String
-
-    :returns: Dictionary of the requested result's directory listing.
-
-    **Successful JSON Response**
-
-    .. sourcecode:: javascript
-
-        {
-            'listing': [
-                'file1',
-                'file2'
-            ]
-        }
-
-    **Failure JSON Response**
-
-    .. sourcecode:: javascript
-
-        {
-            'listing': []
-        }
-    '''
-    dir_info = []
-
-    try:
-        clean_path = _get_clean_directory_path(WORK_DIR, dir_path)
-        dir_listing = os.listdir(clean_path)
-    except:
-        # ValueError - dir_path couldn't be 'cleaned'
-        # OSError - clean_path is not a directory
-        # Either way, we don't have any results to return!
-        pass
-    else:
-        for obj in dir_listing:
-            # Ignore hidden files
-            if obj[0] == '.': continue
-
-            # Create a path to the listed object and strip out the path leader.
-            obj = os.path.join(clean_path, obj)
-            dir_info.append(obj.replace(WORK_DIR, ''))
-
-        sorted(dir_info, key=lambda s: s.lower())
-
-    if request.query.callback:
-        return "%s(%s)" % (request.query.callback, {'listing': dir_info})
-    return {'listing': dir_info}
-
-@dir_app.route('/path_leader/')
-def get_path_leader():
-    ''' Return the path leader used for clean path creation.
-
-    **Example JSON Response**
-
-    .. sourcecode:: javascript
-
-        {'leader': '/usr/local/ocw'}
-    '''
-    return_json = {'leader': PATH_LEADER}
-
-    if request.query.callback:
-        return "%s(%s)" % (request.query.callback, return_json)
-    return return_json
-
-@dir_app.hook('after_request')
-def enable_cors():
-    ''' Allow Cross-Origin Resource Sharing for all URLs. '''
-    response.headers['Access-Control-Allow-Origin'] = '*'
-
-def _get_clean_directory_path(path_leader, dir_path):
-    ''' Return a cleaned directory path with a defined path prefix.
-
-    'Clean' dir_path to remove any relative path components or duplicate 
-    slashes that could cause problems. The final clean path is then the
-    path_leader + dir_path.
-
-    :param path_leader: The path prefix that will be prepended to the cleaned
-        dir_path.
-    :type path_leader: String
-    :param dir_path: The path to clean.
-    :type path_leader: String
-    
-    :returns: The cleaned directory path with path_leader prepended.
-    '''
-    # Strip out any .. or . relative directories and remove duplicate slashes
-    dir_path = re.sub('/[\./]*/?', '/', dir_path)
-    dir_path = re.sub('//+', '/', dir_path)
-
-    # Prevents the directory path from being a substring of the path leader.
-    # os.path.join('/usr/local/ocw', '/usr/local') gives '/usr/local'
-    # which could allow access to unacceptable paths. This also means that
-    if dir_path[0] == '/': dir_path = dir_path[1:]
-
-    return os.path.join(path_leader, dir_path)

http://git-wip-us.apache.org/repos/asf/climate/blob/a53e3af5/ocw-ui/backend/local_file_metadata_extractors.py
----------------------------------------------------------------------
diff --git a/ocw-ui/backend/local_file_metadata_extractors.py b/ocw-ui/backend/local_file_metadata_extractors.py
deleted file mode 100644
index e69b548..0000000
--- a/ocw-ui/backend/local_file_metadata_extractors.py
+++ /dev/null
@@ -1,227 +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.
-#
-
-''' Helpers for local model/observation file metadata extraction. '''
-
-import sys
-import netCDF4
-import json
-
-from bottle import Bottle, request, route, response
-
-import ocw.utils
-
-lfme_app = Bottle()
-
-@lfme_app.route('/list_latlon/<file_path:path>')
-def list_latlon(file_path):
-    ''' Retrieve lat/lon information from given file.
-    
-    :param file_path: Path to the NetCDF file from which lat/lon information
-        should be extracted
-    :type file_path: string:
-
-    :returns: Dictionary containing lat/lon information if successful, otherwise
-        failure information is returned.
-
-    **Example successful JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            'success': true,
-            'lat_name': The guessed latitude variable name,
-            'lon_name': the guessed longitude variable name,
-            'lat_min': The minimum latitude value,
-            'lat_max': The maximum latitude value,
-            'lon_min': The minimum longitude value,
-            'lon_max': The maximum longitude value
-        }
-
-    **Example failure JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            'success': false,
-            'variables': List of all variables present in the NetCDF file
-        }
-    '''
-    in_file = netCDF4.Dataset(file_path, mode='r')
-
-    var_names = set([key.encode().lower() for key in in_file.variables.keys()])
-    var_names_list = list(var_names)
-
-    lat_name_guesses = set(['latitude','lat','lats','latitudes'])
-    lon_name_guesses = set(['longitude','lon','lons','longitudes'])
-
-    # Attempt to determine the lat name
-    found_lat_name = False
-
-    # Find the intersection (if there is one) of the var names with the lat guesses
-    lat_guesses = list(var_names & lat_name_guesses)
-
-    if len(lat_guesses) >= 1:
-        found_lat_name = True
-        lat_name = var_names_list[var_names_list.index(lat_guesses[0])]
-
-        lats = in_file.variables[lat_name][:]
-
-        # Change 0 - 360 degree values to be -180 to 180
-        lats[lats > 180] = lats[lats > 180] - 360
-
-        lat_min = float(lats.min())
-        lat_max = float(lats.max())
-
-    # Attempt to determine the lon name
-    found_lon_name = False
-
-    # Find the intersection (if there is one) of the var names with the lon guesses
-    lon_guesses = list(var_names & lon_name_guesses)
-
-    if len(lon_guesses) >= 1:
-        found_lon_name = True
-        lon_name = var_names_list[var_names_list.index(lon_guesses[0])]
-
-        lons = in_file.variables[lon_name][:]
-
-        # Change 0 - 360 degree values to be -180 to 180
-        lons[lons > 180] = lons[lons > 180] - 360
-
-        lon_min = float(lons.min())
-        lon_max = float(lons.max())
-
-    in_file.close()
-
-    success = found_lat_name and found_lon_name
-    if success:
-        values = [success, lat_name, lon_name, lat_min, lat_max, lon_min, lon_max]
-        value_names = ['success', 'lat_name', 'lon_name', 'lat_min', 'lat_max', 'lon_min', 'lon_max']
-        output = dict(zip(value_names, values))
-    else:
-        output = {'success': success, 'variables': var_names_list}
-
-    if request.query.callback:
-        return '%s(%s)' % (request.query.callback, json.dumps(output))
-    return output
-
-@lfme_app.route('/list_time/<file_path:path>')
-def list_time(file_path):
-    ''' Retrieve time information from provided file.
-
-    :param file_path: Path to the NetCDF file from which time information
-        should be extracted
-    :type file_path: String:
-
-    :returns: Dictionary containing time information if successful, otherwise
-        failure information is returned.
-
-    **Example successful JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            "success": true,
-            "time_name": The guessed time variable name,
-            "start_time": "1988-06-10 00:00:00",
-            "end_time": "2008-01-27 00:00:00"
-        }
-
-    **Example failure JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            "success": false
-            "variables": List of all variable names in the file
-        } 
-    '''
-    in_file = netCDF4.Dataset(file_path, mode='r')
-
-    var_names = set([key.encode().lower() for key in in_file.variables.keys()])
-    var_names_list = list(var_names)
-
-    time_name_guesses = set(['time', 'times', 't', 'date', 'dates', 'julian'])
-
-    # Find the intersection (if there is one) of the var names with the lat guesses
-    time_guesses = list(var_names & time_name_guesses)
-
-    if len(time_guesses) >= 1:
-        # Convert time data to datetime objects
-        time_var_name = time_guesses[0]
-        times = ocw.utils.decode_time_values(in_file, time_var_name)
-
-        start_time = str(min(times))
-        end_time = str(max(times))
-
-        output = {
-            'success': True,
-            'time_name': time_var_name,
-            'start_time': start_time,
-            'end_time': end_time
-        }
-    else:
-        output = {'success': False, 'variables': var_names_list}
-
-    if request.query.callback:
-        return '%s(%s)' % (request.query.callback, json.dumps(output))
-    return output
-
-@lfme_app.route('/list_vars/<file_path:path>')
-def list_vars(file_path):
-    ''' Retrieve variable names from file.
-
-    :param file_path: Path to the NetCDF file from which variable information
-        should be extracted
-    :type file_path: String:
-
-    :returns: Dictionary containing variable information if succesful, otherwise
-        failure information is returned.
-
-    **Example successful JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            "success": true,
-            "variables": List of variable names in the file
-        }
-
-    **Example failure JSON return**
-
-    .. sourcecode:: javascript
-
-        {
-            "success": false
-        }
-    '''
-    try:
-        in_file = netCDF4.Dataset(file_path, mode='r')
-    except RuntimeError:
-        output = {'success': False}
-    else:
-        output = {'success': True, 'variables': in_file.variables.keys()}
-        in_file.close()
-    finally:
-        if request.query.callback:
-            return "%s(%s)" % (request.query.callback, json.dumps(output))
-        return output
-
-@lfme_app.hook('after_request')
-def enable_cors():
-    ''' Allow Cross-Origin Resource Sharing for all URLs. '''
-    response.headers['Access-Control-Allow-Origin'] = '*'