File: namespace.py

package info (click to toggle)
brian 2.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,872 kB
  • sloc: python: 51,820; cpp: 2,033; makefile: 108; sh: 72
file content (80 lines) | stat: -rw-r--r-- 2,327 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""
Implementation of the namespace system, used to resolve the identifiers in
model equations of `NeuronGroup` and `Synapses`
"""

import collections
import inspect
import itertools

from brian2.core.functions import DEFAULT_CONSTANTS, DEFAULT_FUNCTIONS
from brian2.units.fundamentalunits import (
    additional_unit_register,
    standard_unit_register,
)
from brian2.units.stdunits import stdunits
from brian2.utils.logger import get_logger

__all__ = [
    "get_local_namespace",
    "DEFAULT_FUNCTIONS",
    "DEFAULT_UNITS",
    "DEFAULT_CONSTANTS",
]

logger = get_logger(__name__)


def get_local_namespace(level):
    """
    Get the surrounding namespace.

    Parameters
    ----------
    level : int, optional
        How far to go back to get the locals/globals. Each function/method
        call should add ``1`` to this argument, functions/method with a
        decorator have to add ``2``.

    Returns
    -------
    namespace : dict
        The locals and globals at the given depth of the stack frame.
    """
    # Get the locals and globals from the stack frame
    frame = inspect.currentframe()
    for _ in range(level + 1):
        frame = frame.f_back
    # We return the full stack here, even if it contains a lot of stuff we are
    # not interested in -- it is cheaper to later raise an error when we find
    # a specific object with an incorrect type instead of going through this big
    # list now to check the types of all objects
    return dict(itertools.chain(frame.f_globals.items(), frame.f_locals.items()))


def _get_default_unit_namespace():
    """
    Return the namespace that is used by default for looking up units when
    defining equations. Contains all registered units and everything from
    `brian2.units.stdunits` (ms, mV, nS, etc.).

    Returns
    -------
    namespace : dict
        The unit namespace
    """
    namespace = collections.OrderedDict(standard_unit_register.units)
    namespace.update(stdunits)
    # Include all "simple" units from additional_units, i.e. units like mliter
    # but not "newton * metre"
    namespace.update(
        {
            name: unit
            for name, unit in additional_unit_register.units.items()
            if not unit.iscompound
        }
    )
    return namespace


DEFAULT_UNITS = _get_default_unit_namespace()