Skip to content

Commit

Permalink
Merge pull request #356 from PCMDI/issue_351_half_levels
Browse files Browse the repository at this point in the history
Issue 351 half levels
  • Loading branch information
doutriaux1 committed Jun 20, 2018
2 parents 2083cb9 + 4c1ff66 commit 00fb6d2
Show file tree
Hide file tree
Showing 66 changed files with 1,913 additions and 940 deletions.
16 changes: 14 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,42 @@ aliases:
conda config --set always_yes yes --set changeps1 no
conda update -y -q conda
conda config --set anaconda_upload no
conda create -q -n py2 -c cdat/label/nightly -c conda-forge ossuuid udunits2 hdf5 libnetcdf numpy gcc openssl cdms2 "python<3"
#conda create -q -n py3 -c conda-forge ossuuid udunits2 hdf5 libnetcdf numpy gcc "python>3"
conda create -q -n py2 -c cdat/label/nightly -c conda-forge ossuuid udunits2 hdf5 libnetcdf numpy openssl cdms2 python=2.7 $CONDA_COMPILERS
- &setup_cmor
name: setup_cmor
command: |
echo "WE are in: "`pwd`
export PATH=$WORKDIR/miniconda/bin:$PATH
set +e
source activate py2
echo "ACTIVATE RETURN CODE $?"
set -e
export PREFIX=$(python -c "import sys; print sys.prefix")
git clone https://github.com/PCMDI/cmip6-cmor-tables
ln -s cmip6-cmor-tables/Tables Tables
./configure --prefix=$PREFIX --with-python --with-uuid=$PREFIX --with-udunits2=$PREFIX --with-netcdf=$PREFIX --enable-verbose-test
make install
echo "MAKE PASSED"
exit 0
- &run_cmor_tests
name: run_cmor_tests
command: |
export PATH=$WORKDIR/miniconda/bin:$PATH
export UVCDAT_ANONYMOUS_LOG=False
set +e
source activate py2
set -e
make test
- &run_prepare_tests
name: run_prepare_tests
command: |
export PATH=$WORKDIR/miniconda/bin:$PATH
export UVCDAT_ANONYMOUS_LOG=False
set +e
source activate py2
set -e
for file in `ls -1 Test/test_python_CMIP6_CV*.py`; do echo $file; python $file; mystatus=$?; if [[ "$mystatus" != "0" ]]; then return ${mystatus}; fi; done
Expand All @@ -59,6 +67,8 @@ jobs:
xcode: "9.2.0"
environment:
WORKDIR: "workspace/test_macos_cmor"
CONDA_COMPILERS: "clang_osx-64 gfortran_osx-64"
LDSHARED_FLAGS: "-bundle -undefined dynamic_lookup"
steps:
- checkout
- run: *setup_miniconda
Expand All @@ -72,6 +82,8 @@ jobs:
image: circleci/classic:latest
environment:
WORKDIR: "workspace/test_linux_cmor"
CONDA_COMPILERS: "gcc_linux-64 gfortran_linux-64"
LDSHARED_FLAGS: "-shared -pthread"
steps:
- checkout
- run: *setup_miniconda
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.pyc
*.gcno
*.gcda
*.dSYM
.cproject
.project
.settings/
Expand Down
16 changes: 7 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,20 @@ before_install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then wget https://repo.continuum.io/miniconda/Miniconda2-latest-MacOSX-x86_64.sh
-O miniconda.sh; fi
- export PATH="$HOME/miniconda/bin:$PATH"
- export PREFIX="$HOME/miniconda"
- export UDUNITS2_XML_PATH=$HOME/miniconda/share/udunits/udunits2.xml
- export UVCDAT_ANONYMOUS_LOG=no
- bash miniconda.sh -b -p $HOME/miniconda
- conda config --set always_yes yes --set changeps1 no
- conda update -y -q conda
- conda install openssl=1.0.2d
- conda install cdms2 -c cdat/label/nightly -c conda-forge -c cdat
- conda install udunits2 -c cdat/label/nightly -c conda-forge -c cdat
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then conda install gcc; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then conda install gcc; fi
- source deactivate root
- source activate root
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then export CONDA_COMPILERS="gcc_linux-64 gfortran_linux-64"; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export CONDA_COMPILERS="clang_osx-64 gfortran_osx-64"; fi
- conda create -q -n py2 -c cdat/label/nightly -c conda-forge ossuuid udunits2 hdf5 libnetcdf numpy openssl cdms2 python=2.7 $CONDA_COMPILERS
- source activate py2
install:
- export PREFIX=$(python -c "import sys; print sys.prefix")
- git clone https://github.com/PCMDI/cmip6-cmor-tables
- ln -s cmip6-cmor-tables/Tables Tables
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then export LDSHARED_FLAGS="-shared -pthread"; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LDSHARED_FLAGS="-bundle -undefined dynamic_lookup"; fi
- "./configure --prefix=$PREFIX --with-python --with-uuid=$PREFIX --with-udunits2=$PREFIX
--with-netcdf=$PREFIX --enable-verbose-test"
- make install
Expand Down
4 changes: 2 additions & 2 deletions INSTALL
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
INSTALLATION INSTRUCTIONS
-------------------------
Climate Model Output Rewriter (CMOR) version 3.3.1 installation instructions.
Climate Model Output Rewriter (CMOR) version 3.3.3 installation instructions.


DOWNLOAD
Expand All @@ -13,7 +13,7 @@ cd CMOR

INSTALLATION
------------
CMOR 3.3.1 requires external packages that need to be installed first.
CMOR 3.3.3 requires external packages that need to be installed first.
It can be compiled/linked against either NetCDF3 or NetCDF4. If you
decide to go with NetCDF4 be sure to build NetCDF4 with the
--enable-netcdf-4 option!
Expand Down
7 changes: 6 additions & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ VPATH = @srcdir@
srcdir = @srcdir@
FC=@FC@
CC=@CC@
LDSHARED="@CC@ ${LDSHARED_FLAGS}"
CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
CPPFLAGS_USER=""
Expand Down Expand Up @@ -157,7 +158,7 @@ endif
python:
@echo "Building Python interface"
#if [ ! -d "${DIR}" ]; then mkdir -p ${DIR}; fi
${PYTHONEXEC} setup.py install @CDATPREFIX@
LDSHARED=${LDSHARED} ${PYTHONEXEC} setup.py install @CDATPREFIX@
test_a_python:
@echo "${OK_COLOR}Testing ${TEST_NAME} ${NO_COLOR}"
${PYTHONEXEC} ${TEST_NAME} ${VERB}
Expand Down Expand Up @@ -231,6 +232,10 @@ test_python: python
env TEST_NAME=Test/test_site_ts.py make test_a_python
env TEST_NAME=Test/test_python_free_wrapping_issue.py make test_a_python
env TEST_NAME=Test/test_python_filename_time_range.py make test_a_python
env TEST_NAME=Test/test_cmor_half_levels.py make test_a_python
env TEST_NAME=Test/test_cmor_half_levels_with_bounds.py make test_a_python
env TEST_NAME=Test/test_cmor_half_levels_wrong_generic_level.py make test_a_python
env TEST_NAME=Test/test_cmor_double_singleton.py make test_a_python

test_case:
@echo "${OK_COLOR}Testing: "${TEST_NAME}" with input file: ${INPUT_FILE}${NO_COLOR}"
Expand Down
5 changes: 5 additions & 0 deletions Src/cmor_axes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2163,6 +2163,7 @@ void cmor_init_axis_def(cmor_axis_def_t * axis, int table_id)
axis->index_only = 'n';
axis->must_have_bounds = 0;
axis->must_call_cmor_grid = 0;
axis->generic_level_name[0] = '\0';
}

/************************************************************************/
Expand Down Expand Up @@ -2244,6 +2245,10 @@ int cmor_set_axis_def_att(cmor_axis_def_t * axis, char att[CMOR_MAX_STRING],

axis->positive = val[0];

} else if (strcmp(att, AXIS_ATT_GEN_LEVEL_NAME) == 0) {

strncpy(axis->generic_level_name, val, CMOR_MAX_STRING);

} else if (strcmp(att, AXIS_ATT_AXIS) == 0) {

axis->axis = val[0];
Expand Down
40 changes: 33 additions & 7 deletions Src/cmor_variables.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,6 @@ int cmor_zfactor(int *zvar_id, int axis_id, char *name, char *units,
{

extern int cmor_nvars;
extern cmor_var_t cmor_formula[];

int i, j, k;
int n, gid;
Expand Down Expand Up @@ -1581,16 +1580,39 @@ int cmor_variable(int *var_id, char *name, char *units, int ndims,
continue;
}
for (j = 0; j < refvar.ndims; j++) {
if ((strcmp
if (strcmp
(cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].axes
[cmor_axes[laxes_ids[i]].ref_axis_id].id,
cmor_tables[CMOR_TABLE].axes[refvar.dimensions[j]].id) == 0)
||
((cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].axes
cmor_tables[CMOR_TABLE].axes[refvar.dimensions[j]].id) == 0) {
k++;
}
else if ((cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].axes
[cmor_axes[laxes_ids[i]].ref_axis_id].axis == 'Z')
&& (refvar.dimensions[j] == -2))) {

&& (refvar.dimensions[j] == -2)) {
k++;
/* ok it is a olvel or similar (refvar == -2) */
/* we need to ensure it is the correct one */
if (
(strcmp(refvar.generic_level_name,
cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].axes
[cmor_axes[laxes_ids[i]].ref_axis_id].generic_level_name) != 0) &&
(cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].axes
[cmor_axes[laxes_ids[i]].ref_axis_id].generic_level_name[0] != '\0')
) {
snprintf(msg, CMOR_MAX_STRING,
"You defined variable '%s' (table %s) with axis "
"id '%s', the variable calls for a generic axis of type '%s' "
"according to your table, the axis you are providing is of generic type '%s'",
refvar.id,
cmor_tables[cmor_vars[vrid].ref_table_id].szTable_id,
cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].
axes[cmor_axes[laxes_ids[i]].ref_axis_id].id,
refvar.generic_level_name,
cmor_tables[cmor_axes[laxes_ids[i]].ref_table_id].axes
[cmor_axes[laxes_ids[i]].ref_axis_id].generic_level_name
);
cmor_handle_error_var(msg, CMOR_CRITICAL, vrid);
}
}
}
if (k != i) {
Expand Down Expand Up @@ -1879,6 +1901,7 @@ void cmor_init_var_def(cmor_var_def_t * var, int table_id)
var->shuffle = 0;
var->deflate = 1;
var->deflate_level = 1;
var->generic_level_name[0] = '\0';
}

/************************************************************************/
Expand Down Expand Up @@ -1954,6 +1977,7 @@ int cmor_set_var_def_att(cmor_var_def_t * var, char att[CMOR_MAX_STRING],
if (n == -1) {
j = strcmp(DIMENSION_ZLEVEL, dim);
j *= strcmp(DIMENSION_ALEVEL, dim);
j *= strcmp(DIMENSION_ALEVEL_HALF, dim);
j *= strcmp(DIMENSION_OLEVEL, dim);
for (k = 0; k < CMOR_MAX_ELEMENTS; k++) {
if (cmor_tables[var->table_id].generic_levels[k][0] == '\0')
Expand All @@ -1965,6 +1989,8 @@ int cmor_set_var_def_att(cmor_var_def_t * var, char att[CMOR_MAX_STRING],
if (j == 0) {

var->dimensions[var->ndims] = -2;
strncpy(var->generic_level_name, dim, CMOR_MAX_STRING);

} else {
if ((strcmp(dim, DIMENSION_LONGITUDE) != 0)
&& strcmp(dim, DIMENSION_LATITUDE) != 0) {
Expand Down
113 changes: 113 additions & 0 deletions Test/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import numpy
import cmor
import os

specs = {"CLOUD": {"convert": [2.0, 0.], "units": "%", "entry": "cl", "positive": ""},
"U": {"convert": [1., -40.], "units": "m s-1", "entry": "ua", "positive": ""},
"T": {"convert": [1., 220], "units": "K", "entry": "ta", "positive": ""},
"LATENT": {"convert": [4., 0.], "units": "W m-2", "entry": "hfls", "positive": "down"},
"TSURF": {"convert": [1., -15.], "units": "Celsius", "entry": "tas", "positive": ""},
"PSURF": {"convert": [3., 900.], "units": "hPa", "entry": "ps", "positive": ""},
"SOIL_WET": {"convert": [2., 0.], "units": "kg m-2", "entry": "mrsos", "positive": ""},
"MC": {"convert": [2., 0.], "units": "kg m-2 s-1", "entry": "mc", "positive": "up"},
"BS": {"convert": [2., 0.], "units": "m-1 sr-1", "entry": "bs550aer", "positive": ""},
}


def read_coords(nlats, nlons):
alons = (360.*numpy.arange(nlons)/nlons+.5) - 180.
blons = numpy.zeros((nlons, 2), dtype=float)
blons[:, 0] = 360.*numpy.arange(nlons)/nlons - 180.
blons[:, 1] = 360.*numpy.arange(1, nlons+1)/nlons - 180.

alats = (180.*numpy.arange(nlats)/nlats+.5) - 90.
blats = numpy.zeros((nlats, 2), dtype=float)
blats[:, 0] = 180.*numpy.arange(nlats)/nlats - 90.
blats[:, 1] = 180.*numpy.arange(1, nlats+1)/nlats - 90.

levs = numpy.array([1., 5., 10, 20, 30, 50, 70, 100, 150,
200, 250, 300, 400, 500, 600, 700, 850, 925, 1000])

return alats, blats, alons, blons, levs


def read_time(index, refyear=2015., monthdays=30., yeardays=360.):
time0 = (refyear - 1850.) * yeardays
time = time0 + (index + 0.5) * monthdays
b1 = time0 + (index) * monthdays
b2 = time0 + (index+1) * monthdays
return numpy.array([time]), numpy.array([b1, b2])


def read_3d_input_files(index, varname, shape):

print "3d shape", shape
field = numpy.zeros(shape, dtype=numpy.float32)
factor, offset = specs[varname]["convert"]
for i in range(field.shape[2]): # lon
for j in range(field.shape[1]): # lat
for k in range(field.shape[0]): # levs
if i == 0:
field[k, j, 0] = ((k)*3 + (j)*16 + index) * \
factor + offset + 0.225
else:
field[k, j, i] = ((k)*3 + (j)*16 + index +
4*i-2)*factor + offset + 0.225
return field


def read_2d_input_files(index, varname, shape):
sh = list(shape)
sh.insert(0, 1)
return read_3d_input_files(index, varname, sh)[0]


# PARAMETERS

ntimes = 2
lon = 4
lat = 3
plev = 19
lev = 5

p0 = 1.e3
a_coeff = [0.1, 0.2, 0.3, 0.22, 0.1]
b_coeff = [0.0, 0.1, 0.2, 0.5, 0.8]

a_coeff_bnds = [0., .15, .25, .25, .16, 0.]
b_coeff_bnds = [0., .05, .15, .35, .65, 1.]


zlevs = numpy.array([.1, .3, .55, .7, .9])
zlev_bnds = numpy.array([0., .2, .42, .62, .8, 1.])

alats, bnds_lat, alons, bnds_lon, plevs = read_coords(lat, lon)

def init_cmor(pth, dataset_json):
ierr = cmor.setup(inpath=os.path.join(pth, "Test"),
netcdf_file_action=cmor.CMOR_REPLACE) #, logfile="CMOR.log")
ierr = cmor.dataset_json(os.path.join(pth, "Test", dataset_json))

def read_cmor_time_lat_lon():
ilat = cmor.axis(
table_entry='latitude',
units='degrees_north',
length=lat,
coord_vals=alats,
cell_bounds=bnds_lat)
print("ILAT:", ilat)
print(lon, alons, bnds_lon)
ilon = cmor.axis(
table_entry='longitude',
coord_vals=alons,
units='degrees_east',
cell_bounds=bnds_lon)

print("ILON:", ilon)


itim = cmor.axis(
table_entry="time",
units="days since 1850",
length=ntimes)
return itim, ilat, ilon
Loading

0 comments on commit 00fb6d2

Please sign in to comment.