Beispiel #1
0
        def _expand_key(key, val):

            if type(val) in [dict, OrderedDict]:
                data_copy = val.copy() # a copy to iterate over while making changes in original dict
                for key_, val_ in data_copy.items():
                    val.pop(key_)
                    val[_expand_key(key_, val_)] = val_
            if has_expandable_var(key):
                    return _expand_case_var(key, defer_expansion=True)
            return key
Beispiel #2
0
    def infer_values(self, case):
        """ For a variable, if multiple values are provided in a value list, this function
            determines the appropriate value for the case by looking at guards
            to the left of values in yaml file and by comparing them against
            the xml variable of the case, e.g. OCN_GRID."""

        if not self._data:
            raise RuntimeError("Cannot apply the guards. No data found.")

        def _check_guard_satisfied(guard, case):
            " Checks if a given value guard agrees with the case settings."

            if has_expandable_var(guard):
                raise RuntimeError("The guard "+guard+" has an expandable case variable "+\
                                   "that couldn't be determined. Make sure that the expandable "+\
                                   "variable(s) is defined for this case configuration and that "
                                   "expand_case_vars is called before infer_values method.")
            else:
                guard_inferred = guard

            result = eval_formula(guard_inferred)
            assert type(result)==type(True), "Guard is not boolean: "+str(guard)
            return result

        def _do_determine_value(multi_option_dict):
            """ From an ordered dict (multi_option_dict), whose entries are alternative values
                with guards, returns the last entry whose guards are satisfied
                by the case"""

            assert _is_guarded_entry(multi_option_dict)
            assert type(multi_option_dict) in [dict, OrderedDict]

            val = None
            for value_guard in multi_option_dict:
                if value_guard == "else":
                    pass # for now
                elif is_logical_expr(value_guard):
                    if _check_guard_satisfied(value_guard, case):
                        val = multi_option_dict[value_guard]
                else: # invalid guard
                    print("Options:", multi_option_dict)
                    raise RuntimeError("Error while determining guards")

            # If no other guard evaluates to true, get the value prefixed by "else":
            if val==None and "else" in multi_option_dict:
                val = multi_option_dict["else"]

            if has_expandable_var(val):
                raise RuntimeError("Couldn't determine the value of the expanded variables ($) "
                                   "in the following entry of the param template file: "+val)

            return val
Beispiel #3
0
        def _expand_val(val):

            if type(val) in [dict, OrderedDict]:
                for key_, val_ in val.items():
                    val[key_] = _expand_val(val_)
            elif isinstance(val, list):
                pass
            else:
                if has_expandable_var(val):
                    val_eval = _expand_case_var(val, defer_expansion=True)
                    return val_eval

            return val
Beispiel #4
0
        def _check_guard_satisfied(guard, case):
            " Checks if a given value guard agrees with the case settings."

            if has_expandable_var(guard):
                raise RuntimeError("The guard "+guard+" has an expandable case variable "+\
                                   "that couldn't be determined. Make sure that the expandable "+\
                                   "variable(s) is defined for this case configuration and that "
                                   "expand_case_vars is called before infer_values method.")
            else:
                guard_inferred = guard

            result = eval_formula(guard_inferred)
            assert type(result)==type(True), "Guard is not boolean: "+str(guard)
            return result
Beispiel #5
0
        def _expand_case_var(entry, defer_expansion=False):
            """ Returns the version of an entry where cime parameters are expanded

            Parameters
            ----------
            entry: string
                A string that includes expandable case vars, e.g., $OCN_GRID. This
                string is either the key or the value of yaml entries, i.e., 'key': 'val'
            defer_expansion: bool
                If True, defer the expansion of expandable variables whose values cannot be
                determined. defer_expansion may be True for 'key' and 'val' entries, provided
                thay they are dropped after the 'key's, i.e., the guards are evaluated.
            """

            def is_cime_param(param_str):
                """ Returns True if the parameter to expand is a CIME parameter, e.g., OCN_GRID."""
                cime_param = case.get_value(param_str)
                if cime_param==None:
                    return False
                return True

            def aux_rps_param(param_str):
                """ Returns True if the parameter to expand is a variable in the given aux_rps_obj data."""
                assert (isinstance(aux_rps_obj, MOM_RPS))
                vals = search_nested_dict(aux_rps_obj._data, param_str)
                if len(vals) > 1:
                    raise RuntimeError("Multiple entries of "+param_str+" found in aux_rps_obj")
                elif len(vals) == 0:
                    return None
                else:
                    val = vals[0]
                    if "value" in val:
                        val = val['value']
                    assert not isinstance(val, str_type) or "$" not in val, \
                        "Nested expandable parameters detected when inferring "+entry
                    return str(val).strip()

            assert has_expandable_var(entry)
            str_type = get_str_type()

            # first, infer ${*}
            expandable_params = re.findall(r'\$\{.+?\}',entry)
            for word in expandable_params:
                expandable_param = word.replace("${","").replace("}","")
                param_expanded = None
                if is_cime_param(expandable_param):
                    param_expanded = case.get_value(expandable_param)
                elif aux_rps_obj!=None:
                    param_expanded = aux_rps_param(expandable_param)
                if param_expanded == None:
                    if defer_expansion==False:
                        raise RuntimeError("The param "+expandable_param+" is not a CIME xml"
                                           " variable for this case")
                    else:
                        param_expanded = word # do not expand this variable whose value couldn't
                                              # be found. This entry must later be dropped when
                                              # guards are evaluated.
                entry = entry.replace(word, str(param_expanded))

            # now infer $*
            for word in entry.split():
                if word[0] == '$':
                    expandable_param = word[1:]
                    param_expanded = None
                    if is_cime_param(expandable_param):
                        param_expanded = case.get_value(expandable_param)
                    elif aux_rps_obj!=None:
                        param_expanded = aux_rps_param(expandable_param)
                    if param_expanded == None:
                        if defer_expansion==False:
                            raise RuntimeError("The param "+expandable_param+" is not a CIME xml"
                                               " variable for this case")
                        else:
                            param_expanded = word # do not expand this variable whose value couldn't
                                                  # be found. This entry must later be dropped when
                                                  # guards are evaluated.

                    if isinstance(param_expanded,str_type):
                        param_expanded = '"'+param_expanded+'"'
                    entry = entry.replace(word,str(param_expanded))

            return entry