diff --git a/cime_config/SystemTests/fsurdatmodifyctsm.py b/cime_config/SystemTests/fsurdatmodifyctsm.py index 4b35475b65..9b4afeb0f7 100644 --- a/cime_config/SystemTests/fsurdatmodifyctsm.py +++ b/cime_config/SystemTests/fsurdatmodifyctsm.py @@ -4,7 +4,7 @@ import os import re -from subprocess import check_call +import subprocess from CIME.SystemTests.system_tests_common import SystemTestsCommon from CIME.XML.standard_module_setup import * from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files @@ -22,9 +22,6 @@ def __init__(self, case): if not os.path.exists(os.path.join(self._get_caseroot(), 'done_FSURDATMODIFYCTSM_setup.txt')): # Create out-of-the-box lnd_in to obtain fsurdat_in - # TODO next two lines mess up the python environment. - # Need to find the right way to run ncar_pylib before - # tool_path below case.create_namelists(component='lnd') # If fsurdat_in does not exist, download it from the # server @@ -69,19 +66,56 @@ def _create_config_file(self): def _run_modify_fsurdat(self): - """ - Run the tool similarly to what you did for the python system test - """ - - # Hardcode for cheyenne until we come up with a robust - # way of ensuring the correct python environment is loaded tool_path = os.path.join(self._ctsm_root, - 'tools/modify_fsurdat/fsurdat_modifier') - tool_command = tool_path + ' ' + self._cfg_file_path - check_call(tool_command, shell=True) + 'tools/modify_fsurdat/fsurdat_modifier') + + # Need to specify a specific python version that has the required dependencies + python_path = _get_python_path() + subprocess.check_call([python_path, tool_path, self._cfg_file_path]) def _modify_user_nl(self): append_to_user_nl_files(caseroot = self._get_caseroot(), component = "clm", contents = "fsurdat = '{}'".format(self._fsurdat_out)) + +def _get_python_path(): + """Get path to ncar_pylib's python on cheyenne + + This is needed because we need a python environment that includes xarray and its + dependencies. This is currently hard-coded for cheyenne until we come up with a robust + way in CIME of ensuring the correct python environment is loaded. + + """ + out = subprocess.check_output(['/glade/u/apps/opt/ncar_pylib/ncar_pylib', '-l'], + universal_newlines=True) + + # First look for a loaded ('L') python + path = _find_path_from_pylib_output(out, 'L') + # If no loaded python found, look for a default ('D') python + if path is None: + path = _find_path_from_pylib_output(out, 'D') + + if path is None: + raise RuntimeError('No python found') + + return os.path.join(path, 'bin', 'python') + +def _find_path_from_pylib_output(ncar_pylib_output, char): + """Given line-by-line output from ncar_pylib, return the path to python if found + + Args: + - ncar_pylib_output: line-by-line output from ncar_pylib + - char: the character to look for in the leading parenthetical expression (typically 'L' or 'D') + + Returns a path to python, or None if not found + """ + # The line of interest looks like the following (for char = 'L'): + # (L) ... /path/to/python + regex = r'\(' + char + r'\).* (/\S+)' + for line in ncar_pylib_output.splitlines(): + match_line = re.match(regex, line) + if match_line: + return match_line.group(1) + + return None