diff --git a/.gitignore b/.gitignore index c5eef823..d2aaf016 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ ilamb/ilamb reshaper/pyReshaper conformer/conformer mpi_utils/pyTools +ocean_remap/ocean_remap # Ignore python build and dist dirs cesm_utils/dist/ @@ -21,6 +22,7 @@ conform/dist/ diag_utils/dist/ diagnostics/dist/ timeseries/dist/ +ocean_remap/dist/ # Ignore cesm-env2 cesm-env2/ diff --git a/Externals.cfg b/Externals.cfg index aa1d1e17..007ec113 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -33,6 +33,13 @@ repo_url = https://bitbucket.org/ncollier/ilamb local_path = ilamb/ilamb required = True +[ocean_remap] +tag = master +protocol = git +repo_url = https://github.com/bertinia/ocean_remap +local_path = ocean_remap/ocean_remap +required = True + [externals_description] schema_version = 1.0.0 diff --git a/Machines/cheyenne_modules b/Machines/cheyenne_modules index 9d95165e..26b715ce 100755 --- a/Machines/cheyenne_modules +++ b/Machines/cheyenne_modules @@ -2,18 +2,19 @@ echo "Python boot-strap modules for machine cheyenne" -module load python/2.7.14 -module load intel/17.0.1 +module load python/2.7.16 +##module load intel/17.0.1 +module load gnu/8.3.0 module load ncarenv module load ncarcompilers module load mpt/2.19 -module load netcdf/4.6.1 -module load nco/4.7.4 -module load ncl/6.4.0 +module load netcdf/4.6.3 +module load nco/4.7.9 +module load ncl/6.6.2 # clone the ncat virtualenv first with helper script ncar_pylib # use "ncar_pylib --help" to see all options -ncar_pylib -c 20181024 ${pp_dir}/cesm-env2 +ncar_pylib -c 20190627 ${pp_dir}/cesm-env2 export PYTHONPATH=${pp_dir}/cesm-env2/lib/python2.7/site-packages diff --git a/Machines/dav_modules b/Machines/dav_modules index 5dc0672b..fd446245 100755 --- a/Machines/dav_modules +++ b/Machines/dav_modules @@ -2,18 +2,18 @@ echo "Python boot-strap modules for NCAR DAV" -module load python/2.7.14 +module load python/2.7.15 module load intel/17.0.1 module load ncarenv module load ncarcompilers module load impi module load netcdf/4.6.1 module load nco/4.7.4 -module load ncl/6.4.0 +module load ncl/6.6.2 # clone the ncat virtualenv first with helper script ncar_pylib # use "ncar_pylib --help" to see all options -ncar_pylib -c 20181029 ${pp_dir}/cesm-env2 +ncar_pylib -c 20190326 ${pp_dir}/cesm-env2 export PYTHONPATH=${pp_dir}/cesm-env2/lib/python2.7/site-packages diff --git a/Machines/machine_postprocess.xml b/Machines/machine_postprocess.xml index 3e64b060..e052c697 100644 --- a/Machines/machine_postprocess.xml +++ b/Machines/machine_postprocess.xml @@ -5,6 +5,7 @@ 64 64 + 32 srun f2py @@ -24,7 +25,7 @@ module load impi module load netcdf/4.6.1 module load nco/4.7.4 - module load ncl/6.4.0 + module load ncl/6.6.2 @@ -126,26 +127,27 @@ 144 64 + 32 mpiexec_mpt dplace -s 1 f2py - ifort + gfortran -c -g -O2 - -I/glade/u/apps/ch/opt/netcdf/4.6.1/intel/17.0.1/include - -L/glade/u/apps/ch/opt/netcdf/4.6.1/intel/17.0.1/lib -lnetcdff -lnetcdf + -I/glade/u/apps/ch/opt/netcdf/4.6.3/gnu/8.3.0/include + -L/glade/u/apps/ch/opt/netcdf/4.6.3/gnu/8.3.0/lib -lnetcdff -lnetcdf module purge - module load intel/17.0.1 + module load gnu/8.3.0 module load ncarenv module load ncarcompilers module load mpt/2.19 - module load netcdf/4.6.1 - module load nco/4.7.4 - module load ncl/6.4.0 + module load netcdf/4.6.3 + module load nco/4.7.9 + module load ncl/6.6.2 diff --git a/Machines/machine_postprocess.xsd b/Machines/machine_postprocess.xsd index d2765b71..26aecb3d 100644 --- a/Machines/machine_postprocess.xsd +++ b/Machines/machine_postprocess.xsd @@ -38,6 +38,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -158,6 +186,8 @@ + + diff --git a/Makefile b/Makefile index 4f842b11..da5cf6b3 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,8 @@ SUBDIRS = \ conformer \ conform \ ilamb \ - diagnostics + diagnostics \ + ocean_remap # MAKECMDGOALS is the make option: make 'clobber' or 'all' TARGET = $(MAKECMDGOALS) diff --git a/Tools/copy_html b/Tools/copy_html index d292b0a9..025fc139 100755 --- a/Tools/copy_html +++ b/Tools/copy_html @@ -261,6 +261,10 @@ def read_paths(env, comp_data): env[values[-2]].append(values[-1]) else: env[values[-2]] = [] + + if 'OCNDIAG_WEBDIR' not in env: + env['OCNDIAG_WEBDIR'] = list() + return env diff --git a/Tools/ration_script b/Tools/ration_script index b12b24c7..ac7ba3f2 100755 --- a/Tools/ration_script +++ b/Tools/ration_script @@ -23,8 +23,7 @@ pwd . activate ## load the boot-strap modules -##module load python/2.7.14 -module load intel/17.0.1 +module load gnu/8.3.0 module load ncarenv module load ncarcompilers module load mpt/2.19 diff --git a/cesm_utils/cesm_utils/create_postprocess b/cesm_utils/cesm_utils/create_postprocess index 4ba8749a..244f7fea 100755 --- a/cesm_utils/cesm_utils/create_postprocess +++ b/cesm_utils/cesm_utils/create_postprocess @@ -280,7 +280,8 @@ def read_machine_xml(machineName, xmlFile): if machineName.lower() == xmlmachine.get('name').lower(): found = True - # get the timeseries pes first + + # get the timeseries pes tseries_pes = xmlmachine.find('timeseries_pes') machine['timeseries_pes'] = tseries_pes.text machine['timeseries_queue'] = '' @@ -295,7 +296,6 @@ def read_machine_xml(machineName, xmlFile): if 'memory' in tseries_pes.attrib: machine['timeseries_memory'] = tseries_pes.get('memory') - # get the conform pes xconform_pes = xmlmachine.find('xconform_pes') machine['xconform_pes'] = xconform_pes.text @@ -311,6 +311,21 @@ def read_machine_xml(machineName, xmlFile): if 'memory' in xconform_pes.attrib: machine['conform_memory'] = xconform_pes.get('memory') + # get the ocn_remap pes + ocn_remap_pes = xmlmachine.find('ocn_remap_pes') + machine['ocn_remap_pes'] = ocn_remap_pes.text + machine['ocn_remap_queue'] = '' + if 'queue' in ocn_remap_pes.attrib: + machine['ocn_remap_queue'] = ocn_remap_pes.get('queue').lower() + machine['ocn_remap_ppn'] = ocn_remap_pes.get('pes_per_node').lower() + machine['ocn_remap_wallclock'] = ocn_remap_pes.get('wallclock').lower() + machine['ocn_remap_nodes'] = '' + if 'nodes' in ocn_remap_pes.attrib: + machine['ocn_remap_nodes'] = ocn_remap_pes.get('nodes').lower() + machine['ocn_remap_memory'] = '' + if 'memory' in ocn_remap_pes.attrib: + machine['ocn_remap_memory'] = ocn_remap_pes.get('memory') + # get the mpi run command machine['mpi_command'] = xmlmachine.find('mpi_command').text @@ -685,6 +700,13 @@ def main(options): create_env_file(envDict=envDict, configFile=config_file, tmplFile=tmpl_file, envFile=env_file, obs_root='', comp='', standalone=standalone) + # generate the env_ocn_remap.xml file + config_file = '{0}/diagnostics/diagnostics/ocn/Config/config_ocn_remap.xml'.format(envDict['POSTPROCESS_PATH']) + env_file = '{0}/env_ocn_remap.xml'.format(envDict['PP_CASE_PATH']) + tmpl_file = 'env_postprocess.tmpl' + create_env_file(envDict=envDict, configFile=config_file, tmplFile=tmpl_file, + envFile=env_file, obs_root='', comp='', standalone=standalone) + # generate the env_diags_[component].xml files for comp in itertools.chain(compList, imbList): dir_name = comp @@ -769,6 +791,30 @@ def main(options): memory=machine['conform_memory'], options=options, standalone=standalone) + # generate the ocn_remap batch submit script from template files + postProcessCmd = 'ocn_remap_generator.py' + processName = 'ocn_remap' + outFile = '{0}/{1}'.format(envDict['PP_CASE_PATH'],processName) + ocn_remap_tmpl = 'postprocess.tmpl' + create_batch(ppDir=envDict['POSTPROCESS_PATH'], + pes=machine['ocn_remap_pes'], + batchTmpl=batch_tmpl, runTmpl=ocn_remap_tmpl, + postProcessCmd=postProcessCmd, + mpiCmd=machine['mpi_command'], outFile=outFile, + processName=processName, + project=envDict['PROJECT'], + pythonpath=machine['pythonpath'], + caseRoot=envDict['PP_CASE_PATH'], + reset_modules=machine['reset_modules'], + modules=machine['modules'], + queue=machine['ocn_remap_queue'], + ppn=machine['ocn_remap_ppn'], + nodes=machine['ocn_remap_nodes'], + wallclock=machine['ocn_remap_wallclock'], + memory=machine['ocn_remap_memory'], + options=options, standalone=standalone) + + # generate the diagnostics batch submit scripts from template files for comp in compList: # generate the averages batch submit script @@ -980,6 +1026,28 @@ def main(options): memory=machine['conform_memory'], options=options, standalone=standalone) + # generate the ocn_remap batch submit script from template files + postProcessCmd = 'ocn_remap_generator.py' + processName = 'ocn_remap_dav' + outFile = '{0}/{1}'.format(envDict['PP_CASE_PATH'],processName) + create_batch(ppDir=pp_dav, + pes=machine['ocn_remap_pes'], + batchTmpl=batch_tmpl, runTmpl=run_tmpl, + postProcessCmd=postProcessCmd, + mpiCmd=machine['mpi_command'], outFile=outFile, + processName=processName, + project=envDict['PROJECT'], + pythonpath=machine['pythonpath'], + caseRoot=envDict['PP_CASE_PATH'], + reset_modules=machine['reset_modules'], + modules=machine['modules'], + queue=machine['ocn_remap_queue'], + ppn=machine['ocn_remap_ppn'], + nodes=machine['ocn_remap_nodes'], + wallclock=machine['ocn_remap_wallclock'], + memory=machine['ocn_remap_memory'], + options=options, standalone=standalone) + # generate the diagnostics batch submit scripts from template files for comp in compList: # generate the averages batch submit script diff --git a/diagnostics/diagnostics/ocn/Config/config_ocn_remap.xml b/diagnostics/diagnostics/ocn/Config/config_ocn_remap.xml new file mode 100644 index 00000000..ac941e6f --- /dev/null +++ b/diagnostics/diagnostics/ocn/Config/config_ocn_remap.xml @@ -0,0 +1,70 @@ + + + + + + + 0 + Settings for controlling ocean remapping of CMIP6 variables. + + + + + + + + + + + + + + + + + + + + diff --git a/diagnostics/diagnostics/ocn/ocn_remap_generator.py b/diagnostics/diagnostics/ocn/ocn_remap_generator.py new file mode 100755 index 00000000..7814ccac --- /dev/null +++ b/diagnostics/diagnostics/ocn/ocn_remap_generator.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python +# This wrapper script calls the ocean_remap class to remap CESM CMIP6 conformed variables +# on the native 1-degree Greenland displace pole grid (gx1v7) to a regular lat-lon grid. + +from __future__ import print_function +import sys + +# check the system python version and require 2.7.x or greater +if sys.hexversion < 0x02070000: + print(70 * '*') + print('ERROR: {0} requires python >= 2.7.x. '.format(sys.argv[0])) + print('It appears that you are running python {0}'.format( + '.'.join(str(x) for x in sys.version_info[0:3]))) + print(70 * '*') + sys.exit(1) + +import argparse +import glob, sys, os, fnmatch +import netCDF4 as nc + +from asaptools import partition, simplecomm, vprinter, timekeeper +from cesm_utils import cesmEnvLib +from diag_utils import diagUtilsLib + +from ocean_remap import ocean_remap as remap + + +#===================================================== +# commandline_options - parse any command line options +#===================================================== +def commandline_options(): + """Process the command line arguments. + """ + parser = argparse.ArgumentParser( + description='ocn_remap_generator: CESM wrapper python program for ocean remap package.') + + parser.add_argument('--backtrace', action='store_true', + help='show exception backtraces as extra debugging ' + 'output') + + parser.add_argument('--debug', nargs=1, required=False, type=int, default=0, + help='debugging verbosity level output: 0 = none, 1 = minimum, 2 = maximum. 0 is default') + + parser.add_argument('--caseroot', nargs=1, required=True, + help='fully quailfied path to case root directory') + + parser.add_argument('--standalone', action='store_true', + help='switch to indicate stand-alone post processing caseroot') + + options = parser.parse_args() + + # check to make sure CASEROOT is a valid, readable directory + if not os.path.isdir(options.caseroot[0]): + err_msg = ' ERROR: ocn_remap_generator.py invalid option --caseroot {0}'.format(options.caseroot[0]) + raise OSError(err_msg) + + return options + +#====== +# main +#====== + +def main(options, main_comm, debugMsg): + """ + read env_ocn_remap.xml settings to call the ocean_remap class + """ + # initialize the environment dictionary + envDict = dict() + + + # Get rank and size + rank = main_comm.get_rank() + size = main_comm.get_size() + + # CASEROOT is given on the command line as required option --caseroot + if rank == 0: + caseroot = options.caseroot[0] + envDict['CASEROOT'] = options.caseroot[0] + debugMsg('caseroot = {0}'.format(envDict['CASEROOT']), header=True, verbosity=2) + + env_file_list = ['./env_postprocess.xml', './env_ocn_remap.xml'] + envDict = cesmEnvLib.readXML(caseroot, env_file_list) + + # strip the OCNREMAP_ prefix from the envDict entries before setting the + # enviroment to allow for compatibility with all the diag routine calls + envDict = diagUtilsLib.strip_prefix(envDict, 'OCNREMAP_') + + print ("cmip6: {0}".format(envDict['cmip6'])) + print ("filelist: {0}".format(envDict['filelist'])) + print ("matrix_2d_fname: {0}".format(envDict['matrix_2d_fname'])) + print ("matrix_3d_fname: {0}".format(envDict['matrix_3d_fname'])) + print ("indir: {0}".format(envDict['indir'])) + print ("outdir: {0}".format(envDict['outdir'])) + print ("chunk size: {0}".format(envDict['chunk'])) + + # broadcast envDict to all tasks + envDict = main_comm.partition(data=envDict, func=partition.Duplicate(), involved=True) + main_comm.sync() + + files = [] + if rank == 0: + # Find files to regrid + #Do we have a cmip6 variable list? + if envDict['cmip6'] is not None: + if envDict['indir'] is not None: + with open(envDict['cmip6']) as f: + for l in f: + t = l.strip().split(':')[0] + v = l.strip().split(':')[1] + print ("Trying to find: {0}_{1}*.nc".format(v,t)) + for root, dirs, fns in os.walk(envDict['indir']): + for fn in fnmatch.filter(fns, v+'_'+t+"*.nc"): + if 'tmp.nc' not in fn and 'gr' not in fn.split('_'): + print ("Found: {0}".format(fn.split('/'))) + files.append(os.path.join(root, fn)) + else: + print ("You need to specify an indir argument with the cmip6 argument") + file = None + elif envDict['filelist'] is not None: + with open(envDict['filelist']) as f: + for l in f: + files.append(l.strip()) + elif envDict['indir'] is not None: + for root, dirs, fns in os.walk(envDict['indir']): + for fn in fnmatch.filter(fns, "*.nc"): + files.append(os.path.join(root, fn)) + else: + print ('Exiting because no input path or files where given') + files = None + + # All call this + main_comm.sync() + files = main_comm.partition(files, func=partition.Duplicate(), involved=True) + if files is None: + sys.exit() + + #matrix_2d_fname = 'POP_gx1v7_to_latlon_1x1_0E_mask_conserve_20181015.nc' + matrix_2d = remap.ocean_remap(envDict['matrix_2d_fname']) + + #matrix_3d_fname = 'POP_gx1v7_to_latlon_1x1_0E_fulldepth_conserve_20181015.nc' + matrix_3d = remap.ocean_remap(envDict['matrix_3d_fname']) + + # names of coordinate dimensions in output files + dim_names = {'depth': 'olevel', 'lat': 'latitude', 'lon': 'longitude'} + dim_names = {'depth': 'lev', 'lat': 'lat', 'lon': 'lon'} + + main_comm.sync() + # Have only root create these files + if rank == 0: + if len(files) > 0 and envDict['cmip6'] is not None: + temp = files[0] + # create CMIP Ofx files + for var_name in ('areacello', 'deptho', 'thkcello', 'volcello'): + new_outdir = temp.replace(temp.split('/')[-4],var_name).replace(temp.split('/')[-5],'Ofx').replace(temp.split('/')[-3],'gr').replace('_'+temp.split('_')[-1],'')+'.nc' + d = os.path.dirname(new_outdir) + if not os.path.exists(d): + os.makedirs(d) + fptr_out = nc.Dataset(new_outdir, 'w') # pylint: disable=E1101 + matrix_3d.dst_grid.def_dims_common(fptr_out, dim_names) + matrix_3d.dst_grid.write_vars_common(fptr_out, dim_names) + matrix_3d.dst_grid.write_var_CMIP_Ofx(fptr_out, dim_names, var_name) + + # Create a master slave parallel protocol + GWORK_TAG = 10 # global comm mpi tag + if (rank == 0): + for i in files: + main_comm.ration(data=i, tag=GWORK_TAG) + for i in range(1,size): + main_comm.ration(data=-99, tag=GWORK_TAG) + else: + f = -999 + while f != -99: + f = main_comm.ration(tag=GWORK_TAG) + if f != -99: + print ("working on: {0}".format(f)) + testfile_in_fname = f + testfile_out_fname = f.replace(f.split('/')[-3],'gr') + if not os.path.exists(testfile_out_fname): + d = os.path.dirname(testfile_out_fname) + if not os.path.exists(d): + os.makedirs(d) + fptr_in = nc.Dataset(testfile_in_fname, 'r') # pylint: disable=E1101 + if (len(fptr_in[f.split('/')[-4]].dimensions) == 4 or len(fptr_in[f.split('/')[-4]].dimensions) == 3): + fptr_out = nc.Dataset(testfile_out_fname+'.tmp', 'w') # pylint: disable=E1101 + + remap.copy_time(fptr_in, fptr_out) + remap.copy_gAttr(fptr_in, fptr_out) + + if dim_names['depth'] in fptr_in.dimensions: + matrix_3d.dst_grid.def_dims_common(fptr_out, dim_names) + matrix_3d.dst_grid.write_vars_common(fptr_out, dim_names) + else: + matrix_2d.dst_grid.def_dims_common(fptr_out, dim_names) + matrix_2d.dst_grid.write_vars_common(fptr_out, dim_names) + + field_names = [] + for v in fptr_in.variables: + if v not in ['lat', 'lat_bnds', 'lon', 'lon_bnds', 'lev', 'lev_bnds', 'time', 'time_bnds', 'nlat', 'nlon']: + field_names.append(v) + + for field_name in field_names: + + varid_out = remap.def_var(field_name, fptr_in, fptr_out, dim_names) + + # use appropriate matrix for regridding + c = envDict['chunk'] + if c is None: + c = 1 + else: + c = int(c) + try: + if dim_names['depth'] in varid_out.dimensions: + #print ("Running a 3D variable") + b = 0 + for i in range(0,fptr_in.dimensions['time'].size,c): + if b+c >= fptr_in.dimensions['time'].size: + c = fptr_in.dimensions['time'].size - b + varid_out[b:(b+c),:,:,:] = matrix_3d.remap_var(fptr_in.variables[field_name][b:(b+c),:,:,:])#, + #fill_value=getattr(varid_out, 'missing_value')) + b = b+c + else: + #print ("Running a 2D variable") + b = 0 + for i in range(0,fptr_in.dimensions['time'].size,c): + if b+c >= fptr_in.dimensions['time'].size: + c = fptr_in.dimensions['time'].size - b + varid_out[b:(b+c),:,:] = matrix_2d.remap_var(fptr_in.variables[field_name][b:(b+c),:,:])#, + #fill_value=getattr(varid_out, 'missing_value')) + b = b+c + except TypeError as e: + print ('Type Error for variable {0} '.format(field_name)) + fptr_in.close() + fptr_out.close() + try: + os.rename(testfile_out_fname+'.tmp',testfile_out_fname) + except OSError as e: + print ('Could not create {0}'.format(testfile_out_fname)) + else: + print ("Not creating {0}".format(testfile_out_fname)) + main_comm.sync() + +#=================================================================================================== +if __name__ == "__main__": + # initialize simplecomm object + main_comm = simplecomm.create_comm(serial=False) + + # setup an overall timer + timer = timekeeper.TimeKeeper() + + # get commandline options + options = commandline_options() + + # initialize global vprinter object for printing debug messages + if options.debug: + header = "[" + str(main_comm.get_rank()) + "/" + str(main_comm.get_size()) + "]: DEBUG... " + debugMsg = vprinter.VPrinter(header=header, verbosity=options.debug[0]) + + try: + timer.start("Total Time") + status = main(options, main_comm, debugMsg) + main_comm.sync() + timer.stop("Total Time") + if main_comm.is_manager(): + print('***************************************************') + print('Total Time: {0} seconds'.format(timer.get_time("Total Time"))) + print('Successfully completed generating ocean remapped files') + print('***************************************************') + sys.exit(status) + + except Exception as error: + print(str(error)) + if options.backtrace: + traceback.print_exc() + sys.exit(1) + + diff --git a/diagnostics/setup.py b/diagnostics/setup.py index 599d32da..cc46738d 100644 --- a/diagnostics/setup.py +++ b/diagnostics/setup.py @@ -55,7 +55,7 @@ def get_dependencies(): 'diagnostics/ice/ice_diags_generator.py','diagnostics/ice/ice_avg_generator.py', 'diagnostics/lnd/lnd_diags_generator.py','diagnostics/lnd/lnd_avg_generator.py', 'diagnostics/imb/imb_diags_generator.py', 'diagnostics/imb/imb_initialize.py', - 'diagnostics/lnd/lnd_regrid_generator.py'], + 'diagnostics/lnd/lnd_regrid_generator.py', 'diagnostics/ocn/ocn_remap_generator.py'], install_requires=get_requires(), #dependency_links=get_dependencies(), include_package_data=True, diff --git a/ocean_remap/Makefile b/ocean_remap/Makefile new file mode 100644 index 00000000..a58932a1 --- /dev/null +++ b/ocean_remap/Makefile @@ -0,0 +1,30 @@ +all : develop + +test : FORCE + python -m unittest discover --start-directory test + +develop : FORCE + python setup.py $@ + +install : FORCE + python setup.py $@ + +clean : + -rm -f *~ *.CKP *.ln *.BAK *.bak .*.bak \ + core errs \ + ,* .emacs_* \ + tags TAGS \ + make.log MakeOut \ + *.tmp tmp.txt + +# +# clobber - Really clean up the directory. +# +clobber : clean + -rm -f .Makedepend *.o *.mod *.il *.pyc + -rm -rf *.egg-info build + +# +# FORCE - Null rule to force things to happen. +# +FORCE : diff --git a/ocean_remap/VERSION b/ocean_remap/VERSION new file mode 100644 index 00000000..1821d33c --- /dev/null +++ b/ocean_remap/VERSION @@ -0,0 +1 @@ +0.1.0.dev0 diff --git a/ocean_remap/setup.py b/ocean_remap/setup.py new file mode 100644 index 00000000..48d9eef2 --- /dev/null +++ b/ocean_remap/setup.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# based on template example from: +# https://github.com/hcarvalhoalves/python-package-template +# + +from setuptools import setup, find_packages + +import sys +import os + +BASE_LOCATION = os.path.abspath(os.path.dirname(__file__)) + +VERSION_FILE = 'VERSION' +REQUIRES_FILE = 'requirements.txt' +DEPENDENCIES_FILE = 'requirements_links.txt' + + +def readfile(filename, func): + try: + with open(os.path.join(BASE_LOCATION, filename)) as f: + data = func(f) + except (IOError, IndexError): + sys.stderr.write(u""" +Unable to open file: {0} +For development run: + make version + setup.py develop +To build a valid release, run: + make release +""".format(filename)) + sys.exit(1) + return data + + +def get_version(): + return readfile(VERSION_FILE, lambda f: f.read().strip()) + + +def get_requires(): + return readfile(REQUIRES_FILE, lambda f: f.read().strip()) + + +def get_dependencies(): + return readfile(DEPENDENCIES_FILE, lambda f: f.read().strip()) + +setup( + name="ocean_remap", + author="Keith Lindsay", + author_email="klindsay@ucar.edu", + packages=['ocean_remap'], + version=get_version(), + #scripts=[], + #install_requires=get_requires(), + #dependency_links=get_dependencies(), + include_package_data=True, + zip_safe=True, + #test_suite="timeseries.tests", + description="CESM2 CMIP6 Ocean file remapping tool.", + use_2to3=True +) diff --git a/timeseries/timeseries/cesm_tseries_generator.py b/timeseries/timeseries/cesm_tseries_generator.py index 41b1a761..cd1e988e 100755 --- a/timeseries/timeseries/cesm_tseries_generator.py +++ b/timeseries/timeseries/cesm_tseries_generator.py @@ -70,7 +70,7 @@ def commandline_options(): err_msg = 'cesm_tseries_generator.py ERROR: invalid option --caseroot {0}'.format(options.caseroot[0]) raise OSError(err_msg) - return options.caseroot[0], options.debug, options.standalone, options.backtrace + return options.caseroot[0], options.debug[0], options.standalone, options.backtrace #============================================================================================== # readArchiveXML - read the $CASEROOT/env_timeseries.xml file and build the pyReshaper classes