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/02/08 22:00:19 UTC

svn commit: r1566126 - /incubator/climate/trunk/ocw-ui/backend/processing.py

Author: joyce
Date: Sat Feb  8 21:00:19 2014
New Revision: 1566126

URL: http://svn.apache.org/r1566126
Log:
CLIMATE-332 - Add metric loading

Modified:
    incubator/climate/trunk/ocw-ui/backend/processing.py

Modified: incubator/climate/trunk/ocw-ui/backend/processing.py
URL: http://svn.apache.org/viewvc/incubator/climate/trunk/ocw-ui/backend/processing.py?rev=1566126&r1=1566125&r2=1566126&view=diff
==============================================================================
--- incubator/climate/trunk/ocw-ui/backend/processing.py (original)
+++ incubator/climate/trunk/ocw-ui/backend/processing.py Sat Feb  8 21:00:19 2014
@@ -17,9 +17,10 @@
 
 ''' Provides endpoints for running an OCW evaluation. '''
 
-import sys
 from ast import literal_eval
 from datetime import timedelta
+import inspect
+import sys
 
 from bottle import Bottle, request
 
@@ -82,9 +83,9 @@ def run_evaluation():
             // (1, 31], annual/yearly is (31, 366], and full is anything > 366.
             'temporal_resolution': Integer in range(1, 999),
 
-            // The metrics to use in the Evaluation
-            // TODO: Think of a good way to pass this!!!!!
-            'metrics': 
+            // A list of the metric class names to use in the evaluation. The
+            // names must match the class name exactly.
+            'metrics': [BiasMetric, TemporalStdDev, ...]
 
             // The bounding values used in the Evaluation. Note that lat values
             // should range from -180 to 180 and lon values from -90 to 90.
@@ -139,6 +140,8 @@ def run_evaluation():
     target_datasets =  [dsp.spatial_regrid(ds, lat_bins, lon_bins) for ds in datasets]
 
     # Load metrics
+    metrics = _load_metrics(request.query['metrics'])
+
     # Prime evaluation object with data
     # Run evaluation
     # Plot (I have no idea how this is going to work)
@@ -302,3 +305,52 @@ def _calculate_new_latlon_bins(eval_boun
     new_lats = np.arange(eval_bounds['min_lat'], eval_bounds['max_lat'], lat_grid_step)
     new_lons = np.arange(eval_bounds['min_lon'], eval_bounds['max_lon'], lon_grid_step)
     return (new_lats, new_lons)
+
+def _load_metrics(metric_names):
+    ''' Load and create an instance of each requested metric.
+
+    :param metric_names: The names of the metrics that should be loaded and 
+        instantiated from ocw.metrics for use in an evaluation.
+    :type metric_names: List
+
+    :returns: A List of Metric objects
+
+    :raises ValueError: If a metric name cannot be matched.
+    '''
+    instantiated_metrics = []
+    possible_metrics = _get_valid_metric_options()
+    for metric in metric_names:
+        if metric not in possible_metrics:
+            cur_frame = sys._getframe().f_code
+            err = "{}.{}: Invalid metric name - {}".format(
+            cur_frame.co_filename,
+            cur_frame.co_name,
+            metric
+            )
+            raise ValueError(err)
+
+        metric_class = _load_metric_class_from_name(metric)
+        instantiated_metrics.append(metric_class())
+
+    return instantiated_metrics
+
+def _get_valid_metric_options():
+    ''' Get valid metric names from the ocw.metrics module.
+
+    :returns: A dictionary of metric name, object pairs
+    '''
+    invalid_metrics = ['Metric', 'UnaryMetric', 'BinaryMetric']
+    return {name:obj
+            for name, obj in inspect.getmembers(metrics)
+            if inspect.isclass(obj) and name not in invalid_metrics}
+
+def _load_metric_class_from_name(metric_name):
+    ''' Load a metric class by name from ocw.metrics.
+
+    :param metric_name: The name of the metric class to load from ocw.metrics.
+    :type metric_name: String
+
+    :returns: The loaded metric Class
+    '''
+    module = __import__('ocw.metrics', fromlist=[metric_name])
+    return getattr(module, metric_name)