Skip to content

Commit

Permalink
pep8ed , added test suite, and conda recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
doutriaux1 committed Oct 5, 2017
1 parent 3fd478e commit b6c3382
Show file tree
Hide file tree
Showing 11 changed files with 563 additions and 114 deletions.
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
os:
- linux
- osx
dist: trusty
sudo: false
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh; fi
- export PATH="$HOME/miniconda/bin:$PATH"
- bash miniconda.sh -b -p $HOME/miniconda
- conda config --set always_yes yes --set changeps1 no
- conda update -y -q conda
script:
- conda install -c uvcdat/label/nightly -c conda-forge -c uvcdat genutil nose image-compare flake8 matplotlib
- export UVCDAT_ANONYMOUS_LOG=False
- echo $TRAVIS_BRANCH
- export TRAVIS_PR_BRANCH=$TRAVIS_BRANCH
- echo $TRAVIS_EVENT_TYPE
- echo $TRAVIS_PULL_REQUEST
- python setup.py install
- python run_tests.py -v2 -n2
after_success:
- if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" == "false" ]; then conda install conda-build && conda install anaconda-client && bash ci-support/conda_upload.sh ; fi
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BSD 3-clause license
Copyright (c) 2015-2017, conda-forge
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 changes: 43 additions & 0 deletions conda/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{% set name = "ensometrics" %}
{% set version = "0.1" %}

package:
name: {{ name|lower }}
version: {{ version }}

source:
git_url: https://github.com/eguil/Enso_metrics.git
git_rev: master


build:
number: 0
skip: True # [win or py3k]
script: python setup.py install

requirements:
build:
- python
- setuptools
run:
- python
- cdms2
- numpy
- udunits2
- genutil

test:
command:
- export UVCDAT_ANONYMOUS_LOG=false && python run_tests.py -v2

about:
home: http://github.com/eguil/Enso_metrics
license: 'CCLRC'
license_file: LICENSE
summary: "Library to compute ENSO metrics"

extra:
recipe-maintainers:
- doutriaux1
- eguil
- lee1043
37 changes: 19 additions & 18 deletions lib/EnsoMetricsGraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,40 @@
import matplotlib.pyplot as plt


def EnsoMetricsTable(models,metrics, figName):
def EnsoMetricsTable(models, metrics, figName):

fig=plt.figure()
fig = plt.figure()
ax = fig.add_subplot(111)
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
# Labels
colLabels = ("ENSO Amplitude", r'$\mu$')
rowLabels = models
# make the table
the_table = ax.table(cellText=metrics,colWidths=[.2,.2],
colLabels=colLabels,rowLabels=rowLabels,colLoc='center',loc='center')
the_table = ax.table(cellText=metrics, colWidths=[.2, .2],
colLabels=colLabels, rowLabels=rowLabels, colLoc='center', loc='center')
# height of rows
table_props = the_table.properties()
table_cells = table_props['child_artists']
for cell in table_cells: cell.set_height(0.08)
for cell in table_cells:
cell.set_height(0.08)
# size of fonts
the_table.set_fontsize(12)
#the_table.scale(1.5, 1.5)
plt.tight_layout(rect=[0.05,0.15,0.95,.95])
# the_table.scale(1.5, 1.5)
plt.tight_layout(rect=[0.05, 0.15, 0.95, .95])

plt.show()
#plt.savefig(figName+'.jpeg')
# plt.savefig(figName+'.jpeg')

#colLabels=("Model", "ENSO Amplitude", "Mu")
#nrows, ncols = len(clust_data)+1, len(colLables)
#hcell, wcell = 0.3, 1.
#hpad, wpad = 0, 0
#fig=plt.figure(figsize=(ncols*wcell+wpad, nrows*hcell+hpad))
#ax = fig.add_subplot(111)
#ax.axis('off')
##do the table
#the_table = ax.table(cellText=clust_data,
# colLabels=("Model", "ENSO Amplitude", "Mu")
# nrows, ncols = len(clust_data)+1, len(colLables)
# hcell, wcell = 0.3, 1.
# hpad, wpad = 0, 0
# fig=plt.figure(figsize=(ncols*wcell+wpad, nrows*hcell+hpad))
# ax = fig.add_subplot(111)
# ax.axis('off')
# do the table
# the_table = ax.table(cellText=clust_data,
# colLabels=colLabels,
# loc='center')
#plt.savefig("table.png")
# plt.savefig("table.png")
68 changes: 35 additions & 33 deletions lib/EnsoMetricsLib.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import os
import cdms2 as cdm
import numpy as npy
import cdutil as cdu
from genutil import statistics
from cdms2.selectors import Selector
from monthly_variability_statistics import interannual_variabilty_std_annual_cycle_removed, get_slope_linear_regression_from_anomaly
from monthly_variability_statistics import interannual_variabilty_std_annual_cycle_removed
from monthly_variability_statistics import get_slope_linear_regression_from_anomaly
import MV2 as mv

#
# Libray to compute ENSO metrics
# These procedures have file names as inputs and metric as output
#
def Ensoampln3 (sstfile, sstname):
ensoampl = Ensoampl(sstfile,sstname, nino3)


def Ensoampln3(sstfile, sstname):
ensoampl = Ensoampl(sstfile, sstname, nino3) # noqa ??? We need to pass nino3
return ensoampl

def EnsoAmpl (sstfile, sstname, ninobox):

def EnsoAmpl(sstfile, sstname, ninobox):
'''
The EnsoAmpl() function compute the SST standard deviation in a ninobox
Expand Down Expand Up @@ -48,21 +49,21 @@ def EnsoAmpl (sstfile, sstname, ninobox):
cdm.setAutoBounds('on')

# Define metric attributes
Name = 'ENSO amplitude'
Units = 'C'
Method = 'Standard deviation of SST in '+ninobox
Ref = 'Using CDAT std dev calculation'
Name = 'ENSO amplitude'
Units = 'C'
Method = 'Standard deviation of SST in ' + ninobox
Ref = 'Using CDAT std dev calculation'

# Open file and get time dimension
fi = cdm.open(sstfile)
ssth = fi[sstname] # Create variable handle
ssth = fi[sstname] # Create variable handle
# Number of months and years
timN = ssth.shape[0]
yearN = timN / 12

# define ninobox
if ninobox =='nino3':
nbox = cdu.region.domain(latitude=(-5.,5.),longitude=(-150,-90))
if ninobox == 'nino3':
nbox = cdu.region.domain(latitude=(-5., 5.), longitude=(-150, -90))
else:
print '!!! ninobox not defined in EnsoAmpl', ninobox
# Read SST in box
Expand All @@ -73,11 +74,12 @@ def EnsoAmpl (sstfile, sstname, ninobox):
sstStd = interannual_variabilty_std_annual_cycle_removed(sst)

# Create output
amplMetric = {'name':Name, 'value':sstStd, 'units':Units, 'method':Method, 'nyears':yearN, 'ref':Ref}
amplMetric = {'name': Name, 'value': sstStd, 'units': Units, 'method': Method, 'nyears': yearN, 'ref': Ref}

return amplMetric

def EnsoMu (sstfile, tauxfile, sstname, tauxname):

def EnsoMu(sstfile, tauxfile, sstname, tauxname):
'''
The EnsoMu() function compute the regression of nino4 tauxA over nino3 sstA
Expand Down Expand Up @@ -110,39 +112,39 @@ def EnsoMu (sstfile, tauxfile, sstname, tauxname):
cdm.setAutoBounds('on')

# Define metric attributes
Name = 'Bjerknes feedback (mu)'
Units = '10-3 N/m2/C'
Name = 'Bjerknes feedback (mu)'
Units = '10-3 N/m2/C'
Method = 'Regression of nino4 tauxA over nino3 sstA'
Ref = 'Using CDAT regression calculation'
Ref = 'Using CDAT regression calculation'

# Open file and get time dimension
fsst = cdm.open(sstfile)
ftaux = cdm.open(tauxfile)
ssth = fsst[sstname] # Create variable handle
ssth = fsst[sstname] # Create variable handle
# Number of months and years
timN = ssth.shape[0]
yearN = timN / 12

# Read SST and Taux in boxes
n3box = cdu.region.domain(latitude=(-5.,5.),longitude=(-150,-90))
n3box = cdu.region.domain(latitude=(-5., 5.), longitude=(-150, -90))
sst = fsst(sstname, n3box)

n4box = cdu.region.domain(latitude=(-5.,5.),longitude=(160,210))
n4box = cdu.region.domain(latitude=(-5., 5.), longitude=(160, 210))
taux = ftaux(tauxname, n4box)

# Average and compute regression of interannual anomaly
muSlope = get_slope_linear_regression_from_anomaly(taux,sst, 0) # (all points)
muSlopePlus = get_slope_linear_regression_from_anomaly(taux,sst, 1) # (positive SSTA = El Nino)
muSlopeNeg = get_slope_linear_regression_from_anomaly(taux,sst, -1) # (negative SSTA = La Nina)
muSlope = get_slope_linear_regression_from_anomaly(taux, sst, 0) # (all points)
muSlopePlus = get_slope_linear_regression_from_anomaly(taux, sst, 1) # (positive SSTA = El Nino)
muSlopeNeg = get_slope_linear_regression_from_anomaly(taux, sst, -1) # (negative SSTA = La Nina)

# Change units
muSlope = muSlope * 1000.
muSlope = muSlope * 1000.
muSlopePlus = muSlopePlus * 1000.
muSlopeNeg = muSlopeNeg * 1000.
muSlopeNeg = muSlopeNeg * 1000.

# Create output
muMetric = {'name':Name, 'value':muSlope, 'units':Units, 'method':Method, 'nyears':yearN, 'ref':Ref, \
'nonlinearity':muSlopeNeg-muSlopePlus}
muMetric = {'name': Name, 'value': muSlope, 'units': Units, 'method': Method, 'nyears': yearN, 'ref': Ref,
'nonlinearity': muSlopeNeg - muSlopePlus}

return muMetric

Expand All @@ -153,9 +155,9 @@ def computeAnom(var1d, nYears):
:param var:
:return:
'''
varAC = npy.ma.ones([12], dtype='float32')*0.
varAC = npy.ma.ones([12], dtype='float32') * 0.
for m in range(12):
d = var1d[m::12] # select indices for month m every 12 months
varAC[m] = mv.average(d) # average along time axis
varInter = var1d - npy.tile(varAC, nYears) # compute anomaly
d = var1d[m::12] # select indices for month m every 12 months
varAC[m] = mv.average(d) # average along time axis
varInter = var1d - npy.tile(varAC, nYears) # compute anomaly
return varInter
3 changes: 3 additions & 0 deletions lib/__init_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from EnsoMetricsLib import Ensoampln3, EnsoAmpl, EnsoMu, computeAnom # noqa
from metricsCollectionsLib import defCollection, metricReqs # noqa
from EnsoMetricsGraph import EnsoMetricsTable # noqa
15 changes: 9 additions & 6 deletions lib/metricsCollectionsLib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@
# Draft version
#
# Define metrics collections


def defCollection(MC=True):
# Name, list of metrics
# Name, list of metrics
metrics_collection = {
'MC1':{'long_name':'Metrics collection Q1','list_of_metrics':['EnsoAmpl','EnsoMu'],
'description':'Describe which science question this collection is about'},
'MC1': {'long_name': 'Metrics collection Q1', 'list_of_metrics': ['EnsoAmpl', 'EnsoMu'],
'description': 'Describe which science question this collection is about'},
}
if MC:
return metrics_collection
else:
return metrics_collection[MC]

# List of metrics requirements (var name and reference obs)


def metricReqs(VOR=True):
var_obs_requirements = {
'EnsoAmpl':{'nbvar':1,'var_names':['sst'],'ref_obs':['HadiSST1.1']},
'EnsoMu':{'nbvar':2,'var_names':['sst','taux'],'ref_obs':['HadiSST1.1','ERA-interim']},
'EnsoAmpl': {'nbvar': 1, 'var_names': ['sst'], 'ref_obs': ['HadiSST1.1']},
'EnsoMu': {'nbvar': 2, 'var_names': ['sst', 'taux'], 'ref_obs': ['HadiSST1.1', 'ERA-interim']},
}
if VOR:
return var_obs_requirements
else:
return var_obs_requirements[VOR]

Loading

0 comments on commit b6c3382

Please sign in to comment.