Example #1
0
 def sequences(self):
     """Sequence declaration lines."""
     lines = Lines()
     lines.add(0, '@cython.final')
     lines.add(0, 'cdef class Sequences(object):')
     for subseqs in self.model.sequences:
         lines.add(
             1, 'cdef public %s %s' %
             (objecttools.classname(subseqs), subseqs.name))
     if getattr(self.model.sequences, 'states', None) is not None:
         lines.add(1, 'cdef public StateSequences old_states')
         lines.add(1, 'cdef public StateSequences new_states')
     for subseqs in self.model.sequences:
         print('        - %s' % subseqs.name)
         lines.add(0, '@cython.final')
         lines.add(
             0, 'cdef class %s(object):' % objecttools.classname(subseqs))
         for seq in subseqs:
             ctype = 'double' + NDIM2STR[seq.NDIM]
             if isinstance(subseqs, sequencetools.LinkSequences):
                 if seq.NDIM == 0:
                     lines.add(1, 'cdef double *%s' % seq.name)
                 elif seq.NDIM == 1:
                     lines.add(1, 'cdef double **%s' % seq.name)
                     lines.add(1, 'cdef public int len_%s' % seq.name)
             else:
                 lines.add(1, 'cdef public %s %s' % (ctype, seq.name))
             lines.add(1, 'cdef public int _%s_ndim' % seq.name)
             lines.add(1, 'cdef public int _%s_length' % seq.name)
             for idx in range(seq.NDIM):
                 lines.add(
                     1, 'cdef public int _%s_length_%d' % (seq.name, idx))
             if seq.NUMERIC:
                 ctype_numeric = 'double' + NDIM2STR[seq.NDIM + 1]
                 lines.add(
                     1, 'cdef public %s _%s_points' %
                     (ctype_numeric, seq.name))
                 lines.add(
                     1, 'cdef public %s _%s_results' %
                     (ctype_numeric, seq.name))
                 if isinstance(subseqs, sequencetools.FluxSequences):
                     lines.add(
                         1, 'cdef public %s _%s_integrals' %
                         (ctype_numeric, seq.name))
                     lines.add(1,
                               'cdef public %s _%s_sum' % (ctype, seq.name))
             if isinstance(subseqs, sequencetools.IOSequences):
                 lines.extend(self.iosequence(seq))
         if isinstance(subseqs, sequencetools.InputSequences):
             lines.extend(self.load_data(subseqs))
         if isinstance(subseqs, sequencetools.IOSequences):
             lines.extend(self.open_files(subseqs))
             lines.extend(self.close_files(subseqs))
             if not isinstance(subseqs, sequencetools.InputSequence):
                 lines.extend(self.save_data(subseqs))
         if isinstance(subseqs, sequencetools.LinkSequences):
             lines.extend(self.set_pointer(subseqs))
     return lines
Example #2
0
 def _convert_type(self, value):
     try:
         return self.type_(value)
     except BaseException:
         raise TypeError(
             'The value `%s` of type `%s` could not be converted to type '
             '`%s` of the instantaneous unit hydrograph parameter `%s`.' %
             (value, objecttools.classname(value),
              objecttools.classname(self.type_), self.name))
Example #3
0
 def _typeconversion(self, type_):
     if not self.NDIM:
         if isinstance(type_, type):
             return type_(self.value)
         else:
             attr = getattr(self.value, type_)
             try:
                 return attr()
             except TypeError:
                 return attr
     else:
         raise TypeError(
             'The %s instance `%s` is %d-dimensional and thus '
             'cannot be converted to a scalar %s value.'
             % (objecttools.classname(self), self.name,
                self.NDIM, objecttools.classname(type_)))
Example #4
0
 def __init__(self, *values):
     try:
         self._extractvalues(values)
     except BaseException:
         objecttools.augmentexcmessage(
             'While trying to initialize a `%s` object' %
             objecttools.classname(self))
Example #5
0
 def sequences(self):
     """Sequence declaration lines."""
     lines = Lines()
     for (name1, subseqs) in self.model.sequences:
         print('        - %s' % name1)
         lines.add(0, '@cython.final')
         lines.add(
             0, 'cdef class %s(object):' % objecttools.classname(subseqs))
         for (name2, seq) in subseqs:
             ctype = 'double' + NDIM2STR[seq.NDIM]
             if isinstance(subseqs, sequencetools.LinkSequences):
                 if seq.NDIM == 0:
                     lines.add(1, 'cdef double *%s' % name2)
                 elif seq.NDIM == 1:
                     lines.add(1, 'cdef double **%s' % name2)
                     lines.add(1, 'cdef public int len_%s' % name2)
             else:
                 lines.add(1, 'cdef public %s %s' % (ctype, name2))
             lines.add(1, 'cdef public int _%s_ndim' % name2)
             lines.add(1, 'cdef public int _%s_length' % name2)
             for idx in range(seq.NDIM):
                 lines.add(
                     1, 'cdef public int _%s_length_%d' % (seq.name, idx))
             if isinstance(subseqs, sequencetools.IOSubSequences):
                 lines.extend(self.iosequence(seq))
         if isinstance(subseqs, sequencetools.InputSequences):
             lines.extend(self.loaddata(subseqs))
         if isinstance(subseqs, sequencetools.IOSubSequences):
             lines.extend(self.openfiles(subseqs))
             lines.extend(self.closefiles(subseqs))
             if not isinstance(subseqs, sequencetools.InputSequence):
                 lines.extend(self.savedata(subseqs))
         if isinstance(subseqs, sequencetools.LinkSequences):
             lines.extend(self.setpointer(subseqs))
     return lines
Example #6
0
 def assignrepr(self, prefix='') -> str:
     """Return a |repr| string with a prefixed assignment."""
     with objecttools.repr_.preserve_strings(True):
         with hydpy.pub.options.ellipsis(2, optional=True):
             prefix += '%s(' % objecttools.classname(self)
             repr_ = objecttools.assignrepr_values(sorted(self.names),
                                                   prefix, 70)
             return repr_ + ')'
Example #7
0
 def _check_duplicate(fn2var, new_var, filename):
     for (reg_fn, reg_var) in fn2var.items():
         if (reg_fn != filename) and (reg_var == new_var):
             raise ValueError(
                 'You tried to allocate variable `{0!r}` to '
                 'filename `{1}`, but an equal `{2}` object has '
                 'already been allocated to filename `{3}`.'.format(
                     new_var, filename, objecttools.classname(new_var),
                     reg_fn))
Example #8
0
    def assignrepr(self, prefix):
        """Return a |repr| string with an prefixed assignement.

        Argument:
            * prefix(|str|): Usually something like 'x = '.
        """
        with objecttools.repr_.preserve_strings(True):
            with pub.options.ellipsis(2, optional=True):
                prefix += '%s(' % objecttools.classname(self)
                repr_ = objecttools.assignrepr_values(self.names, prefix, 70)
                return repr_ + ')'
Example #9
0
 def __repr__(self):
     parts = [objecttools.classname(self), '(']
     for (name, primpar) in sorted(self._primary_parameters.items()):
         value = primpar.__get__(self)
         if value is not None:
             parts.extend([name, '=', objecttools.repr_(value), ', '])
     if parts[-1] == ', ':
         parts[-1] = ')'
     else:
         parts.append(')')
     return ''.join(parts)
Example #10
0
 def parameters(self):
     """Parameter declaration lines."""
     lines = Lines()
     lines.add(0, '@cython.final')
     lines.add(0, 'cdef class Parameters(object):')
     for subpars in self.model.parameters:
         lines.add(
             1, 'cdef public %s %s' %
             (objecttools.classname(subpars), subpars.name))
     for subpars in self.model.parameters:
         print('        - %s' % subpars.name)
         lines.add(0, '@cython.final')
         lines.add(
             0, 'cdef class %s(object):' % objecttools.classname(subpars))
         for par in subpars:
             try:
                 ctype = TYPE2STR[par.TYPE] + NDIM2STR[par.NDIM]
             except KeyError:
                 ctype = par.TYPE + NDIM2STR[par.NDIM]
             lines.add(1, 'cdef public %s %s' % (ctype, par.name))
     return lines
Example #11
0
 def parameters(self):
     """Parameter declaration lines."""
     lines = Lines()
     for (name1, subpars) in self.model.parameters:
         print('        - %s' % name1)
         lines.add(0, '@cython.final')
         lines.add(
             0, 'cdef class %s(object):' % objecttools.classname(subpars))
         for (name2, par) in subpars:
             ctype = TYPE2STR[par.TYPE] + NDIM2STR[par.NDIM]
             lines.add(1, 'cdef public %s %s' % (ctype, name2))
     return lines
Example #12
0
 def modeldeclarations(self):
     """Attribute declarations of the model class."""
     lines = Lines()
     lines.add(0 ,'@cython.final')
     lines.add(0 ,'cdef class Model(object):')
     lines.add(1, 'cdef public int idx_sim')
     for things in (self.model.parameters, self.model.sequences):
         for (name, thing) in things:
             lines.add(1, 'cdef public %s %s'
                          % (objecttools.classname(thing), name))
     if getattr(self.model.sequences, 'states', None) is not None:
         lines.add(1, 'cdef public StateSequences old_states')
         lines.add(1, 'cdef public StateSequences new_states')
     return lines
Example #13
0
 def assignrepr(self, prefix: str) -> str:
     """Return a |repr| string with a prefixed assignment."""
     with objecttools.repr_.preserve_strings(True):
         with hydpy.pub.options.ellipsis(2, optional=True):
             with objecttools.assignrepr_tuple.always_bracketed(False):
                 classname = objecttools.classname(self)
                 blanks = ' ' * (len(prefix + classname) + 1)
                 nodestr = objecttools.assignrepr_tuple(
                     self.nodes.names, blanks + 'nodes=', 70)
                 elementstr = objecttools.assignrepr_tuple(
                     self.elements.names, blanks + 'elements=', 70)
                 return (f'{prefix}{classname}("{self.name}",\n'
                         f'{nodestr},\n'
                         f'{elementstr})')
Example #14
0
 def assignrepr(self, prefix):
     lines = []
     prefix += '%s(' % objecttools.classname(self)
     blanks = ' ' * len(prefix)
     names = sorted(self.names)
     for (idx, name) in enumerate(names):
         device = self[name]
         if idx == 0:
             lines.append(device.assignrepr(prefix))
         else:
             lines.append(device.assignrepr(blanks))
         lines[-1] += ','
     lines[-1] = lines[-1][:-1] + ')'
     return '\n'.join(lines)
Example #15
0
 def _setdateformat(self, dateformat):
     try:
         dateformat = str(dateformat)
     except BaseException:
         raise TypeError(
             'The given `dateformat` of type `%s` could not be converted '
             'to a `str` instance.' % objecttools.classname(dateformat))
     try:
         datetime.datetime(2000, 1, 1).strftime(dateformat)
     except BaseException:
         raise ValueError(
             "The given `dateformat` `%s` is not a valid format string "
             "for `datetime` objects.  Please read the documentation "
             "on module `datetime` of Python's the standard library "
             "for further information." % dateformat)
     self._dateformat = dateformat
Example #16
0
 def set_primary_parameters(self, **kwargs):
     """Set all primary parameters at once."""
     given = sorted(kwargs.keys())
     required = sorted(self._primary_parameters)
     if given == required:
         for (key, value) in kwargs.items():
             setattr(self, key, value)
     else:
         raise ValueError(
             'When passing primary parameter values as initialization '
             'arguments of the instantaneous unit hydrograph class `%s`, '
             'or when using method `set_primary_parameters, one has to '
             'to define all values at once via keyword arguments.  '
             'But instead of the primary parameter names `%s` the '
             'following keywords were given: %s.' %
             (objecttools.classname(self), ', '.join(required),
              ', '.join(given)))
Example #17
0
 def _checkname(self, name):
     """Raises an :class:`~exceptions.ValueError` if the given name is not
     a valid Python identifier.
     """
     exc = ValueError('For initializing `%s` objects, `value` is a '
                      'necessary function argument.  Principally, any '
                      'object is allowed that supports the Python build-in '
                      'function `str`.  But note that `str(value)` must '
                      'return a valid Python identifier (that does '
                      'not start with a number, that does not contain `-`, '
                      'that is not a Python keyword like `for`...).  The '
                      'given object returned the string `%s`, which is not '
                      'a valid Python identifier.' %
                      (objecttools.classname(self), name))
     try:
         exec('%s = None' % name)
     except SyntaxError:
         raise exc
     if name in dir(__builtins__):
         raise exc
Example #18
0
def trim(self, lower=None, upper=None):
    """Trim the value(s) of a |Variable| instance.

    One can pass the lower and/or the upper boundary as a function
    argument.  Otherwise, boundary values are taken from the class
    attribute `SPAN` of the given |Variable| instance, if available.

    Note that method |trim| works differently on |Variable| instances
    handling values of different types.  For floating point values,

    an actual trimming is performed.  Additionally, a warning message is
    raised if the trimming results in a change in value exceeding the
    threshold value defined by function |tolerance|.  (This warning
    message can be suppressed by setting the related option flag to False.)
    For integer values, instead of a warning an exception is raised.
    """
    span = getattr(self, 'SPAN', (None, None))
    if lower is None:
        lower = span[0]
    if upper is None:
        upper = span[1]
    type_ = getattr(self, 'TYPE', float)
    if type_ is float:
        if self.NDIM == 0:
            _trim_float_0d(self, lower, upper)
        else:
            _trim_float_nd(self, lower, upper)
    elif type_ is int:
        if self.NDIM == 0:
            _trim_int_0d(self, lower, upper)
        else:
            _trim_int_nd(self, lower, upper)
    elif type_ is bool:
        pass
    else:
        raise NotImplementedError(
            'Method `trim` can only be applied on parameters '
            'handling integer or floating point values, but '
            'value type of parameter `%s` is `%s`.'
            % (self.name, objecttools.classname(self.TYPE)))
Example #19
0
 def comparison_function(self, other):
     try:
         method = getattr(self.value, method_string)
     except AttributeError:
         # in Python 2.7, `int` (but not `float`) defines
         # `__cmp__` instead of rich comparisons
         method = getattr(float(self.value), method_string)
     try:
         if isinstance(other, abctools.VariableABC):
             result = method(other.value)
         else:
             result = method(other)
         if result is NotImplemented:
             return result
         try:
             return aggregation_func(result)
         except TypeError:
             return result
     except BaseException:
         objecttools.augment_excmessage(
             'While trying to compare variable `{0!r}` of '
             'element `{1}` with object `{2}` of type `{3}`'
             .format(self, objecttools.devicename(self),
                     other, objecttools.classname(other)))
Example #20
0
 def _arithmetic_exception(self, verb, other):
     objecttools.augment_excmessage(
         'While trying to %s %s instance `%s` and %s `%s`'
         % (verb, objecttools.classname(self), self.name,
            objecttools.classname(other), other))
Example #21
0
    def remove(self, *values):
        """Remove the defined variables.

        The variables to be removed can be selected in two ways.  But the
        first example shows that passing nothing or an empty iterable to
        method |Variable2Auxfile.remove| does not remove any variable:

        >>> from hydpy import dummies
        >>> v2af = dummies.v2af
        >>> v2af.remove()
        >>> v2af.remove([])
        >>> from hydpy import print_values
        >>> print_values(v2af.filenames)
        file1, file2
        >>> print_values(v2af.variables, width=30)
        eqb(5000.0), eqb(10000.0),
        eqd1(100.0), eqd2(50.0),
        eqi1(2000.0), eqi2(1000.0)

        The first option is to pass auxiliary file names:

        >>> v2af.remove('file1')
        >>> print_values(v2af.filenames)
        file2
        >>> print_values(v2af.variables)
        eqb(10000.0), eqd1(100.0), eqd2(50.0)

        The second option is, to pass variables of the correct type
        and value:

        >>> v2af = dummies.v2af
        >>> v2af.remove(v2af.eqb[0])
        >>> print_values(v2af.filenames)
        file1, file2
        >>> print_values(v2af.variables)
        eqb(10000.0), eqd1(100.0), eqd2(50.0), eqi1(2000.0), eqi2(1000.0)

        One can pass multiple variables or iterables containing variables
        at once:

        >>> v2af = dummies.v2af
        >>> v2af.remove(v2af.eqb, v2af.eqd1, v2af.eqd2)
        >>> print_values(v2af.filenames)
        file1
        >>> print_values(v2af.variables)
        eqi1(2000.0), eqi2(1000.0)

        Passing an argument that equals neither a registered file name or a
        registered variable results in the following exception:

        >>> v2af.remove('test')
        Traceback (most recent call last):
        ...
        ValueError: While trying to remove the given object `test` of type \
`str` from the actual Variable2AuxFile object, the following error occured:  \
`'test'` is neither a registered filename nor a registered variable.
        """
        for value in objecttools.extract(values, (str, abctools.VariableABC)):
            try:
                deleted_something = False
                for fn2var in list(self._type2filename2variable.values()):
                    for fn_, var in list(fn2var.items()):
                        if value in (fn_, var):
                            del fn2var[fn_]
                            deleted_something = True
                if not deleted_something:
                    raise ValueError(
                        ' `{0!r}` is neither a registered filename nor a '
                        'registered variable.'.format(value))
            except BaseException:
                objecttools.augment_excmessage(
                    'While trying to remove the given object `{0}` of type '
                    '`{1}` from the actual Variable2AuxFile object'.format(
                        value, objecttools.classname(value)))
Example #22
0
def reverse_model_wildcard_import() -> None:
    """Clear the local namespace from a model wildcard import.

    Calling this method should remove the critical imports into the local
    namespace due to the last wildcard import of a particular application
    model. In this manner, it secures the repeated preparation of different
    types of models via wildcard imports.  See the following example, on
    how it can be applied.

    >>> from hydpy import reverse_model_wildcard_import

    Assume you import the first version of HydPy-L-Land (|lland_v1|):

    >>> from hydpy.models.lland_v1 import *

    This import adds, for example, the collection class for handling control
    parameters of `lland_v1` into the local namespace:

    >>> print(ControlParameters(None).name)
    control

    Calling function |parameterstep| prepares, for example, the control
    parameter object of class |lland_control.NHRU|:

    >>> parameterstep('1d')
    >>> nhru
    nhru(?)

    Calling function |reverse_model_wildcard_import| tries to give its
    best to clear the local namespace (even from unexpected classes as
    the one we define now):

    >>> class Test:
    ...     __module__ = 'hydpy.models.lland_v1'
    >>> test = Test()

    >>> reverse_model_wildcard_import()

    >>> ControlParameters
    Traceback (most recent call last):
    ...
    NameError: name 'ControlParameters' is not defined

    >>> nhru
    Traceback (most recent call last):
    ...
    NameError: name 'nhru' is not defined

    >>> Test
    Traceback (most recent call last):
    ...
    NameError: name 'Test' is not defined

    >>> test
    Traceback (most recent call last):
    ...
    NameError: name 'test' is not defined
    """
    namespace = inspect.currentframe().f_back.f_locals
    model = namespace.get('model')
    if model is not None:
        for subpars in model.parameters:
            for par in subpars:
                namespace.pop(par.name, None)
                namespace.pop(objecttools.classname(par), None)
            namespace.pop(subpars.name, None)
            namespace.pop(objecttools.classname(subpars), None)
        for subseqs in model.sequences:
            for seq in subseqs:
                namespace.pop(seq.name, None)
                namespace.pop(objecttools.classname(seq), None)
            namespace.pop(subseqs.name, None)
            namespace.pop(objecttools.classname(subseqs), None)
        for name in ('parameters', 'sequences', 'masks', 'model', 'Parameters',
                     'Sequences', 'Masks', 'Model', 'cythonizer', 'cymodel',
                     'cythonmodule'):
            namespace.pop(name, None)
        for key in list(namespace.keys()):
            try:
                if namespace[key].__module__ == model.__module__:
                    del namespace[key]
            except AttributeError:
                pass
Example #23
0
    def plot(self,
             filename,
             width=None,
             height=None,
             selected=None,
             activated=None):
        """Save a bokeh html file plotting the current test results.

        (Optional) arguments:
            * filename: Name of the file.  If necessary, the file ending
              `html` is added automatically.  The file is stored in the
              `html` folder of subpackage `docs`.
            * width: Width of the plot in screen units.  Defaults to 600.
            * height: Height of the plot in screen units.  Defaults to 300.
            * selected: List of the sequences to be plotted.
            * activated: List of the sequences to be shown initially.
        """
        if width is None:
            width = self.plotting_options.width
        if height is None:
            height = self.plotting_options.height
        if not filename.endswith('.html'):
            filename += '.html'
        if selected is None:
            selected = self.plotting_options.selected
            if selected is None:
                selected = self.parseqs
        if activated is None:
            activated = self.plotting_options.activated
            if activated is None:
                activated = self.parseqs
        activated = tuple(nm_.name if hasattr(nm_, 'name') else nm_.lower()
                          for nm_ in activated)
        path = os.path.join(docs.__path__[0], 'html', filename)
        plotting.output_file(path)
        plot = plotting.figure(x_axis_type="datetime",
                               tools=['pan', 'ywheel_zoom'],
                               toolbar_location=None)
        plot.toolbar.active_drag = plot.tools[0]
        plot.toolbar.active_scroll = plot.tools[1]
        plot.plot_width = width
        plot.plot_height = height
        legend_entries = []
        viridis = palettes.viridis
        headers = [header for header in self.raw_header_strings[1:] if header]
        zipped = zip(selected, viridis(len(selected)), headers)
        for (seq, col, header) in zipped:
            series = seq.series.copy()
            if not seq.NDIM:
                listofseries = [series]
                listofsuffixes = ['']
            else:
                nmb = seq.shape[0]
                listofseries = [series[:, idx] for idx in range(nmb)]
                if nmb == 1:
                    listofsuffixes = ['']
                else:
                    listofsuffixes = ['-%d' % idx for idx in range(nmb)]
            for subseries, suffix in zip(listofseries, listofsuffixes):
                line = plot.line(self._datetimes,
                                 subseries,
                                 alpha=0.8,
                                 muted_alpha=0.0,
                                 line_width=2,
                                 color=col)
                line.muted = seq.name not in activated
                if header.strip() == seq.name:
                    title = objecttools.classname(seq)
                else:
                    title = header.capitalize()
                title += suffix
                legend_entries.append((title, [line]))
        legend = models.Legend(items=legend_entries, click_policy='mute')
        legend.border_line_color = None
        plot.add_layout(legend, 'right')
        units = self.extract_units(selected)
        ylabel = objecttools.enumeration(units).replace('and', 'or')
        plot.yaxis.axis_label = ylabel
        plot.yaxis.axis_label_text_font_style = 'normal'
        plotting.save(plot)
        self._src = filename
        self._width = width
        self._height = height
Example #24
0
    def search_modeltypes(self,
                          *models: ModelTypesArg,
                          name: str = 'modeltypes') -> 'Selection':
        """Return a |Selection| object containing only the elements
        currently handling models of the given types.

        >>> from hydpy.examples import prepare_full_example_2
        >>> hp, pub, _ = prepare_full_example_2()

        You can pass both |Model| objects and names and, as a keyword
        argument, the name of the newly created |Selection| object:

        >>> test = pub.selections.complete.copy('test')
        >>> from hydpy import prepare_model
        >>> hland_v1 = prepare_model('hland_v1')

        >>> test.search_modeltypes(hland_v1)
        Selection("modeltypes",
                  nodes=(),
                  elements=("land_dill", "land_lahn_1", "land_lahn_2",
                            "land_lahn_3"))
        >>> test.search_modeltypes(
        ...     hland_v1, 'hstream_v1', 'lland_v1', name='MODELTYPES')
        Selection("MODELTYPES",
                  nodes=(),
                  elements=("land_dill", "land_lahn_1", "land_lahn_2",
                            "land_lahn_3", "stream_dill_lahn_2",
                            "stream_lahn_1_lahn_2", "stream_lahn_2_lahn_3"))

        Wrong model specifications result in errors like the following:

        >>> test.search_modeltypes('wrong')
        Traceback (most recent call last):
        ...
        ModuleNotFoundError: While trying to determine the elements of \
selection `test` handling the model defined by the argument(s) `wrong` \
of type(s) `str`, the following error occurred: \
No module named 'hydpy.models.wrong'

        Method |Selection.select_modeltypes| restricts the current selection to
        the one determined with the method the |Selection.search_modeltypes|:

        >>> test.select_modeltypes(hland_v1)
        Selection("test",
                  nodes=(),
                  elements=("land_dill", "land_lahn_1", "land_lahn_2",
                            "land_lahn_3"))

        On the contrary, the method |Selection.deselect_upstream| restricts
        the current selection to all devices not determined by method the
        |Selection.search_upstream|:

        >>> pub.selections.complete.deselect_modeltypes(hland_v1)
        Selection("complete",
                  nodes=(),
                  elements=("stream_dill_lahn_2", "stream_lahn_1_lahn_2",
                            "stream_lahn_2_lahn_3"))
        """
        try:
            typelist = []
            for model in models:
                if not isinstance(model, modeltools.Model):
                    model = importtools.prepare_model(model)
                typelist.append(type(model))
            typetuple = tuple(typelist)
            selection = Selection(name)
            for element in self.elements:
                if isinstance(element.model, typetuple):
                    selection.elements += element
            return selection
        except BaseException:
            values = objecttools.enumeration(models)
            classes = objecttools.enumeration(
                objecttools.classname(model) for model in models)
            objecttools.augment_excmessage(
                f'While trying to determine the elements of selection '
                f'`{self.name}` handling the model defined by the '
                f'argument(s) `{values}` of type(s) `{classes}`')
Example #25
0
def reverse_model_wildcard_import():
    """Clear the local namespace from a model wildcard import.

    Calling this method should remove the critical imports into the local
    namespace due the last wildcard import of a certain application model.
    It is thought for securing the successive preperation of different
    types of models via wildcard imports.  See the following example, on
    how it can be applied.

    >>> from hydpy import reverse_model_wildcard_import

    Assume you wildcard import the first version of HydPy-L-Land (|lland_v1|):

    >>> from hydpy.models.lland_v1 import *

    This for example adds the collection class for handling control
    parameters of `lland_v1` into the local namespace:

    >>> print(ControlParameters(None).name)
    control

    Calling function |parameterstep| for example prepares the control
    parameter object |lland_control.NHRU|:

    >>> parameterstep('1d')
    >>> nhru
    nhru(-999999)

    Calling function |reverse_model_wildcard_import| removes both
    objects (and many more, but not all) from the local namespace:

    >>> reverse_model_wildcard_import()

    >>> ControlParameters
    Traceback (most recent call last):
    ...
    NameError: name 'ControlParameters' is not defined

    >>> nhru
    Traceback (most recent call last):
    ...
    NameError: name 'nhru' is not defined
    """
    namespace = inspect.currentframe().f_back.f_locals
    model = namespace.get('model')
    if model is not None:
        for subpars in model.parameters:
            for par in subpars:
                namespace.pop(par.name, None)
                namespace.pop(objecttools.classname(par), None)
            namespace.pop(subpars.name, None)
            namespace.pop(objecttools.classname(subpars), None)
        for subseqs in model.sequences:
            for seq in subseqs:
                namespace.pop(seq.name, None)
                namespace.pop(objecttools.classname(seq), None)
            namespace.pop(subseqs.name, None)
            namespace.pop(objecttools.classname(subseqs), None)
        for name in ('parameters', 'sequences', 'model', 'Parameters',
                     'Sequences', 'Model', 'cythonizer', 'cymodel',
                     'cythonmodule'):
            namespace.pop(name, None)
        for key in list(namespace.keys()):
            try:
                if namespace[key].__module__ == model.__module__:
                    del namespace[key]
            except AttributeError:
                pass
Example #26
0
 def _check_variable(self, variable):
     if self._model and (variable not in self._model.parameters.control):
         raise TypeError(
             'Variable type `{0}` is not handled by model `{1}`.'.format(
                 objecttools.classname(variable), self._model))