Repository: climate
Updated Branches:
  refs/heads/master 50f6678c8 -> 89a96c0fe


CLIMATE-508: added a class 'Downscaling' and histogram plots


Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/7d2ec541
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/7d2ec541
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/7d2ec541

Branch: refs/heads/master
Commit: 7d2ec541598990255f510f9b89669c47a5625e41
Parents: 50f6678
Author: huikyole <[email protected]>
Authored: Mon Aug 18 10:54:35 2014 -0700
Committer: Kim Whitehall <[email protected]>
Committed: Fri Apr 24 08:04:13 2015 -0700

----------------------------------------------------------------------
 ocw/plotter.py                 |  62 ++++++++++++++++++++
 ocw/statistical_downscaling.py | 111 ++++++++++++++++++++++++++++++++++++
 2 files changed, 173 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/climate/blob/7d2ec541/ocw/plotter.py
----------------------------------------------------------------------
diff --git a/ocw/plotter.py b/ocw/plotter.py
old mode 100644
new mode 100755
index f40bf14..72376bd
--- a/ocw/plotter.py
+++ b/ocw/plotter.py
@@ -538,6 +538,35 @@ def draw_barchart(results, yvalues, fname, ptitle='', 
fmt='png',
     fig.savefig('%s.%s' %(fname, fmt), bbox_inches='tight', dpi=fig.dpi)
     fig.clf()
 
+def draw_marker_on_map(lat, lon, fname, fmt='png', location_name=' 
',gridshape=(1,1)):
+    '''
+    Purpose::
+        Draw a marker on a map
+
+    Input::
+        lat - latitude for plotting a marker
+        lon - longitude for plotting a marker
+        fname  - a string specifying the filename of the plot
+    '''   
+    fig = plt.figure()
+    fig.dpi = 300
+    ax = fig.add_subplot(111)
+    
+    m = Basemap(projection='cyl', resolution = 'c', llcrnrlat =lat-30, 
urcrnrlat = lat+30, llcrnrlon = lon-60, urcrnrlon = lon+60)
+    m.drawcoastlines(linewidth=1)
+    m.drawcountries(linewidth=1)
+    m.drawmapboundary(fill_color='aqua')
+    m.fillcontinents(color='coral',lake_color='aqua')
+    m.ax = ax
+   
+    xpt,ypt = m(lon,lat)
+    m.plot(xpt,ypt,'bo')  # plot a blue dot there
+    # put some text next to the dot, offset a little bit
+    # (the offset is in map projection coordinates)
+    plt.text(xpt+0.5, ypt+1.5,location_name+'\n(lon: %5.1f, lat: %3.1f)' % 
(lon, lat)) 
+                       
+    fig.savefig('%s.%s' %(fname, fmt), bbox_inches='tight', dpi=fig.dpi)
+    fig.clf()
 
 def draw_contour_map(dataset, lats, lons, fname, fmt='png', gridshape=(1, 1),
                      clabel='', ptitle='', subtitles=None, cmap=None,
@@ -992,3 +1021,36 @@ class TaylorDiagram(object):
         r = np.linspace(std1, std2)
 
         return self.ax.plot(t,r,'red',linewidth=2)
+
+def draw_histogram(dataset_array, data_names, fname, fmt='png', nbins=10):
+    '''
+    Purpose::
+        Draw histograms
+
+    Input::
+        dataset_array - a list of data values [data1, data2, ....]
+        data_names    - a list of data names  ['name1','name2',....]
+        fname  - a string specifying the filename of the plot
+        bins - number of bins
+    '''    
+    fig = plt.figure()
+    fig.dpi = 300
+    ndata = len(dataset_array)
+   
+    data_min = 500.
+    data_max = 0.
+ 
+    for data in dataset_array:
+        data_min = np.min([data_min,data.min()]) 
+        data_max = np.max([data_max,data.max()]) 
+
+    bins = np.linspace(np.round(data_min), np.round(data_max+1), nbins)
+    for idata,data in enumerate(dataset_array):
+        ax = fig.add_subplot(ndata, 1, idata+1)
+        ax.hist(data, bins, alpha = 0.5, label=data_names[idata], normed = 
True)
+        leg = ax.legend()
+        leg.get_frame().set_alpha(0.5)
+        ax.set_xlim([data_min-(data_max-data_min)*0.15, 
data_max+(data_max-data_min)*0.15])
+        
+    fig.savefig('%s.%s' %(fname, fmt), bbox_inches='tight', dpi=fig.dpi)
+ 

http://git-wip-us.apache.org/repos/asf/climate/blob/7d2ec541/ocw/statistical_downscaling.py
----------------------------------------------------------------------
diff --git a/ocw/statistical_downscaling.py b/ocw/statistical_downscaling.py
new file mode 100755
index 0000000..75e2adc
--- /dev/null
+++ b/ocw/statistical_downscaling.py
@@ -0,0 +1,111 @@
+# 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 ocw.utils as utils
+import numpy as np
+from scipy.stats import percentileofscore, linregress
+
+class Downscaling:
+    def __init__(self, ref_dataset, model_present, model_future):
+        '''
+        :param ref_dataset: The Dataset to use as the reference dataset 
(observation)
+        :type ref_dataset: Dataset
+        :param model_present: model simulation to be compared with observation
+        :type model_present: Dataset
+        :param model_future: model simulation to be calibrated for prediction
+        :type model_future: Dataset
+        '''
+        self.ref_dataset = ref_dataset[~ref_dataset.mask].ravel()
+        self.model_present = model_present.ravel()
+        self.model_future = model_future.ravel()
+             
+    description = "statistical downscaling methods"
+
+    def Delta_addition(self):
+        '''Calculate the mean difference between future and present 
simulation, 
+           then add the difference to the observed distribution
+
+        :returns: downscaled model_present and model_future
+        ''' 
+        ref = self.ref_dataset 
+        model_present = self.model_present 
+        model_future = self.model_future 
+
+        return model_present, ref + np.mean(model_future-model_present)
+
+    def Delta_correction(self):
+        '''Calculate the mean difference between observation and present 
simulation,
+           then add the difference to the future distribution
+
+        :returns: downscaled model_present and model_future
+        '''
+        ref = self.ref_dataset
+        model_present = self.model_present
+        model_future = self.model_future
+
+        return model_present+np.mean(ref) - np.mean(model_present), 
model_future + np.mean(ref) - np.mean(model_present)
+
+    def Quantile_mapping(self):
+        '''Remove the biases for each quantile value 
+        Wood et al (2004) HYDROLOGIC IMPLICATIONS OF DYNAMICAL AND STATISTICAL 
APPROACHES TO DOWNSCALING CLIMATE MODEL OUTPUTS
+
+        :returns: downscaled model_present and model_future
+        '''
+        ref = self.ref_dataset
+        model_present = self.model_present
+        model_present_corrected = np.zeros(model_present.size)
+        model_future = self.model_future
+        model_future_corrected = np.zeros(model_future.size)
+
+
+        for ival, model_value in enumerate(model_present):
+            percentile = percentileofscore(model_present, model_value)
+            model_present_corrected[ival] = np.percentile(ref, percentile) 
+
+        for ival, model_value in enumerate(model_future):
+            percentile = percentileofscore(model_future, model_value)
+            model_future_corrected[ival] = model_value + np.percentile(ref, 
percentile) - np.percentile(model_present, percentile) 
+
+        return model_present_corrected, model_future_corrected     
+
+    def Asynchronous_regression(self):
+        '''Remove the biases by fitting a linear regression model with ordered 
observational and model datasets
+        Stoner et al (2013) An asynchronous regional regression model for 
statistical downscaling of daily climate variables    
+
+        :returns: downscaled model_present and model_future
+        '''
+
+        ref_original = self.ref_dataset
+        model_present = self.model_present
+        model_present_sorted = np.sort(model_present)
+        model_future = self.model_future
+ 
+        ref = np.zeros(model_present.size)   # For linear regression, the size 
of reference data must be same as model data. 
+
+        for ival, model_value in enumerate(model_present_sorted):
+            percentile = percentileofscore(model_present_sorted, model_value)
+            ref[ival] = np.percentile(ref_original, percentile)       
+
+        slope, intercept = linregress(model_present_sorted, ref)[0:2] 
+        
+        return model_present*slope+intercept, model_future*slope+intercept
+
+
+
+
+

Reply via email to